card 1.17.4 → 1.18.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.
Files changed (389) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/card.gemspec +24 -25
  4. data/config/initializers/01_init_ruby_extensions.rb +0 -4
  5. data/config/initializers/inflections.rb +1 -1
  6. data/config/initializers/notification.rb +2 -2
  7. data/db/migrate/20110511221913_require_earlier_migrations.rb +3 -3
  8. data/db/migrate/20120105203350_require_1_8_migrations.rb +3 -3
  9. data/db/migrate/20121111025347_require_1_10_migrations.rb +3 -3
  10. data/db/migrate/20130106052640_table_cleanup.rb +4 -4
  11. data/db/migrate/20130411210957_update_codenames.rb +2 -2
  12. data/db/migrate/20141001105348_move_revisions_to_actions.rb +4 -4
  13. data/db/migrate/20141121172918_rename_card_migration_table.rb +2 -2
  14. data/db/migrate/20141208132159_remove_present_from_reference_table.rb +2 -2
  15. data/db/migrate/20141216053032_better_index_names.rb +9 -9
  16. data/db/migrate_core_cards/20120611203506_rails_inflection_updates.rb +29 -32
  17. data/db/migrate_core_cards/20130411191151_renaming_for_menu.rb +3 -4
  18. data/db/migrate_core_cards/20130411211600_delete_old_related_tab_cards.rb +1 -1
  19. data/db/migrate_core_cards/20130419215612_import_help_text.rb +1 -2
  20. data/db/migrate_core_cards/20130823192433_add_style_cards.rb +3 -3
  21. data/db/migrate_core_cards/20130910183318_move_styles_to_content.rb +2 -3
  22. data/db/migrate_core_cards/20130920214038_jsonize_tinymce.rb +2 -2
  23. data/db/migrate_core_cards/20130920291703_update_stylesheets.rb +1 -2
  24. data/db/migrate_core_cards/20130927191728_account_events.rb +5 -6
  25. data/db/migrate_core_cards/20131016172445_common_css_patch.rb +2 -3
  26. data/db/migrate_core_cards/20140110193325_reset_account_request_type.rb +0 -1
  27. data/db/migrate_core_cards/20140307231621_user_data_to_cards.rb +23 -32
  28. data/db/migrate_core_cards/20140317035504_account_requests_to_signups.rb +1 -7
  29. data/db/migrate_core_cards/20140512155840_add_script_cards.rb +21 -24
  30. data/db/migrate_core_cards/20140629222005_add_email_cards.rb +17 -22
  31. data/db/migrate_core_cards/20140725180118_config_card_updates.rb +2 -2
  32. data/db/migrate_core_cards/20141111083921_delete_machine_output.rb +1 -3
  33. data/db/migrate_core_cards/20141115034214_config_descriptions_etc.rb +2 -2
  34. data/db/migrate_core_cards/20141119001955_make_symlinks_relative.rb +3 -3
  35. data/db/migrate_core_cards/20141120120605_fix_notification_html_message.rb +1 -1
  36. data/db/migrate_core_cards/20141204061304_watchers_to_following.rb +8 -12
  37. data/db/migrate_core_cards/20141208162106_add_ace_script.rb +2 -3
  38. data/db/migrate_core_cards/20141216155251_add_more_following_cards.rb +10 -10
  39. data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +10 -12
  40. data/db/migrate_core_cards/20150220134731_following_to_follow_rule.rb +4 -4
  41. data/db/migrate_core_cards/20150317162412_bootstrap_themes.rb +3 -3
  42. data/db/migrate_core_cards/20150326205655_bootswatch_themes.rb +7 -7
  43. data/db/migrate_core_cards/20150429090551_search_card_context.rb +18 -20
  44. data/db/migrate_core_cards/20150508212032_menu_compatibility.rb +3 -7
  45. data/db/migrate_core_cards/20150510031118_fix_skin_images.rb +2 -3
  46. data/db/migrate_core_cards/20150528084659_add_session_cardtype.rb +3 -3
  47. data/db/migrate_core_cards/20150601133433_add_recent_setting_session_card.rb +4 -4
  48. data/db/migrate_core_cards/20150610171702_add_debugger_session_card.rb +4 -4
  49. data/db/migrate_core_cards/20150610180019_add_recaptcha_key_and_admin_info_cards.rb +5 -11
  50. data/db/migrate_core_cards/20150724123438_update_file_and_image_cards.rb +29 -35
  51. data/db/migrate_core_cards/20150824135418_update_file_history.rb +10 -14
  52. data/db/migrate_core_cards/20150903130006_attachment_upload_cards.rb +1 -1
  53. data/db/schema.rb +92 -94
  54. data/db/seed/new/card_actions.yml +461 -469
  55. data/db/seed/new/card_acts.yml +154 -172
  56. data/db/seed/new/card_changes.yml +4076 -4031
  57. data/db/seed/new/card_references.yml +1584 -1927
  58. data/db/seed/new/cards.yml +2095 -2112
  59. data/db/seed/test/fixtures/card_actions.yml +1497 -1505
  60. data/db/seed/test/fixtures/card_acts.yml +454 -472
  61. data/db/seed/test/fixtures/card_changes.yml +7309 -7263
  62. data/db/seed/test/fixtures/card_references.yml +2263 -2613
  63. data/db/seed/test/fixtures/cards.yml +3298 -3316
  64. data/db/seed/test/seed.rb +3 -0
  65. data/lib/card.rb +17 -9
  66. data/lib/card/active_record_ext.rb +6 -8
  67. data/lib/card/active_record_helper.rb +42 -32
  68. data/lib/card/auth.rb +3 -3
  69. data/lib/card/cache.rb +4 -4
  70. data/lib/card/cache/persistent.rb +9 -5
  71. data/lib/card/cache/temporary.rb +5 -5
  72. data/lib/card/chunk.rb +1 -1
  73. data/lib/card/codename.rb +3 -2
  74. data/lib/card/content.rb +62 -57
  75. data/lib/card/core_ext.rb +20 -30
  76. data/lib/card/diff.rb +88 -76
  77. data/lib/card/director_register.rb +66 -0
  78. data/lib/card/env.rb +14 -17
  79. data/lib/card/exceptions.rb +7 -9
  80. data/lib/card/format.rb +18 -367
  81. data/lib/card/format/nest.rb +183 -0
  82. data/lib/card/format/permission.rb +63 -0
  83. data/lib/card/format/render.rb +140 -0
  84. data/lib/card/loader.rb +17 -26
  85. data/lib/card/location.rb +6 -6
  86. data/lib/card/mailer.rb +4 -7
  87. data/lib/card/migration.rb +1 -1
  88. data/lib/card/name.rb +3 -6
  89. data/lib/card/query.rb +8 -8
  90. data/lib/card/query/attributes.rb +6 -6
  91. data/lib/card/query/clause.rb +10 -10
  92. data/lib/card/query/join.rb +7 -9
  93. data/lib/card/query/reference.rb +17 -19
  94. data/lib/card/query/sql_statement.rb +2 -2
  95. data/lib/card/query/value.rb +15 -16
  96. data/lib/card/set.rb +106 -209
  97. data/lib/card/set/event.rb +126 -0
  98. data/lib/card/set_pattern.rb +42 -29
  99. data/lib/card/simplecov_helper.rb +19 -19
  100. data/lib/card/spec_helper.rb +40 -16
  101. data/lib/card/stage.rb +72 -0
  102. data/lib/card/stage_director.rb +231 -0
  103. data/lib/card/subcards.rb +56 -24
  104. data/lib/card/subdirector_array.rb +31 -0
  105. data/lib/card/success.rb +15 -18
  106. data/lib/card/version.rb +1 -2
  107. data/lib/card/view_cache.rb +4 -4
  108. data/lib/card/view_name.rb +10 -8
  109. data/lib/cardio.rb +1 -1
  110. data/lib/generators/card.rb +2 -4
  111. data/lib/generators/card/format/format_generator.rb +4 -4
  112. data/lib/generators/card/migration/migration_generator.rb +6 -6
  113. data/lib/generators/card/set/set_generator.rb +5 -6
  114. data/mod/01_core/chunk/include.rb +2 -1
  115. data/mod/01_core/chunk/link.rb +2 -2
  116. data/mod/01_core/chunk/literal.rb +6 -9
  117. data/mod/01_core/chunk/query_reference.rb +1 -1
  118. data/mod/01_core/chunk/reference.rb +2 -2
  119. data/mod/01_core/chunk/uri.rb +52 -63
  120. data/mod/01_core/format/html_format.rb +8 -12
  121. data/mod/01_core/format/text_format.rb +1 -1
  122. data/mod/01_core/set/all/actify.rb +96 -0
  123. data/mod/01_core/set/all/active_card.rb +7 -7
  124. data/mod/01_core/set/all/collection.rb +19 -20
  125. data/mod/01_core/set/all/content.rb +9 -7
  126. data/mod/01_core/set/all/erb.rb +5 -5
  127. data/mod/01_core/set/all/event.rb +60 -0
  128. data/mod/01_core/set/all/fetch.rb +13 -19
  129. data/mod/01_core/set/all/haml.rb +1 -1
  130. data/mod/01_core/set/all/initialize.rb +35 -41
  131. data/mod/01_core/set/all/location_history.rb +3 -5
  132. data/mod/01_core/set/all/name.rb +19 -68
  133. data/mod/01_core/set/all/name_validations.rb +56 -0
  134. data/mod/01_core/set/all/pattern.rb +2 -2
  135. data/mod/01_core/set/all/permissions.rb +14 -20
  136. data/mod/01_core/set/all/phases.rb +9 -200
  137. data/mod/01_core/set/all/references.rb +10 -10
  138. data/mod/01_core/set/all/rules.rb +3 -4
  139. data/mod/01_core/set/all/stages.rb +24 -0
  140. data/mod/01_core/set/all/states.rb +4 -4
  141. data/mod/01_core/set/all/subcards.rb +16 -26
  142. data/mod/01_core/set/all/templating.rb +1 -3
  143. data/mod/01_core/set/all/tracked_attributes.rb +47 -48
  144. data/mod/01_core/set/all/trash.rb +10 -10
  145. data/mod/01_core/set/all/type.rb +9 -8
  146. data/mod/01_core/set/all/utils.rb +10 -14
  147. data/mod/01_core/set/all/view_cache.rb +2 -2
  148. data/mod/01_core/set_pattern/01_all.rb +3 -3
  149. data/mod/01_core/set_pattern/02_all_plus.rb +3 -3
  150. data/mod/01_core/set_pattern/03_type.rb +2 -2
  151. data/mod/01_core/set_pattern/04_star.rb +3 -3
  152. data/mod/01_core/set_pattern/05_rstar.rb +3 -3
  153. data/mod/01_core/set_pattern/06_right.rb +2 -2
  154. data/mod/01_core/set_pattern/07_type_plus_right.rb +2 -2
  155. data/mod/01_core/set_pattern/08_self.rb +1 -1
  156. data/mod/01_core/spec/chunk/literal_spec.rb +7 -8
  157. data/mod/01_core/spec/chunk/uri_spec.rb +140 -142
  158. data/mod/01_core/spec/format/html_format_spec.rb +72 -57
  159. data/mod/01_core/spec/set/all/collection_spec.rb +63 -43
  160. data/mod/01_core/spec/set/all/content_spec.rb +4 -4
  161. data/mod/01_core/spec/set/all/fetch_spec.rb +12 -3
  162. data/mod/01_core/spec/set/all/name_spec.rb +3 -4
  163. data/mod/01_core/spec/set/all/pattern_spec.rb +32 -35
  164. data/mod/01_core/spec/set/all/permissions_spec.rb +17 -5
  165. data/mod/01_core/spec/set/all/phases_spec.rb +0 -1
  166. data/mod/01_core/spec/set/all/references_spec.rb +1 -1
  167. data/mod/01_core/spec/set/all/rules2_spec.rb +79 -91
  168. data/mod/01_core/spec/set/all/rules_spec.rb +63 -56
  169. data/mod/01_core/spec/set/all/templating_spec.rb +0 -1
  170. data/mod/01_core/spec/set/all/tracked_attributes_spec.rb +4 -5
  171. data/mod/01_core/spec/set/all/trash_spec.rb +23 -1
  172. data/mod/01_core/spec/set/all/type_spec.rb +2 -5
  173. data/mod/01_history/lib/card/action.rb +8 -10
  174. data/mod/01_history/set/all/actions.rb +2 -4
  175. data/mod/01_history/set/all/content_history.rb +38 -32
  176. data/mod/01_history/set/all/history.rb +20 -17
  177. data/mod/02_basic_types/format/rss_format.rb +0 -1
  178. data/mod/02_basic_types/set/all/all_css.rb +9 -13
  179. data/mod/02_basic_types/set/all/all_csv.rb +14 -17
  180. data/mod/02_basic_types/set/all/all_js.rb +3 -4
  181. data/mod/02_basic_types/set/all/base.rb +2 -2
  182. data/mod/02_basic_types/set/all/file.rb +2 -5
  183. data/mod/02_basic_types/set/all/json.rb +19 -18
  184. data/mod/02_basic_types/set/all/rss.rb +3 -3
  185. data/mod/02_basic_types/set/all/text.rb +1 -3
  186. data/mod/02_basic_types/set/type/html.rb +4 -8
  187. data/mod/02_basic_types/set/type/plain_text.rb +2 -3
  188. data/mod/02_basic_types/set/type/pointer.rb +82 -92
  189. data/mod/02_basic_types/spec/set/all/all_css_spec.rb +2 -2
  190. data/mod/02_basic_types/spec/set/all/all_csv_spec.rb +6 -4
  191. data/mod/02_basic_types/spec/set/all/base_spec.rb +6 -6
  192. data/mod/02_basic_types/spec/set/all/json_spec.rb +8 -8
  193. data/mod/02_basic_types/spec/set/type/plain_text_spec.rb +3 -3
  194. data/mod/02_basic_types/spec/set/type/pointer_spec.rb +29 -32
  195. data/mod/03_machines/lib/card/machine.rb +95 -81
  196. data/mod/03_machines/lib/card/machine_input.rb +35 -34
  197. data/mod/03_machines/set/right/machine_input.rb +1 -1
  198. data/mod/03_machines/set/self/script_ace.rb +2 -3
  199. data/mod/03_machines/set/self/script_card_menu.rb +2 -3
  200. data/mod/03_machines/set/self/script_jquery_helper.rb +2 -2
  201. data/mod/03_machines/set/self/script_slot.rb +2 -2
  202. data/mod/03_machines/set/self/style_bootstrap_compatible.rb +1 -1
  203. data/mod/03_machines/set/self/style_cards.rb +1 -1
  204. data/mod/03_machines/set/self/style_jquery_ui_smoothness.rb +0 -1
  205. data/mod/03_machines/set/type/coffee_script.rb +9 -13
  206. data/mod/03_machines/set/type/css.rb +12 -13
  207. data/mod/03_machines/set/type/java_script.rb +6 -8
  208. data/mod/03_machines/set/type/scss.rb +4 -5
  209. data/mod/03_machines/set/type/skin.rb +3 -6
  210. data/mod/03_machines/spec/lib/shared_machine_examples.rb +31 -38
  211. data/mod/03_machines/spec/lib/shared_machine_input_examples.rb +7 -8
  212. data/mod/03_machines/spec/set/type/coffeescript_spec.rb +19 -13
  213. data/mod/03_machines/spec/set/type/css_spec.rb +22 -16
  214. data/mod/03_machines/spec/set/type/scss_spec.rb +28 -21
  215. data/mod/03_machines/spec/set/type/skin_spec.rb +28 -30
  216. data/mod/04_settings/lib/card/setting.rb +4 -4
  217. data/mod/04_settings/set/abstract/permission.rb +30 -37
  218. data/mod/04_settings/set/right/add_help.rb +3 -3
  219. data/mod/04_settings/set/right/script.rb +4 -5
  220. data/mod/04_settings/set/right/structure.rb +3 -4
  221. data/mod/04_settings/set/right/style.rb +3 -3
  222. data/mod/04_settings/set/self/add_help.rb +1 -1
  223. data/mod/04_settings/set/self/input.rb +1 -1
  224. data/mod/04_settings/set/self/on_create.rb +1 -1
  225. data/mod/04_settings/set/self/options.rb +1 -1
  226. data/mod/04_settings/set/self/options_label.rb +1 -1
  227. data/mod/04_settings/set/type/setting.rb +29 -44
  228. data/mod/04_settings/spec/set/right/comment_spec.rb +9 -12
  229. data/mod/04_settings/spec/set/right/script_spec.rb +7 -7
  230. data/mod/04_settings/spec/set/right/structure_spec.rb +13 -12
  231. data/mod/04_settings/spec/set/right/style_spec.rb +13 -13
  232. data/mod/04_settings/spec/set/type/setting_spec.rb +1 -1
  233. data/mod/05_email/format/email_html_format.rb +1 -1
  234. data/mod/05_email/format/email_text_format.rb +2 -2
  235. data/mod/05_email/lib/card/follow_option.rb +12 -15
  236. data/mod/05_email/set/all/email_html.rb +2 -3
  237. data/mod/05_email/set/all/email_text.rb +3 -3
  238. data/mod/05_email/set/all/follow.rb +14 -22
  239. data/mod/05_email/set/all/notify.rb +11 -11
  240. data/mod/05_email/set/all/observer.rb +7 -8
  241. data/mod/05_email/set/right/bcc.rb +4 -9
  242. data/mod/05_email/set/right/follow.rb +26 -39
  243. data/mod/05_email/set/right/follow_fields.rb +2 -2
  244. data/mod/05_email/set/right/followers.rb +3 -1
  245. data/mod/05_email/set/right/following.rb +13 -16
  246. data/mod/05_email/set/self/always.rb +1 -2
  247. data/mod/05_email/set/self/created.rb +4 -6
  248. data/mod/05_email/set/self/edited.rb +3 -7
  249. data/mod/05_email/set/self/follow_defaults.rb +11 -12
  250. data/mod/05_email/set/self/never.rb +2 -4
  251. data/mod/05_email/set/type/email_template.rb +40 -27
  252. data/mod/05_email/set/type_plus_right/user/follow.rb +159 -157
  253. data/mod/05_email/spec/set/all/follow_spec.rb +28 -37
  254. data/mod/05_email/spec/set/all/notify_spec.rb +21 -26
  255. data/mod/05_email/spec/set/all/observer_spec.rb +58 -37
  256. data/mod/05_email/spec/set/right/followers_spec.rb +9 -14
  257. data/mod/05_email/spec/set/right/following_spec.rb +1 -1
  258. data/mod/05_email/spec/set/self/follow_defaults_spec.rb +1 -1
  259. data/mod/05_standard/lib/carrier_wave/cardmount.rb +9 -9
  260. data/mod/05_standard/lib/file_uploader.rb +8 -13
  261. data/mod/05_standard/lib/image_uploader.rb +8 -9
  262. data/mod/05_standard/set/abstract/attachment.rb +26 -43
  263. data/mod/05_standard/set/all/account.rb +2 -2
  264. data/mod/05_standard/set/all/comment.rb +11 -13
  265. data/mod/05_standard/set/all/error.rb +18 -18
  266. data/mod/05_standard/set/all/event_viz.rb +16 -29
  267. data/mod/05_standard/set/all/links.rb +35 -34
  268. data/mod/05_standard/set/all/list_changes.rb +10 -12
  269. data/mod/05_standard/set/all/rich_html/content.rb +13 -13
  270. data/mod/05_standard/set/all/rich_html/editing.rb +5 -5
  271. data/mod/05_standard/set/all/rich_html/form.rb +22 -26
  272. data/mod/05_standard/set/all/rich_html/header.rb +18 -25
  273. data/mod/05_standard/set/all/rich_html/menu.rb +20 -22
  274. data/mod/05_standard/set/all/rich_html/modal.rb +3 -3
  275. data/mod/05_standard/set/all/rich_html/toolbar.rb +49 -58
  276. data/mod/05_standard/set/all/rich_html/wrapper.rb +40 -41
  277. data/mod/05_standard/set/right/account.rb +26 -14
  278. data/mod/05_standard/set/right/email.rb +2 -2
  279. data/mod/05_standard/set/right/password.rb +6 -5
  280. data/mod/05_standard/set/right/salt.rb +2 -2
  281. data/mod/05_standard/set/right/stats.rb +17 -20
  282. data/mod/05_standard/set/right/token.rb +1 -1
  283. data/mod/05_standard/set/right/when_created.rb +1 -1
  284. data/mod/05_standard/set/right/when_last_edited.rb +1 -1
  285. data/mod/05_standard/set/rstar/rules.rb +3 -3
  286. data/mod/05_standard/set/rstar/rules_editor.rb +39 -39
  287. data/mod/05_standard/set/self/account_links.rb +21 -22
  288. data/mod/05_standard/set/self/admin_info.rb +5 -5
  289. data/mod/05_standard/set/self/alerts.rb +1 -1
  290. data/mod/05_standard/set/self/all.rb +1 -1
  291. data/mod/05_standard/set/self/foot.rb +1 -1
  292. data/mod/05_standard/set/self/head.rb +19 -22
  293. data/mod/05_standard/set/self/navbox.rb +3 -7
  294. data/mod/05_standard/set/self/now.rb +1 -1
  295. data/mod/05_standard/set/self/recent.rb +19 -25
  296. data/mod/05_standard/set/self/search.rb +2 -4
  297. data/mod/05_standard/set/self/signin.rb +6 -6
  298. data/mod/05_standard/set/self/stats.rb +31 -38
  299. data/mod/05_standard/set/self/version.rb +1 -2
  300. data/mod/05_standard/set/type/basic.rb +15 -17
  301. data/mod/05_standard/set/type/cardtype.rb +3 -3
  302. data/mod/05_standard/set/type/date.rb +1 -2
  303. data/mod/05_standard/set/type/file.rb +22 -33
  304. data/mod/05_standard/set/type/image.rb +30 -23
  305. data/mod/05_standard/set/type/layout_type.rb +4 -4
  306. data/mod/05_standard/set/type/list.rb +32 -38
  307. data/mod/05_standard/set/type/listed_by.rb +11 -13
  308. data/mod/05_standard/set/type/number.rb +5 -6
  309. data/mod/05_standard/set/type/phrase.rb +1 -1
  310. data/mod/05_standard/set/type/search_type.rb +25 -23
  311. data/mod/05_standard/set/type/session.rb +2 -3
  312. data/mod/05_standard/set/type/set.rb +46 -51
  313. data/mod/05_standard/set/type/signup.rb +18 -19
  314. data/mod/05_standard/set/type/toggle.rb +5 -5
  315. data/mod/05_standard/set/type/user.rb +6 -6
  316. data/mod/05_standard/spec/chunk/include_spec.rb +115 -98
  317. data/mod/05_standard/spec/chunk/link_spec.rb +58 -31
  318. data/mod/05_standard/spec/chunk/query_reference_spec.rb +12 -14
  319. data/mod/05_standard/spec/set/all/email_html_spec.rb +3 -3
  320. data/mod/05_standard/spec/set/all/error_spec.rb +3 -3
  321. data/mod/05_standard/spec/set/all/history_spec.rb +52 -38
  322. data/mod/05_standard/spec/set/all/links_spec.rb +2 -2
  323. data/mod/05_standard/spec/set/all/rich_html/editing_spec.rb +0 -1
  324. data/mod/05_standard/spec/set/all/rich_html/form_spec.rb +11 -11
  325. data/mod/05_standard/spec/set/all/rich_html/wrapper_spec.rb +4 -4
  326. data/mod/05_standard/spec/set/right/email_spec.rb +1 -4
  327. data/mod/05_standard/spec/set/right/password_spec.rb +4 -7
  328. data/mod/05_standard/spec/set/right/stats_spec.rb +2 -3
  329. data/mod/05_standard/spec/set/right/when_created_spec.rb +1 -1
  330. data/mod/05_standard/spec/set/right/when_last_edited_spec.rb +1 -1
  331. data/mod/05_standard/spec/set/rstar/rules_spec.rb +6 -6
  332. data/mod/05_standard/spec/set/self/all_spec.rb +11 -13
  333. data/mod/05_standard/spec/set/self/head_spec.rb +1 -3
  334. data/mod/05_standard/spec/set/self/navbox_spec.rb +1 -1
  335. data/mod/05_standard/spec/set/self/now_spec.rb +2 -2
  336. data/mod/05_standard/spec/set/self/signin_spec.rb +1 -1
  337. data/mod/05_standard/spec/set/self/stats_spec.rb +1 -1
  338. data/mod/05_standard/spec/set/self/version_spec.rb +2 -2
  339. data/mod/05_standard/spec/set/type/cardtype_spec.rb +3 -4
  340. data/mod/05_standard/spec/set/type/date_spec.rb +1 -1
  341. data/mod/05_standard/spec/set/type/email_template_spec.rb +5 -5
  342. data/mod/05_standard/spec/set/type/file_spec.rb +50 -28
  343. data/mod/05_standard/spec/set/type/html_spec.rb +12 -7
  344. data/mod/05_standard/spec/set/type/image_spec.rb +55 -45
  345. data/mod/05_standard/spec/set/type/layout_type_spec.rb +2 -2
  346. data/mod/05_standard/spec/set/type/listed_by_spec.rb +2 -2
  347. data/mod/05_standard/spec/set/type/number_spec.rb +1 -1
  348. data/mod/05_standard/spec/set/type/phrase_spec.rb +1 -1
  349. data/mod/05_standard/spec/set/type/search_type_spec.rb +15 -16
  350. data/mod/05_standard/spec/set/type/set_spec.rb +16 -17
  351. data/mod/05_standard/spec/set/type/signup_spec.rb +7 -5
  352. data/mod/05_standard/spec/set/type/toggle_spec.rb +4 -4
  353. data/mod/05_standard/spec/set/type/uri_spec.rb +11 -11
  354. data/mod/05_standard/spec/set/type/user_spec.rb +0 -1
  355. data/mod/06_bootstrap/set/all/bootstrap/form.rb +9 -10
  356. data/mod/06_bootstrap/set/all/bootstrap/helper.rb +22 -27
  357. data/mod/06_bootstrap/set/all/bootstrap/wrapper.rb +1 -2
  358. data/mod/06_bootstrap/set/all/rich_bootstrap.rb +1 -3
  359. data/mod/06_bootstrap/set/self/bootstrap_cards.rb +2 -2
  360. data/mod/06_bootstrap/set/self/bootstrap_js.rb +2 -2
  361. data/mod/06_bootstrap/set/self/bootswatch_shared.rb +19 -19
  362. data/mod/06_bootstrap/set/self/smartmenu_css.rb +2 -2
  363. data/mod/06_bootstrap/set/self/smartmenu_js.rb +3 -3
  364. data/mod/06_bootstrap/spec/set/all/bootstrap/form_spec.rb +5 -5
  365. data/spec/lib/card/action_spec.rb +4 -4
  366. data/spec/lib/card/cache_spec.rb +3 -5
  367. data/spec/lib/card/chunk_spec.rb +6 -8
  368. data/spec/lib/card/codename_spec.rb +4 -6
  369. data/spec/lib/card/content_spec.rb +12 -17
  370. data/spec/lib/card/diff_spec.rb +59 -61
  371. data/spec/lib/card/format_spec.rb +55 -34
  372. data/spec/lib/card/loader_spec.rb +35 -37
  373. data/spec/lib/card/name_spec.rb +159 -145
  374. data/spec/lib/card/query_spec.rb +4 -4
  375. data/spec/lib/card/reference_spec.rb +24 -24
  376. data/spec/lib/card/set_pattern_spec.rb +3 -3
  377. data/spec/lib/card/stage_director_spec.rb +218 -0
  378. data/spec/lib/card/subcards_spec.rb +12 -16
  379. data/spec/lib/card/success_spec.rb +16 -18
  380. data/spec/lib/card/view_cache_spec.rb +1 -1
  381. data/spec/mailers/mailer_spec.rb +3 -5
  382. data/spec/models/card/cardtype_spec.rb +40 -51
  383. data/spec/models/card/create_spec.rb +58 -39
  384. data/spec/models/card/trash_spec.rb +23 -32
  385. data/spec/models/card/type_transition_spec.rb +41 -32
  386. data/spec/models/card/validation_spec.rb +13 -15
  387. data/spec/models/card_spec.rb +48 -59
  388. data/spec/spec_helper.rb +26 -31
  389. metadata +16 -2
