spontaneous 0.2.0.alpha2 → 0.2.0.alpha3

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 (404) hide show
  1. data/Gemfile +3 -40
  2. data/Rakefile +29 -41
  3. data/Readme.markdown +21 -8
  4. data/application/css/add_alias_dialogue.css.scss +79 -0
  5. data/application/css/{v2.scss → core.css.scss} +537 -550
  6. data/application/css/{definitions.scss → definitions.css.scss} +121 -33
  7. data/application/css/dialogue.css.scss +409 -0
  8. data/application/css/{editing.scss → editing.css.scss} +25 -262
  9. data/application/css/font.css.scss +8 -0
  10. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  11. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  12. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_flat_10_000000_40x100.png +0 -0
  13. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  14. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  15. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  16. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  17. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  18. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  19. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_222222_256x240.png +0 -0
  20. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_228ef1_256x240.png +0 -0
  21. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ef8c08_256x240.png +0 -0
  22. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ffd27a_256x240.png +0 -0
  23. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ffffff_256x240.png +0 -0
  24. data/application/css/jquery-ui-1.8.21.custom/ui-lightness.css.scss +565 -0
  25. data/application/css/{login.scss → login.css.scss} +4 -4
  26. data/application/css/meta.css.scss +331 -0
  27. data/application/css/{popover.scss → popover.css.scss} +9 -8
  28. data/application/css/{schema_error.scss → schema_error.css.scss} +4 -4
  29. data/application/css/spontaneous.css +5 -0
  30. data/application/css/unsupported.css.scss +42 -0
  31. data/application/js/add_alias_dialogue.js +72 -10
  32. data/application/js/ajax.js +50 -16
  33. data/application/js/compatibility.js +19 -15
  34. data/application/js/content.js +39 -36
  35. data/application/js/content_area.js +53 -5
  36. data/application/js/dialogue.js +17 -0
  37. data/application/js/dom.js +1 -1
  38. data/application/js/edit_panel.js +23 -8
  39. data/application/js/extensions.js +7 -2
  40. data/application/js/field_preview.js +2 -1
  41. data/application/js/field_types/date_field.js +11 -8
  42. data/application/js/field_types/file_field.js +188 -9
  43. data/application/js/field_types/image_field.js +46 -29
  44. data/application/js/field_types/markdown_field.js +57 -14
  45. data/application/js/field_types/select_field.js +72 -0
  46. data/application/js/field_types/string_field.js +8 -0
  47. data/application/js/field_types/webvideo_field.js +8 -0
  48. data/application/js/init.js +1 -7
  49. data/application/js/location.js +41 -13
  50. data/application/js/login.js +3 -0
  51. data/application/js/meta_view/user_admin.js +543 -0
  52. data/application/js/meta_view.js +1 -0
  53. data/application/js/metadata.js +20 -0
  54. data/application/js/page.js +17 -3
  55. data/application/js/page_browser.js +40 -30
  56. data/application/js/page_entry.js +4 -0
  57. data/application/js/panel/root_menu.js +66 -0
  58. data/application/js/popover.js +2 -2
  59. data/application/js/preview.js +1 -1
  60. data/application/js/publish.js +138 -30
  61. data/application/js/services.js +43 -0
  62. data/application/js/sharded_upload.js +2 -2
  63. data/application/js/spontaneous.js +64 -5
  64. data/application/js/state.js +20 -9
  65. data/application/js/top_bar.js +273 -150
  66. data/application/js/types.js +20 -15
  67. data/application/js/upload.js +1 -2
  68. data/application/js/user.js +18 -4
  69. data/application/js/vendor/date.js +104 -0
  70. data/application/js/vendor/jquery-ui-1.8.18.custom.min.js +356 -0
  71. data/application/js/views/box_view.js +15 -8
  72. data/application/js/views/page_piece_view.js +11 -8
  73. data/application/js/views/page_view.js +21 -3
  74. data/application/js/views/piece_view.js +19 -10
  75. data/application/js/views.js +3 -0
  76. data/application/static/chromelogo-200x52-45c7cbc93be080bea342df5fcda2ef8b.png +0 -0
  77. data/application/static/dot-texture-9eea29e4ac7ad9a772285252078ec127.png +0 -0
  78. data/application/static/editing-textarea-resize-s-b5af62365eb7e19ea4beccf7242d508e.png +0 -0
  79. data/application/static/editing-texture-1-42b06a3439752490988f30f2a06d5e7c.png +0 -0
  80. data/application/static/font/fontawesome-webfont-5c5c21100a346972a82c34c5e96ffcfe.ttf +0 -0
  81. data/application/static/loop_alt1-white-7894b458528e92216196cae26b4c2c96.svg +12 -0
  82. data/application/static/spontaneous-states-e91ec89db525c62da0105b97cdd781ce.png +0 -0
  83. data/application/views/index.erb +2 -2
  84. data/application/views/login.erb +4 -8
  85. data/application/views/schema_modification_error.html.erb +1 -4
  86. data/application/views/unsupported.erb +9 -7
  87. data/bin/spot +1 -1
  88. data/db/migrations/20110209152710_users_and_groups.rb +10 -10
  89. data/db/migrations/20120305112647_site_modification_time.rb +11 -0
  90. data/db/migrations/20120418153903_add_ownership_of_content.rb +14 -0
  91. data/db/migrations/20120423175416_add_pending_modifications.rb +21 -0
  92. data/db/migrations/20120525164947_add_field_versions.rb +27 -0
  93. data/lib/sequel/plugins/scoped_table_name.rb +10 -1
  94. data/lib/spontaneous/asset/file.rb +25 -0
  95. data/lib/spontaneous/asset/source.rb +28 -0
  96. data/lib/spontaneous/asset.rb +75 -0
  97. data/lib/spontaneous/box.rb +6 -4
  98. data/lib/spontaneous/capistrano/deploy.rb +47 -0
  99. data/lib/spontaneous/capistrano/sync.rb +81 -0
  100. data/lib/spontaneous/capistrano.rb +13 -0
  101. data/lib/spontaneous/change.rb +60 -68
  102. data/lib/spontaneous/cli/assets.rb +29 -0
  103. data/lib/spontaneous/cli/base.rb +0 -48
  104. data/lib/spontaneous/cli/console.rb +1 -1
  105. data/lib/spontaneous/cli/server.rb +6 -4
  106. data/lib/spontaneous/cli/site.rb +28 -17
  107. data/lib/spontaneous/cli/user.rb +107 -0
  108. data/lib/spontaneous/cli.rb +100 -4
  109. data/lib/spontaneous/collections/entry_set.rb +2 -2
  110. data/lib/spontaneous/collections/field_set.rb +48 -22
  111. data/lib/spontaneous/collections/prototype_set.rb +20 -13
  112. data/lib/spontaneous/constants.rb +3 -0
  113. data/lib/spontaneous/content.rb +22 -5
  114. data/lib/spontaneous/errors.rb +3 -3
  115. data/lib/spontaneous/extensions/array.rb +12 -0
  116. data/lib/spontaneous/extensions/enumerable.rb +30 -0
  117. data/lib/spontaneous/extensions/nil.rb +3 -1
  118. data/lib/spontaneous/extensions/string.rb +16 -0
  119. data/lib/spontaneous/field_types/date_field.rb +45 -2
  120. data/lib/spontaneous/field_types/field.rb +42 -9
  121. data/lib/spontaneous/field_types/file_field.rb +68 -0
  122. data/lib/spontaneous/field_types/image_field.rb +63 -0
  123. data/lib/spontaneous/field_types/select_field.rb +109 -0
  124. data/lib/spontaneous/field_types/string_field.rb +6 -1
  125. data/lib/spontaneous/field_types/webvideo_field.rb +85 -27
  126. data/lib/spontaneous/field_types.rb +1 -1
  127. data/lib/spontaneous/field_version.rb +8 -0
  128. data/lib/spontaneous/generators/page.rb +1 -1
  129. data/lib/spontaneous/generators/site/Capfile.tt +1 -4
  130. data/lib/spontaneous/generators/site/Gemfile.tt +13 -6
  131. data/lib/spontaneous/generators/site/config/deploy.rb.tt +28 -0
  132. data/lib/spontaneous/generators/site/config/environments/production.rb.tt +7 -2
  133. data/lib/spontaneous/generators/site.rb +1 -0
  134. data/lib/spontaneous/json.rb +34 -11
  135. data/lib/spontaneous/layout.rb +22 -0
  136. data/lib/spontaneous/media/file.rb +4 -0
  137. data/lib/spontaneous/output/assets/compression.rb +58 -0
  138. data/lib/spontaneous/output/assets.rb +32 -0
  139. data/lib/spontaneous/output/context.rb +179 -0
  140. data/lib/spontaneous/output/format/html.rb +5 -0
  141. data/lib/spontaneous/output/format/plain.rb +5 -0
  142. data/lib/spontaneous/output/format.rb +180 -0
  143. data/lib/spontaneous/output/helpers/classes_helper.rb +18 -0
  144. data/lib/spontaneous/{render/helpers/html_helper.rb → output/helpers/conditional_comment_helper.rb} +3 -12
  145. data/lib/spontaneous/output/helpers/script_helper.rb +73 -0
  146. data/lib/spontaneous/output/helpers/stylesheet_helper.rb +61 -0
  147. data/lib/spontaneous/output/helpers.rb +28 -0
  148. data/lib/spontaneous/output/template/engine.rb +59 -0
  149. data/lib/spontaneous/output/template/renderer.rb +153 -0
  150. data/lib/spontaneous/output/template.rb +21 -0
  151. data/lib/spontaneous/output.rb +163 -0
  152. data/lib/spontaneous/page.rb +2 -1
  153. data/lib/spontaneous/paths.rb +6 -1
  154. data/lib/spontaneous/permissions/access_key.rb +5 -5
  155. data/lib/spontaneous/permissions/user.rb +81 -35
  156. data/lib/spontaneous/permissions/user_level.rb +26 -22
  157. data/lib/spontaneous/plugins/aliases.rb +76 -12
  158. data/lib/spontaneous/plugins/allowed_types.rb +60 -18
  159. data/lib/spontaneous/plugins/application/paths.rb +0 -28
  160. data/lib/spontaneous/plugins/application/system.rb +35 -0
  161. data/lib/spontaneous/plugins/boxes.rb +4 -0
  162. data/lib/spontaneous/plugins/content_groups.rb +16 -0
  163. data/lib/spontaneous/plugins/entries.rb +50 -30
  164. data/lib/spontaneous/plugins/fields.rb +15 -0
  165. data/lib/spontaneous/plugins/layouts.rb +8 -2
  166. data/lib/spontaneous/plugins/modifications.rb +228 -0
  167. data/lib/spontaneous/plugins/page/formats.rb +67 -42
  168. data/lib/spontaneous/plugins/page/request.rb +10 -0
  169. data/lib/spontaneous/plugins/page/site_timestamps.rb +28 -0
  170. data/lib/spontaneous/plugins/paths.rb +15 -3
  171. data/lib/spontaneous/plugins/publishing.rb +124 -45
  172. data/lib/spontaneous/plugins/render.rb +13 -8
  173. data/lib/spontaneous/plugins/schema_hierarchy.rb +18 -6
  174. data/lib/spontaneous/plugins/site/helpers.rb +53 -0
  175. data/lib/spontaneous/plugins/site/hooks.rb +50 -0
  176. data/lib/spontaneous/plugins/site/map.rb +1 -1
  177. data/lib/spontaneous/plugins/site/paths.rb +13 -0
  178. data/lib/spontaneous/plugins/site/publishing.rb +6 -2
  179. data/lib/spontaneous/plugins/site/{revisions.rb → state.rb} +5 -1
  180. data/lib/spontaneous/plugins/site/storage.rb +4 -0
  181. data/lib/spontaneous/plugins/site/url.rb +15 -0
  182. data/lib/spontaneous/plugins/site_map.rb +13 -3
  183. data/lib/spontaneous/plugins/styles.rb +5 -1
  184. data/lib/spontaneous/plugins/visibility.rb +39 -12
  185. data/lib/spontaneous/prototypes/box_prototype.rb +4 -0
  186. data/lib/spontaneous/prototypes/field_prototype.rb +15 -10
  187. data/lib/spontaneous/publishing/event_client.rb +46 -0
  188. data/lib/spontaneous/publishing/immediate.rb +81 -44
  189. data/lib/spontaneous/publishing/simultaneous.rb +23 -6
  190. data/lib/spontaneous/publishing.rb +4 -3
  191. data/lib/spontaneous/rack/around_back.rb +1 -5
  192. data/lib/spontaneous/rack/around_front.rb +4 -4
  193. data/lib/spontaneous/rack/around_preview.rb +4 -3
  194. data/lib/spontaneous/rack/assets.rb +81 -54
  195. data/lib/spontaneous/rack/authentication.rb +0 -1
  196. data/lib/spontaneous/rack/back.rb +160 -72
  197. data/lib/spontaneous/rack/cookie_authentication.rb +2 -2
  198. data/lib/spontaneous/rack/css.rb +18 -15
  199. data/lib/spontaneous/rack/event_source.rb +9 -21
  200. data/lib/spontaneous/rack/fiber_pool.rb +26 -0
  201. data/lib/spontaneous/rack/front.rb +12 -4
  202. data/lib/spontaneous/rack/helpers.rb +35 -13
  203. data/lib/spontaneous/rack/js.rb +41 -0
  204. data/lib/spontaneous/rack/public.rb +34 -44
  205. data/lib/spontaneous/rack/sse.rb +18 -0
  206. data/lib/spontaneous/rack/static.rb +3 -0
  207. data/lib/spontaneous/rack/user_admin.rb +100 -0
  208. data/lib/spontaneous/rack/user_helpers.rb +1 -1
  209. data/lib/spontaneous/rack.rb +6 -2
  210. data/lib/spontaneous/schema.rb +31 -4
  211. data/lib/spontaneous/search/index.rb +19 -3
  212. data/lib/spontaneous/search/results.rb +1 -1
  213. data/lib/spontaneous/sequel.rb +17 -0
  214. data/lib/spontaneous/site.rb +11 -4
  215. data/lib/spontaneous/state.rb +11 -0
  216. data/lib/spontaneous/storage/cloud.rb +4 -0
  217. data/lib/spontaneous/storage/local.rb +11 -0
  218. data/lib/spontaneous/style.rb +2 -2
  219. data/lib/spontaneous/tasks/database.rake +21 -22
  220. data/lib/spontaneous/utils/database/mysql_dumper.rb +4 -0
  221. data/lib/spontaneous/utils/database/postgres_dumper.rb +78 -0
  222. data/lib/spontaneous/utils/database.rb +6 -3
  223. data/lib/spontaneous/utils/smart_quotes.rb +499 -0
  224. data/lib/spontaneous/utils/smush_it.rb +66 -0
  225. data/lib/spontaneous/utils.rb +3 -1
  226. data/lib/spontaneous/version.rb +2 -2
  227. data/lib/spontaneous.rb +25 -29
  228. data/spontaneous.gemspec +186 -106
  229. data/test/experimental/test_features.rb +1 -1
  230. data/test/fixtures/asset_pipeline/application/css/basic.css.scss +4 -0
  231. data/test/fixtures/asset_pipeline/application/css/complex.css.scss.erb +6 -0
  232. data/test/fixtures/asset_pipeline/application/css/simple.css +3 -0
  233. data/test/fixtures/asset_pipeline/application/css/spontaneous.css +7 -0
  234. data/test/fixtures/asset_pipeline/application/css/subdir/complex.css.scss.erb +6 -0
  235. data/test/fixtures/asset_pipeline/application/css/subdir/library.css.scss +1 -0
  236. data/test/fixtures/asset_pipeline/application/css/subdir/simple.css +3 -0
  237. data/test/fixtures/asset_pipeline/application/js/basic.js.coffee +1 -0
  238. data/test/fixtures/asset_pipeline/application/js/complex.js.coffee.erb +1 -0
  239. data/test/fixtures/asset_pipeline/application/js/login.js +1 -0
  240. data/test/fixtures/asset_pipeline/application/js/require.js +1 -0
  241. data/test/fixtures/asset_pipeline/application/js/simple.js +1 -0
  242. data/test/fixtures/asset_pipeline/application/js/spontaneous.js +5 -0
  243. data/test/fixtures/asset_pipeline/application/js/subdir/complex.js.coffee.erb +1 -0
  244. data/test/fixtures/asset_pipeline/application/js/subdir/library.js.coffee +1 -0
  245. data/test/fixtures/asset_pipeline/application/js/subdir/simple.js +1 -0
  246. data/test/fixtures/asset_pipeline/application/js/vendor/jquery.js +1 -0
  247. data/test/fixtures/asset_pipeline/application/static/dot-texture.png +0 -0
  248. data/test/fixtures/asset_pipeline/application/static/subdir/px.gif +0 -0
  249. data/test/fixtures/assets/public1/css/a.scss +1 -0
  250. data/test/fixtures/assets/public1/js/a.js +1 -0
  251. data/test/fixtures/assets/public1/js/m.coffee +1 -0
  252. data/test/fixtures/assets/public2/css/b.scss +1 -0
  253. data/test/fixtures/assets/public2/css/c.css +1 -0
  254. data/test/fixtures/assets/public2/js/b.js +1 -0
  255. data/test/fixtures/assets/public2/js/c.js +1 -0
  256. data/test/fixtures/assets/public2/js/n.coffee +1 -0
  257. data/test/fixtures/back/config/user_levels.yml +3 -0
  258. data/test/fixtures/back/public/js/coffeescript.coffee +1 -0
  259. data/test/fixtures/back/templates/layouts/standard.css.cut +1 -0
  260. data/test/fixtures/back/templates/layouts/standard.js.cut +1 -0
  261. data/test/fixtures/example_application/config/database.yml +4 -4
  262. data/test/fixtures/helpers/templates/layouts/standard.html.cut +1 -0
  263. data/test/fixtures/helpers/templates/layouts/standard.mobile.cut +1 -0
  264. data/test/fixtures/images/vimlogo.pdf +0 -0
  265. data/test/fixtures/outputs/templates/layouts/standard.atom.cut +1 -0
  266. data/test/fixtures/permissions/config/user_levels.yml +6 -3
  267. data/test/fixtures/serialisation/class_hash.yaml.erb +1 -0
  268. data/test/fixtures/serialisation/root_hash.yaml.erb +2 -2
  269. data/test/fixtures/templates/extended/grandparent.html.cut +7 -7
  270. data/test/fixtures/templates/extended/main.html.cut +5 -5
  271. data/test/fixtures/templates/extended/parent.html.cut +8 -8
  272. data/test/fixtures/templates/extended/partial_with_locals.html.cut +1 -1
  273. data/test/fixtures/templates/extended/with_includes.html.cut +6 -6
  274. data/test/fixtures/templates/extended/with_includes_and_locals.html.cut +6 -7
  275. data/test/fixtures/templates/layouts/entries.html.cut +4 -4
  276. data/test/fixtures/templates/layouts/standard.html.cut +1 -0
  277. data/test/fixtures/templates/layouts/variables.html.cut +1 -1
  278. data/test/fixtures/templates/publishing/templates/layouts/static.html.cut +1 -1
  279. data/test/fixtures/templates/publishing/templates/layouts/static.rtf.cut +1 -0
  280. data/test/fixtures/templates/template_class/complex_template.html.cut +2 -2
  281. data/test/fixtures/templates/template_class/complex_template.pdf.cut +2 -2
  282. data/test/fixtures/templates/template_class/default_template_style.html.cut +1 -1
  283. data/test/fixtures/templates/template_class/images_with_template.html.cut +2 -2
  284. data/test/fixtures/templates/template_class/slots_template.html.cut +2 -2
  285. data/test/fixtures/templates/template_class/slots_template.pdf.cut +2 -2
  286. data/test/fixtures/user_manager/config/user_levels.yml +9 -0
  287. data/test/functional/test_application.rb +7 -7
  288. data/test/functional/test_back.rb +352 -97
  289. data/test/functional/test_front.rb +71 -20
  290. data/test/functional/test_user_manager.rb +284 -0
  291. data/test/javascript/env.js +13505 -0
  292. data/test/javascript/test_markdown.rb +43 -3
  293. data/test/support/custom_matchers.rb +3 -2
  294. data/test/test_helper.rb +50 -9
  295. data/test/test_javascript.rb +13 -13
  296. data/test/ui_helper.rb +1 -1
  297. data/test/unit/test_alias.rb +79 -8
  298. data/test/unit/test_asset_bundler.rb +220 -0
  299. data/test/unit/test_assets.rb +213 -0
  300. data/test/unit/test_async.rb +55 -0
  301. data/test/unit/test_authentication.rb +52 -39
  302. data/test/unit/test_boxes.rb +20 -15
  303. data/test/unit/test_changesets.rb +261 -0
  304. data/test/unit/test_content.rb +73 -33
  305. data/test/unit/test_content_inheritance.rb +18 -18
  306. data/test/unit/test_extensions.rb +26 -0
  307. data/test/unit/test_fields.rb +303 -16
  308. data/test/unit/test_formats.rb +267 -34
  309. data/test/unit/test_helpers.rb +79 -2
  310. data/test/unit/test_images.rb +10 -0
  311. data/test/unit/test_layouts.rb +21 -13
  312. data/test/unit/test_modifications.rb +648 -0
  313. data/test/unit/test_page.rb +6 -2
  314. data/test/unit/test_permissions.rb +101 -27
  315. data/test/unit/test_piece.rb +4 -4
  316. data/test/unit/test_plugins.rb +3 -2
  317. data/test/unit/test_publishing.rb +332 -0
  318. data/test/unit/test_render.rb +118 -67
  319. data/test/unit/test_revisions.rb +546 -0
  320. data/test/unit/test_schema.rb +83 -1
  321. data/test/unit/test_search.rb +59 -0
  322. data/test/unit/test_serialisation.rb +2 -47
  323. data/test/unit/test_site.rb +217 -108
  324. data/test/unit/test_storage.rb +26 -0
  325. data/test/unit/test_structure.rb +2 -2
  326. data/test/unit/test_styles.rb +90 -75
  327. data/test/unit/test_table_scoping.rb +21 -17
  328. data/test/unit/test_templates.rb +75 -69
  329. data/test/{slow → unit}/test_visibility.rb +78 -22
  330. metadata +528 -221
  331. data/application/css/add_alias_dialogue.scss +0 -27
  332. data/application/css/min/14c2a35812c443001b15d8b12a4780f88c678035.css +0 -1
  333. data/application/css/min/565d4c25e82148acb01c45c8d675b37a08676d77.css +0 -1
  334. data/application/css/min/84dbe894ea96eafd321c30823d630817bfc4b03b.css +0 -1
  335. data/application/css/spontaneous.scss +0 -111
  336. data/application/css/unsupported.scss +0 -16
  337. data/application/css/variables.scss +0 -80
  338. data/application/js/min/2a0c2962537a3181fedfff5c92596ba6d3122dc9.js +0 -3
  339. data/application/js/min/4cf1c493d3379ecba5287758c61238034c0893f9.js +0 -2
  340. data/application/js/min/78ac6b99d96750bb6b9f9aad4cb9cd91cd03f391.js +0 -3
  341. data/application/js/min/b8abf302a824c35385ff517b34111e1710ff3b37.js +0 -2
  342. data/application/js/min/c8efb9b9f7c3f6613fcebc6be60f605b6570a382.js +0 -90
  343. data/application/static/diagonal-texture.png +0 -0
  344. data/application/static/editing-0-noise.png +0 -0
  345. data/application/static/editing-1-noise.png +0 -0
  346. data/application/static/editing-texture-1.png +0 -0
  347. data/application/static/editing-texture.png +0 -0
  348. data/application/static/editing-toolbar-shadow-bottom.png +0 -0
  349. data/application/static/editing-toolbar-shadow-top.png +0 -0
  350. data/application/static/inner-glow.png +0 -0
  351. data/application/static/item-buttons-highlight.png +0 -0
  352. data/application/static/item-buttons.png +0 -0
  353. data/application/static/paper-texture-dark.png +0 -0
  354. data/application/static/plus_alt.svg +0 -8
  355. data/application/static/select-arrow-root.png +0 -0
  356. data/application/static/slot-up-arrow.png +0 -0
  357. data/application/static/spontaneous.png +0 -0
  358. data/lib/cutaneous/context_helper.rb +0 -187
  359. data/lib/cutaneous/preview_context.rb +0 -32
  360. data/lib/cutaneous/preview_renderer.rb +0 -10
  361. data/lib/cutaneous/publish_context.rb +0 -10
  362. data/lib/cutaneous/publish_renderer.rb +0 -14
  363. data/lib/cutaneous/publish_template.rb +0 -62
  364. data/lib/cutaneous/publish_token_parser.rb +0 -8
  365. data/lib/cutaneous/renderer.rb +0 -124
  366. data/lib/cutaneous/request_context.rb +0 -9
  367. data/lib/cutaneous/request_renderer.rb +0 -15
  368. data/lib/cutaneous/request_template.rb +0 -11
  369. data/lib/cutaneous/request_token_parser.rb +0 -9
  370. data/lib/cutaneous/token_parser.rb +0 -125
  371. data/lib/cutaneous.rb +0 -48
  372. data/lib/spontaneous/render/context_base.rb +0 -143
  373. data/lib/spontaneous/render/development_renderer.rb +0 -14
  374. data/lib/spontaneous/render/engine.rb +0 -19
  375. data/lib/spontaneous/render/format/html.rb +0 -5
  376. data/lib/spontaneous/render/format.rb +0 -75
  377. data/lib/spontaneous/render/helpers/script_helper.rb +0 -17
  378. data/lib/spontaneous/render/helpers/stylesheet_helper.rb +0 -16
  379. data/lib/spontaneous/render/helpers.rb +0 -14
  380. data/lib/spontaneous/render/preview_context.rb +0 -8
  381. data/lib/spontaneous/render/preview_renderer.rb +0 -24
  382. data/lib/spontaneous/render/publish_context.rb +0 -22
  383. data/lib/spontaneous/render/published_renderer.rb +0 -53
  384. data/lib/spontaneous/render/publishing_renderer.rb +0 -16
  385. data/lib/spontaneous/render/render_cache.rb +0 -26
  386. data/lib/spontaneous/render/renderer.rb +0 -50
  387. data/lib/spontaneous/render/request_context.rb +0 -8
  388. data/lib/spontaneous/render.rb +0 -214
  389. data/test/experimental/test_cutaneous.rb +0 -309
  390. data/test/fixtures/application/css/test.less +0 -5
  391. data/test/slow/test_publishing.rb +0 -1006
  392. /data/application/css/{developer.scss → developer.css.scss} +0 -0
  393. /data/application/js/vendor/{jquery-1.7.1.min.js → jquery.js} +0 -0
  394. /data/application/static/{location-arrow.png → location-arrow-c1c1d3ca472481c61a0a5f8cb289d743.png} +0 -0
  395. /data/application/static/{missing.png → missing-911ce6dbd9f4602e0f3fbcd7e78846a2.png} +0 -0
  396. /data/application/static/{orange-down-arrow.png → orange-down-arrow-395ae1929e8662b2ff0977daf12c35bb.png} +0 -0
  397. /data/application/static/{page-browser-next.png → page-browser-next-ce781a242c23b980b99b9db7abc20b05.png} +0 -0
  398. /data/application/static/{plus-box.png → plus-box-dcde74a1e496f68298c9b443caa1c5d5.png} +0 -0
  399. /data/application/static/{select-arrow.png → select-arrow-6e7dd3745b00e934b0d7a3250c46558b.png} +0 -0
  400. /data/application/static/{slot-down-arrow.png → slot-down-arrow-59ad5f5ee5b52a7ebd00bca4b3104194.png} +0 -0
  401. /data/application/static/{splash.png → splash-65b493a714df9b8b3ab170103401b53d.png} +0 -0
  402. /data/application/static/{spot.png → spot-71fab1d2f065034f5fc15e7bea2ad36c.png} +0 -0
  403. /data/application/static/{spot.svg → spot-8505041082d8d3bbe8d34c29dddb3b7d.svg} +0 -0
  404. /data/application/static/{texture.png → texture-03f7627e8264b1d607113ab32c593a58.png} +0 -0
