lotusrb 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/{LICENSE.txt → LICENSE.md} +0 -0
- data/README.md +436 -8
- data/lib/lotus.rb +10 -0
- data/lib/lotus/application.rb +121 -0
- data/lib/lotus/config/assets.rb +29 -0
- data/lib/lotus/config/load_paths.rb +27 -0
- data/lib/lotus/config/mapper.rb +36 -0
- data/lib/lotus/config/mapping.rb +12 -0
- data/lib/lotus/config/routes.rb +16 -0
- data/lib/lotus/configuration.rb +961 -0
- data/lib/lotus/frameworks.rb +40 -0
- data/lib/lotus/loader.rb +92 -0
- data/lib/lotus/middleware.rb +42 -0
- data/lib/lotus/rendering_policy.rb +69 -0
- data/lib/lotus/routes.rb +95 -0
- data/lib/lotus/routing/default.rb +25 -0
- data/lib/lotus/templates/default.html.erb +9 -0
- data/lib/lotus/version.rb +6 -0
- data/lib/lotus/views/default.rb +20 -0
- data/lib/lotus/views/null_view.rb +17 -0
- data/lib/lotusrb.rb +1 -5
- data/lotusrb.gemspec +21 -14
- metadata +126 -21
- data/.gitignore +0 -17
- data/Gemfile +0 -4
- data/Rakefile +0 -1
- data/lib/lotusrb/version.rb +0 -3
data/lib/lotus.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'lotus/utils/class_attribute'
|
2
|
+
require 'lotus/frameworks'
|
3
|
+
require 'lotus/configuration'
|
4
|
+
require 'lotus/loader'
|
5
|
+
require 'lotus/rendering_policy'
|
6
|
+
require 'lotus/middleware'
|
7
|
+
|
8
|
+
module Lotus
|
9
|
+
# A full stack Lotus application
|
10
|
+
#
|
11
|
+
# @since 0.1.0
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# require 'lotus'
|
15
|
+
#
|
16
|
+
# module Bookshelf
|
17
|
+
# Application < Lotus::Application
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
class Application
|
21
|
+
include Lotus::Utils::ClassAttribute
|
22
|
+
|
23
|
+
# Application configuration
|
24
|
+
#
|
25
|
+
# @since 0.1.0
|
26
|
+
# @api private
|
27
|
+
class_attribute :configuration
|
28
|
+
self.configuration = Configuration.new
|
29
|
+
|
30
|
+
# Configure the application.
|
31
|
+
# It yields the given block in the context of the configuration
|
32
|
+
#
|
33
|
+
# @param blk [Proc] the configuration block
|
34
|
+
#
|
35
|
+
# @since 0.1.0
|
36
|
+
#
|
37
|
+
# @see Lotus::Configuration
|
38
|
+
#
|
39
|
+
# @example
|
40
|
+
# require 'lotus'
|
41
|
+
#
|
42
|
+
# module Bookshelf
|
43
|
+
# Application < Lotus::Application
|
44
|
+
# configure do
|
45
|
+
# # ...
|
46
|
+
# end
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
def self.configure(&blk)
|
50
|
+
configuration.configure(&blk)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Return the routes for this application
|
54
|
+
#
|
55
|
+
# @return [Lotus::Router] a route set
|
56
|
+
#
|
57
|
+
# @since 0.1.0
|
58
|
+
#
|
59
|
+
# @see Lotus::Configuration#routes
|
60
|
+
attr_reader :routes
|
61
|
+
|
62
|
+
# Set the routes for this application
|
63
|
+
#
|
64
|
+
# @param [Lotus::Router]
|
65
|
+
#
|
66
|
+
# @since 0.1.0
|
67
|
+
# @api private
|
68
|
+
attr_writer :routes
|
69
|
+
|
70
|
+
# Initialize and load a new instance of the application
|
71
|
+
#
|
72
|
+
# @return [Lotus::Application] a new instance of the application
|
73
|
+
#
|
74
|
+
# @since 0.1.0
|
75
|
+
def initialize
|
76
|
+
@loader = Lotus::Loader.new(self)
|
77
|
+
@loader.load!
|
78
|
+
|
79
|
+
@rendering_policy = RenderingPolicy.new(configuration)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Return the configuration for this application
|
83
|
+
#
|
84
|
+
# @since 0.1.0
|
85
|
+
# @api private
|
86
|
+
#
|
87
|
+
# @see Lotus::Application.configuration
|
88
|
+
def configuration
|
89
|
+
self.class.configuration
|
90
|
+
end
|
91
|
+
|
92
|
+
# Process a request.
|
93
|
+
# This method makes Lotus applications compatible with the Rack protocol.
|
94
|
+
#
|
95
|
+
# @param env [Hash] a Rack env
|
96
|
+
#
|
97
|
+
# @return [Array] a serialized Rack response
|
98
|
+
#
|
99
|
+
# @since 0.1.0
|
100
|
+
#
|
101
|
+
# @see http://rack.github.io
|
102
|
+
# @see Lotus::Application#middleware
|
103
|
+
def call(env)
|
104
|
+
middleware.call(env).tap do |response|
|
105
|
+
@rendering_policy.render(response)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Rack middleware stack
|
110
|
+
#
|
111
|
+
# @return [Lotus::Middleware] the middleware stack
|
112
|
+
#
|
113
|
+
# @since 0.1.0
|
114
|
+
# @api private
|
115
|
+
#
|
116
|
+
# @see Lotus::Middleware
|
117
|
+
def middleware
|
118
|
+
@middleware ||= Lotus::Middleware.new(self)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Lotus
|
2
|
+
module Config
|
3
|
+
# Assets configuration
|
4
|
+
#
|
5
|
+
# @since 0.1.0
|
6
|
+
# @api private
|
7
|
+
class Assets
|
8
|
+
DEFAULT_DIRECTORY = 'public'.freeze
|
9
|
+
|
10
|
+
def initialize(root, directory)
|
11
|
+
@path = root.join(directory || DEFAULT_DIRECTORY)
|
12
|
+
end
|
13
|
+
|
14
|
+
def entries
|
15
|
+
if @path.exist?
|
16
|
+
@path.children.map {|child| "/#{ child.basename }" }
|
17
|
+
else
|
18
|
+
[]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
@path.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
alias_method :to_str, :to_s
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'lotus/utils/load_paths'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module Config
|
5
|
+
# Define the load paths where the application should load
|
6
|
+
#
|
7
|
+
# @since 0.1.0
|
8
|
+
# @api private
|
9
|
+
class LoadPaths < Utils::LoadPaths
|
10
|
+
PATTERN = '**/*.rb'.freeze
|
11
|
+
|
12
|
+
def load!(root)
|
13
|
+
@root = root
|
14
|
+
|
15
|
+
each do |path|
|
16
|
+
Dir.glob(path.join(PATTERN)).each {|file| require file }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
def realpath(path)
|
22
|
+
@root.join(path).realpath
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'lotus/utils/kernel'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module Config
|
5
|
+
# Define a mapping for Lotus::Model
|
6
|
+
#
|
7
|
+
# @since 0.1.0
|
8
|
+
# @api private
|
9
|
+
class Mapper
|
10
|
+
EXTNAME = '.rb'
|
11
|
+
|
12
|
+
def initialize(root, path, &blk)
|
13
|
+
@path, @blk = path, blk
|
14
|
+
@path = root.join(path) if root && path
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_proc
|
18
|
+
return @blk if @blk
|
19
|
+
|
20
|
+
code = realpath.read
|
21
|
+
Proc.new { eval(code) }
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def realpath
|
26
|
+
Utils::Kernel.Pathname("#{ @path }#{ EXTNAME }").realpath
|
27
|
+
rescue Errno::ENOENT
|
28
|
+
raise ArgumentError, error_message
|
29
|
+
end
|
30
|
+
|
31
|
+
def error_message
|
32
|
+
'You must specify a block or a file.'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'lotus/config/mapper'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module Config
|
5
|
+
# Defines a route set
|
6
|
+
#
|
7
|
+
# @since 0.1.0
|
8
|
+
# @api private
|
9
|
+
class Routes < Mapper
|
10
|
+
private
|
11
|
+
def error_message
|
12
|
+
'You must specify a block or a file for routes definitions.'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,961 @@
|
|
1
|
+
require 'lotus/utils/kernel'
|
2
|
+
require 'lotus/config/load_paths'
|
3
|
+
require 'lotus/config/assets'
|
4
|
+
require 'lotus/config/routes'
|
5
|
+
require 'lotus/config/mapping'
|
6
|
+
|
7
|
+
module Lotus
|
8
|
+
# Configuration for a Lotus application
|
9
|
+
#
|
10
|
+
# @since 0.1.0
|
11
|
+
class Configuration
|
12
|
+
# Initialize a new configuration instance
|
13
|
+
#
|
14
|
+
# @return [Lotus::Configuration]
|
15
|
+
#
|
16
|
+
# @since 0.1.0
|
17
|
+
# @api private
|
18
|
+
def initialize
|
19
|
+
@blk = Proc.new{}
|
20
|
+
end
|
21
|
+
|
22
|
+
# Set a block yield when the configuration will be loaded
|
23
|
+
#
|
24
|
+
# @param blk [Proc] the configuration block
|
25
|
+
#
|
26
|
+
# @return [self]
|
27
|
+
#
|
28
|
+
# @since 0.1.0
|
29
|
+
# @api private
|
30
|
+
def configure(&blk)
|
31
|
+
@blk = blk if block_given?
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
# Load the configuration
|
36
|
+
#
|
37
|
+
# @param namespace [String,nil] the application namespace
|
38
|
+
#
|
39
|
+
# @return [self]
|
40
|
+
#
|
41
|
+
# @since 0.1.0
|
42
|
+
# @api private
|
43
|
+
def load!(namespace = nil)
|
44
|
+
@namespace = namespace
|
45
|
+
instance_eval(&@blk)
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
# The root of the application
|
50
|
+
#
|
51
|
+
# By default it returns the current directory, for this reason, **all the
|
52
|
+
# commands must be executed from the top level directory of the project**.
|
53
|
+
#
|
54
|
+
# If for some reason, that constraint above cannot be satisfied, please
|
55
|
+
# configure the root directory, so that commands can be executed from
|
56
|
+
# everywhere.
|
57
|
+
#
|
58
|
+
# This is part of a DSL, for this reason when this method is called with
|
59
|
+
# an argument, it will set the corresponding instance variable. When
|
60
|
+
# called without, it will return the already set value, or the default.
|
61
|
+
#
|
62
|
+
# @overload root(value)
|
63
|
+
# Sets the given value
|
64
|
+
# @param value [String,Pathname,#to_pathname] The root directory of the app
|
65
|
+
#
|
66
|
+
# @overload root
|
67
|
+
# Gets the value
|
68
|
+
# @return [Pathname]
|
69
|
+
# @raise [Errno::ENOENT] if the path cannot be found
|
70
|
+
#
|
71
|
+
# @since 0.1.0
|
72
|
+
#
|
73
|
+
# @see http://www.ruby-doc.org/core-2.1.2/Dir.html#method-c-pwd
|
74
|
+
#
|
75
|
+
# @example Getting the value
|
76
|
+
# require 'lotus'
|
77
|
+
#
|
78
|
+
# module Bookshelf
|
79
|
+
# class Application < Lotus::Application
|
80
|
+
# end
|
81
|
+
# end
|
82
|
+
#
|
83
|
+
# Bookshelf::Application.configuration.root # => #<Pathname:/path/to/root>
|
84
|
+
#
|
85
|
+
# @example Setting the value
|
86
|
+
# require 'lotus'
|
87
|
+
#
|
88
|
+
# module Bookshelf
|
89
|
+
# class Application < Lotus::Application
|
90
|
+
# configure do
|
91
|
+
# root '/path/to/another/root'
|
92
|
+
# end
|
93
|
+
# end
|
94
|
+
# end
|
95
|
+
def root(value = nil)
|
96
|
+
if value
|
97
|
+
@root = value
|
98
|
+
else
|
99
|
+
Utils::Kernel.Pathname(@root || Dir.pwd).realpath
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# The application namespace
|
104
|
+
#
|
105
|
+
# By default it returns the Ruby namespace of the application. For instance
|
106
|
+
# for an application `Bookshelf::Application`, it returns `Bookshelf`.
|
107
|
+
#
|
108
|
+
# This value isn't set at the init time, but when the configuration is
|
109
|
+
# loaded with `#load!`.
|
110
|
+
#
|
111
|
+
# Lotus applications are namespaced: all the controllers and views live
|
112
|
+
# under the application module, without polluting the global namespace.
|
113
|
+
# However, if for some reason, you want top level classes, set this value
|
114
|
+
# to `Object` (which is the top level namespace for Ruby).
|
115
|
+
#
|
116
|
+
# This is part of a DSL, for this reason when this method is called with
|
117
|
+
# an argument, it will set the corresponding instance variable. When
|
118
|
+
# called without, it will return the already set value, or the default.
|
119
|
+
#
|
120
|
+
# @overload namespace(value)
|
121
|
+
# Sets the given value
|
122
|
+
# @param value [Class,Module] A valid Ruby namespace
|
123
|
+
#
|
124
|
+
# @overload namespace
|
125
|
+
# Gets the value
|
126
|
+
# @return [Class,Module] a Ruby namespace
|
127
|
+
#
|
128
|
+
# @since 0.1.0
|
129
|
+
#
|
130
|
+
# @example Getting the value
|
131
|
+
# require 'lotus'
|
132
|
+
#
|
133
|
+
# module Bookshelf
|
134
|
+
# class Application < Lotus::Application
|
135
|
+
# end
|
136
|
+
# end
|
137
|
+
#
|
138
|
+
# Bookshelf::Application.configuration.namespace # => Bookshelf
|
139
|
+
#
|
140
|
+
# # It will lookup namespaced controllers under Bookshelf
|
141
|
+
# # eg. Bookshelf::Controllers::Dashboard
|
142
|
+
#
|
143
|
+
# @example Setting the value
|
144
|
+
# require 'lotus'
|
145
|
+
#
|
146
|
+
# module Bookshelf
|
147
|
+
# class Application < Lotus::Application
|
148
|
+
# configure do
|
149
|
+
# namespace Object
|
150
|
+
# end
|
151
|
+
# end
|
152
|
+
# end
|
153
|
+
#
|
154
|
+
# Bookshelf::Application.configuration.namespace # => Object
|
155
|
+
#
|
156
|
+
# # It will lookup top level controllers under Object
|
157
|
+
# # eg. DashboardController
|
158
|
+
def namespace(value = nil)
|
159
|
+
if value
|
160
|
+
@namespace = value
|
161
|
+
else
|
162
|
+
@namespace
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# A Lotus::Layout for this application
|
167
|
+
#
|
168
|
+
# By default it's `nil`.
|
169
|
+
#
|
170
|
+
# It accepts a Symbol as layout name. When the application is loaded, it
|
171
|
+
# will lookup for the corresponding class.
|
172
|
+
#
|
173
|
+
# All the views will use this layout, unless otherwise specified.
|
174
|
+
#
|
175
|
+
# This is part of a DSL, for this reason when this method is called with
|
176
|
+
# an argument, it will set the corresponding instance variable. When
|
177
|
+
# called without, it will return the already set value, or the default.
|
178
|
+
#
|
179
|
+
# @overload layout(value)
|
180
|
+
# Sets the given value
|
181
|
+
# @param value [Symbol] the layout name
|
182
|
+
#
|
183
|
+
# @overload layout
|
184
|
+
# Gets the value
|
185
|
+
# @return [Symbol,nil] the layout name
|
186
|
+
#
|
187
|
+
# @since 0.1.0
|
188
|
+
#
|
189
|
+
# @see http://rdoc.info/gems/lotus-view/Lotus/Layout
|
190
|
+
# @see http://rdoc.info/gems/lotus-view/Lotus/View/Configuration:layout
|
191
|
+
#
|
192
|
+
# @example Getting the value
|
193
|
+
# require 'lotus'
|
194
|
+
#
|
195
|
+
# module Bookshelf
|
196
|
+
# class Application < Lotus::Application
|
197
|
+
# end
|
198
|
+
# end
|
199
|
+
#
|
200
|
+
# Bookshelf::Application.configuration.layout # => nil
|
201
|
+
#
|
202
|
+
# # All the views will render without a layout
|
203
|
+
#
|
204
|
+
# @example Setting the value
|
205
|
+
# require 'lotus'
|
206
|
+
#
|
207
|
+
# module Bookshelf
|
208
|
+
# class Application < Lotus::Application
|
209
|
+
# configure do
|
210
|
+
# layout :application
|
211
|
+
# end
|
212
|
+
# end
|
213
|
+
#
|
214
|
+
# module Views
|
215
|
+
# module Dashboard
|
216
|
+
# class Index
|
217
|
+
# include Bookshelf::Views
|
218
|
+
# end
|
219
|
+
#
|
220
|
+
# class JsonIndex < Index
|
221
|
+
# layout nil
|
222
|
+
# end
|
223
|
+
# end
|
224
|
+
# end
|
225
|
+
# end
|
226
|
+
#
|
227
|
+
# Bookshelf::Application.configuration.namespace layout => :application
|
228
|
+
#
|
229
|
+
# # All the views will use Bookshelf::Views::ApplicationLayout, unless
|
230
|
+
# # they set a different value.
|
231
|
+
#
|
232
|
+
# Bookshelf::Views::Dashboard::Index.layout
|
233
|
+
# # => Bookshelf::Views::ApplicationLayout
|
234
|
+
#
|
235
|
+
# Bookshelf::Views::Dashboard::JsonIndex.layout
|
236
|
+
# # => Lotus::View::Rendering::NullLayout
|
237
|
+
def layout(value = nil)
|
238
|
+
if value
|
239
|
+
@layout = value
|
240
|
+
else
|
241
|
+
@layout
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
# Templates root.
|
246
|
+
# The application will recursively look for templates under this path.
|
247
|
+
#
|
248
|
+
# By default it's equal to the application `root`.
|
249
|
+
#
|
250
|
+
# Otherwise, you can specify a different relative path under `root`.
|
251
|
+
#
|
252
|
+
# This is part of a DSL, for this reason when this method is called with
|
253
|
+
# an argument, it will set the corresponding instance variable. When
|
254
|
+
# called without, it will return the already set value, or the default.
|
255
|
+
#
|
256
|
+
# @overload templates(value)
|
257
|
+
# Sets the given value
|
258
|
+
# @param value [String] the relative path to the templates root.
|
259
|
+
#
|
260
|
+
# @overload templates
|
261
|
+
# Gets the value
|
262
|
+
# @return [Pathname] templates root
|
263
|
+
#
|
264
|
+
# @since 0.1.0
|
265
|
+
#
|
266
|
+
# @see Lotus::Configuration#root
|
267
|
+
# @see http://rdoc.info/gems/lotus-view/Lotus/View/Configuration:root
|
268
|
+
#
|
269
|
+
# @example Getting the value
|
270
|
+
# require 'lotus'
|
271
|
+
#
|
272
|
+
# module Bookshelf
|
273
|
+
# class Application < Lotus::Application
|
274
|
+
# end
|
275
|
+
# end
|
276
|
+
#
|
277
|
+
# Bookshelf::Application.configuration.templates
|
278
|
+
# # => #<Pathname:/root/path>
|
279
|
+
#
|
280
|
+
# @example Setting the value
|
281
|
+
# require 'lotus'
|
282
|
+
#
|
283
|
+
# module Bookshelf
|
284
|
+
# class Application < Lotus::Application
|
285
|
+
# configure do
|
286
|
+
# templates 'app/templates'
|
287
|
+
# end
|
288
|
+
# end
|
289
|
+
# end
|
290
|
+
#
|
291
|
+
# Bookshelf::Application.configuration.templates
|
292
|
+
# # => #<Pathname:/root/path/app/templates>
|
293
|
+
def templates(value = nil)
|
294
|
+
if value
|
295
|
+
@templates = value
|
296
|
+
else
|
297
|
+
root.join @templates.to_s
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
# Assets root.
|
302
|
+
# The application will serve the static assets under this directory.
|
303
|
+
#
|
304
|
+
# By default it's equal to the `public/` directory under the application
|
305
|
+
# `root`.
|
306
|
+
#
|
307
|
+
# Otherwise, you can specify a different relative path under `root`.
|
308
|
+
#
|
309
|
+
# This is part of a DSL, for this reason when this method is called with
|
310
|
+
# an argument, it will set the corresponding instance variable. When
|
311
|
+
# called without, it will return the already set value, or the default.
|
312
|
+
#
|
313
|
+
# @overload assets(value)
|
314
|
+
# Sets the given value
|
315
|
+
# @param value [String] the relative path to the assets dir.
|
316
|
+
#
|
317
|
+
# @overload assets
|
318
|
+
# Gets the value
|
319
|
+
# @return [Lotus::Config::Assets] assets root
|
320
|
+
#
|
321
|
+
# @since 0.1.0
|
322
|
+
#
|
323
|
+
# @see Lotus::Configuration#root
|
324
|
+
#
|
325
|
+
# @example Getting the value
|
326
|
+
# require 'lotus'
|
327
|
+
#
|
328
|
+
# module Bookshelf
|
329
|
+
# class Application < Lotus::Application
|
330
|
+
# end
|
331
|
+
# end
|
332
|
+
#
|
333
|
+
# Bookshelf::Application.configuration.assets
|
334
|
+
# # => #<Pathname:/root/path/public>
|
335
|
+
#
|
336
|
+
# @example Setting the value
|
337
|
+
# require 'lotus'
|
338
|
+
#
|
339
|
+
# module Bookshelf
|
340
|
+
# class Application < Lotus::Application
|
341
|
+
# configure do
|
342
|
+
# assets 'assets'
|
343
|
+
# end
|
344
|
+
# end
|
345
|
+
# end
|
346
|
+
#
|
347
|
+
# Bookshelf::Application.configuration.assets
|
348
|
+
# # => #<Pathname:/root/path/assets>
|
349
|
+
def assets(value = nil)
|
350
|
+
if value
|
351
|
+
@assets = value
|
352
|
+
else
|
353
|
+
Config::Assets.new(root, @assets)
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
# Application load paths
|
358
|
+
# The application will recursively load all the Ruby files under these paths.
|
359
|
+
#
|
360
|
+
# By default it's empty in order to allow developers to decide their own
|
361
|
+
# app structure.
|
362
|
+
#
|
363
|
+
# @return [Lotus::Config::LoadPaths] a set of load paths
|
364
|
+
#
|
365
|
+
# @since 0.1.0
|
366
|
+
#
|
367
|
+
# @see Lotus::Configuration#root
|
368
|
+
#
|
369
|
+
# @example Getting the value
|
370
|
+
# require 'lotus'
|
371
|
+
#
|
372
|
+
# module Bookshelf
|
373
|
+
# class Application < Lotus::Application
|
374
|
+
# end
|
375
|
+
# end
|
376
|
+
#
|
377
|
+
# Bookshelf::Application.configuration.load_paths
|
378
|
+
# # => #<Lotus::Config::LoadPaths:0x007ff4fa212310 @paths=[]>
|
379
|
+
#
|
380
|
+
# @example Setting the value
|
381
|
+
# require 'lotus'
|
382
|
+
#
|
383
|
+
# module Bookshelf
|
384
|
+
# class Application < Lotus::Application
|
385
|
+
# configure do
|
386
|
+
# load_paths << [
|
387
|
+
# 'app/controllers',
|
388
|
+
# 'app/views
|
389
|
+
# ]
|
390
|
+
# end
|
391
|
+
# end
|
392
|
+
# end
|
393
|
+
#
|
394
|
+
# Bookshelf::Application.configuration.assets
|
395
|
+
# # => #<Lotus::Config::LoadPaths:0x007fe3a20b18e0 @paths=[["app/controllers", "app/views"]]>
|
396
|
+
def load_paths
|
397
|
+
@load_paths ||= Config::LoadPaths.new
|
398
|
+
end
|
399
|
+
|
400
|
+
# Application routes.
|
401
|
+
#
|
402
|
+
# Specify a set of routes for the application, by passing a block, or a
|
403
|
+
# relative path where to find the file that describes them.
|
404
|
+
#
|
405
|
+
# By default it's `nil`.
|
406
|
+
#
|
407
|
+
# This is part of a DSL, for this reason when this method is called with
|
408
|
+
# an argument, it will set the corresponding instance variable. When
|
409
|
+
# called without, it will return the already set value, or the default.
|
410
|
+
#
|
411
|
+
# @overload routes(blk)
|
412
|
+
# Specify a set of routes in the given block
|
413
|
+
# @param blk [Proc] the routes definitions
|
414
|
+
#
|
415
|
+
# @overload routes(path)
|
416
|
+
# Specify a relative path where to find the routes file
|
417
|
+
# @param path [String] the relative path
|
418
|
+
#
|
419
|
+
# @overload routes
|
420
|
+
# Gets the value
|
421
|
+
# @return [Lotus::Config::Routes] the set of routes
|
422
|
+
#
|
423
|
+
# @since 0.1.0
|
424
|
+
#
|
425
|
+
# @see http://rdoc.info/gems/lotus-router/Lotus/Router
|
426
|
+
#
|
427
|
+
# @example Getting the value
|
428
|
+
# require 'lotus'
|
429
|
+
#
|
430
|
+
# module Bookshelf
|
431
|
+
# class Application < Lotus::Application
|
432
|
+
# end
|
433
|
+
# end
|
434
|
+
#
|
435
|
+
# Bookshelf::Application.configuration.routes
|
436
|
+
# # => nil
|
437
|
+
#
|
438
|
+
# @example Setting the value, by passing a block
|
439
|
+
# require 'lotus'
|
440
|
+
#
|
441
|
+
# module Bookshelf
|
442
|
+
# class Application < Lotus::Application
|
443
|
+
# configure do
|
444
|
+
# routes do
|
445
|
+
# get '/', to: 'dashboard#index'
|
446
|
+
# resources :books
|
447
|
+
# end
|
448
|
+
# end
|
449
|
+
# end
|
450
|
+
# end
|
451
|
+
#
|
452
|
+
# Bookshelf::Application.configuration.routes
|
453
|
+
# # => #<Lotus::Config::Routes:0x007ff50a991388 @blk=#<Proc:0x007ff50a991338@(irb):4>, @path=#<Pathname:.>>
|
454
|
+
#
|
455
|
+
# @example Setting the value, by passing a relative path
|
456
|
+
# require 'lotus'
|
457
|
+
#
|
458
|
+
# module Bookshelf
|
459
|
+
# class Application < Lotus::Application
|
460
|
+
# configure do
|
461
|
+
# routes 'config/routes'
|
462
|
+
# end
|
463
|
+
# end
|
464
|
+
# end
|
465
|
+
#
|
466
|
+
# Bookshelf::Application.configuration.routes
|
467
|
+
# # => #<Lotus::Config::Routes:0x007ff50a991388 @blk=nil, @path=#<Pathname:config/routes.rb>>
|
468
|
+
def routes(path = nil, &blk)
|
469
|
+
if path or block_given?
|
470
|
+
@routes = Config::Routes.new(root, path, &blk)
|
471
|
+
else
|
472
|
+
@routes
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
# since 0.1.0
|
477
|
+
# @api private
|
478
|
+
def mapping(path = nil, &blk)
|
479
|
+
if path or block_given?
|
480
|
+
@mapping = Config::Mapping.new(root, path, &blk)
|
481
|
+
else
|
482
|
+
@mapping
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
# Set a format as default fallback for all the requests without a strict
|
487
|
+
# requirement for the mime type.
|
488
|
+
#
|
489
|
+
# The given format must be coercible to a symbol, and be a valid mime type
|
490
|
+
# alias. If it isn't, at the runtime the framework will raise a
|
491
|
+
# `Lotus::Controller::UnknownFormatError`.
|
492
|
+
#
|
493
|
+
# By default this value is `:html`.
|
494
|
+
#
|
495
|
+
# This is part of a DSL, for this reason when this method is called with
|
496
|
+
# an argument, it will set the corresponding instance variable. When
|
497
|
+
# called without, it will return the already set value, or the default.
|
498
|
+
#
|
499
|
+
# @overload default_format(format)
|
500
|
+
# Sets the given value
|
501
|
+
# @param format [#to_sym] the symbol format
|
502
|
+
# @raise [TypeError] if it cannot be coerced to a symbol
|
503
|
+
#
|
504
|
+
# @overload default_format
|
505
|
+
# Gets the value
|
506
|
+
# @return [Symbol]
|
507
|
+
#
|
508
|
+
# @since 0.1.0
|
509
|
+
#
|
510
|
+
# @see http://rdoc.info/gems/lotus-controller/Lotus/Controller/Configuration#default_format
|
511
|
+
#
|
512
|
+
# @example Getting the value
|
513
|
+
# require 'lotus'
|
514
|
+
#
|
515
|
+
# module Bookshelf
|
516
|
+
# class Application < Lotus::Application
|
517
|
+
# end
|
518
|
+
# end
|
519
|
+
#
|
520
|
+
# Bookshelf::Application.configuration.default_format # => :html
|
521
|
+
#
|
522
|
+
# @example Setting the value
|
523
|
+
# require 'lotus'
|
524
|
+
#
|
525
|
+
# module Bookshelf
|
526
|
+
# class Application < Lotus::Application
|
527
|
+
# configure do
|
528
|
+
# default_format :json
|
529
|
+
# end
|
530
|
+
# end
|
531
|
+
# end
|
532
|
+
#
|
533
|
+
# Bookshelf::Application.configuration.default_format # => :json
|
534
|
+
def default_format(format = nil)
|
535
|
+
if format
|
536
|
+
@default_format = Utils::Kernel.Symbol(format)
|
537
|
+
else
|
538
|
+
@default_format || :html
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
# The URI scheme for this application.
|
543
|
+
# This is used by the router helpers to generate absolute URLs.
|
544
|
+
#
|
545
|
+
# By default this value is `"http"`.
|
546
|
+
#
|
547
|
+
# This is part of a DSL, for this reason when this method is called with
|
548
|
+
# an argument, it will set the corresponding instance variable. When
|
549
|
+
# called without, it will return the already set value, or the default.
|
550
|
+
#
|
551
|
+
# @overload scheme(value)
|
552
|
+
# Sets the given value
|
553
|
+
# @param value [String] the URI scheme
|
554
|
+
#
|
555
|
+
# @overload scheme
|
556
|
+
# Gets the value
|
557
|
+
# @return [String]
|
558
|
+
#
|
559
|
+
# @since 0.1.0
|
560
|
+
#
|
561
|
+
# @see http://en.wikipedia.org/wiki/URI_scheme
|
562
|
+
#
|
563
|
+
# @example Getting the value
|
564
|
+
# require 'lotus'
|
565
|
+
#
|
566
|
+
# module Bookshelf
|
567
|
+
# class Application < Lotus::Application
|
568
|
+
# end
|
569
|
+
# end
|
570
|
+
#
|
571
|
+
# Bookshelf::Application.configuration.scheme # => "http"
|
572
|
+
#
|
573
|
+
# @example Setting the value
|
574
|
+
# require 'lotus'
|
575
|
+
#
|
576
|
+
# module Bookshelf
|
577
|
+
# class Application < Lotus::Application
|
578
|
+
# configure do
|
579
|
+
# scheme 'https'
|
580
|
+
# end
|
581
|
+
# end
|
582
|
+
# end
|
583
|
+
#
|
584
|
+
# Bookshelf::Application.configuration.scheme # => "https"
|
585
|
+
def scheme(value = nil)
|
586
|
+
if value
|
587
|
+
@scheme = value
|
588
|
+
else
|
589
|
+
@scheme ||= 'http'
|
590
|
+
end
|
591
|
+
end
|
592
|
+
|
593
|
+
# The URI host for this application.
|
594
|
+
# This is used by the router helpers to generate absolute URLs.
|
595
|
+
#
|
596
|
+
# By default this value is `"localhost"`.
|
597
|
+
#
|
598
|
+
# This is part of a DSL, for this reason when this method is called with
|
599
|
+
# an argument, it will set the corresponding instance variable. When
|
600
|
+
# called without, it will return the already set value, or the default.
|
601
|
+
#
|
602
|
+
# @overload host(value)
|
603
|
+
# Sets the given value
|
604
|
+
# @param value [String] the URI host
|
605
|
+
#
|
606
|
+
# @overload scheme
|
607
|
+
# Gets the value
|
608
|
+
# @return [String]
|
609
|
+
#
|
610
|
+
# @since 0.1.0
|
611
|
+
#
|
612
|
+
# @see http://en.wikipedia.org/wiki/URI_scheme
|
613
|
+
#
|
614
|
+
# @example Getting the value
|
615
|
+
# require 'lotus'
|
616
|
+
#
|
617
|
+
# module Bookshelf
|
618
|
+
# class Application < Lotus::Application
|
619
|
+
# end
|
620
|
+
# end
|
621
|
+
#
|
622
|
+
# Bookshelf::Application.configuration.host # => "localhost"
|
623
|
+
#
|
624
|
+
# @example Setting the value
|
625
|
+
# require 'lotus'
|
626
|
+
#
|
627
|
+
# module Bookshelf
|
628
|
+
# class Application < Lotus::Application
|
629
|
+
# configure do
|
630
|
+
# host 'bookshelf.org'
|
631
|
+
# end
|
632
|
+
# end
|
633
|
+
# end
|
634
|
+
#
|
635
|
+
# Bookshelf::Application.configuration.host # => "bookshelf.org"
|
636
|
+
def host(value = nil)
|
637
|
+
if value
|
638
|
+
@host = value
|
639
|
+
else
|
640
|
+
@host ||= 'localhost'
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
644
|
+
# The URI port for this application.
|
645
|
+
# This is used by the router helpers to generate absolute URLs.
|
646
|
+
#
|
647
|
+
# By default this value is `80`, if `scheme` is `"http"`, or `443` if
|
648
|
+
# `scheme` is `"https"`.
|
649
|
+
#
|
650
|
+
# This is optional, you should set this value only if your application
|
651
|
+
# listens on a port not listed above.
|
652
|
+
#
|
653
|
+
# This is part of a DSL, for this reason when this method is called with
|
654
|
+
# an argument, it will set the corresponding instance variable. When
|
655
|
+
# called without, it will return the already set value, or the default.
|
656
|
+
#
|
657
|
+
# @overload port(value)
|
658
|
+
# Sets the given value
|
659
|
+
# @param value [#to_int] the URI port
|
660
|
+
# @raise [TypeError] if the given value cannot be coerced to Integer
|
661
|
+
#
|
662
|
+
# @overload scheme
|
663
|
+
# Gets the value
|
664
|
+
# @return [String]
|
665
|
+
#
|
666
|
+
# @since 0.1.0
|
667
|
+
#
|
668
|
+
# @see http://en.wikipedia.org/wiki/URI_scheme
|
669
|
+
#
|
670
|
+
# @example Getting the value
|
671
|
+
# require 'lotus'
|
672
|
+
#
|
673
|
+
# module Bookshelf
|
674
|
+
# class Application < Lotus::Application
|
675
|
+
# end
|
676
|
+
# end
|
677
|
+
#
|
678
|
+
# Bookshelf::Application.configuration.port # => 80
|
679
|
+
#
|
680
|
+
# @example Setting the value
|
681
|
+
# require 'lotus'
|
682
|
+
#
|
683
|
+
# module Bookshelf
|
684
|
+
# class Application < Lotus::Application
|
685
|
+
# configure do
|
686
|
+
# port 2323
|
687
|
+
# end
|
688
|
+
# end
|
689
|
+
# end
|
690
|
+
#
|
691
|
+
# Bookshelf::Application.configuration.port # => 2323
|
692
|
+
def port(value = nil)
|
693
|
+
if value
|
694
|
+
@port = Integer(value)
|
695
|
+
else
|
696
|
+
@port ||
|
697
|
+
case scheme
|
698
|
+
when 'http' then 80
|
699
|
+
when 'https' then 443
|
700
|
+
end
|
701
|
+
end
|
702
|
+
end
|
703
|
+
|
704
|
+
# Defines a relative pattern to find controllers.
|
705
|
+
#
|
706
|
+
# Lotus supports multiple architectures (aka application structures), this
|
707
|
+
# setting helps to understand the namespace where to find applications'
|
708
|
+
# controllers and actions.
|
709
|
+
#
|
710
|
+
# By default this equals to `"Controllers::%{controller}::%{action}"`
|
711
|
+
# That means controllers must be structured like this:
|
712
|
+
# `Bookshelf::Controllers::Dashboard::Index`, where `Bookshelf` is the
|
713
|
+
# application module, `Controllers` is the first value specified in the
|
714
|
+
# pattern, `Dashboard` the controller and `Index` the action.
|
715
|
+
#
|
716
|
+
# This pattern MUST always contain `"%{controller}"` and `%{action}`.
|
717
|
+
# This pattern SHOULD be used accordingly to `#view_pattern` value.
|
718
|
+
#
|
719
|
+
# This is part of a DSL, for this reason when this method is called with
|
720
|
+
# an argument, it will set the corresponding instance variable. When
|
721
|
+
# called without, it will return the already set value, or the default.
|
722
|
+
#
|
723
|
+
# @overload controller_pattern(value)
|
724
|
+
# Sets the given value
|
725
|
+
# @param value [String] the controller pattern
|
726
|
+
#
|
727
|
+
# @overload controller_pattern
|
728
|
+
# Gets the value
|
729
|
+
# @return [String]
|
730
|
+
#
|
731
|
+
# @since 0.1.0
|
732
|
+
#
|
733
|
+
# @see Lotus::Configuration#view_pattern
|
734
|
+
#
|
735
|
+
# @example Getting the value
|
736
|
+
# require 'lotus'
|
737
|
+
#
|
738
|
+
# module Bookshelf
|
739
|
+
# class Application < Lotus::Application
|
740
|
+
# configure do
|
741
|
+
# routes do
|
742
|
+
# get '/', to: 'dashboard#index'
|
743
|
+
# end
|
744
|
+
# end
|
745
|
+
# end
|
746
|
+
#
|
747
|
+
# module Controllers
|
748
|
+
# module Dashboard
|
749
|
+
# include Bookshelf::Controller
|
750
|
+
#
|
751
|
+
# action 'Index' do
|
752
|
+
# def call(params)
|
753
|
+
# # ...
|
754
|
+
# end
|
755
|
+
# end
|
756
|
+
# end
|
757
|
+
# end
|
758
|
+
# end
|
759
|
+
#
|
760
|
+
# Bookshelf::Application.configuration.controller_pattern
|
761
|
+
# # => "Controllers::%{controller}::%{action}"
|
762
|
+
#
|
763
|
+
# # All the controllers MUST live under Bookshelf::Controllers
|
764
|
+
#
|
765
|
+
# # GET '/' # => Bookshelf::Controllers::Dashboard::Index
|
766
|
+
#
|
767
|
+
# @example Setting the value
|
768
|
+
# require 'lotus'
|
769
|
+
#
|
770
|
+
# module Bookshelf
|
771
|
+
# class Application < Lotus::Application
|
772
|
+
# configure do
|
773
|
+
# controller_pattern "%{controller}Controller::%{action}"
|
774
|
+
#
|
775
|
+
# routes do
|
776
|
+
# get '/', to: 'dashboard#index'
|
777
|
+
# end
|
778
|
+
# end
|
779
|
+
# end
|
780
|
+
#
|
781
|
+
# module DashboardController
|
782
|
+
# include Bookshelf::Controller
|
783
|
+
#
|
784
|
+
# action 'Index' do
|
785
|
+
# def call(params)
|
786
|
+
# end
|
787
|
+
# end
|
788
|
+
# end
|
789
|
+
# end
|
790
|
+
#
|
791
|
+
# Bookshelf::Application.configuration.controller_pattern
|
792
|
+
# # => "%{controller}Controller::%{action}"
|
793
|
+
#
|
794
|
+
# # All the controllers are directly under the Bookshelf module
|
795
|
+
#
|
796
|
+
# # GET '/' # => Bookshelf::DashboardController::Index
|
797
|
+
#
|
798
|
+
# @example Setting the value for a top level name structure
|
799
|
+
# require 'lotus'
|
800
|
+
#
|
801
|
+
# module Bookshelf
|
802
|
+
# class Application < Lotus::Application
|
803
|
+
# configure do
|
804
|
+
# namespace Object
|
805
|
+
# controller_pattern "%{controller}Controller::%{action}"
|
806
|
+
#
|
807
|
+
# routes do
|
808
|
+
# get '/', to: 'dashboard#index'
|
809
|
+
# end
|
810
|
+
# end
|
811
|
+
# end
|
812
|
+
# end
|
813
|
+
#
|
814
|
+
# module DashboardController
|
815
|
+
# include Bookshelf::Controller
|
816
|
+
#
|
817
|
+
# action 'Index' do
|
818
|
+
# def call(params)
|
819
|
+
# end
|
820
|
+
# end
|
821
|
+
# end
|
822
|
+
#
|
823
|
+
# Bookshelf::Application.configuration.controller_pattern
|
824
|
+
# # => "%{controller}Controller::%{action}"
|
825
|
+
#
|
826
|
+
# # All the controllers are at the top level namespace
|
827
|
+
#
|
828
|
+
# # GET '/' # => DashboardController::Index
|
829
|
+
def controller_pattern(value = nil)
|
830
|
+
if value
|
831
|
+
@controller_pattern = value
|
832
|
+
else
|
833
|
+
@controller_pattern ||= 'Controllers::%{controller}::%{action}'
|
834
|
+
end
|
835
|
+
end
|
836
|
+
|
837
|
+
# Defines a relative pattern to find views:.
|
838
|
+
#
|
839
|
+
# Lotus supports multiple architectures (aka application structures), this
|
840
|
+
# setting helps to understand the namespace where to find applications'
|
841
|
+
# views:.
|
842
|
+
#
|
843
|
+
# By default this equals to `"Views::%{controller}::%{action}"`
|
844
|
+
# That means views must be structured like this:
|
845
|
+
# `Bookshelf::Views::Dashboard::Index`, where `Bookshelf` is the
|
846
|
+
# application module, `Views` is the first value specified in the
|
847
|
+
# pattern, `Dashboard` a module corresponding to the controller name
|
848
|
+
# and `Index` the view, corresponding to the action name.
|
849
|
+
#
|
850
|
+
# This pattern MUST always contain `"%{controller}"` and `%{action}`.
|
851
|
+
# This pattern SHOULD be used accordingly to `#controller_pattern` value.
|
852
|
+
#
|
853
|
+
# This is part of a DSL, for this reason when this method is called with
|
854
|
+
# an argument, it will set the corresponding instance variable. When
|
855
|
+
# called without, it will return the already set value, or the default.
|
856
|
+
#
|
857
|
+
# @overload view_pattern(value)
|
858
|
+
# Sets the given value
|
859
|
+
# @param value [String] the view pattern
|
860
|
+
#
|
861
|
+
# @overload controller_pattern
|
862
|
+
# Gets the value
|
863
|
+
# @return [String]
|
864
|
+
#
|
865
|
+
# @since 0.1.0
|
866
|
+
#
|
867
|
+
# @see Lotus::Configuration#controller_pattern
|
868
|
+
#
|
869
|
+
# @example Getting the value
|
870
|
+
# require 'lotus'
|
871
|
+
#
|
872
|
+
# module Bookshelf
|
873
|
+
# class Application < Lotus::Application
|
874
|
+
# configure do
|
875
|
+
# routes do
|
876
|
+
# get '/', to: 'dashboard#index'
|
877
|
+
# end
|
878
|
+
# end
|
879
|
+
# end
|
880
|
+
#
|
881
|
+
# module Views
|
882
|
+
# module Dashboard
|
883
|
+
# class Index
|
884
|
+
# include Bookshelf::View
|
885
|
+
# end
|
886
|
+
# end
|
887
|
+
# end
|
888
|
+
# end
|
889
|
+
#
|
890
|
+
# Bookshelf::Application.configuration.view_pattern
|
891
|
+
# # => "Views::%{controller}::%{action}"
|
892
|
+
#
|
893
|
+
# # All the views MUST live under Bookshelf::Views
|
894
|
+
#
|
895
|
+
# # GET '/' # => Bookshelf::Views::Dashboard::Index
|
896
|
+
#
|
897
|
+
# @example Setting the value
|
898
|
+
# require 'lotus'
|
899
|
+
#
|
900
|
+
# module Bookshelf
|
901
|
+
# class Application < Lotus::Application
|
902
|
+
# configure do
|
903
|
+
# view_pattern "%{controller}::%{action}"
|
904
|
+
#
|
905
|
+
# routes do
|
906
|
+
# get '/', to: 'dashboard#index'
|
907
|
+
# end
|
908
|
+
# end
|
909
|
+
# end
|
910
|
+
#
|
911
|
+
# module Dashboard
|
912
|
+
# class Index
|
913
|
+
# include Bookshelf::View
|
914
|
+
# end
|
915
|
+
# end
|
916
|
+
# end
|
917
|
+
#
|
918
|
+
# Bookshelf::Application.configuration.view_pattern
|
919
|
+
# # => "%{controller}::%{action}"
|
920
|
+
#
|
921
|
+
# # All the views are directly under the Bookshelf module
|
922
|
+
#
|
923
|
+
# # GET '/' # => Bookshelf::Dashboard::Index
|
924
|
+
#
|
925
|
+
# @example Setting the value for a top level name structure
|
926
|
+
# require 'lotus'
|
927
|
+
#
|
928
|
+
# module Bookshelf
|
929
|
+
# class Application < Lotus::Application
|
930
|
+
# configure do
|
931
|
+
# namespace Object
|
932
|
+
# view_pattern "%{controller}::%{action}"
|
933
|
+
#
|
934
|
+
# routes do
|
935
|
+
# get '/', to: 'dashboard#index'
|
936
|
+
# end
|
937
|
+
# end
|
938
|
+
# end
|
939
|
+
# end
|
940
|
+
#
|
941
|
+
# module Dashboard
|
942
|
+
# class Index
|
943
|
+
# include Bookshelf::View
|
944
|
+
# end
|
945
|
+
# end
|
946
|
+
#
|
947
|
+
# Bookshelf::Application.configuration.view_pattern
|
948
|
+
# # => "%{controller}::%{action}"
|
949
|
+
#
|
950
|
+
# # All the views: are at the top level namespace
|
951
|
+
#
|
952
|
+
# # GET '/' # => Dashboard::Index
|
953
|
+
def view_pattern(value = nil)
|
954
|
+
if value
|
955
|
+
@view_pattern = value
|
956
|
+
else
|
957
|
+
@view_pattern ||= 'Views::%{controller}::%{action}'
|
958
|
+
end
|
959
|
+
end
|
960
|
+
end
|
961
|
+
end
|