@@ -1,10 +1,10 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  describe Card::Set::All::AllCss do
4
- it "should render content view" do
4
+ it 'should render content view' do
5
5
  content = '#box { display: block }'
6
6
  rendered = render_card :content, { content: content }, format: :css
7
- # rendered.should =~ /Style Card\:/
7
+ # rendered.should =~ /Style Card\:/
8
8
  expect(rendered).to match(/#{ Regexp.escape content }/)
9
9
  end
10
10
  end
@@ -1,9 +1,11 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
- describe Card::Set::All::AllCsv, "CSV mod" do
4
- context "csv_row view" do
5
- it "should handle inclusions" do
6
- expect(render_card( :csv_row, { content: '{{A+B}} {{T}}' }, format: :csv )).to eq("AlphaBeta,Theta")
3
+ describe Card::Set::All::AllCsv, 'CSV mod' do
4
+ context 'csv_row view' do
5
+ it 'should handle nests' do
6
+ rendered = render_card :csv_row, { content: '{{A+B}} {{T}}' },
7
+ format: :csv
8
+ expect(rendered).to eq('AlphaBeta,Theta')
7
9
  end
8
10
  end
9
11
  end
@@ -21,8 +21,8 @@ describe Card::Set::All::Base do
21
21
  end
22
22
  end
23
23
 
24
- it('key' ) { expect(render_card(:key)).to eq('tempo_rary') }
25
- it('linkname') { expect(render_card(:linkname)).to eq('Tempo_Rary') }
24
+ it('key') { expect(render_card(:key)).to eq('tempo_rary') }
25
+ it('linkname') { expect(render_card(:linkname)).to eq('Tempo_Rary') }
26
26
 
27
27
  it 'url' do
28
28
  Card::Env[:protocol] = 'http://'
@@ -47,12 +47,12 @@ describe Card::Set::All::Base do
47
47
  it 'of search items' do
48
48
  Card.create! name: 'n+a', type: 'Number', content: '10'
49
49
  sleep 1
50
- Card.create! name: 'n+b', type: 'Phrase', content: "say:\"what\""
50
+ Card.create! name: 'n+b', type: 'Phrase', content: 'say:"what"'
51
51
  sleep 1
52
52
  Card.create! name: 'n+c', type: 'Number', content: '30'
53
53
  c = Card.new name: 'nplusarray',
54
54
  content: '{{n+*children+by create|array}}'
55
- expect(c.format._render(:core)).to eq(%{["10", "say:\\"what\\"", "30"]})
55
+ expect(c.format._render(:core)).to eq(%(["10", "say:\\"what\\"", "30"]))
56
56
  end
57
57
 
58
58
  it 'of pointer items' do
@@ -62,11 +62,11 @@ describe Card::Set::All::Base do
62
62
  Card.create! name: 'npoint', type: 'Pointer',
63
63
  content: "[[n+a]]\n[[n+b]]\n[[n+c]]"
64
64
  c = Card.new name: 'npointArray', content: '{{npoint|array}}'
65
- expect(c.format._render(:core)).to eq(%{["10", "20", "30"]})
65
+ expect(c.format._render(:core)).to eq(%(["10", "20", "30"]))
66
66
  end
67
67
 
68
68
  it 'of basic items' do
69
- expect(render_card(:array, content: 'yoing')).to eq(%{["yoing"]})
69
+ expect(render_card(:array, content: 'yoing')).to eq(%(["yoing"]))
70
70
  end
71
71
  end
72
72
  it 'renders template rule of embed cards based on set' do
@@ -1,25 +1,25 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
- describe Card::Set::All::Json, "JSON mod" do
4
- context "status view" do
5
- it "should handle real and virtual cards" do
3
+ describe Card::Set::All::Json, 'JSON mod' do
4
+ context 'status view' do
5
+ it 'should handle real and virtual cards' do
6
6
  jf = Card::JsonFormat
7
7
  real_json = jf.new(Card['T']).show :status, {}
8
- expect(JSON[real_json]).to eq({"key"=>"t","status"=>"real","id"=>Card['T'].id, 'url_key'=>'T'})
8
+ expect(JSON[real_json]).to eq('key' => 't', 'status' => 'real', 'id' => Card['T'].id, 'url_key' => 'T')
9
9
  virtual_json = jf.new(Card.fetch('T+*self')).show :status, {}
10
- expect(JSON[virtual_json]).to eq({"key"=>"t+*self","status"=>"virtual",'url_key'=>'T+*self'})
10
+ expect(JSON[virtual_json]).to eq('key' => 't+*self', 'status' => 'virtual', 'url_key' => 'T+*self')
11
11
  end
12
12
 
13
- it "should treat both unknown and unreadable cards as unknown" do
13
+ it 'should treat both unknown and unreadable cards as unknown' do
14
14
  Card::Auth.as Card::AnonymousID do
15
15
  jf = Card::JsonFormat
16
16
 
17
17
  unknown = Card.new name: 'sump'
18
18
  unreadable = Card.new name: 'kumq', type: 'Fruit'
19
19
  unknown_json = jf.new(unknown).show :status, {}
20
- expect(JSON[unknown_json]).to eq({"key"=>"sump","status"=>"unknown", 'url_key'=>'sump'})
20
+ expect(JSON[unknown_json]).to eq('key' => 'sump', 'status' => 'unknown', 'url_key' => 'sump')
21
21
  unreadable_json = jf.new(unreadable).show :status, {}
22
- expect(JSON[unreadable_json]).to eq({"key"=>"kumq","status"=>"unknown", 'url_key'=>'kumq'})
22
+ expect(JSON[unreadable_json]).to eq('key' => 'kumq', 'status' => 'unknown', 'url_key' => 'kumq')
23
23
  end
24
24
  end
25
25
  end
@@ -1,11 +1,11 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  describe Card::Set::Type::PlainText do
4
- it "should have special editor" do
4
+ it 'should have special editor' do
5
5
  assert_view_select render_editor('Plain Text'), 'textarea[rows="5"]'
6
6
  end
7
7
 
8
- it "should have special content that escapes HTML" do
9
- render_card(:core, type: 'Plain Text', content: "<b></b>").should == '&lt;b&gt;&lt;/b&gt;'
8
+ it 'should have special content that escapes HTML' do
9
+ render_card(:core, type: 'Plain Text', content: '<b></b>').should == '&lt;b&gt;&lt;/b&gt;'
10
10
  end
11
11
  end
@@ -1,9 +1,9 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  describe Card::Set::Type::Pointer do
3
- describe "item_names" do
3
+ describe 'item_names' do
4
4
  it 'should return array of names of items referred to by a pointer' do
5
- card = Card.new(type: 'Pointer', content:"[[Busy]]\n[[Body]]")
6
- card.item_names.should == ['Busy', 'Body']
5
+ card = Card.new(type: 'Pointer', content: "[[Busy]]\n[[Body]]")
6
+ card.item_names.should == %w(Busy Body)
7
7
  end
8
8
  end
9
9
 
@@ -49,7 +49,6 @@ describe Card::Set::Type::Pointer do
49
49
  end
50
50
  end
51
51
 
52
-
53
52
  let(:pointer) do
54
53
  Card.create name: 'tp', type: 'pointer',
55
54
  content: "[[item1]]\n[[item2]]"
@@ -59,13 +58,13 @@ describe Card::Set::Type::Pointer do
59
58
  it 'recognizes added items' do
60
59
  Card::Auth.as_bot do
61
60
  pointer
62
- in_phase before: :approve,
61
+ in_stage :validate,
63
62
  on: :save,
64
- trigger: ->{
65
- pointer.update_attributes!(
66
- content: "[[item1]]\n[[item2]]\n[[item3]]"
67
- )
68
- } do
63
+ trigger: -> do
64
+ pointer.update_attributes!(
65
+ content: "[[item1]]\n[[item2]]\n[[item3]]"
66
+ )
67
+ end do
69
68
  expect(added_item_names).to eq ['item3']
70
69
  end
71
70
  end
@@ -74,13 +73,13 @@ describe Card::Set::Type::Pointer do
74
73
  it 'ignores order' do
75
74
  Card::Auth.as_bot do
76
75
  pointer
77
- in_phase before: :approve,
76
+ in_stage :validate,
78
77
  on: :save,
79
- trigger: ->{
78
+ trigger: -> do
80
79
  pointer.update_attributes!(
81
80
  content: "[[item2]]\n[[item1]]"
82
81
  )
83
- } do
82
+ end do
84
83
  expect(added_item_names).to eq []
85
84
  end
86
85
  end
@@ -91,13 +90,13 @@ describe Card::Set::Type::Pointer do
91
90
  it 'recognizes dropped items' do
92
91
  Card::Auth.as_bot do
93
92
  pointer
94
- in_phase before: :approve,
93
+ in_stage :validate,
95
94
  on: :save,
96
- trigger: ->{
95
+ trigger: -> do
97
96
  pointer.update_attributes!(
98
- content: "[[item1]]"
97
+ content: '[[item1]]'
99
98
  )
100
- } do
99
+ end do
101
100
  expect(dropped_item_names).to eq ['item2']
102
101
  end
103
102
  end
@@ -106,13 +105,13 @@ describe Card::Set::Type::Pointer do
106
105
  it 'ignores order' do
107
106
  Card::Auth.as_bot do
108
107
  pointer
109
- in_phase before: :approve,
108
+ in_stage :validate,
110
109
  on: :save,
111
- trigger: ->{
110
+ trigger: -> do
112
111
  pointer.update_attributes!(
113
112
  content: "[[item2]]\n[[item1]]"
114
113
  )
115
- } do
114
+ end do
116
115
  expect(dropped_item_names).to eq []
117
116
  end
118
117
  end
@@ -123,21 +122,19 @@ describe Card::Set::Type::Pointer do
123
122
  it 'recognizes changed items' do
124
123
  Card::Auth.as_bot do
125
124
  pointer
126
- in_phase before: :approve,
125
+ in_stage :validate,
127
126
  on: :save,
128
- trigger: ->{
127
+ trigger: -> do
129
128
  pointer.update_attributes!(
130
129
  content: "[[item1]]\n[[item3]]"
131
130
  )
132
- } do
133
- expect(changed_item_names.sort).to eq ['item2','item3']
131
+ end do
132
+ expect(changed_item_names.sort).to eq %w(item2 item3)
134
133
  end
135
134
  end
136
135
  end
137
136
  end
138
137
 
139
-
140
-
141
138
  describe 'html' do
142
139
  before do
143
140
  Card::Auth.as_bot do
@@ -184,17 +181,17 @@ describe Card::Set::Type::Pointer do
184
181
  end
185
182
  it 'should render CSS of items' do
186
183
  css_list = render_card(:content,
187
- { type: Card::PointerID, name: 'my style list', content: '[[my css]]' },
188
- format: :css
189
- )
190
- # css_list.should =~ /STYLE GROUP\: \"my style list\"/
191
- # css_list.should =~ /Style Card\: \"my css\"/
184
+ { type: Card::PointerID, name: 'my style list', content: '[[my css]]' },
185
+ format: :css
186
+ )
187
+ # css_list.should =~ /STYLE GROUP\: \"my style list\"/
188
+ # css_list.should =~ /Style Card\: \"my css\"/
192
189
  css_list.should =~ /#{ Regexp.escape @css }/