@@ -5,24 +5,16 @@ require File.expand_path('../../test_helper', __FILE__)
5
5
 
6
6
  class StylesTest < MiniTest::Spec
7
7
 
8
-
9
- # context "template root" do
10
- # should "be settable" do
11
- # File.exists?(template_root).should be_true
12
- # Spontaneous.template_root = template_root
13
- # Spontaneous.template_root.should == template_root
14
- # end
15
- # end
16
-
17
-
18
8
  def teardown
19
9
  teardown_site
20
10
  end
21
11
 
22
12
  def setup
23
13
  @site = setup_site
24
- self.template_root = File.expand_path(File.join(File.dirname(__FILE__), "../fixtures/styles"))
25
- Spontaneous::Render.use_development_renderer
14
+ @template_root = File.expand_path(File.join(File.dirname(__FILE__), "../fixtures/styles"))
15
+ @site.paths.add(:templates, @template_root)
16
+ @renderer = S::Output::Template::PreviewRenderer.new
17
+ S::Output.renderer = @renderer
26
18
  end
27
19
 
28
20
  context "styles for" do
@@ -33,6 +25,8 @@ class StylesTest < MiniTest::Spec
33
25
  class ::Piece < Spontaneous::Piece; end
34
26
  class ::Box < Spontaneous::Box; end
