dryml 1.3.3 → 1.4.0.pre2

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.
Files changed (44) hide show
  1. data/Gemfile +6 -0
  2. data/README +2 -0
  3. data/Rakefile +2 -1
  4. data/VERSION +1 -1
  5. data/cucumber.yml +9 -0
  6. data/dryml.gemspec +4 -2
  7. data/features/cookbook/01_simple_page_templates.feature +44 -0
  8. data/features/cookbook/02_defining_simple_tags.feature +375 -0
  9. data/features/cookbook/03_implicit_context.feature +229 -0
  10. data/features/cookbook/04_tag_attributes.feature +120 -0
  11. data/features/cookbook/05_repeated_and_optional_content.feature +241 -0
  12. data/features/cookbook/06_pseudo_parameters.feature +191 -0
  13. data/features/cookbook/07_nested_parameters.feature +147 -0
  14. data/features/cookbook/08_customizing_tags.feature +307 -0
  15. data/features/cookbook/09_aliasing_tags.feature +50 -0
  16. data/features/cookbook/10_polymorphic_tags.feature +168 -0
  17. data/features/cookbook/11_wrapping_content.feature +57 -0
  18. data/features/cookbook/12_local_and_scoped_variables.feature +102 -0
  19. data/features/doctest_examples.feature +187 -0
  20. data/features/merge_params.feature +36 -0
  21. data/features/replace_parameters.feature +21 -0
  22. data/features/static_tags.feature +91 -0
  23. data/features/step_definitions/contexts.rb +25 -0
  24. data/features/step_definitions/dom_comparison.rb +10 -0
  25. data/features/step_definitions/rendering.rb +21 -0
  26. data/features/support/env.rb +32 -0
  27. data/features/support/models/author.rb +18 -0
  28. data/features/support/models/blog_post.rb +37 -0
  29. data/features/support/models/discussion.rb +15 -0
  30. data/features/support/models/post.rb +12 -0
  31. data/features/support/strip_formatter.rb +14 -0
  32. data/lib/dryml/dryml_builder.rb +4 -14
  33. data/lib/dryml/dryml_doc.rb +6 -1
  34. data/lib/dryml/helper.rb +17 -1
  35. data/lib/dryml/part_context.rb +12 -15
  36. data/lib/dryml/railtie/template_handler.rb +1 -3
  37. data/lib/dryml/railtie.rb +1 -0
  38. data/lib/dryml/taglib.rb +24 -30
  39. data/lib/dryml/template.rb +32 -86
  40. data/lib/dryml/template_environment.rb +40 -17
  41. data/lib/dryml.rb +22 -11
  42. data/taglibs/core.dryml +18 -12
  43. data/taglibs/dryml.dryml +3 -0
  44. metadata +97 -56