193
190
  end
194
191
  end
195
192
 
196
193
  describe '#standardize_item' do
197
- it "should handle unlinked items" do
194
+ it 'should handle unlinked items' do
198
195
  pointer1 = Card.create!(
199
196
  name: 'pointer1', type: 'Pointer', content: 'bracketme'
200
197
  )
@@ -1,15 +1,16 @@
1
1
  # WHAT IS THIS?
2
2
  # The Machine module together with the MachineInput module implements a kind of
3
3
  # observer pattern. It handles a collection of input cards to generate an
4
- # outputcard (default is a file card). If one of the input cards is changed the
4
+ # output card (default is a file card). If one of the input cards is changed the
5
5
  # output card will be updated.
6
6
  #
7
7
  # The classic example: A style card observes a collection of css and sccs card
8
- # to generate a file card with a css file containg the assembled compressed css.
8
+ # to generate a file card with a css file that contains the assembled
9
+ # compressed css.
9
10
  #
10
11
  # HOW TO USE IT?
11
12
  # Include the Machine module in the card set that is supposed to produce the
12
- # output card. If the output card should be autmatically updated when a input
13
+ # output card. If the output card should be automatically updated when a input
13
14
  # card is changed the input card has to be in a set that includes the
14
15
  # MachineInput module.