35
27
 
28
+ ::Page.box :box1
29
+
36
30
  class ::MissingClass < Piece; end
37
31
  class ::TemplateClass < Piece; end
38
32
  class ::TemplateSubClass1 < TemplateClass; end
@@ -41,6 +35,7 @@ class StylesTest < MiniTest::Spec
41
35
  end
42
36
 
43
37
  teardown do
38
+ Object.send(:remove_const, :Page)
44
39
  Object.send(:remove_const, :MissingClass)
45
40
  Object.send(:remove_const, :TemplateClass)
46
41
  Object.send(:remove_const, :TemplateSubClass1)
@@ -52,7 +47,9 @@ class StylesTest < MiniTest::Spec
52
47
 
53
48
  context "default styles" do
54
49
  setup do
50
+ @page = ::Page.new
55
51
  @piece = TemplateClass.new
52
+ @page.box1 << @piece
56
53
  end
57
54
 
58
55
  should "return anonymous style if no templates are found" do
@@ -63,7 +60,7 @@ class StylesTest < MiniTest::Spec
63
60
  end
64
61
 
65
62
  should "derive path from owning class and name" do
66
- assert_correct_template(@piece, 'template_class')
63
+ assert_correct_template(@piece, @template_root / 'template_class')
67
64
  end
68
65
 
