dialog_bot_ruby 0.8.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.rubocop.yml +18 -0
- data/.rubocop_todo.yml +13 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +68 -0
- data/Gemfile +3 -0
- data/LICENSE +14 -0
- data/README.md +197 -0
- data/Rakefile +15 -0
- data/bin/console +6 -0
- data/bin/setup +5 -0
- data/dialog_bot_ruby.gemspec +32 -0
- data/examples/bot.rb +17 -0
- data/lib/telegram/bot/adapters/socks5.rb +24 -0
- data/lib/telegram/bot/api.rb +172 -0
- data/lib/telegram/bot/client.rb +77 -0
- data/lib/telegram/bot/configuration.rb +11 -0
- data/lib/telegram/bot/exceptions/base.rb +7 -0
- data/lib/telegram/bot/exceptions/response_error.rb +32 -0
- data/lib/telegram/bot/exceptions.rb +2 -0
- data/lib/telegram/bot/null_logger.rb +11 -0
- data/lib/telegram/bot/types/animation.rb +13 -0
- data/lib/telegram/bot/types/audio.rb +14 -0
- data/lib/telegram/bot/types/base.rb +10 -0
- data/lib/telegram/bot/types/callback_game.rb +8 -0
- data/lib/telegram/bot/types/callback_query.rb +15 -0
- data/lib/telegram/bot/types/chat.rb +22 -0
- data/lib/telegram/bot/types/chat_member.rb +24 -0
- data/lib/telegram/bot/types/chat_photo.rb +10 -0
- data/lib/telegram/bot/types/chosen_inline_result.rb +15 -0
- data/lib/telegram/bot/types/compactable.rb +26 -0
- data/lib/telegram/bot/types/contact.rb +13 -0
- data/lib/telegram/bot/types/document.rb +13 -0
- data/lib/telegram/bot/types/encrypted_credentials.rb +11 -0
- data/lib/telegram/bot/types/encrypted_passport_element.rb +16 -0
- data/lib/telegram/bot/types/file.rb +11 -0
- data/lib/telegram/bot/types/force_reply.rb +10 -0
- data/lib/telegram/bot/types/game.rb +14 -0
- data/lib/telegram/bot/types/game_high_score.rb +11 -0
- data/lib/telegram/bot/types/inline_keyboard_button.rb +15 -0
- data/lib/telegram/bot/types/inline_keyboard_markup.rb +20 -0
- data/lib/telegram/bot/types/inline_query.rb +15 -0
- data/lib/telegram/bot/types/inline_query_result_article.rb +19 -0
- data/lib/telegram/bot/types/inline_query_result_audio.rb +17 -0
- data/lib/telegram/bot/types/inline_query_result_cached_audio.rb +14 -0
- data/lib/telegram/bot/types/inline_query_result_cached_document.rb +16 -0
- data/lib/telegram/bot/types/inline_query_result_cached_gif.rb +15 -0
- data/lib/telegram/bot/types/inline_query_result_cached_mpeg4_gif.rb +15 -0
- data/lib/telegram/bot/types/inline_query_result_cached_photo.rb +16 -0
- data/lib/telegram/bot/types/inline_query_result_cached_sticker.rb +13 -0
- data/lib/telegram/bot/types/inline_query_result_cached_video.rb +16 -0
- data/lib/telegram/bot/types/inline_query_result_cached_voice.rb +15 -0
- data/lib/telegram/bot/types/inline_query_result_contact.rb +19 -0
- data/lib/telegram/bot/types/inline_query_result_document.rb +20 -0
- data/lib/telegram/bot/types/inline_query_result_game.rb +12 -0
- data/lib/telegram/bot/types/inline_query_result_gif.rb +19 -0
- data/lib/telegram/bot/types/inline_query_result_location.rb +18 -0
- data/lib/telegram/bot/types/inline_query_result_mpeg4_gif.rb +19 -0
- data/lib/telegram/bot/types/inline_query_result_photo.rb +19 -0
- data/lib/telegram/bot/types/inline_query_result_venue.rb +20 -0
- data/lib/telegram/bot/types/inline_query_result_video.rb +21 -0
- data/lib/telegram/bot/types/inline_query_result_voice.rb +16 -0
- data/lib/telegram/bot/types/input_contact_message_content.rb +12 -0
- data/lib/telegram/bot/types/input_location_message_content.rb +10 -0
- data/lib/telegram/bot/types/input_media_photo.rb +11 -0
- data/lib/telegram/bot/types/input_media_video.rb +14 -0
- data/lib/telegram/bot/types/input_message_content.rb +8 -0
- data/lib/telegram/bot/types/input_text_message_content.rb +11 -0
- data/lib/telegram/bot/types/input_venue_message_content.rb +13 -0
- data/lib/telegram/bot/types/invoice.rb +13 -0
- data/lib/telegram/bot/types/keyboard_button.rb +11 -0
- data/lib/telegram/bot/types/labeled_price.rb +10 -0
- data/lib/telegram/bot/types/location.rb +10 -0
- data/lib/telegram/bot/types/mask_position.rb +12 -0
- data/lib/telegram/bot/types/message.rb +52 -0
- data/lib/telegram/bot/types/message_entity.rb +15 -0
- data/lib/telegram/bot/types/order_info.rb +12 -0
- data/lib/telegram/bot/types/passport_data.rb +10 -0
- data/lib/telegram/bot/types/passport_file.rb +11 -0
- data/lib/telegram/bot/types/photo_size.rb +12 -0
- data/lib/telegram/bot/types/pre_checkout_query.rb +15 -0
- data/lib/telegram/bot/types/reply_keyboard_markup.rb +23 -0
- data/lib/telegram/bot/types/reply_keyboard_remove.rb +10 -0
- data/lib/telegram/bot/types/shipping_address.rb +14 -0
- data/lib/telegram/bot/types/shipping_option.rb +11 -0
- data/lib/telegram/bot/types/shipping_query.rb +12 -0
- data/lib/telegram/bot/types/sticker.rb +16 -0
- data/lib/telegram/bot/types/sticker_set.rb +12 -0
- data/lib/telegram/bot/types/successful_payment.rb +15 -0
- data/lib/telegram/bot/types/update.rb +23 -0
- data/lib/telegram/bot/types/user.rb +14 -0
- data/lib/telegram/bot/types/user_profile_photos.rb +10 -0
- data/lib/telegram/bot/types/venue.rb +12 -0
- data/lib/telegram/bot/types/video.rb +15 -0
- data/lib/telegram/bot/types/video_note.rb +13 -0
- data/lib/telegram/bot/types/voice.rb +12 -0
- data/lib/telegram/bot/types.rb +77 -0
- data/lib/telegram/bot/version.rb +5 -0
- data/lib/telegram/bot.rb +29 -0
- metadata +286 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class InlineQueryResultContact < Base
|
5
|
+
attribute :type, String, default: 'contact'
|
6
|
+
attribute :id, String
|
7
|
+
attribute :phone_number, String
|
8
|
+
attribute :first_name, String
|
9
|
+
attribute :last_name, String
|
10
|
+
attribute :reply_markup, InlineKeyboardMarkup
|
11
|
+
attribute :input_message_content, InputMessageContent
|
12
|
+
attribute :thumb_url, String
|
13
|
+
attribute :thumb_width, Integer
|
14
|
+
attribute :thumb_height, Integer
|
15
|
+
attribute :vcard, String
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class InlineQueryResultDocument < Base
|
5
|
+
attribute :type, String, default: 'document'
|
6
|
+
attribute :id, String
|
7
|
+
attribute :title, String
|
8
|
+
attribute :caption, String
|
9
|
+
attribute :document_url, String
|
10
|
+
attribute :mime_type, String
|
11
|
+
attribute :description, String
|
12
|
+
attribute :reply_markup, InlineKeyboardMarkup
|
13
|
+
attribute :input_message_content, InputMessageContent
|
14
|
+
attribute :thumb_url, String
|
15
|
+
attribute :thumb_width, Integer
|
16
|
+
attribute :thumb_height, Integer
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class InlineQueryResultGame < Base
|
5
|
+
attribute :type, String, default: 'game'
|
6
|
+
attribute :id, String
|
7
|
+
attribute :game_short_name, String
|
8
|
+
attribute :reply_markup, InlineKeyboardMarkup
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class InlineQueryResultGif < Base
|
5
|
+
attribute :type, String, default: 'gif'
|
6
|
+
attribute :id, String
|
7
|
+
attribute :gif_url, String
|
8
|
+
attribute :gif_width, Integer
|
9
|
+
attribute :gif_height, Integer
|
10
|
+
attribute :gif_duration, Integer
|
11
|
+
attribute :thumb_url, String
|
12
|
+
attribute :title, String
|
13
|
+
attribute :caption, String
|
14
|
+
attribute :reply_markup, InlineKeyboardMarkup
|
15
|
+
attribute :input_message_content, InputMessageContent
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class InlineQueryResultLocation < Base
|
5
|
+
attribute :type, String, default: 'location'
|
6
|
+
attribute :id, String
|
7
|
+
attribute :latitude, Float
|
8
|
+
attribute :longitude, Float
|
9
|
+
attribute :title, String
|
10
|
+
attribute :reply_markup, InlineKeyboardMarkup
|
11
|
+
attribute :input_message_content, InputMessageContent
|
12
|
+
attribute :thumb_url, String
|
13
|
+
attribute :thumb_width, Integer
|
14
|
+
attribute :thumb_height, Integer
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class InlineQueryResultMpeg4Gif < Base
|
5
|
+
attribute :type, String, default: 'mpeg4_gif'
|
6
|
+
attribute :id, String
|
7
|
+
attribute :mpeg4_url, String
|
8
|
+
attribute :mpeg4_width, Integer
|
9
|
+
attribute :mpeg4_height, Integer
|
10
|
+
attribute :mpeg4_duration, Integer
|
11
|
+
attribute :thumb_url, String
|
12
|
+
attribute :title, String
|
13
|
+
attribute :caption, String
|
14
|
+
attribute :reply_markup, InlineKeyboardMarkup
|
15
|
+
attribute :input_message_content, InputMessageContent
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class InlineQueryResultPhoto < Base
|
5
|
+
attribute :type, String, default: 'photo'
|
6
|
+
attribute :id, String
|
7
|
+
attribute :photo_url, String
|
8
|
+
attribute :thumb_url, String
|
9
|
+
attribute :photo_width, Integer
|
10
|
+
attribute :photo_height, Integer
|
11
|
+
attribute :title, String
|
12
|
+
attribute :description, String
|
13
|
+
attribute :caption, String
|
14
|
+
attribute :reply_markup, InlineKeyboardMarkup
|
15
|
+
attribute :input_message_content, InputMessageContent
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class InlineQueryResultVenue < Base
|
5
|
+
attribute :type, String, default: 'venue'
|
6
|
+
attribute :id, String
|
7
|
+
attribute :latitude, Float
|
8
|
+
attribute :longitude, Float
|
9
|
+
attribute :title, String
|
10
|
+
attribute :address, String
|
11
|
+
attribute :foursquare_id, String
|
12
|
+
attribute :reply_markup, InlineKeyboardMarkup
|
13
|
+
attribute :input_message_content, InputMessageContent
|
14
|
+
attribute :thumb_url, String
|
15
|
+
attribute :thumb_width, Integer
|
16
|
+
attribute :thumb_height, Integer
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class InlineQueryResultVideo < Base
|
5
|
+
attribute :type, String, default: 'video'
|
6
|
+
attribute :id, String
|
7
|
+
attribute :video_url, String
|
8
|
+
attribute :mime_type, String
|
9
|
+
attribute :thumb_url, String
|
10
|
+
attribute :title, String
|
11
|
+
attribute :caption, String
|
12
|
+
attribute :video_width, Integer
|
13
|
+
attribute :video_height, Integer
|
14
|
+
attribute :video_duration, Integer
|
15
|
+
attribute :description, String
|
16
|
+
attribute :reply_markup, InlineKeyboardMarkup
|
17
|
+
attribute :input_message_content, InputMessageContent
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class InlineQueryResultVoice < Base
|
5
|
+
attribute :type, String, default: 'voice'
|
6
|
+
attribute :id, String
|
7
|
+
attribute :voice_url, String
|
8
|
+
attribute :title, String
|
9
|
+
attribute :caption, String
|
10
|
+
attribute :voice_duration, Integer
|
11
|
+
attribute :reply_markup, InlineKeyboardMarkup
|
12
|
+
attribute :input_message_content, InputMessageContent
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class InputMediaVideo < Base
|
5
|
+
attribute :type, String, default: 'video'
|
6
|
+
attribute :media, String
|
7
|
+
attribute :caption, String
|
8
|
+
attribute :width, Integer
|
9
|
+
attribute :height, Integer
|
10
|
+
attribute :duration, Integer
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class InputVenueMessageContent < InputMessageContent
|
5
|
+
attribute :latitude, Float
|
6
|
+
attribute :longitude, Float
|
7
|
+
attribute :title, String
|
8
|
+
attribute :address, String
|
9
|
+
attribute :foursquare_id, String
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class Invoice < Base
|
5
|
+
attribute :title, String
|
6
|
+
attribute :description, String
|
7
|
+
attribute :start_parameter, String
|
8
|
+
attribute :currency, String
|
9
|
+
attribute :total_amount, Integer
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class Message < Base
|
5
|
+
attribute :message_id, Integer
|
6
|
+
attribute :from, User
|
7
|
+
attribute :date, Integer
|
8
|
+
attribute :chat, Chat
|
9
|
+
attribute :forward_from, User
|
10
|
+
attribute :forward_from_chat, Chat
|
11
|
+
attribute :forward_from_message_id, Integer
|
12
|
+
attribute :forward_signature, String
|
13
|
+
attribute :forward_date, Integer
|
14
|
+
attribute :reply_to_message, Message
|
15
|
+
attribute :edit_date, Integer
|
16
|
+
attribute :author_signature, String
|
17
|
+
attribute :text, String
|
18
|
+
attribute :entities, Array[MessageEntity]
|
19
|
+
attribute :caption_entities, Array[MessageEntity]
|
20
|
+
attribute :audio, Audio
|
21
|
+
attribute :document, Document
|
22
|
+
attribute :game, Game
|
23
|
+
attribute :photo, Array[PhotoSize]
|
24
|
+
attribute :sticker, Sticker
|
25
|
+
attribute :video, Video
|
26
|
+
attribute :voice, Voice
|
27
|
+
attribute :video_note, VideoNote
|
28
|
+
attribute :caption, String
|
29
|
+
attribute :contact, Contact
|
30
|
+
attribute :location, Location
|
31
|
+
attribute :venue, Venue
|
32
|
+
attribute :new_chat_members, Array[User]
|
33
|
+
attribute :left_chat_member, User
|
34
|
+
attribute :new_chat_title, String
|
35
|
+
attribute :new_chat_photo, Array[PhotoSize]
|
36
|
+
attribute :delete_chat_photo, Boolean
|
37
|
+
attribute :group_chat_created, Boolean
|
38
|
+
attribute :supergroup_chat_created, Boolean
|
39
|
+
attribute :channel_chat_created, Boolean
|
40
|
+
attribute :migrate_to_chat_id, Integer
|
41
|
+
attribute :migrate_from_chat_id, Integer
|
42
|
+
attribute :pinned_message, Message
|
43
|
+
attribute :invoice, Invoice
|
44
|
+
attribute :successful_payment, SuccessfulPayment
|
45
|
+
attribute :connected_website, String
|
46
|
+
attribute :passport_data, PassportData
|
47
|
+
|
48
|
+
alias to_s text
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class MessageEntity < Base
|
5
|
+
attribute :type, String
|
6
|
+
attribute :offset, Integer
|
7
|
+
attribute :length, Integer
|
8
|
+
attribute :url, String
|
9
|
+
attribute :user, User
|
10
|
+
attribute :cashtag, String
|
11
|
+
attribute :phone_number, String
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class PreCheckoutQuery < Base
|
5
|
+
attribute :id, String
|
6
|
+
attribute :from, User
|
7
|
+
attribute :currency, String
|
8
|
+
attribute :total_amount, Integer
|
9
|
+
attribute :invoice_payload, String
|
10
|
+
attribute :shipping_option_id, String
|
11
|
+
attribute :order_info, OrderInfo
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class ReplyKeyboardMarkup < Base
|
5
|
+
attribute :keyboard, Array[Array[KeyboardButton]]
|
6
|
+
attribute :resize_keyboard, Boolean, default: false
|
7
|
+
attribute :one_time_keyboard, Boolean, default: false
|
8
|
+
attribute :selective, Boolean, default: false
|
9
|
+
|
10
|
+
def to_compact_hash
|
11
|
+
hsh = super
|
12
|
+
hsh[:keyboard].map! do |arr|
|
13
|
+
arr.map do |item|
|
14
|
+
item.is_a?(KeyboardButton) ? item.to_compact_hash : item
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
hsh
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class ShippingAddress < Base
|
5
|
+
attribute :country_code, String
|
6
|
+
attribute :state, String
|
7
|
+
attribute :city, String
|
8
|
+
attribute :street_line1, String
|
9
|
+
attribute :street_line2, String
|
10
|
+
attribute :post_code, String
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class Sticker < Base
|
5
|
+
attribute :file_id, String
|
6
|
+
attribute :width, Integer
|
7
|
+
attribute :height, Integer
|
8
|
+
attribute :thumb, PhotoSize
|
9
|
+
attribute :emoji, String
|
10
|
+
attribute :set_name, String
|
11
|
+
attribute :mask_position, MaskPosition
|
12
|
+
attribute :file_size, Integer
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class SuccessfulPayment < Base
|
5
|
+
attribute :currency, String
|
6
|
+
attribute :total_amount, Integer
|
7
|
+
attribute :invoice_payload, String
|
8
|
+
attribute :shipping_option_id, String
|
9
|
+
attribute :order_info, OrderInfo
|
10
|
+
attribute :telegram_payment_charge_id, String
|
11
|
+
attribute :provider_payment_charge_id, String
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class Update < Base
|
5
|
+
attribute :update_id, Integer
|
6
|
+
attribute :message, Message
|
7
|
+
attribute :edited_message, Message
|
8
|
+
attribute :channel_post, Message
|
9
|
+
attribute :edited_channel_post, Message
|
10
|
+
attribute :inline_query, InlineQuery
|
11
|
+
attribute :chosen_inline_result, ChosenInlineResult
|
12
|
+
attribute :callback_query, CallbackQuery
|
13
|
+
attribute :shipping_query, ShippingQuery
|
14
|
+
attribute :pre_checkout_query, PreCheckoutQuery
|
15
|
+
|
16
|
+
def current_message
|
17
|
+
@current_message ||=
|
18
|
+
Hash[*attributes.find { |k, v| k != :update_id && v }].values.first
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
module Types
|
4
|
+
class User < Base
|
5
|
+
attribute :id, Integer
|
6
|
+
attribute :is_bot, Boolean
|
7
|
+
attribute :first_name, String
|
8
|
+
attribute :last_name, String
|
9
|
+
attribute :username, String
|
10
|
+
attribute :language_code, String
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|