15
16
  #
@@ -19,19 +20,17 @@
19
20
  # - can be changed by passing a block to collect_input_cards
20
21
  # - takes the raw view of the input cards to generate the output;
21
22
  # - can be changed by passing a block to machine_input (in the input card set)
22
- # - stores the output as a .txt file in the "+machine output" card;
23
+ # - stores the output as a .txt file in the '+machine output' card;
23
24
  # - can be changed by passing a filetype and/or a block to
24
25
  # store_machine_output
25
26
  #
26
27
  #
27
28
  # HOW DOES IT WORK?
28
- # Machine cards have a "+machine input" and a "+machine output" card. The
29
- # "+machine input" card is a pointer to all input cards. Including the
30
- # MachineInput module creates an "on: save" event that runs the machines of
29
+ # Machine cards have a '+machine input' and a '+machine output' card. The
30
+ # '+machine input' card is a pointer to all input cards. Including the
31
+ # MachineInput module creates an 'on: save' event that runs the machines of
31
32
  # all cards that are linked to that card via the +machine input pointer.
32
33
 
33
-
34
-
35
34
  class Card
36
35
  module Machine
37
36
  module ClassMethods
@@ -51,103 +50,120 @@ class Card
51
50
 
52
51
  def store_machine_output args={}, &block