69
66
  should "render using correct template" do
@@ -77,41 +74,44 @@ class StylesTest < MiniTest::Spec
77
74
 
78
75
  should "simply render an empty string if no templates are available" do
79
76
  piece = InvisibleClass.new
77
+ @page.box1 << piece
80
78
  piece.render.should == ""
81
79
  end
82
80
  end
83
81
 
84
82
 
85
83
  context "named styles" do
84
+ setup do
85
+ @page = ::Page.new
86
+ @piece = TemplateClass.new
87
+ @page.box1 << @piece
88
+ end
89
+
86
90
  should "use template found in class directory if exists" do
87
91
  TemplateClass.style :named1
88
- piece = TemplateClass.new
89
- assert_correct_template(piece, 'template_class/named1')
90
- piece.render.should == "template_class/named1.html.cut\n"
92
+ assert_correct_template(@piece, @template_root / 'template_class/named1')
93
+ @piece.render.should == "template_class/named1.html.cut\n"
91
94
  end
92
95
 
93
96
  should "use template in template root with correct name if it exists" do
94
97
  TemplateClass.style :named2
95
- piece = TemplateClass.new
96
- assert_correct_template(piece, 'named2')
97
- piece.render.should == "named2.html.cut\n"
98
+ assert_correct_template(@piece, @template_root / 'named2')
99
+ @piece.render.should == "named2.html.cut\n"
98
100
  end