@@ -0,0 +1,191 @@
1
+ Feature: Pseudo-parameters: before, after, append and prepend
2
+
3
+ Background:
4
+ Given a file named "example_taglib.dryml" with:
5
+ """
6
+ <def tag="page">
7
+ <body>
8
+ <h1 param="heading"><%= this.name %></h1>
9
+ <div param="content"></div>
10
+ </body>
11
+ </def>
12
+
13
+ <def tag="help-link" attrs="file, new-window">
14
+ <a class="help" href="/help/#{file}.html" target="#{new_window ? '_blank' : '_self' }" param="default"/>
15
+ </def>
16
+
17
+ <def tag="decorated-help" attrs="image, alt">
18
+ <help-link merge-attrs="&attributes - attrs_for(:help_link)">
19
+ <img src="/images/#{image}.png" alt="#{alt || image}" /><do param="default"/>
20
+ </help-link>
21
+ </def>
22
+
23
+ <def tag="helpful-page">
24
+ <page merge>
25
+ <content:>
26
+ <decorated-help image="intro" param>Intro Help</decorated-help>
27
+ </content:>
28
+ </page>
29
+ </def>
30
+ """
31
+ When I include the taglib "example_taglib"
32
+
33
+ Scenario: append parameter
34
+ Given a file named "example.dryml" with:
35
+ """
36
+ <page>
37
+ <append-heading:> -- The Hobo Blog</append-heading:>
38
+ <content:>
39
+ <%= this.body %>
40
+ </content>
41
+ </page>
42
+ """
43
+ When the current context is a blog post
44
+ And I render "example.dryml"
45
+ Then the output DOM should be:
46
+ """
47
+ <body>
48
+ <h1 class="heading">A Blog Post -- The Hobo Blog</h1>
49
+ <div class="content">
50
+ Some body content
51
+ </div>
52
+ </body>
53
+ """
54
+
55
+ Scenario: prepend parameter
56
+ Given a file named "example.dryml" with:
57
+ """
58
+ <page>
59
+ <prepend-heading:>The Hobo Blog -- </prepend-heading:>
60
+ <content:>
61
+ <%= this.body %>
62
+ </content>
63
+ </page>
64
+ """
65
+ When the current context is a blog post
66
+ And I render "example.dryml"
67
+ Then the output DOM should be:
68
+ """
69
+ <body>
70
+ <h1 class="heading">The Hobo Blog -- A Blog Post</h1>
71
+ <div class="content">
72
+ Some body content
73
+ </div>
74
+ </body>
75
+ """
76
+
77
+ Scenario: before parameter
78
+ Given a file named "example.dryml" with:
79
+ """
80
+ <page>
81
+ <before-heading:><h1>The Hobo Blog</h1></before-heading:>
82
+ <content:>
83
+ <%= this.body %>
84
+ </content>
85
+ </page>
86
+ """
87
+ When the current context is a blog post
88
+ And I render "example.dryml"
89
+ Then the output DOM should be:
90
+ """
91
+ <body>
92
+ <h1>The Hobo Blog</h1>
93
+ <h1 class="heading">A Blog Post</h1>
94
+ <div class="content">
95
+ Some body content
96
+ </div>
97
+ </body>
98
+ """
99
+
100
+ Scenario: after parameter
101
+ Given a file named "example.dryml" with:
102
+ """
103
+ <page>
104
+ <after-heading:><h1>The Hobo Blog</h1></after-heading:>
105
+ <content:>
106
+ <%= this.body %>
107
+ </content>
108
+ </page>
109
+ """
110
+ When the current context is a blog post
111
+ And I render "example.dryml"
112
+ Then the output DOM should be:
113
+ """
114
+ <body>
115
+ <h1 class="heading">A Blog Post</h1>
116
+ <h1>The Hobo Blog</h1>
117
+ <div class="content">
118
+ Some body content
119
+ </div>
120
+ </body>
121
+ """
122
+
123
+ Scenario: append parameter uses the default parameter
124
+ Given a file named "example.dryml" with:
125
+ """
126
+ <helpful-page>
127
+ <append-decorated-help:> And More</append-decorated-help:>
128
+ </helpful-page>
129
+ """
130
+ When the current context is a blog post
131
+ And I render "example.dryml"
132
+ Then the output DOM should be:
133
+ """
134
+ <body>
135
+ <h1 class="heading">A Blog Post</h1>
136
+ <div class="content">
137
+ <a class="help" href="/help/.html" target="_self">
138
+ <img alt="intro" src="/images/intro.png"/>Intro Help And More
139
+ </a>
140
+ </div>
141
+ </body>
142
+ """
143
+
144
+ Scenario: a replace parameter
145
+ Given a file named "example.dryml" with:
146
+ """
147
+ <page>
148
+ <heading: replace><h2>My Awesome Page</h2></heading:>
149
+ <content:>Some content</content:>
150
+ </page>
151
+ """
152
+ When I render "example.dryml"
153
+ Then the output DOM should be:
154
+ """
155
+ <body>
156
+ <h2>My Awesome Page</h2>
157
+ <div class="content">Some content</div>
158
+ </body>
159
+ """
160
+
161
+ Scenario: a replace parameter with no content
162
+ Given a file named "example.dryml" with:
163
+ """
164
+ <page>
165
+ <heading: replace />
166
+ <content:>Some content</content:>
167
+ </page>
168
+ """
169
+ When I render "example.dryml"
170
+ Then the output DOM should be:
171
+ """
172
+ <body>
173
+ <div class="content">Some content</div>
174
+ </body>
175
+ """
176
+
177
+ Scenario: using without
178
+ Given a file named "example.dryml" with:
179
+ """
180
+ <page without-heading>
181
+ <content:>Some content</content:>
182
+ </page>
183
+ """
184
+ When I render "example.dryml"
185
+ Then the output DOM should be:
186
+ """
187
+ <body>
188
+ <div class="content">Some content</div>
189
+ </body>
190
+ """
191
+
@@ -0,0 +1,147 @@
1
+ Feature: Nested parameters
2
+
3
+ Background:
4
+ Given a file named "example_taglib.dryml" with:
5
+ """
6
+ <def tag="card">
7
+ <div class="card" merge-attrs>
8
+ <h3 param="heading"><%= this.name %></h3>
9
+ <div param="body"></div>
10
+ </div>
11
+ </def>
12
+
13
+ <def tag="collection">
14
+ <h2 param="heading"></h2>
15
+ <ul>
16
+ <li repeat>
17
+ <card param />
18
+ </li>
19
+ </ul>
20
+ </def>
21
+
22
+ <def tag="index-page">
23
+ <html>
24
+ <head><title param>Index Page</title></head>
25
+ <body>
26
+ <h1 param="heading"></h1>
27
+ <collection param />
28
+ </body>
29
+ </html>
30
+ </def>
31
+ """
32
+ When I include the taglib "example_taglib"
33
+
34
+ Scenario: Single level of nesting
35
+ Given a file named "example.dryml" with:
36
+ """
37
+ <collection>
38
+ <heading:>Discussions</heading:>
39
+ <card:><body:><%= this.posts.length %> posts</body:></card:>
40
+ </collection>
41
+ """
42
+ When the current context is a list of discussions
43
+ And I render "example.dryml"
44
+ Then the output DOM should be:
45
+ """
46
+ <h2 class="heading">Discussions</h2>
47
+ <ul>
48
+ <li>
49
+ <div class="card">
50
+ <h3 class="heading">Discussion 1</h3>
51
+ <div class="body">1 posts</div>
52
+ </div>
53
+ </li>
54
+ <li>
55
+ <div class="card">
56
+ <h3 class="heading">Discussion 2</h3>
57
+ <div class="body">2 posts</div>
58
+ </div>
59
+ </li>
60
+ <li>
61
+ <div class="card">
62
+ <h3 class="heading">Discussion 3</h3>
63
+ <div class="body">3 posts</div>
64
+ </div>
65
+ </li>
66
+ </ul>
67
+ """
68
+
69
+ Scenario: Single level of nesting with extra attributes
70
+ Given a file named "example.dryml" with:
71
+ """
72
+ <collection>
73
+ <heading:>Discussions</heading:>
74
+ <card: class="#{scope.even_odd}"><body:><%= this.posts.length %> posts</body:></card:>
75
+ </collection>
76
+ """
77
+ When the current context is a list of discussions
78
+ And I render "example.dryml"
79
+ Then the output DOM should be:
80
+ """
81
+ <h2 class="heading">Discussions</h2>
82
+ <ul>
83
+ <li>
84
+ <div class="card odd">
85
+ <h3 class="heading">Discussion 1</h3>
86
+ <div class="body">1 posts</div>
87
+ </div>
88
+ </li>
89
+ <li>
90
+ <div class="card even">
91
+ <h3 class="heading">Discussion 2</h3>
92
+ <div class="body">2 posts</div>
93
+ </div>
94
+ </li>
95
+ <li>
96
+ <div class="card odd">
97
+ <h3 class="heading">Discussion 3</h3>
98
+ <div class="body">3 posts</div>
99
+ </div>
100
+ </li>
101
+ </ul>
102
+ """
103
+
104
+ Scenario: Multiple levels of nesting
105
+ Given a file named "example.dryml" with:
106
+ """
107
+ <index-page>
108
+ <heading:>Welcome to our forum</heading:>
109
+ <collection:>
110
+ <heading:>Discussions</heading:>
111
+ <card:><body:><%= this.posts.length %> posts</body:></card:>
112
+ </collection:>
113
+ </index-page>
114
+ """
115
+ When the current context is a list of discussions
116
+ And I render "example.dryml"
117
+ Then the output DOM should be:
118
+ """
119
+ <html>
120
+ <head><title>Index Page</title></head>
121
+ <body>
122
+ <h1 class="heading">Welcome to our forum</h1>
123
+ <h2 class="heading">Discussions</h2>
124
+ <ul>
125
+ <li>
126
+ <div class="card">
127
+ <h3 class="heading">Discussion 1</h3>
128
+ <div class="body">1 posts</div>
129
+ </div>
130
+ </li>
131
+ <li>
132
+ <div class="card">
133
+ <h3 class="heading">Discussion 2</h3>
134
+ <div class="body">2 posts</div>
135
+ </div>
136
+ </li>
137
+ <li>
138
+ <div class="card">
139
+ <h3 class="heading">Discussion 3</h3>
140
+ <div class="body">3 posts</div>
141
+ </div>
142
+ </li>
143
+ </ul>
144
+ </body>
145
+ </html>
146
+ """
147
+
@@ -0,0 +1,307 @@
1
+ Feature: Customizing tags
2
+
3
+ Scenario: a broken custom tag
4
+ Given a file named "example_taglib.dryml" with:
5
+ """
6
+ <def tag="card">
7
+ <div class="card" merge-attrs>
8
+ <h3 param="heading"><%= this.name %></h3>
9
+ <div param="body"></div>
10
+ </div>
11
+ </def>
12
+
13
+ <def tag="linked-card">
14
+ <card>
15
+ <heading: param><a href="&this.url"><%= this.name %></a></heading:>
16
+ </card>
17
+ </def>
18
+ """
19
+ And a file named "example.dryml" with:
20
+ """
21
+ <linked-card class="emphasized">
22
+ <body:><%= this.body %></body:>
23
+ </linked-card>
24
+ """
25
+ When I include the taglib "example_taglib"
26
+ And the current context is a blog post
27
+ And I render "example.dryml"
28
+ Then the output DOM should be:
29
+ """
30
+ <div class="card">
31
+ <h3 class="heading">
32
+ <a href="/blog_posts/1">A Blog Post</a>
33
+ </h3>
34
+ <div class="body"/>
35
+ </div>
36
+ """
37
+
38
+ Scenario: merging attributes for a custom tag
39
+ Given a file named "example_taglib.dryml" with:
40
+ """
41
+ <def tag="card">
42
+ <div class="card" merge-attrs>
43
+ <h3 param="heading"><%= this.name %></h3>
44
+ <div param="body"></div>
45
+ </div>
46
+ </def>
47
+
48
+ <def tag="linked-card">
49
+ <card merge-attrs>
50
+ <heading: param><a href="&this.url"><%= this.name %></a></heading:>
51
+ </card>
52
+ </def>
53
+ """
54
+ And a file named "example.dryml" with:
55
+ """
56
+ <linked-card class="emphasized">
57
+ <body:><%= this.body %></body:>
58
+ </linked-card>
59
+ """
60
+ When I include the taglib "example_taglib"
61
+ And the current context is a blog post
62
+ And I render "example.dryml"
63
+ Then the output DOM should be:
64
+ """
65
+ <div class="card emphasized">
66
+ <h3 class="heading">
67
+ <a href="/blog_posts/1">A Blog Post</a>
68
+ </h3>
69
+ <div class="body"/>
70
+ </div>
71
+ """
72
+
73
+ Scenario: merging attributes and adding params for a custom tag
74
+ Given a file named "example_taglib.dryml" with:
75
+ """
76
+ <def tag="card">
77
+ <div class="card" merge-attrs>
78
+ <h3 param="heading"><%= this.name %></h3>
79
+ <div param="body"></div>
80
+ </div>
81
+ </def>
82
+
83
+ <def tag="linked-card">
84
+ <card merge-attrs>
85
+ <heading: param><a href="&this.url"><%= this.name %></a></heading:>
86
+ <body: param />
87
+ </card>
88
+ </def>
89
+ """
90
+ And a file named "example.dryml" with:
91
+ """
92
+ <linked-card class="emphasized">
93
+ <body:><%= this.body %></body:>
94
+ </linked-card>
95
+ """
96
+ When I include the taglib "example_taglib"
97
+ And the current context is a blog post
98
+ And I render "example.dryml"
99
+ Then the output DOM should be:
100
+ """
101
+ <div class="card emphasized">
102
+ <h3 class="heading">
103
+ <a href="/blog_posts/1">A Blog Post</a>
104
+ </h3>
105
+ <div class="body">
106
+ Some body content
107
+ </div>
108
+ </div>
109
+ """
110
+
111
+ Scenario: merging attributes and params for a custom tag
112
+ Given a file named "example_taglib.dryml" with:
113
+ """
114
+ <def tag="card">
115
+ <div class="card" merge-attrs>
116
+ <h3 param="heading"><%= this.name %></h3>
117
+ <div param="body"></div>
118
+ </div>
119
+ </def>
120
+
121
+ <def tag="linked-card">
122
+ <card merge-attrs merge-params>
123
+ <heading: param><a href="&this.url"><%= this.name %></a></heading:>
124
+ </card>
125
+ </def>
126
+ """
127
+ And a file named "example.dryml" with:
128
+ """
129
+ <linked-card class="emphasized">
130
+ <body:><%= this.body %></body:>
131
+ </linked-card>
132
+ """
133
+ When I include the taglib "example_taglib"
134
+ And the current context is a blog post
135
+ And I render "example.dryml"
136
+ Then the output DOM should be:
137
+ """
138
+ <div class="card emphasized">
139
+ <h3 class="heading">
140
+ <a href="/blog_posts/1">A Blog Post</a>
141
+ </h3>
142
+ <div class="body">
143
+ Some body content
144
+ </div>
145
+ </div>
146
+ """
147
+
148
+ Scenario: using the merge shorthand for a custom tag
149
+ Given a file named "example_taglib.dryml" with:
150
+ """
151
+ <def tag="card">
152
+ <div class="card" merge-attrs>
153
+ <h3 param="heading"><%= this.name %></h3>
154
+ <div param="body"></div>
155
+ </div>
156
+ </def>
157
+
158
+ <def tag="linked-card">
159
+ <card merge>
160
+ <heading: param><a href="&this.url"><%= this.name %></a></heading:>
161
+ </card>
162
+ </def>
163
+ """
164
+ And a file named "example.dryml" with:
165
+ """
166
+ <linked-card class="emphasized">
167
+ <body:><%= this.body %></body:>
168
+ </linked-card>
169
+ """
170
+ When I include the taglib "example_taglib"
171
+ And the current context is a blog post
172
+ And I render "example.dryml"
173
+ Then the output DOM should be:
174
+ """
175
+ <div class="card emphasized">
176
+ <h3 class="heading">
177
+ <a href="/blog_posts/1">A Blog Post</a>
178
+ </h3>
179
+ <div class="body">
180
+ Some body content
181
+ </div>
182
+ </div>
183
+ """
184
+
185
+ Scenario: extending a tag
186
+ Given a file named "example_taglib.dryml" with:
187
+ """
188
+ <def tag="card">
189
+ <div class="card" merge-attrs>
190
+ <h3 param="heading"><%= this.name %></h3>
191
+ <div param="body"></div>
192
+ </div>
193
+ </def>
194
+
195
+ <extend tag="card">
196
+ <old-card merge>
197
+ <heading: param><a href="&this.url"><%= this.name %></a></heading:>
198
+ </old-card>
199
+ </extend>
200
+ """
201
+ And a file named "example.dryml" with:
202
+ """
203
+ <card class="emphasized">
204
+ <body:><%= this.body %></body:>
205
+ </card>
206
+ """
207
+ When I include the taglib "example_taglib"
208
+ And the current context is a blog post
209
+ And I render "example.dryml"
210
+ Then the output DOM should be:
211
+ """
212
+ <div class="card emphasized">
213
+ <h3 class="heading">
214
+ <a href="/blog_posts/1">A Blog Post</a>
215
+ </h3>
216
+ <div class="body">
217
+ Some body content
218
+ </div>
219
+ </div>
220
+ """
221
+
222
+ Scenario: extending a tag and aliasing a param
223
+ Given a file named "example_taglib.dryml" with:
224
+ """
225
+ <def tag="card">
226
+ <div class="card" merge-attrs>
227
+ <h3 param="heading"><%= this.name %></h3>
228
+ <div param="body"></div>
229
+ </div>
230
+ </def>
231
+
232
+ <extend tag="card">
233
+ <old-card merge>
234
+ <heading: param><a href="&this.url"><%= this.name %></a></heading:>
235
+ <body: param="xbody" />
236
+ </old-card>
237
+ </extend>
238
+ """
239
+ And a file named "example.dryml" with:
240
+ """
241
+ <card class="emphasized">
242
+ <xbody:><%= this.body %></xbody:>
243
+ </card>
244
+ """
245
+ When I include the taglib "example_taglib"
246
+ And the current context is a blog post
247
+ And I render "example.dryml"
248
+ Then the output DOM should be:
249
+ """
250
+ <div class="card emphasized">
251
+ <h3 class="heading">
252
+ <a href="/blog_posts/1">A Blog Post</a>
253
+ </h3>
254
+ <div class="body">
255
+ Some body content
256
+ </div>
257
+ </div>
258
+ """
259
+
260
+ Scenario: extending a tag and using attributes (fails)
261
+ Given a file named "example_taglib.dryml" with:
262
+ """
263
+ <def tag="help-link" attrs="file">
264
+ <a class="help" href="/help/#{file}.html" param="default"/>
265
+ </def>
266
+
267
+ <extend tag="help-link">
268
+ <old-help-link merge>
269
+ <img src="/images/#{file}.png" /><do param="default" />
270
+ </old-help-link>
271
+ </extend>
272
+ """
273
+ And a file named "example.dryml" with:
274
+ """
275
+ <help-link file="intro">Intro Help</help-link>
276
+ """
277
+ When I include the taglib "example_taglib"
278
+ And I render "example.dryml"
279
+ Then the output DOM should be:
280
+ """
281
+ <a class="help" href="/help/intro.html"><img src="/images/intro.png" />Intro Help</a>
282
+ """
283
+
284
+ Scenario: extending a tag and using attributes take 2 (fails)
285
+ Given a file named "example_taglib.dryml" with:
286
+ """
287
+ <def tag="help-link" attrs="file">
288
+ <a class="help" href="/help/#{file}.html" param="default"/>
289
+ </def>
290
+
291
+ <extend tag="help-link" attrs="file">
292
+ <old-help-link merge>
293
+ <img src="/images/#{file}.png" /><do param="default" />
294
+ </old-help-link>
295
+ </extend>
296
+ """
297
+ And a file named "example.dryml" with:
298
+ """
299
+ <help-link file="intro">Intro Help</help-link>
300
+ """
301
+ When I include the taglib "example_taglib"
302
+ And I render "example.dryml"
303
+ Then the output DOM should be:
304
+ """
305
+ <a class="help" href="/help/intro.html"><img src="/images/intro.png" />Intro Help</a>
306
+ """
307
+
@@ -0,0 +1,50 @@
1
+ Feature: Aliasing tags
2
+
3
+ Scenario: Simple alias
4
+ Given a file named "example_taglib.dryml" with:
5
+ """
6
+ <def tag="help-link" attrs="file">
7
+ <a class="help" href="/help/#{file}.html" param="default"/>
8
+ </def>
9
+
10
+ <def tag="help" alias-of="help-link" />
11
+ """
12
+ And a file named "example.dryml" with:
13
+ """
14
+ <help file="intro">Intro Help</help>
15
+ """
16
+ When I include the taglib "example_taglib"
17
+ And I render "example.dryml"
18
+ Then the output DOM should be:
19
+ """
20
+ <a class="help" href="/help/intro.html">Intro Help</a>
21
+ """
22
+
23
+ Scenario: Alias before extend
24
+ Given a file named "example_taglib.dryml" with:
25
+ """
26
+ <def tag="help-link" attrs="file">
27
+ <a class="help" href="/help/#{file}.html" param="default"/>
28
+ </def>
29
+
30
+ <def tag="basic-help" alias-of="help-link" />
31
+
32
+ <extend tag="help-link">
33
+ <old-help-link merge>
34
+ <img src="/images/logo.png" /><do param="default" />
35
+ </old-help-link>
36
+ </extend>
37
+ """
38
+ And a file named "example.dryml" with:
39
+ """
40
+ <basic-help file="basic">Basic Help</basic-help>
41
+ <help-link file="intro">Intro Help</help-link>
42
+ """
43
+ When I include the taglib "example_taglib"
44
+ And I render "example.dryml"
45
+ Then the output DOM should be:
46
+ """
47
+ <a class="help" href="/help/basic.html">Basic Help</a>
48
+ <a class="help" href="/help/intro.html"><img src="/images/logo.png" />Intro Help</a>
49
+ """
50
+