53
52
  output_config.merge!(args)
54
- if block_given?
55
- define_method :after_engine, &block
56
- end
53
+ return unless block_given?
54
+ define_method :after_engine, &block
57
55
  end
58
56
  end
59
57
 
60
- def self.included(host_class)
61
- host_class.extend( ClassMethods )
58
+ def self.included host_class
59
+ host_class.extend(ClassMethods)
62
60
  host_class.output_config = { filetype: 'txt' }
63
61
 
62
+ # for compatibility with old migrations
63
+ return unless Codename[:machine_output]
64
64
 
65
- if Codename[:machine_output] # for compatibility with old migrations
66
- host_class.card_accessor :machine_output, type: :file
67
- host_class.card_accessor :machine_input, type: :pointer
68
-
69
- # define default machine behaviour
70
- host_class.collect_input_cards do
71
- # traverse through all levels of pointers and
72
- # collect all item cards as input
73
- items = [self]
74
- new_input = []
75
- already_extended = {} # avoid loops
76
- loop_limit = 5
77
- while items.size > 0
78
- item = items.shift
79
- next if item.trash
80
- next if already_extended[item.id].to_i > loop_limit
81
- if item.item_cards == [item] # no pointer card
82
- new_input << item
83
- else
84
- items.insert(0, item.item_cards)
85
- items.flatten!
86
- new_input << item if item != self
87
- already_extended[item] = already_extended[item].to_i + 1
88
- end
89
- end
90
- new_input
91
- end
65
+ host_class.card_accessor :machine_output, type: :file
66
+ host_class.card_accessor :machine_input, type: :pointer
92
67
 