99
101
 
100
102
  should "allow passing of directory/stylename" do
101
103
  TemplateClass.style :'orange/apple'
102
- piece = TemplateClass.new
103
104
  # piece.style.template.should == 'orange/apple'
104
- assert_correct_template(piece, 'orange/apple')
105
- piece.render.should == "orange/apple.html.cut\n"
105
+ assert_correct_template(@piece, @template_root / 'orange/apple')
106
+ @piece.render.should == "orange/apple.html.cut\n"
106
107
  end
107
108
 
108
109
  should "default to styles marked as 'default'" do
109
110
  TemplateClass.style :named1
110
111
  TemplateClass.style :named2, :default => true
111
- piece = TemplateClass.new
112
- assert_correct_template(piece, 'named2')
113
- # piece.style.template.should == 'named2'
114
- piece.render.should == "named2.html.cut\n"
112
+ assert_correct_template(@piece, @template_root / 'named2')
113
+ # @piece.style.template.should == 'named2'
114
+ @piece.render.should == "named2.html.cut\n"
115
115
  end
116
116
  end
117
117
 
@@ -119,16 +119,17 @@ class StylesTest < MiniTest::Spec
119
119
  setup do
120
120
  TemplateClass.style :named1
121
121
  TemplateClass.style :named2, :default => true
