action_blocks 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 +7 -0
- data/LICENSE +21 -0
- data/README.md +121 -0
- data/Rakefile +33 -0
- data/app/assets/config/action_blocks.js +2 -0
- data/app/assets/javascripts/action_blocks/application.js +15 -0
- data/app/assets/stylesheets/action_blocks/application.css +15 -0
- data/app/controllers/action_blocks/attachments_controller.rb +22 -0
- data/app/controllers/action_blocks/barchart_blocks_controller.rb +14 -0
- data/app/controllers/action_blocks/base_controller.rb +22 -0
- data/app/controllers/action_blocks/blocks_controller.rb +16 -0
- data/app/controllers/action_blocks/command_blocks_controller.rb +6 -0
- data/app/controllers/action_blocks/form_blocks_controller.rb +13 -0
- data/app/controllers/action_blocks/model_blocks_controller.rb +13 -0
- data/app/controllers/action_blocks/table_blocks_controller.rb +13 -0
- data/app/controllers/action_blocks/workspace_blocks_controller.rb +6 -0
- data/app/helpers/action_blocks/application_helper.rb +4 -0
- data/app/jobs/action_blocks/application_job.rb +4 -0
- data/app/mailers/action_blocks/application_mailer.rb +6 -0
- data/app/models/action_blocks/application_record.rb +5 -0
- data/app/views/layouts/action_blocks/application.html.erb +16 -0
- data/config/initializers/action_blocks.rb +9 -0
- data/config/routes.rb +10 -0
- data/lib/action_block_loader.rb +120 -0
- data/lib/action_blocks.rb +76 -0
- data/lib/action_blocks/builders/authorization_builder.rb +21 -0
- data/lib/action_blocks/builders/barchart_builder.rb +48 -0
- data/lib/action_blocks/builders/base_builder.rb +221 -0
- data/lib/action_blocks/builders/block_type.rb +11 -0
- data/lib/action_blocks/builders/command_builder.rb +6 -0
- data/lib/action_blocks/builders/form_builder.rb +117 -0
- data/lib/action_blocks/builders/layout_builder.rb +15 -0
- data/lib/action_blocks/builders/model_builder.rb +566 -0
- data/lib/action_blocks/builders/summary_field_aggregation_functions.rb +41 -0
- data/lib/action_blocks/builders/table_builder.rb +259 -0
- data/lib/action_blocks/builders/workspace_builder.rb +282 -0
- data/lib/action_blocks/data_engine/authorization_adapter.rb +127 -0
- data/lib/action_blocks/data_engine/data_engine.rb +116 -0
- data/lib/action_blocks/data_engine/database_functions.rb +39 -0
- data/lib/action_blocks/data_engine/fields_engine.rb +103 -0
- data/lib/action_blocks/data_engine/filter_adapter.rb +105 -0
- data/lib/action_blocks/data_engine/filter_engine.rb +88 -0
- data/lib/action_blocks/data_engine/selections_via_where_engine.rb +134 -0
- data/lib/action_blocks/data_engine/summary_engine.rb +72 -0
- data/lib/action_blocks/engine.rb +5 -0
- data/lib/action_blocks/error.rb +62 -0
- data/lib/action_blocks/generator_helper.rb +134 -0
- data/lib/action_blocks/generators/action_blocks/model_block/USAGE +8 -0
- data/lib/action_blocks/generators/action_blocks/model_block/model_block_generator.rb +17 -0
- data/lib/action_blocks/generators/action_blocks/model_block/templates/model_block.rb +13 -0
- data/lib/action_blocks/generators/action_blocks/type/USAGE +8 -0
- data/lib/action_blocks/generators/action_blocks/type/templates/controller.rb +3 -0
- data/lib/action_blocks/generators/action_blocks/type/templates/dsl.rb +38 -0
- data/lib/action_blocks/generators/action_blocks/type/templates/type.css +3 -0
- data/lib/action_blocks/generators/action_blocks/type/templates/type.js +22 -0
- data/lib/action_blocks/generators/action_blocks/type/type_generator.rb +33 -0
- data/lib/action_blocks/store.rb +151 -0
- data/lib/action_blocks/version.rb +3 -0
- data/lib/generators/active_blocks/model_block/USAGE +8 -0
- data/lib/generators/active_blocks/model_block/model_block_generator.rb +17 -0
- data/lib/generators/active_blocks/model_block/templates/model_block.rb +13 -0
- data/lib/generators/active_blocks/type/USAGE +8 -0
- data/lib/generators/active_blocks/type/templates/controller.rb +3 -0
- data/lib/generators/active_blocks/type/templates/dsl.rb +38 -0
- data/lib/generators/active_blocks/type/templates/type.css +3 -0
- data/lib/generators/active_blocks/type/templates/type.js +22 -0
- data/lib/generators/active_blocks/type/type_generator.rb +33 -0
- data/lib/tasks/active_blocks_tasks.rake +4 -0
- metadata +128 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'rails/generators/base'
|
|
2
|
+
require 'rails/generators/resource_helpers'
|
|
3
|
+
|
|
4
|
+
module ActionBlocks
|
|
5
|
+
module Generators
|
|
6
|
+
class ModelBlockGenerator < Rails::Generators::NamedBase
|
|
7
|
+
include ::Rails::Generators::ResourceHelpers
|
|
8
|
+
include ActionBlocks::GeneratorHelper
|
|
9
|
+
|
|
10
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
11
|
+
|
|
12
|
+
def view_templates
|
|
13
|
+
template "model_block.rb", "app/blocks/#{variable}_model_block.rb"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
ActionBlocks.model <%=variable.to_sym.inspect%> do
|
|
2
|
+
active_model <%=class_name%>
|
|
3
|
+
singular_name <%=class_name.titleize.inspect%>
|
|
4
|
+
plural_name <%=class_name.pluralize.titleize.inspect%>
|
|
5
|
+
name_column <%=content_columns.first.to_sym.inspect%>
|
|
6
|
+
sort {date_created: :desc}
|
|
7
|
+
|
|
8
|
+
# Columns
|
|
9
|
+
<%content_column_details.each do |attribute| -%>
|
|
10
|
+
<%=attribute.type%> <%=attribute.name.to_sym.inspect%>
|
|
11
|
+
<%end -%>
|
|
12
|
+
|
|
13
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module ActionBlocks
|
|
2
|
+
class <%=class_name%>Builder < ActionBlocks::BlockType
|
|
3
|
+
block_type :<%=variable%>
|
|
4
|
+
<%@fields.each do |f| -%>
|
|
5
|
+
sets :<%=variableize(f)%>
|
|
6
|
+
<%end -%>
|
|
7
|
+
<%@builds.each do |b| -%>
|
|
8
|
+
# builds :<%=variableize(b)%>, 'ActionBlocks::<%=variableize(b).camelize%>Builder'
|
|
9
|
+
# builds_many :<%=variableize(b).pluralize%>, :<%=variableize(b)%>, 'ActionBlocks::<%=variableize(b).camelize%>Builder'
|
|
10
|
+
<%end -%>
|
|
11
|
+
|
|
12
|
+
# to json
|
|
13
|
+
def hashify(user)
|
|
14
|
+
{
|
|
15
|
+
<%@fields.each do |f| -%>
|
|
16
|
+
<%=variableize(f)%>: @<%=variable%>.<%=variableize(f)%>,
|
|
17
|
+
<%end -%>
|
|
18
|
+
<%@builds.each do |f| -%>
|
|
19
|
+
<%=variableize(f)%>: @<%=variableize(f)%>,
|
|
20
|
+
<%end -%>
|
|
21
|
+
key: key,
|
|
22
|
+
type: type,
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
<%@builds.each do |b| -%>
|
|
28
|
+
class <%=class_name%>Builder < ActionBlocks::BaseBuilder
|
|
29
|
+
|
|
30
|
+
def hashify(user)
|
|
31
|
+
key: key,
|
|
32
|
+
type: type,
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
<%end -%>
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { Component, createContext, Fragment } from 'react';
|
|
2
|
+
import { Router, Link } from "@reach/router"
|
|
3
|
+
import { navigate } from "@reach/router"
|
|
4
|
+
import BlockConsumer from '../BlockConsumer';
|
|
5
|
+
|
|
6
|
+
import './<%=class_name%>.css';
|
|
7
|
+
|
|
8
|
+
class <%=class_name%> extends Component {
|
|
9
|
+
|
|
10
|
+
render() {
|
|
11
|
+
const block = this.props.block;
|
|
12
|
+
const blocks = this.props.blocks;
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div className="ActionBlock-<%=class_name%>">
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default BlockConsumer(<%=class_name%>);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'rails/generators/base'
|
|
2
|
+
require 'rails/generators/resource_helpers'
|
|
3
|
+
|
|
4
|
+
module ActionBlocks
|
|
5
|
+
module Generators
|
|
6
|
+
class TypeGenerator < Rails::Generators::NamedBase
|
|
7
|
+
attr_accessor :fields, :sub_blocks
|
|
8
|
+
include ::Rails::Generators::ResourceHelpers
|
|
9
|
+
include ActionBlocks::GeneratorHelper
|
|
10
|
+
|
|
11
|
+
class_option :fields, type: :array, default: []
|
|
12
|
+
class_option :builds, type: :array, default: []
|
|
13
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
14
|
+
|
|
15
|
+
def view_templates
|
|
16
|
+
# @struct_methods = ask("Struct Methods: (e.g. title)").split()
|
|
17
|
+
# @builder_methods = ask("Builder Methods: (e.g. string_field, float_field)").split()
|
|
18
|
+
@fields = options[:fields]
|
|
19
|
+
@builds = options[:builds]
|
|
20
|
+
template "dsl.rb", "lib/action_blocks/#{variable}_builder.rb"
|
|
21
|
+
template "controller.rb", "app/controllers/#{variable}_blocks_controller.rb"
|
|
22
|
+
template "type.css", "client/src/ActionBlocks/#{class_name}/#{class_name}.css"
|
|
23
|
+
template "type.js", "client/src/ActionBlocks/#{class_name}/#{class_name}.js"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def dsl_attr_accessors
|
|
29
|
+
[variable, @builds].flatten.map {|f|f.to_sym.inspect}.join(", ")
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# ActionBlocks.method delegates calls to here
|
|
2
|
+
|
|
3
|
+
module ActionBlocks
|
|
4
|
+
class Store
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
super
|
|
8
|
+
@block_store = {};
|
|
9
|
+
@validation_store = [];
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# ActionBlocks.layout
|
|
13
|
+
def layout(*p, &block)
|
|
14
|
+
l = ActionBlocks::LayoutBuilder.new()
|
|
15
|
+
l.id = 'main'
|
|
16
|
+
l.before_build(nil, *p)
|
|
17
|
+
store(l)
|
|
18
|
+
add_to_validator(l)
|
|
19
|
+
l.evaluate(&block) if block
|
|
20
|
+
l.after_build(nil, *p)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def form(*p, &block)
|
|
24
|
+
rs = ActionBlocks::FormBuilder.new()
|
|
25
|
+
rs.id = p.first
|
|
26
|
+
rs.before_build(nil, *p)
|
|
27
|
+
store(rs)
|
|
28
|
+
add_to_validator(rs)
|
|
29
|
+
rs.evaluate(&block) if block
|
|
30
|
+
rs.after_build(nil, *p)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def authorization(*p, &block)
|
|
34
|
+
rs = ActionBlocks::AuthorizationBuilder.new()
|
|
35
|
+
rs.active_model = p.first
|
|
36
|
+
rs.id = rs.active_model.to_s.underscore
|
|
37
|
+
rs.before_build(nil, *p)
|
|
38
|
+
store(rs)
|
|
39
|
+
add_to_validator(rs)
|
|
40
|
+
rs.evaluate(&block) if block
|
|
41
|
+
rs.after_build(nil, *p)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def model(*p, &block)
|
|
45
|
+
m = ActionBlocks::ModelBuilder.new()
|
|
46
|
+
m.id = p.first
|
|
47
|
+
m.before_build(nil, *p)
|
|
48
|
+
store(m)
|
|
49
|
+
add_to_validator(m)
|
|
50
|
+
m.evaluate(&block) if block
|
|
51
|
+
m.after_build(nil, *p)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def valid?
|
|
55
|
+
@validation_store.all? { |builder| builder.valid? }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def invalid?
|
|
59
|
+
!valid?
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# def errors
|
|
63
|
+
# results = []
|
|
64
|
+
# @validation_store.each do |b|
|
|
65
|
+
# results << b.errors if b.invalid?
|
|
66
|
+
# end
|
|
67
|
+
# results
|
|
68
|
+
# end
|
|
69
|
+
|
|
70
|
+
def errors
|
|
71
|
+
results = []
|
|
72
|
+
@validation_store.each do |b|
|
|
73
|
+
results << {
|
|
74
|
+
builder: b.class.to_s.sub("ActionBlocks::",""),
|
|
75
|
+
key: b.key,
|
|
76
|
+
fields: b.errors.keys,
|
|
77
|
+
messages: b.errors.map {|k,v| [k,v]}
|
|
78
|
+
} if b.invalid?
|
|
79
|
+
end
|
|
80
|
+
results
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def has_error_for(block_type, field_name)
|
|
84
|
+
type_errors = errors.select { |e|
|
|
85
|
+
e[:builder] == block_type &&
|
|
86
|
+
e[:fields].include?(field_name)
|
|
87
|
+
}
|
|
88
|
+
if type_errors == []
|
|
89
|
+
return false
|
|
90
|
+
else
|
|
91
|
+
return type_errors
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def has_error(substring)
|
|
96
|
+
all_errors = errors.map {|e| e.messages}.map {|h| h.values}.flatten.join("\n")
|
|
97
|
+
all_errors[substring]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def unload!
|
|
101
|
+
# If classes were dynamically created.
|
|
102
|
+
# We would remove const here (JRH)
|
|
103
|
+
@block_store = {};
|
|
104
|
+
@validation_store = [];
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def keys()
|
|
108
|
+
@block_store.keys
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def store(block)
|
|
112
|
+
@block_store[block.key] = block
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def add_to_validator(builder)
|
|
116
|
+
@validation_store << builder
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def find(block_key)
|
|
120
|
+
@block_store[block_key]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def get(params)
|
|
124
|
+
@block_store[params[:block_key]].get(params)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def hashify(user)
|
|
128
|
+
result = {}
|
|
129
|
+
@block_store.each do |key, block|
|
|
130
|
+
result[block.key] = block.hashify(user)
|
|
131
|
+
result[block.key][:key] = block.key
|
|
132
|
+
end
|
|
133
|
+
result[:errors] = errors
|
|
134
|
+
result
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def freeze_builders
|
|
138
|
+
@block_store.values.each do |v|
|
|
139
|
+
v.freeze
|
|
140
|
+
puts "#Freezing #{v.key}"
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def after_load
|
|
145
|
+
@validation_store.each do |v|
|
|
146
|
+
v.after_load
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
end
|
|
151
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'rails/generators/base'
|
|
2
|
+
require 'rails/generators/resource_helpers'
|
|
3
|
+
|
|
4
|
+
module ActionBlocks
|
|
5
|
+
module Generators
|
|
6
|
+
class ModelBlockGenerator < Rails::Generators::NamedBase
|
|
7
|
+
include ::Rails::Generators::ResourceHelpers
|
|
8
|
+
include ActionBlocks::GeneratorHelper
|
|
9
|
+
|
|
10
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
11
|
+
|
|
12
|
+
def view_templates
|
|
13
|
+
template "model_block.rb", "app/blocks/#{variable}_model_block.rb"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
ActionBlocks.model <%=variable.to_sym.inspect%> do
|
|
2
|
+
<%=class_name%>
|
|
3
|
+
singular_name <%=class_name.titleize.inspect%>
|
|
4
|
+
plural_name <%=class_name.pluralize.titleize.inspect%>
|
|
5
|
+
name_column <%=content_columns.first.to_sym.inspect%>
|
|
6
|
+
sort {date_created: :desc}
|
|
7
|
+
|
|
8
|
+
# Columns
|
|
9
|
+
<%content_column_details.each do |attribute| -%>
|
|
10
|
+
<%=attribute.type%> <%=attribute.name.to_sym.inspect%>
|
|
11
|
+
<%end -%>
|
|
12
|
+
|
|
13
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module ActionBlocks
|
|
2
|
+
class <%=class_name%>Builder < ActionBlocks::BlockType
|
|
3
|
+
block_type :<%=variable%>
|
|
4
|
+
<%@fields.each do |f| -%>
|
|
5
|
+
sets :<%=variableize(f)%>
|
|
6
|
+
<%end -%>
|
|
7
|
+
<%@builds.each do |b| -%>
|
|
8
|
+
# builds :<%=variableize(b)%>, 'ActionBlocks::<%=variableize(b).camelize%>Builder'
|
|
9
|
+
# builds_many :<%=variableize(b).pluralize%>, :<%=variableize(b)%>, 'ActionBlocks::<%=variableize(b).camelize%>Builder'
|
|
10
|
+
<%end -%>
|
|
11
|
+
|
|
12
|
+
# to json
|
|
13
|
+
def hashify(user)
|
|
14
|
+
{
|
|
15
|
+
<%@fields.each do |f| -%>
|
|
16
|
+
<%=variableize(f)%>: @<%=variable%>.<%=variableize(f)%>,
|
|
17
|
+
<%end -%>
|
|
18
|
+
<%@builds.each do |f| -%>
|
|
19
|
+
<%=variableize(f)%>: @<%=variableize(f)%>,
|
|
20
|
+
<%end -%>
|
|
21
|
+
key: key,
|
|
22
|
+
type: type,
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
<%@builds.each do |b| -%>
|
|
28
|
+
class <%=class_name%>Builder < ActionBlocks::BaseBuilder
|
|
29
|
+
|
|
30
|
+
def hashify(user)
|
|
31
|
+
key: key,
|
|
32
|
+
type: type,
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
<%end -%>
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { Component, createContext, Fragment } from 'react';
|
|
2
|
+
import { Router, Link } from "@reach/router"
|
|
3
|
+
import { navigate } from "@reach/router"
|
|
4
|
+
import BlockConsumer from '../BlockConsumer';
|
|
5
|
+
|
|
6
|
+
import './<%=class_name%>.css';
|
|
7
|
+
|
|
8
|
+
class <%=class_name%> extends Component {
|
|
9
|
+
|
|
10
|
+
render() {
|
|
11
|
+
const block = this.props.block;
|
|
12
|
+
const blocks = this.props.blocks;
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div className="ActionBlock-<%=class_name%>">
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default BlockConsumer(<%=class_name%>);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'rails/generators/base'
|
|
2
|
+
require 'rails/generators/resource_helpers'
|
|
3
|
+
|
|
4
|
+
module ActionBlocks
|
|
5
|
+
module Generators
|
|
6
|
+
class TypeGenerator < Rails::Generators::NamedBase
|
|
7
|
+
attr_accessor :fields, :sub_blocks
|
|
8
|
+
include ::Rails::Generators::ResourceHelpers
|
|
9
|
+
include ActionBlocks::GeneratorHelper
|
|
10
|
+
|
|
11
|
+
class_option :fields, type: :array, default: []
|
|
12
|
+
class_option :builds, type: :array, default: []
|
|
13
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
14
|
+
|
|
15
|
+
def view_templates
|
|
16
|
+
# @struct_methods = ask("Struct Methods: (e.g. title)").split()
|
|
17
|
+
# @builder_methods = ask("Builder Methods: (e.g. string_field, float_field)").split()
|
|
18
|
+
@fields = options[:fields]
|
|
19
|
+
@builds = options[:builds]
|
|
20
|
+
template "dsl.rb", "lib/action_blocks/#{variable}_builder.rb"
|
|
21
|
+
template "controller.rb", "app/controllers/#{variable}_blocks_controller.rb"
|
|
22
|
+
template "type.css", "client/src/ActionBlocks/#{class_name}/#{class_name}.css"
|
|
23
|
+
template "type.js", "client/src/ActionBlocks/#{class_name}/#{class_name}.js"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def dsl_attr_accessors
|
|
29
|
+
[variable, @builds].flatten.map {|f|f.to_sym.inspect}.join(", ")
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|