93
- host_class.prepare_machine_input {}
94
- host_class.machine_engine { |input| input }
95
- host_class.store_machine_output do |output|
96
- filetype = host_class.output_config[:filetype]
97
- file = Tempfile.new [ id.to_s, ".#{filetype}" ]
98
- file.write output
99
- file.rewind
100
- Card::Auth.as_bot do
101
- p = machine_output_card
102
- p.file = file
103
- p.save!
104
- end
105
- file.close
106
- file.unlink
68
+ set_default_machine_behaviour host_class
69
+ define_machine_views host_class
70
+ define_machine_events host_class
71
+ end
72
+
73
+ def self.define_machine_events host_class
74
+ event_suffix = host_class.name.tr ':', '_'
75
+ event_name = "reset_machine_output_#{event_suffix}".to_sym
76
+ host_class.event event_name, after: :expire_related, on: :save do
77
+ reset_machine_output!
78
+ end
79
+ end
80
+
81
+ def self.define_machine_views host_class
82
+ host_class.format do
83
+ view :machine_output_url do |_args|
84
+ machine_output_url
107
85
  end
86
+ end
87
+ end
108
88
 
89
+ def self.set_default_machine_behaviour host_class
90
+ set_default_input_collection_method host_class
91
+ set_default_input_preparation_method host_class
92
+ set_default_output_storage_method host_class
93
+ host_class.machine_engine { |input| input }
94
+ end
109
95
 