122
+ @page = ::Page.new
122
123
  @piece = TemplateClass.new
123
- assert_correct_template(@piece, 'named2')
124
+ @page.box1 << @piece
125
+ assert_correct_template(@piece, @template_root / 'named2')
124
126
  # @piece.style.template.should == 'named2'
125
127
  @piece.render.should == "named2.html.cut\n"
126
128
  end
127
129
 
128
130
  should "be possible" do
129
131
  @piece.style = :named1
130
- # @piece.style.template.should == 'template_class/named1'
131
- assert_correct_template(@piece, 'template_class/named1')
132
+ assert_correct_template(@piece, @template_root / 'template_class/named1')
132
133
  @piece.render.should == "template_class/named1.html.cut\n"
133
134
  end
134
135
 
@@ -137,26 +138,26 @@ class StylesTest < MiniTest::Spec
137
138
  @piece.save
138
139
  @piece = Content[@piece.id]
139
140
  # @piece.style.template.should == 'template_class/named1'
140
- assert_correct_template(@piece, 'template_class/named1')
141
+ assert_correct_template(@piece, @template_root / 'template_class/named1')
141
142
  end
142
143
  end
143
144
 
144
145
  context "inheriting styles" do
145
146
  should "use default for sub class if it exists" do
146
147
  piece = TemplateSubClass1.new
147
- assert_correct_template(piece, 'template_sub_class1')
148
+ assert_correct_template(piece, @template_root / 'template_sub_class1')
148
149
  end
149
150
 
150
151
  should "fall back to default style for superclass if default for class doesn't exist" do
151
152
  piece = TemplateSubClass2.new
152
- assert_correct_template(piece, 'template_class')
153
+ assert_correct_template(piece, @template_root / 'template_class')
153
154
  # piece.style.template.should == 'template_class'
154
155
  end
155
156
  should "fall back to defined default style for superclass if default for class doesn't exist" do
156
157
  TemplateClass.style :named1
157
158
  piece = TemplateSubClass2.new
158
159
  # piece.style.template.should == 'template_class/named1'
159
- assert_correct_template(piece, 'template_class/named1')
160
+ assert_correct_template(piece, @template_root / 'template_class/named1')
160
161
  end
161
162
  end
162
163
 
@@ -270,14 +271,17 @@ class StylesTest < MiniTest::Spec
270
271
 
271
272
  context "inline templates" do
272
273
  setup do
273
- class ::InlineTemplateClass < Content
274
+ Page.add_output :pdf
275
+ class ::InlineTemplateClass < Piece
274
276
  field :title
275
277
 
276
278
  template 'html: {{title}}'
277
279
  template :pdf, 'pdf: {{title}}'
278
280
  end
279
281
 
282
+ @page = ::Page.new
280
283
  @a = InlineTemplateClass.new
284
+ @page.box1 << @a
281
285
  @a.title = "Total Title"
282
286
  end
283
287
 
