pi 0.1.19 → 0.1.20
Sign up to get free protection for your applications and to get access to all the features.
- data/README +50 -25
- data/lib/cli.rb +5 -0
- data/lib/cli/choose_helper.rb +50 -0
- data/lib/cli/commands/admin.rb +19 -0
- data/lib/cli/commands/apps.rb +566 -0
- data/lib/cli/commands/base.rb +2 -2
- data/lib/cli/commands/dns.rb +120 -0
- data/lib/cli/commands/projects.rb +85 -102
- data/lib/cli/commands/services.rb +134 -0
- data/lib/cli/commands/user.rb +14 -19
- data/lib/cli/runner.rb +112 -4
- data/lib/cli/usage.rb +24 -0
- data/lib/cli/version.rb +1 -1
- data/lib/pi/client.rb +151 -6
- data/lib/pi/const.rb +2 -0
- metadata +42 -21
data/lib/cli/commands/base.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require "interact"
|
2
2
|
require 'rubygems'
|
3
3
|
require 'terminal-table/import'
|
4
4
|
require 'highline/import'
|
@@ -8,7 +8,7 @@ module PI::Cli
|
|
8
8
|
module Command
|
9
9
|
|
10
10
|
class Base
|
11
|
-
|
11
|
+
include Interactive
|
12
12
|
def initialize(options={})
|
13
13
|
@options = options.dup
|
14
14
|
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require "interact"
|
2
|
+
module PI::Cli::Command
|
3
|
+
class Dns < Base
|
4
|
+
include PI::Cli::ChooseHelper
|
5
|
+
include Interactive
|
6
|
+
|
7
|
+
def usable_dns(appname=nil)
|
8
|
+
unless appname
|
9
|
+
useproject = choose_project
|
10
|
+
projectid = useproject[:id]
|
11
|
+
useapp = choose_app(projectid)
|
12
|
+
appname = useapp[:name]
|
13
|
+
end
|
14
|
+
dns = client.usable_dns(appname)
|
15
|
+
return display JSON.pretty_generate(dns) if @options[:json]
|
16
|
+
return display "No Dns" if dns.nil? || dns.empty?
|
17
|
+
dns.sort! {|a, b| a[:name] <=> b[:name] }
|
18
|
+
dns_table = table do |t|
|
19
|
+
t.headings = 'Name'
|
20
|
+
dns.each do |s|
|
21
|
+
t << [s[:name]]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
display dns_table
|
25
|
+
end
|
26
|
+
|
27
|
+
def app_dns(appname=nil)
|
28
|
+
unless appname
|
29
|
+
useproject = choose_project
|
30
|
+
projectid = useproject[:id]
|
31
|
+
useapp = choose_app(projectid)
|
32
|
+
appname = useapp[:name]
|
33
|
+
end
|
34
|
+
dns = client.app_dns(appname)
|
35
|
+
return display JSON.pretty_generate(dns) if @options[:json]
|
36
|
+
return display "No DNS!" if dns.nil? || dns.empty?
|
37
|
+
dns_table = table do |t|
|
38
|
+
t.headings = 'Mapped DNS Name'
|
39
|
+
dns.each do |s|
|
40
|
+
t << s
|
41
|
+
end
|
42
|
+
end
|
43
|
+
display dns_table
|
44
|
+
end
|
45
|
+
|
46
|
+
def map_dns(appname=nil)
|
47
|
+
unless appname
|
48
|
+
useproject = choose_project
|
49
|
+
projectid = useproject[:id]
|
50
|
+
useapp = choose_app(projectid)
|
51
|
+
appname = useapp[:name]
|
52
|
+
end
|
53
|
+
app = client.app_get_byname(appname)
|
54
|
+
err "The application is not found! App name :#{appname}" unless (appname == app[:name] ? true : false)
|
55
|
+
|
56
|
+
dns = client.usable_dns(appname)
|
57
|
+
err "No usable dns!" if dns.nil? || dns.empty?
|
58
|
+
choices = Array.new
|
59
|
+
dns.each do |s|
|
60
|
+
choices << s[:name]
|
61
|
+
end
|
62
|
+
manifest = ask "Select dns, indexed list?", :choices => choices, :indexed => true
|
63
|
+
manifest = manifest.to_a
|
64
|
+
display "Selected dns: ",false
|
65
|
+
display "#{manifest}"
|
66
|
+
display "Mapping dns: ",false
|
67
|
+
|
68
|
+
t = Thread.new do
|
69
|
+
loop do
|
70
|
+
display '.', false
|
71
|
+
sleep (1)
|
72
|
+
break unless t.alive?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
client.map_dns(appname,manifest)
|
77
|
+
Thread.kill(t)
|
78
|
+
display "OK".green
|
79
|
+
end
|
80
|
+
|
81
|
+
def unmap_dns(appname=nil)
|
82
|
+
unless appname
|
83
|
+
useproject = choose_project
|
84
|
+
projectid = useproject[:id]
|
85
|
+
useapp = choose_app(projectid)
|
86
|
+
appname = useapp[:name]
|
87
|
+
end
|
88
|
+
app = client.app_get_byname(appname)
|
89
|
+
err "The application is not found! App name :#{appname}" unless (appname == app[:name] ? true : false)
|
90
|
+
dns = client.app_dns(appname)
|
91
|
+
err "No mapped dns!" if dns.nil? || dns.empty?
|
92
|
+
usedns = nil
|
93
|
+
choose do |menu|
|
94
|
+
display "=============DNS============"
|
95
|
+
menu.prompt = "Select DNS: "
|
96
|
+
menu.select_by = :index_or_name
|
97
|
+
dns.each do |d|
|
98
|
+
menu.choice("#{d}") { usedns = d }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
display "Selected DNS: ",false
|
102
|
+
display "#{usedns}"
|
103
|
+
manifest = [usedns]
|
104
|
+
display "Unmapping dns: ",false
|
105
|
+
|
106
|
+
t = Thread.new do
|
107
|
+
loop do
|
108
|
+
display '.', false
|
109
|
+
sleep (1)
|
110
|
+
break unless t.alive?
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
client.unmap_dns(appname,manifest)
|
115
|
+
Thread.kill(t)
|
116
|
+
display "OK".green
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
@@ -7,19 +7,36 @@ require 'set'
|
|
7
7
|
module PI::Cli::Command
|
8
8
|
|
9
9
|
class Projects < Base
|
10
|
-
|
11
|
-
YES_SET = Set.new(["y", "Y", "yes", "YES"])
|
10
|
+
include PI::Cli::ChooseHelper
|
12
11
|
|
13
12
|
def projects
|
14
|
-
projects = client.projects
|
15
|
-
|
16
|
-
|
13
|
+
projects = client.projects
|
14
|
+
# size = projects.size-1
|
15
|
+
# if size >= 100
|
16
|
+
# new_range_projects = Array.new
|
17
|
+
# puts "Total projects: #{size}"
|
18
|
+
# start = ask("start number:", Integer) { |q| q.in = 0..size }
|
19
|
+
# stop = ask("stop number:", Integer) { |q| q.in = 0..size }
|
20
|
+
# start.upto(stop) do |i|
|
21
|
+
# new_range_projects << projects[i]
|
22
|
+
# i += 1
|
23
|
+
# end
|
24
|
+
# new_range_projects_table = table do |t|
|
25
|
+
# t.headings = 'Name', 'Runtime', 'Framework', 'Git Type','GitUrl', 'Description'
|
26
|
+
# new_range_projects.each do |project|
|
27
|
+
# t << [project[:name], project[:runtime] ,project[:framework], project[:repositoryType], project[:gitUrl],project[:description]]
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
# display new_range_projects_table
|
31
|
+
# else
|
17
32
|
return display JSON.pretty_generate(projects) if @options[:json]
|
18
|
-
return display "No Projects" if projects.nil? || projects.empty?
|
33
|
+
return display "No Projects" if projects.nil? || projects.empty?
|
34
|
+
projects.sort! {|a, b| a[:name] <=> b[:name] }
|
35
|
+
display "\n"
|
19
36
|
projects_table = table do |t|
|
20
|
-
t.headings = 'Name', 'Runtime', 'Framework', 'Git Type','GitUrl', 'Description'
|
37
|
+
t.headings = 'Name', 'Runtime', 'Framework', 'Git Type','GitUrl', 'ID', 'Description'
|
21
38
|
projects.each do |project|
|
22
|
-
t << [project[:name], project[:runtime] ,project[:framework], project[:repositoryType], project[:gitUrl],project[:description]]
|
39
|
+
t << [project[:name], project[:runtime] ,project[:framework], project[:repositoryType], project[:gitUrl],project[:id],project[:description]]
|
23
40
|
end
|
24
41
|
end
|
25
42
|
display projects_table
|
@@ -28,8 +45,8 @@ module PI::Cli::Command
|
|
28
45
|
def create_project(projectname=nil)
|
29
46
|
loop{
|
30
47
|
unless projectname
|
31
|
-
|
32
|
-
|
48
|
+
projectname = ask "Project Name"
|
49
|
+
err "Project Name required." if projectname.nil? || projectname.empty?
|
33
50
|
end
|
34
51
|
if project_exists?(projectname)
|
35
52
|
display "Project '#{projectname}' already exists."
|
@@ -67,7 +84,7 @@ module PI::Cli::Command
|
|
67
84
|
display "Selected Framework: ",false
|
68
85
|
display "#{framework}".green
|
69
86
|
|
70
|
-
description = ask
|
87
|
+
description = ask "Please enter in the description"
|
71
88
|
|
72
89
|
github_info = client.github_info
|
73
90
|
|
@@ -119,35 +136,43 @@ module PI::Cli::Command
|
|
119
136
|
}
|
120
137
|
end
|
121
138
|
|
122
|
-
display "Creating project #{projectname}: ",false
|
139
|
+
display "Creating project \"#{projectname}\": ",false
|
140
|
+
|
141
|
+
t = Thread.new do
|
142
|
+
loop do
|
143
|
+
display '.', false
|
144
|
+
sleep (1)
|
145
|
+
break unless t.alive?
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
123
149
|
client.create_project(projectname, manifest)
|
150
|
+
Thread.kill(t)
|
124
151
|
display "OK".green
|
125
152
|
end
|
126
153
|
|
127
154
|
def delete_project(projectname=nil)
|
128
155
|
unless projectname
|
129
|
-
|
130
|
-
|
131
|
-
projects.sort! {|a, b| a[:name] <=> b[:name] }
|
132
|
-
choose do |menu|
|
133
|
-
display "=============Project Name======="
|
134
|
-
menu.prompt = "Select Project: "
|
135
|
-
menu.select_by = :index_or_name
|
136
|
-
projects.each do |project|
|
137
|
-
menu.choice(project[:name]) { projectname = project[:name] }
|
138
|
-
end
|
156
|
+
useproject = choose_project
|
157
|
+
projectname = useproject[:name]
|
139
158
|
end
|
140
|
-
display "
|
141
|
-
|
159
|
+
display "Deleting project \"#{projectname}\": ",false
|
160
|
+
|
161
|
+
t = Thread.new do
|
162
|
+
loop do
|
163
|
+
display '.', false
|
164
|
+
sleep (1)
|
165
|
+
break unless t.alive?
|
142
166
|
end
|
143
|
-
|
167
|
+
end
|
168
|
+
|
144
169
|
client.delete_project(projectname)
|
170
|
+
Thread.kill(t)
|
145
171
|
display 'OK'.green
|
146
172
|
end
|
147
173
|
|
148
174
|
def upload(projectname=nil)
|
149
|
-
file = nil
|
150
|
-
java_projects = nil
|
175
|
+
file, java_projects = nil, nil
|
151
176
|
unless projectname
|
152
177
|
projects = client.projects
|
153
178
|
err "No Projects" if projects.nil? || projects.empty?
|
@@ -165,18 +190,15 @@ module PI::Cli::Command
|
|
165
190
|
display "#{projectname}".green
|
166
191
|
end
|
167
192
|
|
168
|
-
version = ask
|
169
|
-
description = ask
|
193
|
+
version = ask "Please enter the version"
|
194
|
+
description = ask "Please enter in the description"
|
170
195
|
|
171
196
|
path = nil
|
172
197
|
loop{
|
173
|
-
path = ask
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
if not File.exists? path
|
178
|
-
display "Deployment path does not exist!"
|
179
|
-
path =nil
|
198
|
+
path = ask "Please enter the path of upload war file"
|
199
|
+
if not ((path =~ /\.(war)$/) && (File.exists? path))
|
200
|
+
display "Not war file or path does not exist!"
|
201
|
+
path =nil
|
180
202
|
next
|
181
203
|
else
|
182
204
|
break
|
@@ -190,26 +212,25 @@ module PI::Cli::Command
|
|
190
212
|
:versionName => "#{version.downcase}",
|
191
213
|
:description => "#{description}"
|
192
214
|
}
|
193
|
-
display "Uploading ",false
|
215
|
+
display "Uploading \"#{File.basename(path)}\": ",false
|
216
|
+
|
217
|
+
t = Thread.new do
|
218
|
+
loop do
|
219
|
+
display '.', false
|
220
|
+
sleep (1)
|
221
|
+
break unless t.alive?
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
194
225
|
client.upload(manifest)
|
226
|
+
Thread.kill(t)
|
195
227
|
display 'OK'.green
|
196
228
|
end
|
197
229
|
|
198
230
|
def project_events(projectname=nil)
|
199
231
|
unless projectname
|
200
|
-
|
201
|
-
|
202
|
-
projects.sort! {|a, b| a[:name] <=> b[:name] }
|
203
|
-
choose do |menu|
|
204
|
-
display "=============Project Name======="
|
205
|
-
menu.prompt = "Select Project: "
|
206
|
-
menu.select_by = :index_or_name
|
207
|
-
projects.each do |project|
|
208
|
-
menu.choice(project[:name]) { projectname = project[:name] }
|
209
|
-
end
|
210
|
-
end
|
211
|
-
display "Selected Project: ",false
|
212
|
-
display "#{projectname}".green
|
232
|
+
useproject = choose_project
|
233
|
+
projectname = useproject[:name]
|
213
234
|
end
|
214
235
|
events = client.project_events(projectname)
|
215
236
|
return display JSON.pretty_generate(events || []) if @options[:json]
|
@@ -225,19 +246,8 @@ module PI::Cli::Command
|
|
225
246
|
|
226
247
|
def project_tags(projectname=nil)
|
227
248
|
unless projectname
|
228
|
-
|
229
|
-
|
230
|
-
projects.sort! {|a, b| a[:name] <=> b[:name] }
|
231
|
-
choose do |menu|
|
232
|
-
display "=============Project Name======="
|
233
|
-
menu.prompt = "Select Project: "
|
234
|
-
menu.select_by = :index_or_name
|
235
|
-
projects.each do |project|
|
236
|
-
menu.choice(project[:name]) { projectname = project[:name] }
|
237
|
-
end
|
238
|
-
end
|
239
|
-
display "Selected Project: ",false
|
240
|
-
display "#{projectname}".green
|
249
|
+
useproject = choose_project
|
250
|
+
projectname = useproject[:name]
|
241
251
|
end
|
242
252
|
tags ||= client.project_tags(projectname)
|
243
253
|
return display JSON.pretty_generate(tags || []) if @options[:json]
|
@@ -252,21 +262,9 @@ module PI::Cli::Command
|
|
252
262
|
|
253
263
|
def project_commits(projectname=nil)
|
254
264
|
unless projectname
|
255
|
-
|
256
|
-
|
257
|
-
projects.sort! {|a, b| a[:name] <=> b[:name] }
|
258
|
-
choose do |menu|
|
259
|
-
display "=============Project Name======="
|
260
|
-
menu.prompt = "Select Project: "
|
261
|
-
menu.select_by = :index_or_name
|
262
|
-
projects.each do |project|
|
263
|
-
menu.choice(project[:name]) { projectname = project[:name] }
|
264
|
-
end
|
265
|
+
useproject = choose_project
|
266
|
+
projectname = useproject[:name]
|
265
267
|
end
|
266
|
-
display "Selected Project: ",false
|
267
|
-
display "#{projectname}".green
|
268
|
-
end
|
269
|
-
|
270
268
|
tag =nil
|
271
269
|
tags = client.project_tags(projectname)
|
272
270
|
return display JSON.pretty_generate(tags || []) if @options[:json]
|
@@ -298,43 +296,28 @@ module PI::Cli::Command
|
|
298
296
|
|
299
297
|
def project_apps(projectname=nil)
|
300
298
|
unless projectname
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
display "=============Project Name======="
|
306
|
-
menu.prompt = "Select Project: "
|
307
|
-
menu.select_by = :index_or_name
|
308
|
-
projects.each do |project|
|
309
|
-
menu.choice(project[:name]) { projectname = project[:name] }
|
310
|
-
end
|
311
|
-
end
|
312
|
-
display "Selected Project: ",false
|
313
|
-
display "#{projectname}".green
|
314
|
-
end
|
315
|
-
|
316
|
-
apps = client.project_apps(projectname)
|
317
|
-
apps.sort! {|a, b| a[:appname] <=> b[:appname] }
|
299
|
+
useproject = choose_project
|
300
|
+
projectname = useproject[:name]
|
301
|
+
end
|
302
|
+
apps = client.project_apps(projectname)
|
318
303
|
return display JSON.pretty_generate(apps || []) if @options[:json]
|
319
304
|
return display "No applications" if apps.nil? || apps.empty?
|
320
|
-
|
305
|
+
|
306
|
+
apps.sort! {|a, b| a[:name] <=> b[:name] }
|
321
307
|
apps_table = table do |t|
|
322
308
|
t.headings = 'Target', 'AppName', 'URL', 'Tag', 'Status', 'Instances'
|
323
309
|
apps.each do |app|
|
324
|
-
t << [app[:targetName], app[:
|
310
|
+
t << [app[:targetName], app[:name], app[:url], app[:tag], app[:status], app[:instances]]
|
325
311
|
end
|
326
312
|
end
|
327
313
|
display apps_table
|
328
314
|
end
|
329
315
|
|
330
316
|
private
|
331
|
-
|
317
|
+
|
332
318
|
def project_exists?(projectname)
|
333
|
-
|
334
|
-
|
335
|
-
return true if project[:name] == projectname
|
336
|
-
end
|
337
|
-
return false
|
319
|
+
project = client.project_get(projectname)
|
320
|
+
projectname == project[:name] ? true : false
|
338
321
|
end
|
339
322
|
|
340
323
|
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require "interact"
|
2
|
+
module PI::Cli::Command
|
3
|
+
class Services < Base
|
4
|
+
include PI::Cli::ChooseHelper
|
5
|
+
include Interactive
|
6
|
+
|
7
|
+
def usable_services(appname=nil)
|
8
|
+
unless appname
|
9
|
+
useproject = choose_project
|
10
|
+
projectid = useproject[:id]
|
11
|
+
useapp = choose_app(projectid)
|
12
|
+
appname = useapp[:name]
|
13
|
+
end
|
14
|
+
services = client.usable_services(appname)
|
15
|
+
return display JSON.pretty_generate(services) if @options[:json]
|
16
|
+
return display "No Services" if services.nil? || services.empty?
|
17
|
+
services.sort! {|a, b| a[:name] <=> b[:name] }
|
18
|
+
services_table = table do |t|
|
19
|
+
t.headings = 'Name', 'Version', 'Type'
|
20
|
+
services.each do |s|
|
21
|
+
t << [s[:name], s[:version] ,s[:service_type]]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
display services_table
|
25
|
+
end
|
26
|
+
|
27
|
+
def app_service(appname=nil)
|
28
|
+
unless appname
|
29
|
+
useproject = choose_project
|
30
|
+
projectid = useproject[:id]
|
31
|
+
useapp = choose_app(projectid)
|
32
|
+
appname = useapp[:name]
|
33
|
+
end
|
34
|
+
services = client.app_service(appname)
|
35
|
+
return display JSON.pretty_generate(services) if @options[:json]
|
36
|
+
return display "No Services" if services.nil? || services.empty?
|
37
|
+
services.sort! {|a, b| a[:name] <=> b[:name] }
|
38
|
+
services_table = table do |t|
|
39
|
+
t.headings = 'Name', 'Version', 'Type'
|
40
|
+
services.each do |s|
|
41
|
+
t << [s[:name], s[:version] ,s[:service_type]]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
display services_table
|
45
|
+
end
|
46
|
+
|
47
|
+
def bind_service(appname=nil)
|
48
|
+
unless appname
|
49
|
+
useproject = choose_project
|
50
|
+
projectid = useproject[:id]
|
51
|
+
useapp = choose_app(projectid)
|
52
|
+
appname = useapp[:name]
|
53
|
+
end
|
54
|
+
app = client.app_get_byname(appname)
|
55
|
+
err "The application is not found! App name :#{appname}" unless (appname == app[:name] ? true : false)
|
56
|
+
|
57
|
+
services = client.usable_services(appname)
|
58
|
+
err "No usable services!" if services.nil? || services.empty?
|
59
|
+
|
60
|
+
choices = Array.new
|
61
|
+
services.each do |s|
|
62
|
+
choices << s[:name]
|
63
|
+
end
|
64
|
+
|
65
|
+
manifest = ask "Select services, indexed list?", :choices => choices, :indexed => true
|
66
|
+
manifest = manifest.to_a
|
67
|
+
display "Selected services: ",false
|
68
|
+
display "#{manifest}"
|
69
|
+
display "Binding service: ",false
|
70
|
+
|
71
|
+
t = Thread.new do
|
72
|
+
loop do
|
73
|
+
display '.', false
|
74
|
+
sleep (1)
|
75
|
+
break unless t.alive?
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
client.bind_service(appname,manifest)
|
80
|
+
result = check_status(app[:name], "bindservice")
|
81
|
+
Thread.kill(t)
|
82
|
+
if result[:code] == 200
|
83
|
+
display "OK".green
|
84
|
+
else
|
85
|
+
err result[:text]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def unbind_service(appname=nil)
|
90
|
+
unless appname
|
91
|
+
useproject = choose_project
|
92
|
+
projectid = useproject[:id]
|
93
|
+
useapp = choose_app(projectid)
|
94
|
+
appname = useapp[:name]
|
95
|
+
end
|
96
|
+
app = client.app_get_byname(appname)
|
97
|
+
err "The application is not found! App name :#{appname}" unless (appname == app[:name] ? true : false)
|
98
|
+
services = client.app_service(appname)
|
99
|
+
err "No binded services!" if services.nil? || services.empty?
|
100
|
+
|
101
|
+
useservice = nil
|
102
|
+
choose do |menu|
|
103
|
+
display "=============Services============"
|
104
|
+
menu.prompt = "Select Service: "
|
105
|
+
menu.select_by = :index_or_name
|
106
|
+
services.each do |service|
|
107
|
+
menu.choice("#{service[:name]}") { useservice = service }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
display "Selected Service: ",false
|
111
|
+
display "#{useservice[:name]}"
|
112
|
+
manifest = [useservice[:name]]
|
113
|
+
display "Unbinding service: ",false
|
114
|
+
|
115
|
+
t = Thread.new do
|
116
|
+
loop do
|
117
|
+
display '.', false
|
118
|
+
sleep (1)
|
119
|
+
break unless t.alive?
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
client.unbind_service(appname,manifest)
|
124
|
+
result = check_status(app[:name], "unbindservice")
|
125
|
+
Thread.kill(t)
|
126
|
+
if result[:code] == 200
|
127
|
+
display "OK".green
|
128
|
+
else
|
129
|
+
err result[:text]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|