110
- host_class.format do
111
- view :machine_output_url do |args|
112
- machine_output_url
113
- end
96
+ def self.set_default_input_preparation_method host_class
97
+ host_class.prepare_machine_input {}
98
+ end
99
+
100
+ def self.set_default_output_storage_method host_class
101
+ host_class.store_machine_output do |output|
102
+ filetype = host_class.output_config[:filetype]
103
+ file = Tempfile.new [id.to_s, ".#{filetype}"]
104
+ file.write output
105
+ file.rewind
106
+ Card::Auth.as_bot do
107
+ p = machine_output_card
108
+ p.file = file
109
+ p.save!
114
110
  end
111
+ file.close
112
+ file.unlink
113
+ end
114
+ end
115
115
 
116
- event_suffix = host_class.name.gsub ':', '_'
117
- host_class.event(
118
- "reset_machine_output_#{ event_suffix }".to_sym,
119
- after: :expire_related, on: :save
120
- ) do
121
- reset_machine_output!
116
+ def self.set_default_input_collection_method host_class
117
+ host_class.collect_input_cards do
118
+ # traverse through all levels of pointers and
119
+ # collect all item cards as input
120
+ items = [self]
121
+ new_input = []
122
+ already_extended = {} # avoid loops
123
+ loop_limit = 5
124
+ while items.size > 0
125
+ item = items.shift
126
+ next if item.trash || already_extended[item.id].to_i > loop_limit
127
+ if item.item_cards == [item] # no pointer card
128
+ new_input << item
129
+ else
130
+ # item_cards instantiates non-existing cards
131
+ # we don't want those
132
+ items.insert(0, item.item_cards.reject(&:unknown?))
133
+ items.flatten!
134
+
135
+ new_input << item if item != self && item.known?
136
+ already_extended[item] = already_extended[item].to_i + 1
137
+ end
122
138
  end