@@ -289,7 +293,7 @@ class StylesTest < MiniTest::Spec
289
293
  @a.render.should == "html: Total Title"
290
294
  end
291
295
 
292
- should "be used to render the content with the right format" do
296
+ should "be used to render the content with the right format xxx" do
293
297
  @a.render(:pdf).should == "pdf: Total Title"
294
298
  end
295
299
  end
@@ -353,21 +357,22 @@ class StylesTest < MiniTest::Spec
353
357
  setup do
354
358
  TemplateClass.box :results
355
359
  TemplateClass.box :entities
360
+ @page = ::Page.new
361
+ @piece = TemplateClass.new
362
+ @page.box1 << @piece
356
363
  end
357
364
 
358
365
  should "use template with their name inside container class template dir if it exists" do
359
- piece = TemplateClass.new
360
- piece.results << TemplateClass.new
361
- assert_correct_template(piece.results, 'template_class/results')
362
- piece.results.render.should == "template_class/results.html.cut\n"
366
+ @piece.results << TemplateClass.new
367
+ assert_correct_template(@piece.results, @template_root / 'template_class/results')
368
+ @piece.results.render.should == "template_class/results.html.cut\n"
363
369
  end
364
370
 
365
371
  should "render a simple list of content if named template doesn't exist" do
366
- piece = TemplateClass.new
367
- piece.entities << TemplateClass.new
368
- piece.entities << TemplateClass.new
369
- piece.entities.render.should == "template_class.html.cut\n\ntemplate_class.html.cut\n"
370
- piece.entities.style.template.call.should == '#{ render_content }'
372
+ @piece.entities << TemplateClass.new
373
+ @piece.entities << TemplateClass.new
374
+ @piece.entities.render.should == "template_class.html.cut\n\ntemplate_class.html.cut\n"
375
+ @piece.entities.style.template.call.should == '#{ render_content }'
371
376
  end
372
377
 
373
378
 
@@ -375,21 +380,21 @@ class StylesTest < MiniTest::Spec
375
380
  TemplateClass.box :things do
376
381
  style :named1
377
382
  end
378
- piece = TemplateClass.new
379
- assert_correct_template(piece.things, 'template_class/named1')
380
- piece.things.render.should == "template_class/named1.html.cut\n"
383
+ @piece = TemplateClass.new
384
+ @page.box1 << @piece
385
+ assert_correct_template(@piece.things, @template_root / 'template_class/named1')
386
+ @piece.things.render.should == "template_class/named1.html.cut\n"
381
387
 
382
388
  TemplateClass.box :dongles do
383
389
  style :named2
384
390
  end
385
- piece = TemplateClass.new
386
- assert_correct_template(piece.dongles, 'named2')
387
- piece.dongles.render.should == "named2.html.cut\n"
391
+ @piece = TemplateClass.new
392
+ @page.box1 << @piece
393
+ assert_correct_template(@piece.dongles, @template_root / 'named2')
394
+ @piece.dongles.render.should == "named2.html.cut\n"
388
395
  end
389
396
 
390
397
  should "use styles assigned in a subclass" do
391
- saved_template_root = self.template_root
392
- self.template_root = Spontaneous.template_root
393
398
  ::TemplateSubClass = Class.new(TemplateClass)
394
399
  ::TemplateSubSubClass = Class.new(TemplateSubClass)
395
400
 
@@ -399,30 +404,36 @@ class StylesTest < MiniTest::Spec
399
404
  style :oranges
400
405
  end
401
406
 
402
- # FileUtils.mkdir_p(Spontaneous.template_root)
407
+ Dir.mktmpdir do |template_root|
408
+ @site.paths.add(:templates, template_root / "templates")
409
+
410
+
411
+ piece = TemplateSubSubClass.new
412
+ @page.box1 << piece
403
413
 
404
- piece = TemplateSubSubClass.new
405
- assert Proc === piece.bananas.template
414
+ # make sure we're running in a 'virgin' template dir
415
+ assert Proc === piece.bananas.template, "Expected Proc not #{piece.bananas.template}"
406
416
 
407
- [[piece.bananas, %w(template_sub_sub_class/bananas template_sub_class/bananas)],
408
- [piece.apples, %w(template_sub_sub_class/apples template_sub_class/apples apples)],
409
- [piece.oranges, %w(template_sub_sub_class/oranges template_sub_class/oranges oranges)]
410
- ].each do |box, test_templates|
411
- test_templates.each do |test_template|
412
- FileUtils.mkdir_p(File.dirname(Spontaneous.template_root(test_template)))
413
- FileUtils.touch(Spontaneous.template_root(test_template) + '.html.cut')
414
417
 
415
- assert_correct_template(box, test_template)
418
+ [[piece.bananas, %w(template_sub_sub_class/bananas template_sub_class/bananas)],
419
+ [piece.apples, %w(template_sub_sub_class/apples template_sub_class/apples apples)],
420
+ [piece.oranges, %w(template_sub_sub_class/oranges template_sub_class/oranges oranges)]
421
+ ].each do |box, test_templates|
422
+ test_templates.each do |test_template|
423
+ path = template_root / "templates" / test_template
424
+ FileUtils.mkdir_p(File.dirname(path))
425
+ FileUtils.touch(path + '.html.cut')
416
426
 
417
- FileUtils.rm_r(::File.dirname(Spontaneous.template_root(test_template)))
427
+ assert_correct_template(box, template_root / "templates" / test_template)
428
+
429
+ FileUtils.rm_r(template_root / "templates")
430
+ end
418
431
  end
419
432
  end
420
433
 
421
434
 
422
435
  Object.send(:remove_const, :TemplateSubClass)
423
436
  Object.send(:remove_const, :TemplateSubSubClass)
424
- FileUtils.rm_r(Spontaneous.template_root) rescue nil
425
- self.template_root = saved_template_root
426
437
  end
427
438
  end
428
439
 
@@ -430,18 +441,19 @@ class StylesTest < MiniTest::Spec
430
441
  setup do
431
442
  TemplateClass.box :entities, :type => :BoxA
432
443
  TemplateClass.box :results, :type => :BoxB
444
+ @page = ::Page.new
445
+ @piece = TemplateClass.new
446
+ @page.box1 << @piece
433
447
  end