139
+ new_input
123
140
  end
124
141
  end
125
142
 
126
143
  def run_machine joint="\n"
127
144
  before_engine
128
- output = input_item_cards.map do |input|
129
- unless input.kind_of? Card::Set::Type::Pointer
145
+ output =
146
+ input_item_cards.map do |input|
147
+ next if input.is_a? Card::Set::Type::Pointer
130
148
  if input.respond_to? :machine_input
131
- engine( input.machine_input )
149
+ engine(input.machine_input)
132
150
  else
133
- engine( input.format._render_raw )
151
+ engine(input.format._render_raw)
134
152
  end
135
- end
136
- end.select(&:present?).join( joint )
153
+ end.select(&:present?).join(joint)
137
154
  after_engine output
138
155
  end
139
156
 
140
157
  def reset_machine_output!
141
158
  Auth.as_bot do
142
- moc = machine_output_card and moc.real? and moc.delete!
143
- #mic = machine_input_card and mic.real? and mic.delete!
159
+ (moc = machine_output_card) && moc.real? && moc.delete!
160
+ # mic = machine_input_card and mic.real? and mic.delete!
144
161
  update_input_card
145
162
  end
146
163
  end
147
164
 
148
-
149
165
  def update_machine_output
150
- if ok? :read and not was_already_locked = locked?
166
+ if ok?(:read) && !(was_already_locked = locked?)
151
167
  Auth.as_bot do
152
168
  lock!
153
169
  update_input_card
@@ -155,7 +171,7 @@ class Card
155
171
  end
156
172
  end
157
173
  ensure
158
- unlock! unless was_already_locked
174
+ unlock! unless was_already_locked
159
175
  end
160
176
 
161
177
  def lock_cache_key
@@ -184,7 +200,7 @@ class Card
184
200
 
185
201
  def machine_output_url
186
202
  ensure_machine_output
187
- machine_output_card.file.url #(:default, timestamp: false)
203
+ machine_output_card.file.url # (:default, timestamp: false)
188
204
  # to get rid of additional number in url
189
205
  end
190
206
 
@@ -195,10 +211,8 @@ class Card
195
211
 
196
212
  def ensure_machine_output
197
213
  output = fetch trait: :machine_output
198
- if !output || !output.selected_content_action_id
199
- update_machine_output
200
- end
214
+ return if output && output.selected_content_action_id
215
+ update_machine_output
201
216
  end
202
217
  end
203
218
  end
204
-