434
448
 
435
449
  should "use the box name template if it exists" do
436
- piece = TemplateClass.new
437
- assert_correct_template(piece.results, 'template_class/results')
438
- piece.results.render.should == "template_class/results.html.cut\n"
450
+ assert_correct_template(@piece.results, @template_root / 'template_class/results')
451
+ @piece.results.render.should == "template_class/results.html.cut\n"
439
452
  end
440
453
 
441
454
  should "use the box classes default template if box name template is missing" do
442
- piece = TemplateClass.new
443
- assert_correct_template(piece.entities, 'box_a')
444
- piece.entities.render.should == "box_a.html.cut\n"
455
+ assert_correct_template(@piece.entities, @template_root / 'box_a')
456
+ @piece.entities.render.should == "box_a.html.cut\n"
445
457
  end
446
458
 
447
459
  should "find templates for box subclasses with specified types defined in a supertype" do
@@ -452,7 +464,8 @@ class StylesTest < MiniTest::Spec
452
464
  class ::TemplateSubClass < TemplateClass
453
465
  end
454
466
  piece = TemplateSubClass.new
455
- assert_correct_template(piece.lastly, 'box_a')
467
+ @page.box1 << piece
468
+ assert_correct_template(piece.lastly, @template_root / 'box_a')
456
469
  Object.send(:remove_const, :BoxASubclass)
457
470
  Object.send(:remove_const, :TemplateSubClass)
458
471
  end
@@ -466,9 +479,11 @@ class StylesTest < MiniTest::Spec
466
479
  should "be configurable to use a specific style" do
467
480
  TemplateClass.box :sprinters, :type => :BoxA, :style => :runny
468
481
  TemplateClass.box :strollers, :type => :BoxA, :style => :walky
482
+ page = ::Page.new
469
483
  piece = TemplateClass.new
470
- assert_correct_template(piece.strollers, 'template_class/walky')
471
- assert_correct_template(piece.sprinters, 'box_a/runny')
484
+ page.box1 << piece
485
+ assert_correct_template(piece.strollers, @template_root / 'template_class/walky')
486
+ assert_correct_template(piece.sprinters, @template_root / 'box_a/runny')
472
487
  end
473
488
  end
474
489
  end
@@ -12,24 +12,28 @@ class TableScopingTest < MiniTest::Spec
12
12
  teardown_site
13
13
  end
14
14
 
15
+ def ident(ident)
16
+ Spontaneous.database.dataset.quote_identifier(ident)
17
+ end
18
+
15
19
  context "Tablename scoping" do
16
20
  should "correctly change the table name within a scope" do
17
- Content.dataset.sql.should == "SELECT * FROM `content`"
21
+ Content.dataset.sql.should == "SELECT * FROM #{ident "content"}"
18
22
  Content.with_table("new_content_table") do
19
- Content.dataset.sql.should == "SELECT * FROM `new_content_table`"
23
+ Content.dataset.sql.should == "SELECT * FROM #{ident "new_content_table"}"
20
24
  end
21
- Content.dataset.sql.should == "SELECT * FROM `content`"
25
+ Content.dataset.sql.should == "SELECT * FROM #{ident "content"}"
22
26
  end
23
27
 
24
28
  should "allow the nesting of scopes" do
25
- Content.dataset.sql.should == "SELECT * FROM `content`"
29
+ Content.dataset.sql.should == "SELECT * FROM #{ident "content"}"
26
30
  Content.with_table("content_1") do
27
31
  Content.with_table("content_2") do
28
- Content.dataset.sql.should == "SELECT * FROM `content_2`"
32
+ Content.dataset.sql.should == "SELECT * FROM #{ident "content_2"}"
29
33
  end
30
- Content.dataset.sql.should == "SELECT * FROM `content_1`"
34
+ Content.dataset.sql.should == "SELECT * FROM #{ident "content_1"}"
31
35
  end
32
- Content.dataset.sql.should == "SELECT * FROM `content`"
36
+ Content.dataset.sql.should == "SELECT * FROM #{ident "content"}"
33
37
  end
34
38
 
35
39
  should "preserve single table inheritance" do
@@ -49,28 +53,28 @@ class TableScopingTest < MiniTest::Spec
49
53
  end
50
54
 
51
55
  should "restore original state if an exception is raised" do
52
- Content.dataset.sql.should == "SELECT * FROM `content`"
56
+ Content.dataset.sql.should == "SELECT * FROM #{ident "content"}"
53
57
  begin
54
58
  Content.with_table("new_content_table") do
55
- Content.dataset.sql.should == "SELECT * FROM `new_content_table`"
59
+ Content.dataset.sql.should == "SELECT * FROM #{ident "new_content_table"}"
56
60
  raise "havoc"
57
61
  end
58
62
  rescue; end
59
- Content.dataset.sql.should == "SELECT * FROM `content`"
63
+ Content.dataset.sql.should == "SELECT * FROM #{ident "content"}"
60
64
  end
61
65
 
62
66
  should "Be able to handle scoping multiple models at once" do
63
- Spontaneous::Change.plugin :scoped_table_name
64
- Content.dataset.sql.should == "SELECT * FROM `content`"
67
+ Spontaneous::State.plugin :scoped_table_name
68
+ Content.dataset.sql.should == "SELECT * FROM #{ident "content"}"
65
69
  Content.with_table("content_1") do
66
- Change.with_table("change_1") do
67
- Content.dataset.sql.should == "SELECT * FROM `content_1`"
68
- Change.dataset.sql.should == "SELECT * FROM `change_1`"
70
+ State.with_table("state_1") do
71
+ Content.dataset.sql.should == "SELECT * FROM #{ident "content_1"}"
72
+ State.dataset.sql.should == "SELECT * FROM #{ident "state_1"}"
69
73
  end
70
74
  end
71
75
 
72
- Content.dataset.sql.should == "SELECT * FROM `content`"
73
- Change.dataset.sql.should == "SELECT * FROM `changes`"
76
+ Content.dataset.sql.should == "SELECT * FROM #{ident "content"}"
77
+ State.dataset.sql.should == "SELECT * FROM #{ident "spontaneous_state"}"
74
78
  end
75
79
  end
76
80
  end