├── .gitattributes ├── .gitignore ├── .travis.yml ├── Gemfile ├── Gemfile.lock ├── RAILS.md ├── README.md ├── README.rdoc ├── Rakefile ├── app ├── assets │ ├── images │ │ ├── cellgrowth.svg │ │ ├── dna.svg │ │ ├── icon-done.png │ │ ├── icon-pencil.png │ │ ├── icon-resize-small.png │ │ ├── icon-trash.png │ │ ├── lipid.svg │ │ ├── protein.svg │ │ └── rails.png │ ├── javascripts │ │ ├── MVC.js.coffee │ │ ├── application.js.coffee │ │ ├── controllers │ │ │ ├── _.js.coffee │ │ │ ├── cell.js.coffee │ │ │ ├── graph.js.coffee │ │ │ ├── graphs.js.coffee │ │ │ ├── main.js.coffee │ │ │ ├── module.dummy.js.coffee │ │ │ ├── module.js.coffee │ │ │ ├── presentation.js.coffee │ │ │ ├── report.js.coffee │ │ │ ├── settings.js.coffee │ │ │ ├── slide.js.coffee │ │ │ ├── tutorial.js.coffee │ │ │ └── undo.js.coffee │ │ ├── helpers │ │ │ ├── mixin._.js.coffee │ │ │ ├── mixin.catcher.js.coffee │ │ │ ├── mixin.dynamicproperties.js.coffee │ │ │ ├── mixin.eventbindings.js.coffee │ │ │ ├── mixin.nomad.js.coffee │ │ │ └── mixin.timemachine.js.coffee │ │ ├── ie.js.coffee │ │ ├── models │ │ │ ├── action.js.coffee │ │ │ ├── cell.js.coffee │ │ │ ├── eventmanager.js.coffee │ │ │ ├── module._.js.coffee │ │ │ ├── module.cellgrowth.js.coffee │ │ │ ├── module.dna.js.coffee │ │ │ ├── module.lipid.js.coffee │ │ │ ├── module.metabolism.js.coffee │ │ │ ├── module.metabolite.js.coffee │ │ │ ├── module.protein.js.coffee │ │ │ ├── module.transporter.js.coffee │ │ │ ├── node.js.coffee │ │ │ ├── tree.js.coffee │ │ │ └── undotree.js.coffee │ │ ├── numeric.async.js.coffee │ │ ├── raphael-animate-along.js │ │ ├── raphael-guide.js │ │ ├── raphael-snapends.js │ │ └── views │ │ │ ├── collection._.js.coffee │ │ │ ├── modal._.js.coffee │ │ │ ├── modal.confirm.coffee │ │ │ ├── modal.load.js.coffee │ │ │ ├── modal.settings.coffee │ │ │ ├── pane.js.coffee │ │ │ ├── popover._.js.coffee │ │ │ ├── popover.module._.js.coffee │ │ │ ├── popover.notification._.js.coffee │ │ │ ├── popover.notification.cell.js.coffee │ │ │ ├── popover.notification.main.js.coffee │ │ │ ├── popover.notification.module.js.coffee │ │ │ ├── popover.tutorial.js.coffee │ │ │ ├── raphael._.js.coffee │ │ │ ├── raphael.cell.js.coffee │ │ │ ├── raphael.graph.js.coffee │ │ │ ├── raphael.main.js.coffee │ │ │ ├── raphael.module._.js.coffee │ │ │ ├── raphael.module.dummy.js.coffee │ │ │ ├── raphael.report.js.coffee │ │ │ ├── raphael.spline.js.coffee │ │ │ └── undo.js.coffee │ └── stylesheets │ │ ├── application.css │ │ ├── graph.css.scss │ │ ├── hook.css.scss │ │ ├── main.css.scss │ │ ├── notifications.css.scss │ │ ├── pane.css.scss │ │ ├── popovers.css.scss │ │ ├── presentation.css │ │ ├── report.css.scss │ │ ├── scaffolds.css.scss │ │ ├── svg.css.scss │ │ └── undo.css.scss ├── controllers │ ├── application_controller.rb │ ├── cells_controller.rb │ ├── hook_controller.rb │ ├── main_controller.rb │ ├── module_instances_controller.rb │ ├── module_templates_controller.rb │ └── reports_controller.rb ├── helpers │ ├── application_helper.rb │ ├── cells_helper.rb │ ├── hook_helper.rb │ ├── main_helper.rb │ ├── module_instances_helper.rb │ ├── module_templates_helper.rb │ └── report_helper.rb ├── mailers │ └── .gitkeep ├── models │ ├── .gitkeep │ ├── cell.rb │ ├── module_instance.rb │ ├── module_instance_observer.rb │ ├── module_parameter.rb │ ├── module_template.rb │ ├── module_value.rb │ ├── module_value_observer.rb │ └── report.rb └── views │ ├── cells │ ├── _form.html.erb │ ├── _module_instance_fields.erb │ ├── edit.html.erb │ ├── index.html.erb │ ├── new.html.erb │ └── show.html.erb │ ├── hook │ ├── index.html.erb │ └── post.html.erb │ ├── layouts │ ├── application.html.erb │ ├── hook.html.erb │ ├── main.html.erb │ └── pdf.html.erb │ ├── main │ ├── _actions.html.erb │ └── index.html.erb │ ├── module_instances │ ├── _form.html.erb │ ├── _module_value_fields.erb │ ├── edit.html.erb │ ├── index.html.erb │ ├── new.html.erb │ └── show.html.erb │ ├── module_templates │ ├── _form.html.erb │ ├── _module_parameter_fields.erb │ ├── edit.html.erb │ ├── index.html.erb │ ├── new.html.erb │ └── show.html.erb │ └── reports │ ├── _cell.html.erb │ ├── _form.html.erb │ ├── index.html.erb │ ├── new.html.erb │ └── show.html.erb ├── config.ru ├── config ├── application.rb ├── boot.rb ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── backtrace_silencers.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── secret_token.rb │ ├── session_store.rb │ ├── teabag.rb │ ├── wicked_pdf.rb │ └── wrap_parameters.rb ├── locales │ └── en.yml └── routes.rb ├── db ├── migrate │ ├── 20130505231415_create_cells.rb │ ├── 20130505233228_create_module_templates.rb │ ├── 20130505233612_create_module_instances.rb │ ├── 20130505234453_create_module_parameters.rb │ ├── 20130505235132_create_module_values.rb │ ├── 20130506000950_add_name_to_module_templates.rb │ ├── 20130506023516_add_foreign_keys_module_instance.rb │ ├── 20130506023549_add_foreign_keys_module_parameter.rb │ ├── 20130506023614_add_foreign_keys_module_value.rb │ ├── 20130506174008_change_module_value_type_to_string.rb │ ├── 20130506205936_add_step_to_module_template.rb │ ├── 20130506210523_add_file_to_module_template.rb │ ├── 20130508155940_add_javascript_model_to_module_template.rb │ ├── 20130508160008_add_start_amount_to_module_instance.rb │ ├── 20130509005755_create_reports.rb │ ├── 20130509041842_change_module_value_type_to_string2.rb │ ├── 20130510215435_add_name_to_module_instance.rb │ └── 20130510222748_remove_module_template_from_module_template.rb ├── schema.rb └── seeds.rb ├── doc ├── README.md.html ├── assets │ ├── codo.css │ ├── codo.js │ └── search_data.js ├── class_index.html ├── class_list.html ├── classes │ ├── CancelToken.html │ ├── Controller │ │ ├── Base.html │ │ ├── Cell.html │ │ ├── Graph.html │ │ ├── Graphs.html │ │ ├── Main.html │ │ ├── Report.html │ │ ├── Settings.html │ │ └── Undo.html │ ├── Graph.html │ ├── Helper │ │ └── Mixable.html │ ├── Main.html │ ├── Mixin │ │ └── Catcher.html │ ├── Model │ │ ├── Action.html │ │ ├── Cell.html │ │ ├── CellGrowth.html │ │ ├── DNA.html │ │ ├── EventManager.html │ │ ├── Lipid.html │ │ ├── Metabolism.html │ │ ├── Metabolite.html │ │ ├── Module.html │ │ ├── Node.html │ │ ├── Protein.html │ │ ├── Substrate.html │ │ ├── Transporter.html │ │ ├── Tree.html │ │ └── UndoTree.html │ ├── Node.html │ ├── Tree.html │ ├── UndoTree.html │ └── View │ │ ├── Action.html │ │ ├── Cell.html │ │ ├── CellNotification.html │ │ ├── Collection.html │ │ ├── ConfirmModal.html │ │ ├── DummyModule.html │ │ ├── DummyModuleProperties.html │ │ ├── Graph.html │ │ ├── HTMLModal.html │ │ ├── HTMLPopOver.html │ │ ├── LoadModal.html │ │ ├── Main.html │ │ ├── MainNotification.html │ │ ├── Module.html │ │ ├── ModuleNotification.html │ │ ├── ModulePreview.html │ │ ├── ModuleProperties.html │ │ ├── Node.html │ │ ├── Notification.html │ │ ├── Pane.html │ │ ├── Play.html │ │ ├── RaphaelBase.html │ │ ├── Report.html │ │ ├── SettingsModal.html │ │ ├── Spline.html │ │ ├── SplinePreview.html │ │ ├── Tree.html │ │ └── Undo.html ├── client │ ├── README.md.html │ ├── assets │ │ ├── codo.css │ │ ├── codo.js │ │ └── search_data.js │ ├── class_index.html │ ├── class_list.html │ ├── classes │ │ └── Module.html │ ├── extra_list.html │ ├── file_list.html │ ├── files │ │ └── app │ │ │ └── assets │ │ │ └── javascripts │ │ │ └── Module.js.coffee.html │ ├── index.html │ ├── method_list.html │ └── mixin_list.html ├── extra_list.html ├── file_list.html ├── files │ └── app │ │ └── assets │ │ └── javascripts │ │ ├── MVC.js.coffee.html │ │ ├── helpers │ │ ├── mixin._.js.coffee.html │ │ ├── mixin.dynamicproperties.js.coffee.html │ │ ├── mixin.eventbindings.js.coffee.html │ │ └── mixin.timemachine.js.coffee.html │ │ ├── models │ │ ├── action.js.coffee.html │ │ ├── cell.js.coffee.html │ │ ├── module._.js.coffee.html │ │ ├── module.cellgrowth.js.coffee.html │ │ ├── module.dna.js.coffee.html │ │ ├── module.lipid.js.coffee.html │ │ ├── module.metabolism.js.coffee.html │ │ ├── module.metabolite.js.coffee.html │ │ ├── module.protein.js.coffee.html │ │ ├── module.substrate.js.coffee.html │ │ ├── module.transporter.js.coffee.html │ │ ├── node.js.coffee.html │ │ ├── tree.js.coffee.html │ │ └── undotree.js.coffee.html │ │ ├── numeric.async.js.coffee.html │ │ └── views │ │ ├── action.js.coffee.html │ │ ├── cell.js.coffee.html │ │ ├── graph.js.coffee.html │ │ ├── main.js.coffee.html │ │ ├── module._.js.coffee.html │ │ ├── module.dummy.js.coffee.html │ │ ├── node.js.coffee.html │ │ ├── play.js.coffee.html │ │ ├── popover._.js.coffee.html │ │ ├── popover.module.js.coffee.html │ │ ├── popover.notification._.js.coffee.html │ │ ├── raphael._.js.coffee.html │ │ ├── raphael.cell.js.coffee.html │ │ ├── raphael.graph.js.coffee.html │ │ ├── raphael.main.js.coffee.html │ │ ├── raphael.module._.js.coffee.html │ │ ├── raphael.module.dummy.coffee.html │ │ ├── raphael.node.js.coffee.html │ │ ├── raphael.pane.js.coffee.html │ │ ├── raphael.play.js.coffee.html │ │ ├── raphael.tree.js.coffee.html │ │ ├── tree.js.coffee.html │ │ ├── undo.js.coffee.html │ │ ├── view.main.js.coffee.html │ │ └── view.module.js.coffee.html ├── index.html ├── method_list.html ├── mixin_list.html ├── mixins │ ├── DynamicProperties.html │ └── Mixin │ │ ├── Catcher.html │ │ ├── DynamicProperties.html │ │ ├── EventBindings.html │ │ └── TimeMachine.html └── server │ ├── ActiveSupport.html │ ├── ActiveSupport │ └── TestCase.html │ ├── ApplicationController.html │ ├── ApplicationHelper.html │ ├── BrowsingTest.html │ ├── Gemfile.html │ ├── Gemfile_lock.html │ ├── GreetingsControllerTest.html │ ├── GreetingsHelperTest.html │ ├── HookController.html │ ├── HookControllerTest.html │ ├── HookHelper.html │ ├── HookHelperTest.html │ ├── MainController.html │ ├── MainControllerTest.html │ ├── MainHelper.html │ ├── MainHelperTest.html │ ├── Object.html │ ├── ProgrammingLife.html │ ├── ProgrammingLife │ └── Application.html │ ├── README_md.html │ ├── README_rdoc.html │ ├── Rakefile.html │ ├── app │ └── assets │ │ ├── javascripts │ │ ├── Module_js_coffee.html │ │ ├── application_js.html │ │ ├── hook_js_coffee.html │ │ ├── jasmine_examples │ │ │ ├── Player_js.html │ │ │ └── Song_js.html │ │ └── main_js_coffee.html │ │ └── stylesheets │ │ ├── application_css.html │ │ ├── hook_css_scss.html │ │ └── main_css_scss.html │ ├── config_ru.html │ ├── created.rid │ ├── db │ └── development_sqlite3.html │ ├── doc │ └── server │ │ └── created_rid.html │ ├── docs │ ├── deliverables │ │ ├── Emergent Architertural Design_tex.html │ │ └── summaries │ │ │ └── Seminar 2 │ │ │ ├── Samenvatting_tex.html │ │ │ └── samenvatting-Mathematics-of-Biology_tex.html │ └── planning samenvatten_txt.html │ ├── hook_php.html │ ├── images │ ├── add.png │ ├── arrow_up.png │ ├── brick.png │ ├── brick_link.png │ ├── bug.png │ ├── bullet_black.png │ ├── bullet_toggle_minus.png │ ├── bullet_toggle_plus.png │ ├── date.png │ ├── delete.png │ ├── find.png │ ├── loadingAnimation.gif │ ├── macFFBgHack.png │ ├── package.png │ ├── page_green.png │ ├── page_white_text.png │ ├── page_white_width.png │ ├── plugin.png │ ├── ruby.png │ ├── tag_blue.png │ ├── tag_green.png │ ├── transparent.png │ ├── wrench.png │ ├── wrench_orange.png │ └── zoom.png │ ├── index.html │ ├── js │ ├── darkfish.js │ ├── jquery.js │ ├── navigation.js │ ├── search.js │ ├── search_index.js │ └── searcher.js │ ├── public │ ├── 404_html.html │ ├── 422_html.html │ ├── 500_html.html │ ├── favicon_ico.html │ └── robots_txt.html │ ├── rdoc.css │ ├── spec │ └── javascripts │ │ ├── ModuleSpec_js.html │ │ └── helpers │ │ └── SpecHelper_js.html │ ├── table_of_contents.html │ └── vendor │ └── assets │ └── javascripts │ ├── backbone_js.html │ └── underscore_js.html ├── docs ├── deliverables │ ├── cts │ │ ├── Context Seminar Report.tex │ │ ├── DJ.png │ │ ├── SS.jpeg │ │ ├── TP.jpeg │ │ ├── VR.jpeg │ │ └── Yoloost.png │ ├── ead │ │ ├── EAD.png │ │ ├── Emergent Architectural Design.fnt │ │ ├── Emergent Architectural Design.pdf │ │ ├── Emergent Architectural Design.tex │ │ ├── Emergent Architectural Design.tex~ │ │ ├── SequenceDiagramLife.png │ │ ├── cell_struct.png │ │ ├── class.vsd │ │ ├── controllers.png │ │ ├── erd.pdf │ │ ├── helpers.png │ │ ├── main_struct.png │ │ ├── models.png │ │ ├── the-virtual-cell.png │ │ └── views.png │ ├── final-report │ │ ├── final-report.tex │ │ ├── personal-reflection-dj.tex │ │ ├── personal-reflection-joost.tex │ │ ├── personal-reflection-steffan.tex │ │ ├── personal-reflection-tung.tex │ │ ├── personal-reflection-vincent.tex │ │ └── teamwork.txt │ ├── img │ │ ├── DJ.png │ │ ├── SS.jpeg │ │ ├── TP.jpeg │ │ ├── VR.jpeg │ │ └── Yoloost.png │ ├── product-vision │ │ ├── Draft product vision.docx │ │ ├── Initial product vision.docx │ │ ├── Roadmap-template.vsdx │ │ ├── Roadmap.jpg │ │ ├── Roadmap.png │ │ ├── Roadmap.vsdx │ │ ├── mockup.jpg │ │ └── product-vision.tex │ ├── summaries │ │ ├── Seminar 1 │ │ │ └── Programming Life 1.docx │ │ ├── Seminar 2 │ │ │ ├── Samenvatting.tex │ │ │ └── samenvatting-Mathematics-of-Biology.tex │ │ └── Seminar-3 │ │ │ └── samenvatting.txt │ └── template │ │ └── template.tex ├── onduidelijkheden.txt ├── planning samenvatten.txt └── resources │ ├── Programming life 1.pdf │ └── Programming life 2.pdf ├── lib ├── assets │ └── .gitkeep └── tasks │ └── .gitkeep ├── log.txt ├── public ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico ├── img │ ├── cellgrowth.png │ ├── cursor.png │ ├── dna.png │ ├── glyphicons-halflings-white.png │ ├── glyphicons-halflings.png │ ├── icon-chevron-left.png │ ├── icon-chevron-right.png │ ├── lipid.png │ └── protein.png └── robots.txt ├── script └── rails ├── spec ├── javascripts │ ├── controller_specs │ │ ├── __spec.js │ │ ├── graph_spec.js │ │ ├── graphs_spec.js │ │ └── undo_spec.js │ ├── helper_specs │ │ ├── mixable___spec.js │ │ ├── mixable_dynamicproperties_spec.js │ │ ├── mixable_eventbindings_spec.js │ │ └── mixable_timemachine_spec.js │ ├── helpers │ │ ├── .gitkeep │ │ ├── SpecHelper.js │ │ └── numeric.js │ ├── model_specs │ │ ├── action_spec.js │ │ ├── cell_spec.js │ │ ├── eventmanager_spec.js │ │ ├── module___spec.js │ │ ├── module_cellgrowth_spec.js │ │ ├── module_dna_spec.js │ │ ├── module_lipid_spec.js │ │ ├── module_metabolism_spec.js │ │ ├── module_metabolite_spec.js │ │ ├── module_protein_spec.js │ │ ├── module_transporter_spec.js │ │ ├── node_spec.js │ │ ├── tree_spec.js │ │ └── undotree_spec.js │ ├── numeric_spec.js │ ├── spec_helper.js │ ├── support │ │ ├── jasmine.yml │ │ └── jasmine_helper.rb │ └── view_specs │ │ ├── __spec.js │ │ ├── modal___spec.js │ │ ├── modal_confirm_spec.js │ │ ├── modal_load_spec.js │ │ ├── modal_settings_spec.js │ │ ├── module___spec.js │ │ ├── pane_spec.js │ │ ├── popover_module_spec.js │ │ └── undo_spec.js └── teabag_env.rb ├── test ├── fixtures │ ├── .gitkeep │ ├── cells.yml │ ├── module_instances.yml │ ├── module_parameters.yml │ ├── module_templates.yml │ ├── module_values.yml │ └── reports.yml ├── functional │ ├── .gitkeep │ ├── cells_controller_test.rb │ ├── hook_controller_test.rb │ ├── main_controller_test.rb │ ├── module_instances_controller_test.rb │ ├── module_templates_controller_test.rb │ └── reports_controller_test.rb ├── integration │ ├── .gitkeep │ ├── cells_view_test.rb │ ├── main_view_test.rb │ └── reports_view_test.rb ├── performance │ └── browsing_test.rb ├── test_helper.rb └── unit │ ├── .gitkeep │ ├── cell_test.rb │ ├── helpers │ ├── application_helper_test.rb │ ├── cells_helper_test.rb │ ├── hook_helper_test.rb │ ├── main_helper_test.rb │ ├── module_instances_helper_test.rb │ ├── module_templates_helper_test.rb │ └── reports_helper_test.rb │ ├── module_instance_test.rb │ ├── module_parameter_test.rb │ ├── module_template_test.rb │ ├── module_value_test.rb │ └── report_test.rb └── vendor ├── assets ├── images │ ├── glyphicons-halflings-white.png │ └── glyphicons-halflings.png ├── javascripts │ ├── .gitkeep │ ├── big.min.js │ ├── bigdecimal-all-last.min.js │ ├── bootstrap.js │ ├── chart.js │ ├── g.bar-min.js │ ├── g.dot-min.js │ ├── g.line-min.js │ ├── g.pie-min.js │ ├── g.raphael-min.js │ ├── jquery.svg.js │ ├── jquery.svgdom.patched.js │ ├── json2.js │ ├── locache.js │ ├── lodash.custom.js │ ├── md5.min.js │ ├── numeric-1.2.6.js │ ├── raphael-animatevb.js │ ├── raphael-arrow.js │ ├── raphael-triangle.js │ ├── raphael.min.js │ └── underscore.js └── stylesheets │ ├── .gitkeep │ └── bootstrap.css └── plugins └── .gitkeep /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: ruby 3 | bundler_args: --without development 4 | rvm: 5 | - 1.9.3 6 | - 2.0.0 7 | - ruby-head 8 | env: 9 | matrix: 10 | - DB=postgres DISPLAY=":99.0" 11 | matrix: 12 | allow_failures: 13 | - rvm: ruby-head 14 | branches: 15 | only: 16 | - master 17 | - develop 18 | - /^release.*$/ 19 | - /^hotfix.*$/ 20 | - /^test.*$/ 21 | postgres: 22 | adapter: postgresql 23 | database: life_test 24 | username: postgres 25 | before_script: 26 | - psql -c "create role life with createdb login password 'life';" -U postgres 27 | - rake db:create 28 | - rake db:migrate 29 | - rake db:seed 30 | - rake db:test:prepare 31 | - export DISPLAY=:99.0 32 | - sh -e /etc/init.d/xvfb start 33 | script: 34 | - bundle exec rake test 35 | - bundle exec rake jasmine:ci 36 | notifications: 37 | webhooks: 38 | urls: 39 | - http://life.jstfy.com/hook 40 | on_succes: always 41 | on_failure: never 42 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'rails', '3.2.12' 4 | gem 'rack-offline' 5 | 6 | # Gems used for the database 7 | gem 'sqlite3' 8 | gem 'pg' 9 | 10 | # Gems used only for assets and not required 11 | # in production environments by default. 12 | group :assets do 13 | 14 | gem 'sass-rails', '~> 3.2.3' 15 | gem 'coffee-rails', '~> 3.2.1' 16 | gem 'coffee-script-source', '1.5.0' 17 | 18 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes 19 | # gem 'therubyracer', :platforms => :ruby 20 | 21 | gem 'uglifier', '>= 1.0.3' 22 | gem "yui-compressor", "~> 0.9.6" 23 | gem "teabag" 24 | 25 | end 26 | 27 | # Gems used only for development and testing 28 | # not rquired in production environments by default 29 | group :development, :test do 30 | gem 'rake' 31 | gem 'jasmine' 32 | gem 'coveralls', require: false 33 | end 34 | 35 | # Always required 36 | gem 'will_paginate', '~> 3.0' 37 | gem 'nested_form' 38 | gem 'jquery-rails' 39 | gem 'wicked_pdf' 40 | gem 'wkhtmltopdf-binary', '~> 0.9.9' 41 | gem 'json' 42 | 43 | # To use ActiveModel has_secure_password 44 | # gem 'bcrypt-ruby', '~> 3.0.0' 45 | 46 | # To use Jbuilder templates for JSON 47 | # gem 'jbuilder' 48 | 49 | # Use unicorn as the app server 50 | # gem 'unicorn' 51 | 52 | # Deploy with Capistrano 53 | # gem 'capistrano' 54 | 55 | # To use debugger 56 | # gem 'debugger' 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Programming Life: Gigabase 2 | ================ 3 | Gigabase: Synthetic Biology Cell Modeling Project 4 | 5 | GitHub Pages: http://sleeplessbyte.github.io/programming-life 6 | 7 | Life/Live Application: http://life.jstfy.com/ 8 | 9 | ## The virtual Cell 10 | Developing a visual environment for designing and simulating virtual cells. 11 | 12 | - Substrate, s. 13 | - Metabolism converting substrate s into product p. 14 | - Substrate and product transporter. 15 | - DNA synthesis. 16 | - Protein synthesis and degratation. 17 | - Lipid synthesis. 18 | 19 | The lipid membrane separates the inside of the cell from the outside environment, 20 | allowing for unequal substrate and product concentrations inside and outside the 21 | cell (s#in, p#in and s#ext, p#ext respectively). Each of the components is 22 | associated with a cellular process (e.g. molecule synthesis or substrate conversion), 23 | which is modeled by one or more differential equations. The proposed model describes 24 | an av- erage cell in a growing population of cells. Ordinary Differential Equations (ODEs) 25 | in this model describe the change of molecule concentrations in time. 26 | 27 | ## Installation 28 | Gigabase runs on Rails. You can load this repository onto your hard drive and directly use 29 | it as a rails app. Just run `bundle install` and `rake db:setup` and you are good to go. 30 | For windows users, some gems might not install and display a message such as not native build. 31 | Download the Ruby Devkit and run the `bundle install` command in `mysys` terminal. All the 32 | gems will then perfectly build. Don't forget you might need administrator rights. 33 | 34 | ## Build Status 35 | 36 | ### develop 37 | [![develop](https://travis-ci.org/SleeplessByte/programming-life.png?branch=develop)](https://travis-ci.org/SleeplessByte/programming-life) 38 | 39 | ### master 40 | [![master](https://travis-ci.org/SleeplessByte/programming-life.png?branch=master)](https://travis-ci.org/SleeplessByte/programming-life) 41 | 42 | ## Pull Requests 43 | After June 2013 the project will no longer have constraints so we could go any direction. 44 | We do not allow pull requests on master or release branches. Fork the repository, create 45 | a patch/feature/issue branch and merge to develop. 46 | 47 | Your code should be `rdoc` or `codo/coffeedoc` commented, assets should be `/spec/` tested 48 | and when applied should have `/test/functional` integration tests. Server side code should 49 | also be `/test/` unit tested. 50 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | ProgrammingLife::Application.load_tasks 8 | -------------------------------------------------------------------------------- /app/assets/images/icon-done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/app/assets/images/icon-done.png -------------------------------------------------------------------------------- /app/assets/images/icon-pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/app/assets/images/icon-pencil.png -------------------------------------------------------------------------------- /app/assets/images/icon-resize-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/app/assets/images/icon-resize-small.png -------------------------------------------------------------------------------- /app/assets/images/icon-trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/app/assets/images/icon-trash.png -------------------------------------------------------------------------------- /app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/app/assets/images/rails.png -------------------------------------------------------------------------------- /app/assets/javascripts/MVC.js.coffee: -------------------------------------------------------------------------------- 1 | (exports ? this).Model = {} 2 | (exports ? this).Controller = {} 3 | (exports ? this).View = {} 4 | (exports ? this).Helper = {} 5 | (exports ? this).Mixin = {} 6 | (exports ? this).GIGABASE_VERSION = 7 | major: 2 8 | minor: 0 9 | revision: 0 10 | full: '2.0.0' 11 | 12 | document.mvc = null 13 | 14 | # Cache settings 15 | locache.cachePrefix += '.gigabase.' 16 | locache.cleanup() 17 | 18 | (exports ? this).RouteTo = ( controller, args... ) -> 19 | 20 | # Updating the localstorage/serverstorage 21 | # 22 | updating = off 23 | update = () -> 24 | return if updating 25 | 26 | if document.mvc? and document.mvc.onUpdate? 27 | console.info 'Connection established: updating!' 28 | promise = document.mvc.onUpdate() 29 | promise.always( () => 30 | updating = off 31 | ) 32 | else 33 | updating = on 34 | 35 | # Upgrading the appstorage 36 | # 37 | upgrading = off 38 | upgrade = () -> 39 | return if upgrading 40 | if document.mvc? and document.mvc.onUpgrade? 41 | console.info 'Application downloaded: upgrading!' 42 | document.mvc.onUpgrade() 43 | upgrading = on 44 | 45 | # Window events 46 | # 47 | $( window ) 48 | .on( 'beforeunload', () -> 49 | if document.mvc? and document.mvc.beforeUnload? 50 | console.info 'Just before unloading this window...' 51 | message = document.mvc.beforeUnload() 52 | return message if message? 53 | return undefined 54 | ) 55 | .on( 'unload', () -> 56 | if document.mvc? and document.mvc.onUnload? 57 | console.info '...unloaded this window' 58 | document.mvc.onUnload() 59 | ) 60 | .on( 'online', update ) 61 | 62 | # Application cache events 63 | # 64 | $( window.applicationCache ) 65 | .on( 'updateready', upgrade ) 66 | 67 | # Route 68 | $( document ).ready( () -> 69 | document.mvc = new controller( args... ) 70 | update() if window.navigator.onLine 71 | upgrade() if window.applicationCache.status is window.applicationCache.UPDATEREADY 72 | ) 73 | return document.mvc 74 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js.coffee: -------------------------------------------------------------------------------- 1 | # This is a manifest file that'll be compiled into application.js, which will include all the files 2 | # listed below. 3 | # 4 | # Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | # or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 6 | # 7 | # It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | # the compiled file. 9 | # 10 | # WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | # GO AFTER THE REQUIRES BELOW. 12 | # 13 | #= require jquery 14 | #= require jquery_ujs 15 | #= require jquery_nested_form 16 | #= require json2 17 | #= require lodash.custom 18 | #= require locache 19 | #= require big.min 20 | #= require jquery.svg.js 21 | #= require jquery.svgdom.patched.js 22 | # 23 | #= require MVC 24 | # 25 | #= require_tree ./helpers 26 | #= require_tree ./models 27 | #= require_tree ./views 28 | #= require_tree ./controllers 29 | # 30 | #= require bootstrap 31 | #= require raphael.min 32 | #= require g.raphael-min 33 | #= require g.bar-min 34 | #= require g.pie-min 35 | #= require g.dot-min 36 | #= require g.line-min 37 | #= require raphael-triangle 38 | #= require raphael-arrow 39 | #= require raphael-animatevb 40 | # 41 | #= require chart 42 | #= require md5.min 43 | #= require numeric-1.2.6 44 | #= require numeric.async 45 | # 46 | #= require_tree . 47 | 'use strict' 48 | $( () -> 49 | $( window.applicationCache ).on( 'error', () -> 50 | console.error 'There was an error when loading the cache manifest.' 51 | console.warn arguments 52 | ) 53 | ) -------------------------------------------------------------------------------- /app/assets/javascripts/controllers/_.js.coffee: -------------------------------------------------------------------------------- 1 | # The base of all controllers 2 | # 3 | # @concern Mixin.EventBindings 4 | # @concern Mixin.Catcher 5 | # @concern Mixin.DynamicProperties 6 | # 7 | class Controller.Base extends Helper.Mixable 8 | 9 | @concern Mixin.EventBindings 10 | @concern Mixin.Catcher 11 | @concern Mixin.DynamicProperties 12 | 13 | # Creates the controller 14 | # 15 | # @param view [View.*] the view 16 | # 17 | constructor: ( @view ) -> 18 | @_children = {} 19 | @_allowEventBindings() 20 | 21 | # Adds a child controller 22 | # 23 | # @param id [String] the id of the controller 24 | # @param controller [Controller.*] the controller 25 | # @return [self] the chainable self 26 | # 27 | addChild: ( id, controller ) -> 28 | @_children[ id ] = controller 29 | return this 30 | 31 | # Remove a child controller 32 | # 33 | # @param id [String] the id of the controller to remove 34 | # @param kill [Boolean] kill on remove 35 | # @return [self] the chainable self 36 | # 37 | removeChild: ( id, kill = on ) -> 38 | @_children[ id ]?.kill() if kill 39 | delete @_children[ id ] 40 | return this 41 | 42 | # 43 | # 44 | each: ( func ) -> 45 | _( @_children ).each func 46 | 47 | # Gets the controller with the id 48 | # 49 | # @param id [String] the id to get 50 | # @return [Controller.*] the controller 51 | # 52 | controller: ( id ) -> 53 | return @_children[ id ] 54 | 55 | # Returns all the controllers 56 | # 57 | # @return [Array] The controllers 58 | # 59 | controllers: () -> 60 | return @_children 61 | 62 | # Finds the key of a controller 63 | # 64 | # @param func [Function] function to evaluate a value 65 | # @return [String] the key 66 | # 67 | findKey: ( func ) -> 68 | result = null 69 | if _( @controllers() ).find( ( v, key ) -> 70 | result = key 71 | return func v ) 72 | return result 73 | return null 74 | 75 | # Kills the controler and all subsequent views 76 | # 77 | # @return [self] the chainable self 78 | # 79 | kill: () -> 80 | @removeChild( id, on ) for id, child of @_children 81 | @view?.kill() 82 | @_unbindAll() 83 | return this 84 | 85 | # Runs when the user comes online 86 | # 87 | onUpdate: () -> 88 | return $.Deferred().promise() 89 | 90 | # Runs when the user tries to unload the page 91 | # 92 | beforeUnload: () -> 93 | return undefined 94 | 95 | # Runs when the user has unloaded the page 96 | # 97 | onUnload: () -> 98 | @each( ( child ) -> child.onUnload() ) 99 | return undefined 100 | 101 | # Catcher for the cell controller errors 102 | # 103 | _catcher: ( source, e ) -> 104 | text = if _( e ).isObject() then e.message ? 'no message' else e 105 | @_notificate( @, 'global', text , text, [], View.RaphaelBase.Notification.Error) 106 | -------------------------------------------------------------------------------- /app/assets/javascripts/controllers/graph.js.coffee: -------------------------------------------------------------------------------- 1 | # The controller for the Graph view 2 | # 3 | class Controller.Graph extends Controller.Base 4 | 5 | # Maximum number of simultaneously displayed data sets 6 | @MAX_DATASETS : 3 7 | 8 | # Maximum length of a set 9 | @MAX_LENGTH : 100 10 | 11 | # Constructs a new graph controller 12 | # 13 | # @param view [View.Graph] The view to control 14 | # 15 | constructor: ( @_parent, view ) -> #@container, title, parentview, id = _( 'graph-' ).uniqueId() ) -> 16 | super view #new View.Graph( id, title, parentview, @container ) 17 | 18 | @_datasets = [] 19 | @_automagically = on 20 | @_xMax = 0 21 | @_createBindings() 22 | 23 | # Create event bindings 24 | # 25 | _createBindings: ( ) -> 26 | @_bind "view.graph.hover", @, _.throttle(@_onGraphHover, 33) 27 | 28 | # Add a dataset to visualize in this graphs 29 | # 30 | # @param data [Array] An array of datapoints 31 | # @return [self] chainable self 32 | # 33 | add: ( data ) -> 34 | @_datasets.unshift data 35 | xMax = _(data.xValues).last() 36 | @_xMax = xMax if xMax > @_xMax 37 | return @ 38 | 39 | # Append a dataset to the most recently added dataset 40 | # 41 | # @param data [Array] The data to append 42 | # @return [self] chainable self 43 | # 44 | append: ( data ) -> 45 | if @_datasets.length is 0 46 | @add data 47 | return @ 48 | 49 | newest = _( @_datasets ).first() 50 | 51 | newest.xValues.push data.xValues... 52 | newest.yValues.push data.yValues... 53 | 54 | xMax = _(data.xValues).last() 55 | @_xMax = xMax if xMax > @_xMax 56 | return @ 57 | 58 | # Shows a dataset in the graph view 59 | # 60 | # @param dataset [Object] An object containing an xValues and yValues array 61 | # @param append [Boolean] Whether to append the dataset or add it as a new dataset 62 | # 63 | show: ( dataset, append = false ) -> 64 | if @_automagically and append 65 | dataset.xValues = dataset.xValues.splice(1) 66 | dataset.yValues = dataset.yValues.splice(1) 67 | 68 | @add dataset unless append 69 | @append dataset if append 70 | @view.draw @_datasets 71 | 72 | _onGraphHover:( graph, xFactor ) -> 73 | unless graph is @ 74 | @_parent.showColumnData( xFactor ) 75 | 76 | # Shows the column data of the column at the relative location 77 | # 78 | # @param xFactor [Float] The relative location of the column to the width of the graph 79 | # 80 | showColumnData: ( xFactor ) -> 81 | dataset = _(@_datasets).first() 82 | 83 | xValue = @_xMax * xFactor 84 | 85 | # Set new xFactor so the line is only drawn on steps 86 | #xFactor = dataset.xValues[index] / max 87 | 88 | text = [] 89 | for dataset in @_datasets 90 | index = _.sortedIndex dataset.xValues, xValue 91 | unless index >= dataset.xValues.length 92 | yData = dataset.yValues[index] 93 | text.push yData 94 | else 95 | text.push undefined 96 | 97 | @view.showColumn( xFactor, text ) 98 | -------------------------------------------------------------------------------- /app/assets/javascripts/controllers/graphs.js.coffee: -------------------------------------------------------------------------------- 1 | # The controller for the Graphs view 2 | # 3 | class Controller.Graphs extends Controller.Base 4 | 5 | # Creates a new instance of graph controller 6 | # 7 | # @param view [View.Collection] The view to contain the graphs controller by this 8 | # @param id [String] A string id for the container of the graphs 9 | # 10 | constructor: ( id ) -> 11 | super new View.Collection( id ) 12 | 13 | # Clears the view 14 | # 15 | clear: () -> 16 | @each( ( child, id ) => @removeChild id, on ) 17 | @view.kill() 18 | 19 | # Shows the graphs with the data from the datasets 20 | # 21 | # @param datasets [Object] An object of datasets 22 | # @return [Object] graphs 23 | # 24 | show: ( datasets, append = off, id = 'id' ) -> 25 | template = _.template("graph-<%= #{id} %>") 26 | for key, graph of @controllers() when graph instanceof Controller.Graph 27 | 28 | # ( ( key, graph ) => 29 | # _( => 30 | unless datasets[ key ]? 31 | @view.remove graph.kill().view 32 | @removeChild key 33 | # ).defer() 34 | # ) key, graph 35 | 36 | for key, dataset of datasets 37 | ( ( key, dataset ) => 38 | _( => 39 | unless @controller( key )? 40 | id = template({ id: _.uniqueId(), key: key.replace(/#/g, '_') }) 41 | graph = new View.Graph( id, key, @view ) 42 | @addChild key, new Controller.Graph( @, graph ) 43 | @view.add graph, false 44 | @controller( key ).show( dataset, append ) 45 | ).defer() 46 | ) key, dataset 47 | 48 | return this 49 | 50 | # Shows the column data for the column where xData is displayed 51 | # 52 | # @param xFactor [Float] The relative location of the column to the width of the graph 53 | # 54 | showColumnData: ( xFactor ) -> 55 | @each( (child) -> child.showColumnData( xFactor ) ) 56 | 57 | -------------------------------------------------------------------------------- /app/assets/javascripts/controllers/settings.js.coffee: -------------------------------------------------------------------------------- 1 | # The controller for the Graphs view 2 | # 3 | class Controller.Settings extends Controller.Base 4 | 5 | # Creates a new instance of settings controller 6 | # 7 | constructor: ( id ) -> 8 | 9 | @options = @_loadOptions() 10 | super new View.SettingsModal @meta_options 11 | @view.onClose( @, @_saveOptions ) 12 | 13 | # Load the options 14 | # 15 | _loadOptions: () -> 16 | @meta_options = 17 | simulate: 18 | iterations: 19 | type: 'number' 20 | min: 0 21 | max: 100 22 | step: 1 23 | value: 4 24 | iteration_length: 25 | type: 'number' 26 | min: 1 27 | max: 25 28 | step: 1 29 | value: 20 30 | ode: 31 | tolerance: 32 | type: 'number' 33 | min: 1e-18 34 | max: 1 35 | step: 1e-18 36 | value: 1e-9 37 | iterations: 38 | type: 'number' 39 | min: 100 40 | max: 10000 41 | step: 100 42 | value: 4000 43 | dt: 44 | type: 'number' 45 | min: 1e-9 46 | max: 1 47 | step: 1e-9 48 | value: 0.01 49 | interpolate: 50 | type: 'boolean' 51 | active: 'interpolation on' 52 | inactive: 'interpolation off' 53 | value: off 54 | 55 | results = {} 56 | for section, options of @meta_options 57 | results[ section ] = {} 58 | for option, meta of options 59 | cached = locache.get( "options.#{section}.#{option}" ) 60 | meta.value = if cached? then cached else meta.value 61 | results[ section ][ option ] = meta.value 62 | 63 | return results 64 | 65 | # Save options 66 | # 67 | _saveOptions: ( modal ) -> 68 | return if modal isnt @view 69 | for input in modal.getInput() 70 | input = $( input ) 71 | value = input.val() 72 | section = input.data( 'section' ) 73 | key = input.data( 'key' ) 74 | switch input.attr( 'type' ) 75 | when 'number' 76 | if isNaN( value ) or not value.length 77 | input.val( input.attr( 'value' ) ) 78 | continue 79 | value = +value 80 | when 'checkbox' 81 | value = input.is(':checked') 82 | @options[ section ][ key ] = value 83 | locache.async.set( "options.#{section}.#{key}", value ) 84 | 85 | @_callback( @options ) if @_callback? 86 | 87 | # Show the modal 88 | # 89 | show: ( @_callback ) -> 90 | @view.show() 91 | 92 | 93 | -------------------------------------------------------------------------------- /app/assets/javascripts/controllers/slide.js.coffee: -------------------------------------------------------------------------------- 1 | # Slide for presentation 2 | # 3 | class Controller.Slide extends Controller.Base 4 | 5 | # Constructs a new slide 6 | # 7 | # @param parent [Controller.Presentation] The presentation this slide belongs to 8 | # @param selector [String] A DOM selector 9 | # @param value [Object] An optional value for the element 10 | # 11 | constructor: ( @parent, @selector, @argument ) -> 12 | super( new View.Collection() ) 13 | 14 | Object.defineProperty( @, "element", 15 | get: () => $(@selector).first() 16 | ) 17 | 18 | # Prepares the slide 19 | # 20 | prepare: ( done ) -> 21 | console.log "Preparing", @ 22 | @_moveTo @element, done 23 | 24 | # Animates the cursor to a specific DOM element 25 | # 26 | # @param element [JQuery] The element 27 | # @param done [Function] Function to execute when done moving 28 | # 29 | _moveTo: ( element = @element, done ) -> 30 | centreX = element.offset().left #+ 10 #(element.width() / 2 ) 31 | centreY = element.offset().top # + 10 #(element.height() / 2 ) 32 | console.log element.width() 33 | object = { 34 | top: centreY 35 | left: centreX 36 | } 37 | @parent.cursor.animate(object, 500,"swing", done) 38 | 39 | # Inputs a character into an element 40 | # 41 | # @param element [JQuery] The element to input into 42 | # @param char [Character] The character to input 43 | # 44 | _inputCharacter: ( element, char ) -> 45 | element.val( element.val() + char ) 46 | 47 | # Animates the input of value into element 48 | # 49 | _inputValue: ( element, value ) -> 50 | console.log "Inputting", value, "into", element 51 | element.val("") 52 | for i,character of value 53 | setTimeout( @_inputCharacter, i * 200, element, character ) 54 | 55 | 56 | # Presents this slide 57 | # 58 | present: ( ) -> 59 | console.log "Presenting", @ 60 | 61 | @element.select() 62 | if @argument 63 | @_inputValue @element, @argument 64 | else 65 | console.log @element 66 | @element.click() 67 | -------------------------------------------------------------------------------- /app/assets/javascripts/helpers/mixin._.js.coffee: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | class Helper.Mixable 4 | 5 | @ModuleKeyWords : [ 'extended', 'included' ] 6 | 7 | # Extends a class by adding the properties of the mixins to the class 8 | # 9 | # @param classmixins [Object*] the mixins to add 10 | # 11 | @extend: ( classmixins... ) -> 12 | 13 | for mixin in classmixins 14 | for key, value of mixin when key not in Mixable.ModuleKeyWords 15 | @[ key ] = value 16 | 17 | mixin.extended?.apply( @ ) 18 | this 19 | 20 | # Includes mixins to a class by adding the properties to the Prototype 21 | # 22 | # @param instancemixins [Object*] the mixins to add 23 | # 24 | @include: ( instancemixins... ) -> 25 | for mixin in instancemixins 26 | for key, value of mixin when key not in Mixable.ModuleKeyWords 27 | # Assign properties to the prototype 28 | @::[ key ] = value 29 | 30 | mixin.included?.apply( @ ) 31 | return this 32 | 33 | # Concerns automagically include and extend a class 34 | # 35 | # @param concerns [Object*] the mixins to add 36 | # 37 | @concern: ( concerns... ) -> 38 | 39 | for concern in concerns 40 | @include concern.InstanceMethods 41 | @extend concern.ClassMethods 42 | 43 | return this 44 | 45 | # Extracts id plus metadata 46 | # 47 | # @param id [String,Integer,Object] the id 48 | # @return [Object] the id plus metadata 49 | # 50 | @extractId: ( id ) -> 51 | return id if _( id ).isObject() 52 | return { id: id, origin: "server" } if _( id ).isNumber() 53 | return null unless _( id ).isString() 54 | data = id.split( ':' ) 55 | return { id: parseInt( data[0] ), origin: "server" } if data.length is 1 56 | return { id: parseInt( data[2] ), origin: data[0] } 57 | 58 | # Returns true if this is a local instance 59 | # 60 | # @return [Boolean] true if local, false if synced instance 61 | # 62 | isLocal : () -> 63 | return Helper.Mixable.extractId( @id ).origin isnt "server" 64 | 65 | # Parses a date with or without timezone offset to a javascript date 66 | # 67 | # @param data [String] the date in ISO-something format 68 | # @return [Date] the parsed date 69 | # 70 | @parseDate: ( date ) -> 71 | unless _( date ).isString() 72 | return new Date( date ) 73 | matchOffset = /(Z|([+-])(\d\d):(\d\d))$/ 74 | offset = matchOffset.exec date 75 | result = new Date( date.replace( 'T', 'T' ).replace( matchOffset, 'Z' ) ) 76 | unless offset[ 1 ] is 'Z' 77 | timezone = ( if offset[ 2 ] is '+' then -1 else 1 ) * ( offset[ 3 ] * 60 + Number( offset[ 3 ] ) ) 78 | result.setMinutes( result.getMinutes() + timezone ) #- result.getTimezoneOffset() 79 | return result 80 | 81 | # Generates a colour based on the module name 82 | # 83 | # @param hashee [String] the name to use as hash 84 | # @return [String] the CSS color 85 | # 86 | @hashColor : ( hashee = @_name ) -> 87 | hashee = hashee.split('#')[0] 88 | return '#' + md5( hashee ).slice(0, 6) -------------------------------------------------------------------------------- /app/assets/javascripts/helpers/mixin.catcher.js.coffee: -------------------------------------------------------------------------------- 1 | # The TimeMachine allows for registering, undoing and redoing actions 2 | # 3 | # @see {Model.UndoTree} for the storage datastructure 4 | # @see {Model.Action} for the action datastructure 5 | # 6 | # @mixin 7 | # 8 | Mixin.Catcher = 9 | 10 | ClassMethods: 11 | catchable: ( fns ) -> 12 | for name, fn of fns 13 | @::[ name ] = ( ) -> 14 | try 15 | return fn.apply( @, arguments ) 16 | catch e 17 | @_catcher.apply( @, [ @, e ] ) 18 | return undefined 19 | 20 | InstanceMethods: {} -------------------------------------------------------------------------------- /app/assets/javascripts/helpers/mixin.timemachine.js.coffee: -------------------------------------------------------------------------------- 1 | # The TimeMachine allows for registering, undoing and redoing actions 2 | # 3 | # @see {Model.UndoTree} for the storage datastructure 4 | # @see {Model.Action} for the action datastructure 5 | # 6 | # @mixin 7 | # 8 | Mixin.TimeMachine = 9 | 10 | ClassMethods: {} 11 | 12 | InstanceMethods: 13 | 14 | # Intializes the timemachine 15 | # 16 | _allowTimeMachine: () -> 17 | unless @_tree? 18 | 19 | Object.defineProperty( @, 'tree', 20 | value: new Model.UndoTree() 21 | writable: false 22 | configurable: false 23 | enumerable: false 24 | ) 25 | 26 | Object.defineProperty( @, 'timemachine', 27 | get: -> @tree 28 | ) 29 | 30 | return this 31 | 32 | # Adds an undoable event to the tree 33 | # 34 | # @params action [Model.Action] action that is undoable 35 | # @return [Model.Node] the tree node returned 36 | # 37 | addUndoableEvent: ( action ) -> 38 | return @tree.add action 39 | 40 | # Undoes the last action 41 | # 42 | undo: () -> 43 | action = @tree.undo() 44 | action.undo() if action? 45 | return this 46 | 47 | # Redoes the last action 48 | # 49 | redo: () -> 50 | action = @tree.redo() 51 | action.redo() if action? 52 | return this 53 | 54 | # Creates an empty action 55 | # 56 | # @param description [String] the description for the action 57 | # @param context [Context] defaults to this 58 | # @return [Model.Action] the action 59 | # 60 | _createAction: ( description, context = @ ) -> 61 | return new Model.Action( context, undefined, undefined, description ) 62 | -------------------------------------------------------------------------------- /app/assets/javascripts/ie.js.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | Hack in support for Function.name for browsers that don't support it. 3 | * IE, I'm looking at you. 4 | ### 5 | 6 | if not Function.prototype.name? and Object.defineProperty? 7 | Object.defineProperty( Function.prototype, 'name', 8 | get: () -> 9 | funcNameRegex = /function\s([^(]{1,})\(/ 10 | results = (funcNameRegex).exec @.toString() 11 | return if results and results.length > 1 then results[1].trim() else "" 12 | ) -------------------------------------------------------------------------------- /app/assets/javascripts/models/action.js.coffee: -------------------------------------------------------------------------------- 1 | # A model for the action object used for (un)doing 2 | # 3 | class Model.Action 4 | 5 | # Creates a new action object 6 | # 7 | # @param context [Object] The context to execute the action is 8 | # @param do [Function] The function to execute in the context on (re)do 9 | # @param undo [Function] The function to execute in the context on undo 10 | # @param description [String] A description of the action 11 | # 12 | constructor: ( context, todo, undo, description = "Action" ) -> 13 | @_context = context 14 | @_todo = todo 15 | @_undo = undo 16 | @_description = description 17 | 18 | # Sets the up and down functions for this action 19 | # 20 | # @param todo [Function] The function to execute in the context on (re)do 21 | # @param undo [Function] The function to execute in the context on undo 22 | # 23 | set: ( todo, undo ) -> 24 | @_todo = todo 25 | @_undo = undo 26 | return this 27 | 28 | # Apply the do function on context 29 | # 30 | do: ( ) -> 31 | @_todo?.apply( @_context ) 32 | return this 33 | 34 | # Apply the undo function on context 35 | # 36 | undo: ( ) -> 37 | @_undo?.apply( @_context ) 38 | return this 39 | 40 | # Wrapper for do for convenience 41 | # 42 | redo: ( ) -> 43 | return @do() -------------------------------------------------------------------------------- /app/assets/javascripts/models/node.js.coffee: -------------------------------------------------------------------------------- 1 | # Basic node class 2 | # 3 | # @concern Mixin.EventBindings 4 | # 5 | class Model.Node extends Helper.Mixable 6 | 7 | @concern Mixin.EventBindings 8 | 9 | # Constructor for node 10 | # 11 | # @param object [Object] The object stored in the node 12 | # @param parent [Node] The parent of this node 13 | # @param children [Array] An array contraining the children. Default is empty. 14 | # 15 | constructor: ( @object, @parent, children ) -> 16 | @id = _.uniqueId('node') 17 | @branch = null 18 | 19 | @_defineProperties( children ) 20 | 21 | @parent?.children.push( this ) 22 | @parent?.branch = this 23 | 24 | @_allowEventBindings() 25 | @_trigger( 'node.creation', @, [] ) 26 | 27 | # Define the properties of the node 28 | # 29 | # @param children [Array] Initial children of this node 30 | # 31 | _defineProperties: ( children = [] ) -> 32 | Object.defineProperty( @, "children", 33 | value: children 34 | writable: off 35 | configurable: off 36 | ) 37 | Object.defineProperty( @, "creation", 38 | value: new Date() 39 | writable: off 40 | configurable: off 41 | ) 42 | 43 | # Add a child to this node 44 | # 45 | # @param object [Object] The object to be contained in the child 46 | # @return [Model.Node] The created node 47 | # 48 | addChild: ( object ) -> 49 | node = new Model.Node(object, this) 50 | return node 51 | 52 | # Replace this node with a different node 53 | # 54 | # @param other [Model.Node] The other node 55 | # @return [Model.Node] The other node 56 | # 57 | replace: ( other ) -> 58 | index = @parent?.children.indexOf this 59 | @parent?.children.splice( index, 1 ) 60 | 61 | for child in @children 62 | child.parent = other 63 | -------------------------------------------------------------------------------- /app/assets/javascripts/raphael-animate-along.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | You can copy and paste the below into your codebase somewhere. 4 | As long as Raphael is a global object, it'll just work. 5 | 6 | USAGE (same default values for optional parameters as Raphaël's "animate" method) 7 | ===== 8 | element.animateAlong({ 9 | path: REQUIRED - Path data string or path element, 10 | rotate: OPTIONAL - Boolean whether to rotate element with the direction it is moving 11 | (this is a beta feature - currently kills existing transformations 12 | and rotation may not be perfect), 13 | duration: OPTIONAL - Number in milliseconds, 14 | easing: OPTIONAL - String (see Raphaël's docs), 15 | debug: OPTIONAL - Boolean, when set to true, paints the animating path, which is 16 | helpful if it isn't already rendered to the screen 17 | }, 18 | props - Object literal containing other properties to animate, 19 | callback - Function where the "this" object refers to the element itself 20 | ); 21 | 22 | EXAMPLE 23 | ======= 24 | var rect = paper.rect(0,0,50,50); 25 | rect.animateAlong({ 26 | path: "M0,0L100,100", 27 | rotate: true, 28 | duration: 5000, 29 | easing: 'ease-out', 30 | debug: true 31 | }, 32 | { 33 | transform: 's0.25', 34 | opacity: 0 35 | }, 36 | function() { 37 | alert("Our opacity is now:" + this.attr('opacity')); 38 | }); 39 | 40 | */ 41 | 42 | Raphael.el.animateAlong = function(params, props, callback) { 43 | var element = this, 44 | paper = element.paper, 45 | path = params.path, 46 | rotate = params.rotate, 47 | duration = params.duration, 48 | easing = params.easing, 49 | debug = params.debug, 50 | isElem = typeof path !== 'string'; 51 | 52 | element.path = 53 | isElem 54 | ? path 55 | : paper.path(path); 56 | element.pathLen = element.path.getTotalLength(); 57 | element.rotateWith = rotate; 58 | 59 | element.path.attr({ 60 | stroke: debug ? 'red' : isElem ? path.attr('stroke') : 'rgba(0,0,0,0)', 61 | 'stroke-width': debug ? 2 : isElem ? path.attr('stroke-width') : 0 62 | }); 63 | 64 | paper.customAttributes.along = function(v) { 65 | var point = this.path.getPointAtLength(v * this.pathLen), 66 | attrs = { 67 | cx: point.x, 68 | cy: point.y 69 | }; 70 | this.rotateWith && (attrs.transform = 'r'+point.alpha); 71 | // TODO: rotate along a path while also not messing 72 | // up existing transformations 73 | 74 | return attrs; 75 | }; 76 | 77 | if(props instanceof Function) { 78 | callback = props; 79 | props = null; 80 | } 81 | if(!props) { 82 | props = { 83 | along: 1 84 | }; 85 | } else { 86 | props.along = 1; 87 | } 88 | 89 | var startAlong = element.attr('along') || 0; 90 | 91 | element.attr({along: startAlong}).animate(props, duration, easing, function() { 92 | !isElem && element.path.remove(); 93 | 94 | callback && callback.call(element); 95 | }); 96 | }; -------------------------------------------------------------------------------- /app/assets/javascripts/raphael-guide.js: -------------------------------------------------------------------------------- 1 | ;(function() { 2 | Raphael.fn.addGuides = function() { 3 | this.ca.guide = function(g) { 4 | return { 5 | guide: g 6 | }; 7 | }; 8 | this.ca.along = function(percent) { 9 | var g = this.attr("guide"); 10 | var len = g.getTotalLength(); 11 | var point = g.getPointAtLength(percent * len); 12 | var t = { 13 | transform: "t" + point.x + " " + point.y 14 | }; 15 | return t; 16 | }; 17 | }; 18 | })(); -------------------------------------------------------------------------------- /app/assets/javascripts/raphael-snapends.js: -------------------------------------------------------------------------------- 1 | original = Raphael.g.snapEnds 2 | Raphael.g.snapEnds = function() { 3 | ret = original.apply(this, arguments); 4 | if (arguments[1] < ret.to) { 5 | ret.to = arguments[1]; 6 | } 7 | return ret; 8 | }; 9 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/collection._.js.coffee: -------------------------------------------------------------------------------- 1 | class View.Collection extends Helper.Mixable 2 | 3 | # Creates a collection of views 4 | # 5 | # @param id [String] The id of the container for the views 6 | # 7 | constructor: ( @id ) -> 8 | if @id? 9 | @container = $( id ) 10 | 11 | @_views = [] 12 | 13 | # Clears the collection 14 | # 15 | clear: () -> 16 | view.clear() for view in @_views 17 | return this 18 | 19 | # Kills the collection 20 | # 21 | # @param reset [Boolean] if true, clears the internal array 22 | # 23 | kill: ( reset = off ) -> 24 | @clear() 25 | view.kill?() for view in @_views 26 | @_views = [] if reset 27 | return this 28 | 29 | # Add a view to draw 30 | # 31 | # @param view [View.*] the view to add 32 | # 33 | add: ( view, draw = on ) -> 34 | @_views.push view 35 | view.draw() if draw 36 | return this 37 | 38 | # Removes the view 39 | # 40 | # @param view [View.*] the view to remove 41 | # 42 | remove: ( view ) -> 43 | @_views = _( @_views ).without view 44 | return this 45 | 46 | # Draw ths collection 47 | # 48 | draw: () -> 49 | view.draw() for view in @_views 50 | return this 51 | 52 | # Redraws this collection 53 | # 54 | redraw: () -> 55 | view.redraw() for view in @_views 56 | return this 57 | 58 | # 59 | # 60 | each: ( func ) -> 61 | _( @_views ).each func 62 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/modal.confirm.coffee: -------------------------------------------------------------------------------- 1 | # Provides an HTML Modal 2 | # 3 | class View.ConfirmModal extends View.HTMLModal 4 | 5 | # Create the modal footer 6 | # 7 | # 8 | _createFooter: () -> 9 | footer = $ '' 10 | cancel = $ '' 11 | confirm = $ '' 12 | footer.append cancel 13 | footer.append confirm 14 | @_bindKeys( [13, false, false, false], @, () -> confirm.click() ) 15 | return [ footer, cancel, confirm ] 16 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/pane.js.coffee: -------------------------------------------------------------------------------- 1 | # View for extensible Pane 2 | # 3 | class View.Pane extends Helper.Mixable 4 | 5 | @Position: 6 | Left: 'left' 7 | Right: 'right' 8 | 9 | # Creates a new Pane 10 | # 11 | # @param position [View.Pane.Position] The side the pane needs to be on 12 | # 13 | constructor: ( @position ) -> 14 | @_extended = on 15 | @_buttonWidth = 40 16 | 17 | @_containerOptions = {} 18 | 19 | @_views = [] 20 | 21 | # Clears this view 22 | # 23 | clear: ( ) -> 24 | for view in @_views 25 | view.kill() 26 | 27 | # Kills the view 28 | # 29 | kill: ( ) -> 30 | @_elem?.remove() 31 | 32 | # Draw the view 33 | # 34 | # @param position [View.Pane.Position] The side the pane needs to be on 35 | # 36 | draw: ( position = @position ) -> 37 | @kill() 38 | 39 | @_elem = $('
') 40 | @_elem.addClass("pane-#{position}") 41 | 42 | button = $('
') 43 | button.click( => 44 | @toggle() 45 | ) 46 | @_elem.append(button) 47 | 48 | for view in @_views 49 | @_elem.append(view.draw()) 50 | 51 | $('body').append(@_elem) 52 | 53 | if @_extended 54 | @extend() 55 | else 56 | @retract() 57 | 58 | # Add a view to draw in the container 59 | # 60 | # @param view [Object] The view to add 61 | # 62 | addView: ( view ) -> 63 | @_views.push(view) 64 | @draw() 65 | 66 | # Removes a view from the container 67 | # 68 | # @param [Object] The view to remove 69 | # 70 | removeView: ( view ) -> 71 | @_views = _( @_views ).without view 72 | @draw() 73 | 74 | # Toggle the panes extension 75 | # 76 | toggle: ( ) -> 77 | if @_extended 78 | @retract() 79 | else 80 | @extend() 81 | 82 | # Extends the pane if not already extended 83 | # 84 | extend: ( ) -> 85 | @_elem.addClass('extended') 86 | @_extended = on 87 | 88 | # Retracts the pane if not already retracted 89 | # 90 | retract: ( ) -> 91 | @_elem.removeClass('extended') 92 | @_extended = off 93 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/popover.notification.cell.js.coffee: -------------------------------------------------------------------------------- 1 | # Displays the notifications of a module in a neat HTML popover 2 | # 3 | class View.CellNotification extends View.Notification 4 | 5 | # Constructs a new CellNotification view. 6 | # 7 | # @param parent [View.Cell] the accompanying cell view 8 | # @param cell [Model.Cell] the cell for which to display its notifications 9 | # @param params [Object] options 10 | # 11 | constructor: ( parent, cell, params = {} ) -> 12 | super parent, cell 13 | 14 | # Filters incoming messages 15 | # 16 | _filter: ( message ) -> 17 | 18 | if message.identifier.indexOf('save') isnt -1 or message.identifier.indexOf('load') isnt -1 19 | if message.type is View.CellNotification.Notification.Info 20 | message.closable = off 21 | message.message = ' 22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | ' + message.message + ' 30 | ' 31 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/popover.notification.main.js.coffee: -------------------------------------------------------------------------------- 1 | # Displays the notifications of a module in a neat HTML popover 2 | # 3 | class View.MainNotification extends View.Notification 4 | 5 | # Constructs a new MainNotification view. 6 | # 7 | # @param parent [View.Main] the accompanying view 8 | # @param subject [Model.*] the cell for which to display its notifications 9 | # @param params [Object] options 10 | # 11 | constructor: ( parent, subject, params = {} ) -> 12 | super parent, subject 13 | 14 | # Filters incoming messages 15 | # 16 | _filter: ( message ) -> 17 | if message.identifier isnt 'solution' 18 | message.visible = off 19 | 20 | # Create footer content and append to footer 21 | # 22 | # @param onclick [Function] the function to yield on click 23 | # @param saveText [String] the text on the save button 24 | # @return [Array] the footer and the button element 25 | # 26 | _createFooter: ( ) -> 27 | @_footer = $('') 28 | @_footer.append @_button 29 | return [ @_footer, @_button ] 30 | 31 | # 32 | # 33 | setSolutionMessage: ( message, @_button ) -> 34 | @display( @, @, 'solution', View.Main.Notification.Info, message, [] ) 35 | #@display( @, @, 'solution-action', View.Main.Notification.Info, button, [] ) 36 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/popover.notification.module.js.coffee: -------------------------------------------------------------------------------- 1 | # Displays the notifications of a module in a neat HTML popover 2 | # 3 | class View.ModuleNotification extends View.Notification 4 | 5 | # Constructs a new ModuleProperties view. 6 | # 7 | # @param parent [View.Module] the accompanying module view 8 | # @param module [Model.Module] the module for which to display its notifications 9 | # @param cellView [View.Cell] the accompanying cell view 10 | # @param cell [Model.Cell] the parent cell of the module 11 | # @param params [Object] options 12 | # 13 | constructor: ( parent, cellView, cell, module, params = {} ) -> 14 | @_cellView = cellView 15 | @_cell = cell 16 | 17 | super parent, module 18 | 19 | @_bind( 'cell.module.added', @, ( cell ) => @hide() if cell is @_cell ) 20 | @_bind( 'cell.module.removed', @, ( cell, module ) => @kill().hide() if module is @_source ) 21 | @_bind( 'cell.metabolite.added', @, ( cell ) => @hide() if cell is @_cell ) 22 | @_bind( 'cell.metabolite.removed', @, ( cell, module ) => @kill().hide() if module is @_source ) 23 | #@_bind( 'cell.before.run', @, ( cell ) => @hide() if cell is @_cell ) 24 | 25 | # Filters incoming messages 26 | # 27 | _filter: ( message ) -> 28 | message.message = message.message.replace(/#([^\., ]*)/g, "$1") 29 | if message.identifier.indexOf('save') isnt -1 or message.identifier.indexOf('load') isnt -1 30 | message.closable = off 31 | 32 | if message.type is View.ModuleNotification.Notification.Info 33 | message.message = ' 34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | ' + message.message + ' 42 | ' 43 | else 44 | message.visible = off 45 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/raphael.report.js.coffee: -------------------------------------------------------------------------------- 1 | # Class to generate the cell in the report 2 | # 3 | class View.Report extends View.RaphaelBase 4 | 5 | # Constructor for this view 6 | # 7 | constructor: ( container = "#paper", @_target = container ) -> 8 | super( Raphael( $(container)[0], 900, 567 ) ) 9 | 10 | @paper.setViewBox(-750, -500, 1500, 1000) 11 | 12 | $( window ).on( 'resize', => _( @resize() ).debounce( 100 ) ) 13 | @resize() 14 | 15 | # Resizes the cell to the target size 16 | # 17 | resize: ( ) => 18 | width = $( @_target ).width() 19 | height = $( @_target ).height() 20 | 21 | edge = Math.min( width / 1.5, height) 22 | @paper.setSize( edge * 1.5 , edge ) 23 | @_trigger( 'paper.resize', @paper ) 24 | 25 | # Gets the progress bar 26 | # 27 | # @return [jQuery.Elem] the progress bar 28 | # 29 | getProgressBar: () -> 30 | return $( '#progress' ) 31 | 32 | # Sets the progress bar 33 | # 34 | # @param value [Float] range 0..1 percentage filled 35 | # @return [self] chainable self 36 | # 37 | setProgressBar: ( value ) -> 38 | @getProgressBar() 39 | .find( '.bar' ) 40 | .css( 'width', "#{value * 100}%" ) 41 | return this 42 | 43 | # Hides the progress bar 44 | # 45 | # @return [self] chainable self 46 | # 47 | hideProgressBar: ( ) -> 48 | @getProgressBar().css( 'opacity', 0 ) 49 | return this 50 | 51 | # Shows the progress bar 52 | # 53 | # @return [self] chainable self 54 | # 55 | showProgressBar: () -> 56 | @getProgressBar().css( 'visibility', 'visible' ) 57 | @getProgressBar().css( 'opacity', 1 ) 58 | return this -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require bootstrap 12 | * 13 | *= require_self 14 | *= require_tree . 15 | * 16 | */ 17 | -------------------------------------------------------------------------------- /app/assets/stylesheets/graph.css.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the graph here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | .graph, .graph-report { 5 | 6 | position: relative; 7 | display: -moz-inline-stack; 8 | display: inline-block; 9 | vertical-align: top; 10 | margin-right: 24px; 11 | margin-bottom: 8px; 12 | zoom: 1; 13 | *display: inline; 14 | 15 | h2 { 16 | font-size: 1.5rem; 17 | } 18 | 19 | padding: 0px; 20 | 21 | .information { 22 | position: absolute; 23 | left: 53px; 24 | background: rgba( 255, 255, 255, .8 ); 25 | z-index: 100; 26 | padding: 4px; 27 | border-radius: 4px; 28 | box-shadow: rgba( 0, 0, 0, .1 ) 1px 1px 5px; 29 | 30 | span { 31 | display: block; 32 | font-size: 11px; 33 | } 34 | } 35 | } 36 | 37 | .graph-report { 38 | margin-right: 0; 39 | } 40 | -------------------------------------------------------------------------------- /app/assets/stylesheets/hook.css.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the hook controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/main.css.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the main controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | 5 | body { 6 | overflow-y:scroll; 7 | } 8 | 9 | .left { 10 | position: absolute; 11 | left: 0px; 12 | } 13 | 14 | .right { 15 | position: absolute; 16 | right: 0px; 17 | } 18 | 19 | div#paper svg { 20 | display:block; 21 | margin:0 auto; 22 | } 23 | 24 | div#paper svg, .pane, .btn { 25 | -webkit-user-select: none; 26 | -khtml-user-select: none; 27 | -moz-user-select: none; 28 | -o-user-select: none; 29 | user-select: none; 30 | 31 | cursor: default; 32 | } 33 | 34 | #graphs { 35 | height: 100%; 36 | } 37 | 38 | #actions form, #actions .form-actions { 39 | margin-bottom: 0; 40 | } 41 | 42 | #progress.progress .bar { 43 | -webkit-transition: none; 44 | -moz-transition: none; 45 | -o-transition: none; 46 | transition: none; 47 | } 48 | 49 | .modal-load .dropdown-menu { 50 | min-width: 100px; 51 | } 52 | 53 | [data-action], [data-toggle] { 54 | cursor:pointer; 55 | } 56 | 57 | .bottom-up {top: auto; bottom: 100%; } 58 | -------------------------------------------------------------------------------- /app/assets/stylesheets/notifications.css.scss: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes spin { 2 | from { -webkit-transform: rotate(0deg); } 3 | to { -webkit-transform: rotate(360deg); } 4 | } 5 | 6 | @-moz-keyframes spin { 7 | from { -webkit-transform: rotate(0deg); } 8 | to { -webkit-transform: rotate(360deg); } 9 | } 10 | 11 | @keyframes spin { 12 | from { transform: rotate(0deg); } 13 | to { transform: rotate(360deg); } 14 | } 15 | 16 | 17 | /* Loading animation container */ 18 | .loading { 19 | //position: absolute; 20 | //top: 50%; 21 | left: 50%; 22 | width: 18px; 23 | height: 18px; 24 | margin: 0 0 0 -9px; 25 | position:relative; 26 | display: none; 27 | 28 | .maskedCircle { 29 | width: 12px; 30 | height: 12px; 31 | border-radius: 12px; 32 | border: 3px solid black; 33 | } 34 | 35 | .mask { 36 | width: 10px; 37 | height: 10px; 38 | overflow: hidden; 39 | } 40 | 41 | .spinner { 42 | //position: absolute; 43 | left: 1px; 44 | top: 1px; 45 | width: 16px; 46 | height: 16px; 47 | -webkit-animation: spin 1s infinite linear; 48 | -moz-animation: spin 1s infinite linear; 49 | animation: spin 1s infinite linear; 50 | } 51 | 52 | &.active { 53 | display: block; 54 | } 55 | } 56 | 57 | .notification { 58 | small { 59 | font-size: .7rem; 60 | color: grey; 61 | } 62 | 63 | &.global { 64 | max-width: 700px; 65 | 66 | &.active { 67 | display: block; 68 | opacity: .75; 69 | 70 | &:hover { 71 | opacity: .9; 72 | } 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /app/assets/stylesheets/popovers.css.scss: -------------------------------------------------------------------------------- 1 | 2 | .module-properties { 3 | max-width: 251px; 4 | width: 251px; 5 | position: absolute; 6 | display: none; 7 | outline: none; 8 | 9 | &.selected { 10 | display: block; 11 | opacity: 1; 12 | z-index: 999; 13 | } 14 | 15 | &:not(.selected) { 16 | input[type=checkbox], input[type=radio] { 17 | display:none; 18 | } 19 | } 20 | 21 | .control-group { 22 | margin-bottom:8px; 23 | } 24 | 25 | .control-label { 26 | width: 104px; 27 | } 28 | 29 | .controls { 30 | margin-left: 119px; 31 | 32 | label { 33 | display:block; 34 | min-height: 0px; 35 | height:20px; 36 | transition: opacity .3s ease-in-out, height .3s ease-in-out, margin .3s ease-in-out, padding .3s ease-in-out; 37 | 38 | &.selectable-hide { 39 | opacity: 0; 40 | 41 | height:0px; 42 | margin-top:0px; 43 | margin-bottom:0px; 44 | 45 | input { 46 | display:none !important; 47 | } 48 | } 49 | } 50 | 51 | input, select{ 52 | transition: opacity 1s ease-in-out; 53 | 54 | &[disabled] { 55 | border-color: rgba(0, 0, 0, 0); 56 | box-shadow: none; 57 | background:none; 58 | 59 | &[type=checkbox], &[type=radio] { 60 | 61 | & + .badge { 62 | margin-left:-18px; 63 | } 64 | } 65 | } 66 | } 67 | 68 | .badge { 69 | transition: margin-left .3s ease-in-out; 70 | 71 | &.compounds { 72 | border-radius:2px; 73 | } 74 | } 75 | 76 | .badge-metabolite { 77 | font-size:14px; 78 | line-hight:18px; 79 | margin-top:5px; 80 | margin-left:5px; 81 | } 82 | } 83 | 84 | hr { 85 | margin:8px; 86 | } 87 | 88 | &.hovered { 89 | display: block; 90 | opacity: .9; 91 | z-index: 1000; 92 | 93 | .close { 94 | display: none; 95 | } 96 | 97 | .modal-footer { 98 | display: none; 99 | } 100 | } 101 | } 102 | 103 | .tutorial { 104 | width: 350px; 105 | max-width: 350px; 106 | line-height: 24px; 107 | position: fixed; 108 | 109 | p { 110 | line-height: 24px; 111 | } 112 | 113 | &.active { 114 | display: block; 115 | opacity: .75; 116 | 117 | &:hover { 118 | opacity: .9; 119 | } 120 | } 121 | 122 | .badge.compounds { 123 | border-radius: 2px; 124 | } 125 | } 126 | 127 | .close { 128 | margin-left: 10px; 129 | 130 | i { 131 | vertical-align: baseline; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /app/assets/stylesheets/presentation.css: -------------------------------------------------------------------------------- 1 | div#cursor { 2 | position: absolute; 3 | background-color: rgba( 100, 100, 100, .5 ); 4 | border-radius: 8px; 5 | top: 400px; 6 | left: 500px; 7 | width: 16px; 8 | height: 16px; 9 | z-index: 1000; 10 | } 11 | -------------------------------------------------------------------------------- /app/assets/stylesheets/scaffolds.css.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #fff; 3 | color: #333; 4 | font-size: 13px; 5 | line-height: 18px; 6 | } 7 | 8 | p, ol, ul, td { 9 | font-size: 13px; 10 | line-height: 18px; 11 | } 12 | 13 | pre { 14 | background-color: #eee; 15 | padding: 10px; 16 | font-size: 11px; 17 | } 18 | 19 | div { 20 | &.field, &.actions { 21 | margin-bottom: 10px; 22 | } 23 | } 24 | 25 | #notice { 26 | color: green; 27 | } 28 | 29 | .field_with_errors { 30 | padding: 2px; 31 | border: 1px dashed darken( #eed3d7, 30%); 32 | background-color: darken( #f2dede, 10% ); 33 | border-radius: 5px; 34 | display: inline-block; 35 | } 36 | 37 | #error_explanation { 38 | width: 450px; 39 | border: 2px solid red; 40 | padding: 7px; 41 | padding-bottom: 0; 42 | margin-bottom: 20px; 43 | background-color: #f0f0f0; 44 | h2 { 45 | text-align: left; 46 | font-weight: bold; 47 | padding: 5px 5px 5px 15px; 48 | font-size: 12px; 49 | margin: -7px; 50 | margin-bottom: 0px; 51 | background-color: #c00; 52 | color: #fff; 53 | } 54 | ul li { 55 | font-size: 12px; 56 | list-style: square; 57 | } 58 | } 59 | 60 | #filters div { 61 | display: inline-block; 62 | } -------------------------------------------------------------------------------- /app/assets/stylesheets/undo.css.scss: -------------------------------------------------------------------------------- 1 | 2 | .undo-view { 3 | 4 | .undo-contents { 5 | width:100%; 6 | 7 | .undo-body { 8 | position:absolute; 9 | top:41px; 10 | bottom:41px; 11 | width:100%; 12 | } 13 | 14 | .pane-footer { 15 | 16 | .navbar-inner { 17 | padding:0; 18 | 19 | .branch-button { 20 | padding: 10px 15px 10px; 21 | opacity: .2; 22 | 23 | border:0px solid #ccc; 24 | 25 | -webkit-transition: opacity 0.3s ease-in-out; 26 | -moz-transition: opacity 0.3s ease-in-out; 27 | -o-transition: opacity 0.3s ease-in-out; 28 | transition: opacity 0.3s ease-in-out; 29 | 30 | &.pull-left { 31 | border-right-width:1px; 32 | } 33 | 34 | &.pull-right { 35 | border-left-width:1px; 36 | } 37 | } 38 | } 39 | 40 | &.active-buttons { 41 | 42 | .branch-button { 43 | opacity: .7; 44 | cursor: pointer; 45 | } 46 | } 47 | } 48 | } 49 | } 50 | 51 | .undo-list { 52 | position:relative; 53 | height:100%; 54 | width:100%; 55 | overflow-y:auto; 56 | 57 | .undo-row { 58 | padding:8px 8px 8px 20px; 59 | line-height:20px; 60 | 61 | border-bottom:1px solid #ddd; 62 | 63 | cursor:pointer; 64 | 65 | -webkit-transition: all 0.15s ease-in-out; 66 | -moz-transition: all 0.15s ease-in-out; 67 | -o-transition: all 0.15s ease-in-out; 68 | transition: all 0.15s ease-in-out; 69 | 70 | dl { 71 | margin:0; 72 | 73 | dt { 74 | font-weight:normal; 75 | font-size:14px; 76 | } 77 | 78 | dd { 79 | text-align: right; 80 | color:#aaa; 81 | } 82 | } 83 | 84 | &.inactive { 85 | opacity: .5; 86 | } 87 | 88 | &:nth-child(odd):not(.selected) { 89 | background-color: #f9f9f9; 90 | } 91 | 92 | &:nth-child(even):not(.selected) { 93 | background-color: lighten( #f9f9f9, 2% ); 94 | } 95 | 96 | &:hover:not(.selected) { 97 | background-color: darken( #f9f9f9, 5% ); 98 | } 99 | 100 | &.selected { 101 | background-color: darken( #f9f9f9, 5% ); 102 | //border-bottom: 2px rgba( 100, 100, 255, 1) solid; 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | include ApplicationHelper 4 | end 5 | -------------------------------------------------------------------------------- /app/controllers/hook_controller.rb: -------------------------------------------------------------------------------- 1 | class HookController < ApplicationController 2 | before_filter :set_cache_buster 3 | 4 | def index 5 | @version = `git describe` 6 | @branch = `git rev-parse --abbrev-ref HEAD` 7 | end 8 | 9 | def post 10 | @host = `host #{request.remote_ip}` 11 | @branch = params[:branch] 12 | @status = params[:status_message] 13 | 14 | if ( 15 | @host.include? "amazonaws.com" and 16 | @branch == "master" and 17 | @status == "Passed" 18 | ) 19 | @command = "cd /var/www/life/ && " + 20 | "git fetch --tags && " + 21 | "git checkout master && " + 22 | "git reset --hard HEAD && " + 23 | "git pull origin master" 24 | 25 | `#{@command}` 26 | @exitcode = $?.exitstatus 27 | @version = `git describe --abbrev=0` 28 | 29 | `bundle install --deployment` 30 | `rake db:migrate` 31 | end 32 | end 33 | 34 | def version 35 | respond_to do | format | 36 | format.json { render json: { major: 2, minor: 0, revision: 0, full: '2.0.0' } } 37 | end 38 | end 39 | 40 | def set_cache_buster 41 | response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate" 42 | response.headers["Pragma"] = "no-cache" 43 | response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT" 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /app/controllers/main_controller.rb: -------------------------------------------------------------------------------- 1 | class MainController < ApplicationController 2 | def index 3 | @controller = 'Controller.Main' 4 | @cell = Cell.new 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | # Listifies a list 3 | # 4 | def listify( list ) 5 | result = case list.count 6 | when 0 then 'none' 7 | when 1 then list.first 8 | else list.first( list.count - 1 ).join( ', ') + ' and ' + list.last 9 | end 10 | return result 11 | end 12 | 13 | def filter_on_key( results, key, value ) 14 | return results.where( key.to_sym => value ) 15 | end 16 | 17 | def filter_on_key!( results, key, value ) 18 | results = results.where( key.to_sym => value ) 19 | end 20 | 21 | # This will create a link to the current document with the provided options 22 | # being added to the URL as query string parameters. You may either provide 23 | # the link text (the body) as the first parameter, or instead provide a block 24 | # that returns the content of the link. You may also provide a standard 25 | # html_options hash. 26 | # 27 | # In addition to adding any provided options as parameters to the query string 28 | # this will also add all query string parameters from the current request back 29 | # into the query string as well. To override an existing query string 30 | # parameter, simply provide an option of the same name (string or symbol form) 31 | # with the new value. If the new value is nil, the existing parameter will be 32 | # omitted. All non-string values will be converted using #to_s. 33 | # 34 | # Finally, you may provide an option with the key :fragment to specify a 35 | # fragment identifier you'd like to be appended onto the end of the URL. You 36 | # _must_ use the symbol :fragment, not the string "fragment" for the key, 37 | # otherwise the value will be added to the query string: "?fragment=value" 38 | # 39 | # == Signatures 40 | # 41 | # link_to_self(body, options = {}, html_options = {}) 42 | # # body is the "name" (contents) of the link 43 | # 44 | # link_to_self(options = {}, html_options = {}) do 45 | # # link contents defined here 46 | # end 47 | # 48 | def link_to_self(*args, &block) 49 | if block_given? 50 | options = args.first || {} 51 | html_options = args.second 52 | link_to_self(capture(&block), options, html_options) 53 | else 54 | name = args[0] 55 | options = args[1] ? args[1].dup : {} 56 | html_options = args[2] 57 | fragment = options.delete(:fragment) 58 | query_string = 59 | options 60 | .with_indifferent_access 61 | .reverse_merge( request.query_parameters ).map { |k, v| 62 | v.nil? ? nil : "#{Rack::Utils.escape(k.to_s)}=#{Rack::Utils.escape(v.to_s)}" 63 | }.compact.join( "&" ) 64 | path = request.path 65 | path += "?#{query_string}" unless query_string.blank? 66 | path += "##{fragment}" unless fragment.blank? 67 | result = link_to(name, path, html_options) 68 | result 69 | end 70 | end 71 | 72 | end 73 | -------------------------------------------------------------------------------- /app/helpers/cells_helper.rb: -------------------------------------------------------------------------------- 1 | module CellsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/hook_helper.rb: -------------------------------------------------------------------------------- 1 | module HookHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/main_helper.rb: -------------------------------------------------------------------------------- 1 | module MainHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/module_instances_helper.rb: -------------------------------------------------------------------------------- 1 | module ModuleInstancesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/module_templates_helper.rb: -------------------------------------------------------------------------------- 1 | module ModuleTemplatesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/report_helper.rb: -------------------------------------------------------------------------------- 1 | module ReportHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/mailers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/app/mailers/.gitkeep -------------------------------------------------------------------------------- /app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/app/models/.gitkeep -------------------------------------------------------------------------------- /app/models/cell.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: cells 4 | # 5 | # id :integer not null, primary key 6 | # name :string(255) 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | 11 | class Cell < ActiveRecord::Base 12 | default_scope order('updated_at DESC') 13 | attr_accessible :id, :name, :module_instances_attributes 14 | 15 | has_many :module_instances, :dependent => :destroy 16 | has_many :module_templates, :through => :module_instances 17 | has_one :report, :dependent => :destroy 18 | 19 | accepts_nested_attributes_for :module_instances, :reject_if => proc { |attr| attr[:module_template_id].to_i == 0 }, :allow_destroy => true 20 | 21 | end 22 | -------------------------------------------------------------------------------- /app/models/module_instance.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: module_instances 4 | # 5 | # id :integer not null, primary key 6 | # created_at :datetime not null 7 | # updated_at :datetime not null 8 | # module_template_id :integer 9 | # cell_id :integer 10 | # amount :float 11 | # name :string(255) 12 | # 13 | 14 | class ModuleInstance < ActiveRecord::Base 15 | attr_accessible :id, :module_template_id, :cell_id, :module_values_attributes, :name, :amount 16 | 17 | has_many :module_values, :dependent => :destroy 18 | has_many :module_parameters, :through => :module_template 19 | belongs_to :module_template 20 | belongs_to :cell 21 | 22 | accepts_nested_attributes_for :module_values, :allow_destroy => true 23 | 24 | validates :module_template_id, :presence => true 25 | validates :cell_id, :presence => true 26 | validates :name, :presence => true 27 | 28 | after_create :create_parameters 29 | 30 | private 31 | def create_parameters 32 | self.module_template.module_parameters.each { |param| 33 | ModuleValue.create( {:value => nil, :module_instance_id => self.id, :module_parameter_id => param.id } ) 34 | } 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /app/models/module_instance_observer.rb: -------------------------------------------------------------------------------- 1 | class ModuleInstanceObserver < ActiveRecord::Observer 2 | def after_create( instance ) 3 | instance.cell.update_attribute(:updated_at, Time.now) 4 | end 5 | 6 | def after_update( instance ) 7 | instance.cell.update_attribute(:updated_at, Time.now) 8 | end 9 | 10 | def after_destroy( instance ) 11 | instance.cell.update_attribute(:updated_at, Time.now) 12 | end 13 | end -------------------------------------------------------------------------------- /app/models/module_parameter.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: module_parameters 4 | # 5 | # id :integer not null, primary key 6 | # key :string(255) 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # module_template_id :integer 10 | # 11 | 12 | class ModuleParameter < ActiveRecord::Base 13 | attr_accessible :id, :key, :module_template_id 14 | 15 | belongs_to :module_template 16 | has_many :module_values, :dependent => :destroy 17 | end 18 | -------------------------------------------------------------------------------- /app/models/module_template.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: module_templates 4 | # 5 | # id :integer not null, primary key 6 | # created_at :datetime not null 7 | # updated_at :datetime not null 8 | # name :string(255) 9 | # step :text 10 | # file :string(255) 11 | # javascript_model :string(255) 12 | # 13 | 14 | class ModuleTemplate < ActiveRecord::Base 15 | attr_accessible :id, :name, :step, :file, :module_parameters_attributes, :javascript_model 16 | 17 | validates :name, :presence => true 18 | 19 | has_many :module_instances, :dependent => :destroy 20 | has_many :module_parameters, :dependent => :destroy 21 | has_many :cells, :through => :module_instances 22 | 23 | accepts_nested_attributes_for :module_parameters, :allow_destroy => true 24 | end 25 | -------------------------------------------------------------------------------- /app/models/module_value.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: module_values 4 | # 5 | # id :integer not null, primary key 6 | # value :text 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # module_parameter_id :integer 10 | # module_instance_id :integer 11 | # 12 | 13 | class ModuleValue < ActiveRecord::Base 14 | attr_accessible :value, :module_parameter_id, :module_instance_id 15 | 16 | belongs_to :module_parameter 17 | belongs_to :module_instance 18 | 19 | delegate :cell, :to => :module_instance 20 | end 21 | -------------------------------------------------------------------------------- /app/models/module_value_observer.rb: -------------------------------------------------------------------------------- 1 | class ModuleValueObserver < ActiveRecord::Observer 2 | def after_update( value ) 3 | value.module_instance.update_attribute(:updated_at, Time.now) 4 | end 5 | end -------------------------------------------------------------------------------- /app/models/report.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: reports 4 | # 5 | # id :integer not null, primary key 6 | # cell_id :integer 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | 11 | class Report < ActiveRecord::Base 12 | validates_uniqueness_of :cell_id 13 | 14 | attr_accessible :id, :cell_id 15 | belongs_to :cell 16 | validates :cell_id, :presence => true 17 | end 18 | -------------------------------------------------------------------------------- /app/views/cells/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= nested_form_for(@cell, :html => {:class => "form-horizontal"} ) do |f| %> 2 | <% if @cell.errors.any? %> 3 |
4 |

<%= pluralize(@cell.errors.count, "error") %>

5 | 6 |
    7 | <% @cell.errors.full_messages.each do |msg| %> 8 |
  • <%= msg %>
  • 9 | <% end %> 10 |
11 |
12 | <% end %> 13 | 14 |
15 | <%= f.label :id, :class => "control-label" %> 16 |
17 |
18 | <%= (@cell.new_record? ? 'new unique id'.html_safe : @cell.id) %> 19 |
20 |
21 |
22 | 23 |
24 | <%= f.label :name, :class => "control-label" %> 25 |
26 | <%= f.text_field :name %> 27 |
28 |
29 | 30 | 31 | <% if (@cell.new_record?) %> 32 |
33 |
34 | Save before editing contained modules 35 |
36 |
37 | <% else %> 38 |
39 | <%= f.fields_for :module_instances do |builder| %> 40 | <%= render "module_instance_fields", :f => builder%> 41 | <% end %> 42 |
43 | 44 |
45 |
46 | <%= f.link_to_add ' Add Module'.html_safe, :module_instances, :class => 'btn', :data => { :target => "#instances" } %> 47 |
48 |
49 | <% end %> 50 | 51 |
52 | <%= f.submit :class => "btn btn-primary" %> 53 |
54 | <% end %> 55 | -------------------------------------------------------------------------------- /app/views/cells/_module_instance_fields.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= f.label :module_template_id, :class => "control-label" %> 3 |
4 | <%= f.select :module_template_id, ModuleTemplate.all.collect {|x| [ x.name, x.id ] }, {}, :multiple => false %> 5 | <%= f.text_field :name, :placeholder => "compound name" %> 6 | <%= f.link_to_remove ''.html_safe, :class => 'btn btn-danger' %> 7 |
8 |
-------------------------------------------------------------------------------- /app/views/cells/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing Cell

2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Show', @cell %> | 6 | <%= link_to 'Back', cells_path %> 7 | -------------------------------------------------------------------------------- /app/views/cells/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Listing cells

3 |
4 | <% @filters.each { |filter, value| %> 5 |
6 | <%= link_to_self raw('×'), { template: nil } , { class: 'close' } %> 7 | <%= filter %> 8 |
9 | <% } %> 10 |
11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | <% @cells.each do |cell| %> 28 | 29 | 30 | 33 | 36 | 39 | 40 | 41 | 44 | 45 | <% end %> 46 | 47 |
IdShowEditGenerate reportNameContainsDestroy
<%= cell.id %> 31 | <%= link_to raw(''), cell, :class => 'btn btn-small', :title => 'Show' %> 32 | 34 | <%= link_to raw(''), edit_cell_path(cell), :class => 'btn btn-small', :title => 'Edit' %> 35 | 37 | <%= link_to raw(''), new_report_path, :class => 'btn btn-small', :title => 'Report' %> 38 | <%= cell.name %><%= link_to pluralize( ModuleInstance.where( :cell_id => cell.id ).count, 'module'), module_instances_path( :cell => cell.id ) %> 42 | <%= link_to raw(''), cell, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-small btn-danger', :title => 'Destroy' %> 43 |
48 | 49 |
50 |
51 | <%= will_paginate %> 52 |
53 |
54 | <%= link_to raw(' New Cell'), new_cell_path, :class => 'btn btn-small btn-primary' %> 55 |
56 |
57 | 58 | -------------------------------------------------------------------------------- /app/views/cells/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

New cell

3 |
4 | 5 | <%= render 'form' %> 6 | 7 | <%= link_to 'Back', cells_path %> 8 | -------------------------------------------------------------------------------- /app/views/cells/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Cell #<%= @cell.id %>

3 | <% if (notice.present?) %> 4 |

<%= notice %>

5 | <% end %> 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
KeyValue
Id<%= @cell.id %>
Name<%= @cell.name %>
Modules 28 | 29 | <% 30 | modules = [] 31 | @module_instances.each do |module_instance| 32 | modules.push link_to ModuleTemplate.find( module_instance.module_template_id).name, module_instance, :class => 'btn btn-mini' 33 | end 34 | %> 35 | 36 | <%= (listify modules).html_safe %> 37 |
Creation<%= @cell.created_at.strftime("%a %d %B %Y at %H:%M") %>
Updated<%= (@cell.updated_at == @cell.created_at ? "Never" : @cell.updated_at.strftime("%a %d %B %Y at %H:%M") ) %>
51 | 52 |
53 | 56 |
57 | <%= link_to raw(' Edit'), edit_cell_path(@cell), :class => 'btn btn-primary' %> 58 | <%= link_to raw(' Destroy'), @cell, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-danger' %> 59 | <%= link_to 'Back', cells_path %> 60 |
61 |
62 | -------------------------------------------------------------------------------- /app/views/hook/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |

<%= @version %>

4 |

Branch: <%= @branch %>

5 |
6 |
7 | -------------------------------------------------------------------------------- /app/views/hook/post.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= @command %>
3 | returned with exit status <%= @exitcode %> 4 |
5 |

Now at version <%= @version %>!

6 |
7 |

Host: <%= @host %>

8 |

Branch: <%= @branch %>

9 |

Build status: <%= @status %>

10 |
11 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Programming Life: Gigabase 5 | 6 | 7 | <%= stylesheet_link_tag "application", :media => "all" %> 8 | <%= javascript_include_tag "application" %> 9 | <%= csrf_meta_tags %> 10 | 11 | 12 | 13 | 14 |
15 | <%= yield %> 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/views/layouts/hook.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Programming Life: Gigabase Hook 5 | 6 | 7 | <%= stylesheet_link_tag "application", :media => "all" %> 8 | <%= javascript_include_tag "application" %> 9 | <%= csrf_meta_tags %> 10 | 11 | 12 | 13 | <%= yield %> 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/views/layouts/main.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Programming Life: Gigabase 5 | 6 | 7 | <%= stylesheet_link_tag "application", :media => "all" %> 8 | <%= javascript_include_tag "application" %> 9 | <%= csrf_meta_tags %> 10 | 11 | 12 | 13 | <%= yield %> 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/views/layouts/pdf.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Programming Life: Gigabase PDF 5 | 6 | 7 | <%= wicked_pdf_stylesheet_link_tag "application", :media => "all" %> 8 | <%= javascript_include_tag "application" %> 9 | <%= csrf_meta_tags %> 10 | 11 | 12 | 13 | <%= yield %> 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/views/main/index.html.erb: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 |
6 | <%= render 'actions' %> 7 |
8 | 9 |
10 |
11 | -------------------------------------------------------------------------------- /app/views/module_instances/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= nested_form_for(@module_instance, :html => {:class => "form-horizontal"} ) do |f| %> 2 | <% if @module_instance.errors.any? %> 3 |
4 |

<%= pluralize(@module_instance.errors.count, "error") %>

5 | 6 |
    7 | <% @module_instance.errors.full_messages.each do |msg| %> 8 |
  • <%= msg %>
  • 9 | <% end %> 10 |
11 |
12 | <% end %> 13 | 14 |
15 | <%= f.label :id, :class => "control-label" %> 16 |
17 |
18 | <%= (@module_instance.new_record? ? 'new unique id'.html_safe : @module_instance.id) %> 19 |
20 |
21 |
22 | 23 |
24 | <%= f.label :module_template_id, 'Based on', :class => "control-label" %> 25 |
26 | <%= f.select :module_template_id, ModuleTemplate.all.collect {|x| [ x.name, x.id ] }, {}, :multiple => false, :disabled => !@module_instance.new_record? %> 27 |
28 |
29 | 30 |
31 | <%= f.label :cell_id, 'Part of', :class => "control-label" %> 32 |
33 | <%= f.select :cell_id, Cell.all.collect {|x| [ x.name, x.id ] }, {}, :multiple => false, :disabled => !@module_instance.new_record? %> 34 |
35 |
36 | 37 |
38 | <%= f.label :name, 'Compound name', :class => "control-label" %> 39 |
40 | <%= f.text_field :name %> 41 |
42 |
43 | 44 | <% if (@module_instance.new_record?) %> 45 |
46 |
47 | Save before editing parameters 48 |
49 |
50 | <% else %> 51 |
52 | <%= f.fields_for :module_values do |builder| %> 53 | <%= render "module_value_fields", :f => builder%> 54 | <% end %> 55 |
56 | <% end %> 57 | 58 |
59 | <%= f.submit :class => "btn btn-primary" %> 60 |
61 | <% end %> 62 | -------------------------------------------------------------------------------- /app/views/module_instances/_module_value_fields.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= f.label :value, f.object.module_parameter.key, :class => "control-label" %> 3 |
4 | <%= f.text_field :value %> 5 |
6 |
-------------------------------------------------------------------------------- /app/views/module_instances/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing Module (Instance) #<%= @module_instance.id %>

2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Show', @module_instance %> | 6 | <%= link_to 'Back', module_instances_path %> 7 | -------------------------------------------------------------------------------- /app/views/module_instances/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Listing modules (Instances)

3 |
4 | <% @filters.each { |filter, value| 5 | remove = { } 6 | remove["#{filter}"] = nil 7 | %> 8 |
9 | <%= link_to_self raw('×'), remove , { class: 'close' } %> 10 | <%= filter %> 11 |
12 | <% } %> 13 |
14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | <% @module_instances.each do |module_instance| 30 | 31 | module_template = ModuleTemplate.find( module_instance.module_template_id ) 32 | cell = Cell.find( module_instance.cell_id ) 33 | %> 34 | 35 | 36 | 39 | 42 | 43 | 44 | 47 | 48 | <% end %> 49 | 50 |
IdShowEdit Based on Part ofDestroy
<%= module_instance.id %> 37 | <%= link_to raw(''), module_instance, :class => 'btn btn-small', :title => 'Show' %> 38 | 40 | <%= link_to raw(''), edit_module_instance_path( module_instance ), :class => 'btn btn-small', :title => 'Edit' %> 41 | <%= link_to module_template.name, module_template %><%= link_to cell.name, cell %> 45 | <%= link_to raw(''), module_instance, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-small btn-danger', :title => 'Destroy' %> 46 |
51 | 52 |
53 |
54 | <%= will_paginate %> 55 |
56 |
57 | <%= link_to raw(' New Module (Instance)'), new_module_instance_path, :class => 'btn btn-small btn-primary' %> 58 |
59 |
-------------------------------------------------------------------------------- /app/views/module_instances/new.html.erb: -------------------------------------------------------------------------------- 1 |

New Module (Instance)

2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Back', module_instances_path %> 6 | -------------------------------------------------------------------------------- /app/views/module_instances/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Module (Instance) #<%= @module_instance.id %>

3 | <% if (notice.present?) %> 4 |

<%= notice %>

5 | <% end %> 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
KeyValue
Id<%= @module_instance.id %>
Based on<%= link_to raw(' ' + @module_template.name + ' template'), @module_template, :class => 'btn btn-mini' %> module.<%= @module_template.file %>.js
Part of<%= link_to raw(' ' + @cell.name), @cell, :class => 'btn btn-mini' %>
Compound name<%= @module_instance.name %>
Parameters 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | 45 | 46 | 47 | 48 | <% } %> 49 | 50 |
KeyValue
<%= key %><%= value.nil? ? 'missing'.html_safe : value %>
51 |
Creation<%= @module_instance.created_at.strftime("%a %d %B %Y at %H:%M") %>
Updated<%= (@module_instance.updated_at == @module_instance.created_at ? "Never" : @module_instance.updated_at.strftime("%a %d %B %Y at %H:%M") ) %>
63 | 64 |
65 |
66 | <%= link_to raw(' Edit'), edit_module_instance_path(@module_instance), :class => 'btn btn-primary' %> 67 | <%= link_to raw(' Destroy'), @module_instance, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-danger' %> 68 | <%= link_to 'Back', module_instances_path %> 69 |
70 |
71 | -------------------------------------------------------------------------------- /app/views/module_templates/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= nested_form_for(@module_template, :html => {:class => "form-horizontal"} ) do |f| %> 2 | <% if @module_template.errors.any? %> 3 |
4 |

<%= pluralize(@module_template.errors.count, "error") %>

5 | 6 |
    7 | <% @module_template.errors.full_messages.each do |msg| %> 8 |
  • <%= msg %>
  • 9 | <% end %> 10 |
11 |
12 | <% end %> 13 | 14 |
15 | <%= f.label :id, :class => "control-label" %> 16 |
17 |
18 | <%= (@module_template.new_record? ? 'new unique id'.html_safe : @module_template.id) %> 19 |
20 |
21 |
22 | 23 |
24 | <%= f.label :name, :class => "control-label" %> 25 |
26 | <%= f.text_field :name %> 27 |
28 |
29 | 30 |
31 | <%= f.label :file, :class => "control-label" %> 32 |
33 | <%= f.text_field :file %> 34 |
35 |
36 | 37 |
38 | <%= f.label :javascript_model, :class => "control-label" %> 39 |
40 | <%= f.text_field :javascript_model %> 41 |
42 |
43 | 44 |
45 | <%= f.fields_for :module_parameters do |builder| %> 46 | <%= render "module_parameter_fields", :f => builder %> 47 | <% end %> 48 |
49 | 50 |
51 |
52 | <%= f.link_to_add ' Add Parameter'.html_safe, :module_parameters, :class => 'btn', :data => { :target => "#parameters" } %> 53 |
54 |
55 | 56 |
57 | <%= f.submit :class => "btn btn-primary" %> 58 |
59 | <% end %> 60 | -------------------------------------------------------------------------------- /app/views/module_templates/_module_parameter_fields.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= f.label :key, :class => "control-label" %> 3 |
4 | <%= f.text_field :key %> <%= f.link_to_remove ''.html_safe, :class => 'btn btn-mini btn-danger' %> 5 |
6 |
-------------------------------------------------------------------------------- /app/views/module_templates/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing Module (Template)

2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Show', @module_template %> | 6 | <%= link_to 'Back', module_templates_path %> 7 | -------------------------------------------------------------------------------- /app/views/module_templates/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Listing modules (Templates)

3 |
4 | <% @filters.each { |filter, value| 5 | remove = { } 6 | remove["#{filter}"] = nil 7 | %> 8 |
9 | <%= link_to_self raw('×'), remove , { class: 'close' } %> 10 | <%= filter %> 11 |
12 | <% } %> 13 |
14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | <% @module_templates.each do |module_template| %> 31 | 32 | 33 | 36 | 39 | 40 | 41 | 42 | 43 | 46 | 47 | <% end %> 48 | 49 |
IdShowEditName Used in Derived toDestroy
<%= module_template.id %> 34 | <%= link_to raw(''), module_template, :class => 'btn btn-small', :title => 'Show' %> 35 | 37 | <%= link_to raw(''), edit_module_template_path(module_template), :class => 'btn btn-small', :title => 'Edit' %> 38 | <%= module_template.name %><%= link_to pluralize( ModuleInstance.where( :module_template_id => module_template.id ).map { |c| c.cell_id }.uniq.count, 'cell'), cells_path( :template => module_template.id ) %><%= link_to pluralize( ModuleInstance.where( :module_template_id => module_template.id ).count, 'instance'), module_instances_path( :template => module_template.id ) %> 44 | <%= link_to raw(''), module_template, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-small btn-danger', :title => 'Destroy' %> 45 |
50 | 51 |
52 |
53 | <%= will_paginate %> 54 |
55 |
56 | <%= link_to raw(' New Module (Template)'), new_module_template_path, :class => 'btn btn-small btn-primary' %> 57 |
58 |
-------------------------------------------------------------------------------- /app/views/module_templates/new.html.erb: -------------------------------------------------------------------------------- 1 |

New Module (Template)

2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Back', module_templates_path %> 6 | -------------------------------------------------------------------------------- /app/views/module_templates/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Module (Template) #<%= @module_template.id %>

3 | <% if (notice.present?) %> 4 |

<%= notice %>

5 | <% end %> 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 40 | 41 | 42 | 43 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |
KeyValue
Id<%= @module_template.id %>
Name<%= @module_template.name %>
File<%= link_to "module.#{@module_template.file}.js", asset_path( "models/module.#{@module_template.file}.js"), :class => 'btn btn-info btn-mini' + ( @module_template.file.nil? ? ' disabled' : '' ) %>
Parameters 31 | <% 32 | parameters = [] 33 | @module_parameters.each do |module_parameter| 34 | parameters.push module_parameter.key 35 | end 36 | %> 37 | 38 | <%= listify parameters %> 39 |
Instances 44 | 45 | <% 46 | instances = [] 47 | @module_instances_page.each do |module_instance| 48 | instances.push link_to '#' + module_instance.id.to_s, module_instance, :class => 'btn btn-mini' 49 | end 50 | %> 51 | <%= (listify instances).html_safe %> 52 | <%= will_paginate @module_instances_page %> 53 |
Creation<%= @module_template.created_at.strftime("%a %d %B %Y at %H:%M") %>
Updated<%= (@module_template.updated_at == @module_template.created_at ? "Never" : @module_template.updated_at.strftime("%a %d %B %Y at %H:%M") ) %>
65 | 66 |
67 | 71 |
72 | <%= link_to raw(' Edit'), edit_module_template_path(@module_template), :class => 'btn btn-primary' %> 73 | <%= link_to raw(' Destroy'), @module_template, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-danger' %> 74 | <%= link_to 'Back', module_templates_path %> 75 |
76 |
-------------------------------------------------------------------------------- /app/views/reports/_cell.html.erb: -------------------------------------------------------------------------------- 1 | <% if @isPDF %> 2 | "> 3 | <% else %> 4 | 5 |
6 |
7 | <% end %> -------------------------------------------------------------------------------- /app/views/reports/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= nested_form_for(@report, :html => {:class => "form-horizontal"} ) do |f| %> 2 | <% if @report.errors.any? %> 3 |
4 |

<%= pluralize(@report.errors.count, "error") %>

5 | 6 |
    7 | <% @report.errors.full_messages.each do |msg| %> 8 |
  • <%= msg %>
  • 9 | <% end %> 10 |
11 |
12 | <% end %> 13 | 14 |
15 | <%= f.label :id, :class => "control-label" %> 16 |
17 |
18 | <%= (@report.new_record? ? 'new unique id'.html_safe : @report.id) %> 19 |
20 |
21 |
22 | 23 |
24 | <%= f.label :cell_id, 'Reports on', :class => "control-label" %> 25 |
26 | <%= f.select :cell_id, Cell.all.collect {|x| [ x.name, x.id ] }, {}, :multiple => false, :disabled => !@report.new_record? %> 27 |
28 |
29 | 30 |
31 | <%= f.submit :class => "btn btn-primary" %> 32 |
33 | <% end %> 34 | -------------------------------------------------------------------------------- /app/views/reports/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Listing reports

3 |
4 | <% @filters.each { |filter, value| 5 | remove = { } 6 | remove["#{filter}"] = nil 7 | %> 8 |
9 | <%= link_to_self raw('×'), remove , { class: 'close' } %> 10 | <%= filter %> 11 |
12 | <% } if !@filters.nil? %> 13 |
14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | <% @reports.each do |report| %> 26 | 27 | 28 | 31 | 32 | 33 | 36 | 37 | <% end %> 38 | 39 |
IdShowCellCreatedDestroy
<%= report.id %> 29 | <%= link_to raw(''), report, :class => 'btn btn-small', :title => 'Show' %> 30 | #<%= report.cell_id %> <%= link_to report.cell.name, report.cell %><%= report.created_at.strftime("%a %d %B %Y at %H:%M") %> 34 | <%= link_to raw(''), report, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-small btn-danger', :title => 'Destroy' %> 35 |
40 | 41 |
42 |
43 | <%= will_paginate %> 44 |
45 |
46 | <%= link_to raw(' New Report'), new_report_path, :class => 'btn btn-small btn-primary' %> 47 |
48 |
-------------------------------------------------------------------------------- /app/views/reports/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

New report

3 |
4 | 5 | <%= render 'form' %> 6 | 7 | <%= link_to 'Back', reports_path %> 8 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run ProgrammingLife::Application 5 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 7 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | development: 7 | adapter: postgresql 8 | database: life_development 9 | pool: 5 10 | username: life 11 | password: life 12 | 13 | # Warning: The database defined as "test" will be erased and 14 | # re-generated from your development database when you run "rake". 15 | # Do not set this db to the same as development or production. 16 | test: 17 | adapter: postgresql 18 | database: life_test 19 | timeout: 5000 20 | username: life 21 | password: life 22 | 23 | production: 24 | adapter: postgresql 25 | database: life_production 26 | timeout: 5000 27 | username: life 28 | password: life 29 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | ProgrammingLife::Application.initialize! 6 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | ProgrammingLife::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger 20 | config.active_support.deprecation = :log 21 | 22 | # Only use best-standards-support built into browsers 23 | config.action_dispatch.best_standards_support = :builtin 24 | 25 | # Raise exception on mass assignment protection for Active Record models 26 | config.active_record.mass_assignment_sanitizer = :strict 27 | 28 | # Log the query plan for queries taking more than this (works 29 | # with SQLite, MySQL, and PostgreSQL) 30 | config.active_record.auto_explain_threshold_in_seconds = 0.5 31 | 32 | # Do not compress assets 33 | config.assets.compress = false 34 | config.assets.js_compressor = false #Uglifier.new( :output => { :beautify => true }, :mangle => false ) 35 | config.assets.css_compressor = false 36 | 37 | # Expands the lines which load the assets 38 | config.assets.debug = true 39 | end 40 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | ProgrammingLife::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Configure static asset server for tests with Cache-Control for performance 11 | config.serve_static_assets = true 12 | config.static_cache_control = "public, max-age=3600" 13 | 14 | # Log error messages when you accidentally call methods on nil 15 | config.whiny_nils = true 16 | 17 | # Show full error reports and disable caching 18 | config.consider_all_requests_local = true 19 | config.action_controller.perform_caching = false 20 | 21 | # Raise exceptions instead of rendering exception templates 22 | config.action_dispatch.show_exceptions = false 23 | 24 | # Disable request forgery protection in test environment 25 | config.action_controller.allow_forgery_protection = false 26 | 27 | # Tell Action Mailer not to deliver emails to the real world. 28 | # The :test delivery method accumulates sent emails in the 29 | # ActionMailer::Base.deliveries array. 30 | config.action_mailer.delivery_method = :test 31 | 32 | # Raise exception on mass assignment protection for Active Record models 33 | config.active_record.mass_assignment_sanitizer = :strict 34 | 35 | # Print deprecation notices to the stderr 36 | config.active_support.deprecation = :stderr 37 | end 38 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | # 12 | # These inflection rules are supported but not enabled by default: 13 | # ActiveSupport::Inflector.inflections do |inflect| 14 | # inflect.acronym 'RESTful' 15 | # end 16 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | 7 | # Add the cache manifest type 8 | Mime::Type.register "text/cache-manifest", :manifest 9 | Mime::Type.register "text/cache-manifest", :appcache -------------------------------------------------------------------------------- /config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | ProgrammingLife::Application.config.secret_token = '8f4aba4b7872d73c1d1ab83f3de5b83fc0836aac0b2da21b2ab432d60c03cb3efedd8394cfeae7a34d422a145e091675fd2f4bd4da44cd3771f5245696d747d9' 8 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | ProgrammingLife::Application.config.session_store :cookie_store, key: '_programming-life_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # ProgrammingLife::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /config/initializers/wicked_pdf.rb: -------------------------------------------------------------------------------- 1 | WickedPdf.config = { 2 | :exe_path => '/usr/local/bin/wkhtmltopdf', 3 | :layout => 'pdf.html' 4 | } 5 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /db/migrate/20130505231415_create_cells.rb: -------------------------------------------------------------------------------- 1 | class CreateCells < ActiveRecord::Migration 2 | def change 3 | create_table :cells do |t| 4 | t.string :name 5 | t.integer :id 6 | 7 | t.timestamps 8 | end 9 | add_index :cells, :id, :unique => true 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20130505233228_create_module_templates.rb: -------------------------------------------------------------------------------- 1 | class CreateModuleTemplates < ActiveRecord::Migration 2 | def change 3 | create_table :module_templates do |t| 4 | t.integer :id 5 | t.timestamps 6 | end 7 | add_index :module_templates, :id, :unique => true 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20130505233612_create_module_instances.rb: -------------------------------------------------------------------------------- 1 | class CreateModuleInstances < ActiveRecord::Migration 2 | def change 3 | create_table :module_instances do |t| 4 | t.integer :id 5 | t.timestamps 6 | end 7 | add_index :module_instances, :id, :unique => true 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20130505234453_create_module_parameters.rb: -------------------------------------------------------------------------------- 1 | class CreateModuleParameters < ActiveRecord::Migration 2 | def change 3 | create_table :module_parameters do |t| 4 | t.integer :id 5 | t.string :key 6 | 7 | t.timestamps 8 | end 9 | add_index :module_parameters, :id, :unique => true 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20130505235132_create_module_values.rb: -------------------------------------------------------------------------------- 1 | class CreateModuleValues < ActiveRecord::Migration 2 | def change 3 | create_table :module_values do |t| 4 | t.float :value 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20130506000950_add_name_to_module_templates.rb: -------------------------------------------------------------------------------- 1 | class AddNameToModuleTemplates < ActiveRecord::Migration 2 | def change 3 | add_column :module_templates, :name, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20130506023516_add_foreign_keys_module_instance.rb: -------------------------------------------------------------------------------- 1 | class AddForeignKeysModuleInstance < ActiveRecord::Migration 2 | def change 3 | add_column :module_instances, :module_template_id, :integer 4 | add_column :module_instances, :cell_id, :integer 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20130506023549_add_foreign_keys_module_parameter.rb: -------------------------------------------------------------------------------- 1 | class AddForeignKeysModuleParameter < ActiveRecord::Migration 2 | def change 3 | add_column :module_parameters, :module_template_id, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20130506023614_add_foreign_keys_module_value.rb: -------------------------------------------------------------------------------- 1 | class AddForeignKeysModuleValue < ActiveRecord::Migration 2 | def change 3 | add_column :module_values, :module_parameter_id, :integer 4 | add_column :module_values, :module_instance_id, :integer 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20130506174008_change_module_value_type_to_string.rb: -------------------------------------------------------------------------------- 1 | class ChangeModuleValueTypeToString < ActiveRecord::Migration 2 | def up 3 | change_column :module_values, :value, :string 4 | end 5 | 6 | def down 7 | change_column :module_values, :value, :float 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20130506205936_add_step_to_module_template.rb: -------------------------------------------------------------------------------- 1 | class AddStepToModuleTemplate < ActiveRecord::Migration 2 | def change 3 | add_column :module_templates, :step, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20130506210523_add_file_to_module_template.rb: -------------------------------------------------------------------------------- 1 | class AddFileToModuleTemplate < ActiveRecord::Migration 2 | def change 3 | add_column :module_templates, :file, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20130508155940_add_javascript_model_to_module_template.rb: -------------------------------------------------------------------------------- 1 | class AddJavascriptModelToModuleTemplate < ActiveRecord::Migration 2 | def change 3 | add_column :module_templates, :javascript_model, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20130508160008_add_start_amount_to_module_instance.rb: -------------------------------------------------------------------------------- 1 | class AddStartAmountToModuleInstance < ActiveRecord::Migration 2 | def change 3 | add_column :module_instances, :amount, :float 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20130509005755_create_reports.rb: -------------------------------------------------------------------------------- 1 | class CreateReports < ActiveRecord::Migration 2 | def change 3 | create_table :reports do |t| 4 | t.integer :id 5 | t.integer :cell_id 6 | 7 | t.timestamps 8 | end 9 | add_index :reports, :id, :unique => true 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20130509041842_change_module_value_type_to_string2.rb: -------------------------------------------------------------------------------- 1 | class ChangeModuleValueTypeToString2 < ActiveRecord::Migration 2 | def up 3 | change_column :module_values, :value, :text 4 | end 5 | 6 | def down 7 | change_column :module_values, :value, :string 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20130510215435_add_name_to_module_instance.rb: -------------------------------------------------------------------------------- 1 | class AddNameToModuleInstance < ActiveRecord::Migration 2 | def change 3 | add_column :module_instances, :name, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20130510222748_remove_module_template_from_module_template.rb: -------------------------------------------------------------------------------- 1 | class RemoveModuleTemplateFromModuleTemplate < ActiveRecord::Migration 2 | def up 3 | #remove_column :module_templates, :module_template 4 | end 5 | 6 | def down 7 | add_column :module_templates, :module_template, :string 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended to check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(:version => 20130510222748) do 15 | 16 | create_table "cells", :force => true do |t| 17 | t.string "name" 18 | t.datetime "created_at", :null => false 19 | t.datetime "updated_at", :null => false 20 | end 21 | 22 | add_index "cells", ["id"], :name => "index_cells_on_id", :unique => true 23 | 24 | create_table "module_instances", :force => true do |t| 25 | t.datetime "created_at", :null => false 26 | t.datetime "updated_at", :null => false 27 | t.integer "module_template_id" 28 | t.integer "cell_id" 29 | t.float "amount" 30 | t.string "name" 31 | end 32 | 33 | add_index "module_instances", ["id"], :name => "index_module_instances_on_id", :unique => true 34 | 35 | create_table "module_parameters", :force => true do |t| 36 | t.string "key" 37 | t.datetime "created_at", :null => false 38 | t.datetime "updated_at", :null => false 39 | t.integer "module_template_id" 40 | end 41 | 42 | add_index "module_parameters", ["id"], :name => "index_module_parameters_on_id", :unique => true 43 | 44 | create_table "module_templates", :force => true do |t| 45 | t.datetime "created_at", :null => false 46 | t.datetime "updated_at", :null => false 47 | t.string "name" 48 | t.text "step" 49 | t.string "file" 50 | t.string "javascript_model" 51 | end 52 | 53 | add_index "module_templates", ["id"], :name => "index_module_templates_on_id", :unique => true 54 | 55 | create_table "module_values", :force => true do |t| 56 | t.text "value" 57 | t.datetime "created_at", :null => false 58 | t.datetime "updated_at", :null => false 59 | t.integer "module_parameter_id" 60 | t.integer "module_instance_id" 61 | end 62 | 63 | create_table "reports", :force => true do |t| 64 | t.integer "cell_id" 65 | t.datetime "created_at", :null => false 66 | t.datetime "updated_at", :null => false 67 | end 68 | 69 | add_index "reports", ["id"], :name => "index_reports_on_id", :unique => true 70 | 71 | end 72 | -------------------------------------------------------------------------------- /doc/client/assets/search_data.js: -------------------------------------------------------------------------------- 1 | window.searchData = [{"t":"Module","p":"classes/Module.html"},{"t":"#constructor","h":"Module","p":"classes/Module.html#constructor-instance"},{"t":"Module.js.coffee","p":"files/app/assets/javascripts/Module.js.coffee.html"},{"t":"README.md","p":"README.md.html"}] -------------------------------------------------------------------------------- /doc/client/class_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CoffeeScript API Documentation 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Class List

13 | 19 | 23 |
    24 |
  • 25 | Module 26 | 27 | 28 | 29 |
  • 30 |
31 | 32 |
33 | 34 | -------------------------------------------------------------------------------- /doc/client/extra_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CoffeeScript API Documentation 6 | 7 | 8 | 9 | 10 | 11 |
12 |

File List

13 | 19 | 23 | 28 |
29 | 30 | -------------------------------------------------------------------------------- /doc/client/file_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CoffeeScript API Documentation 6 | 7 | 8 | 9 | 10 | 11 |
12 |

File List

13 | 19 | 23 |
    24 |
  • 25 | 26 | app 27 | 28 |
  • 29 |
      30 |
    • 31 | 32 | assets 33 | 34 |
    • 35 |
        36 |
      • 37 | 38 | javascripts 39 | 40 |
      • 41 | 49 | 50 |
      51 | 52 |
    53 | 54 |
55 | 56 |
57 | 58 | -------------------------------------------------------------------------------- /doc/client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CoffeeScript API Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /doc/client/method_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CoffeeScript API Documentation 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Method List

13 | 19 | 23 |
    24 |
25 |
26 | 27 | -------------------------------------------------------------------------------- /doc/client/mixin_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CoffeeScript API Documentation 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Mixin List

13 | 19 | 23 |
    24 |
25 | 26 |
27 | 28 | -------------------------------------------------------------------------------- /doc/extra_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CoffeeScript API Documentation 6 | 7 | 8 | 9 | 10 | 11 |
12 |

File List

13 | 20 | 24 | 29 |
30 | 31 | -------------------------------------------------------------------------------- /doc/file_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CoffeeScript API Documentation 6 | 7 | 8 | 9 | 10 | 11 |
12 |

File List

13 | 20 | 24 |
    25 |
  • 26 | 27 | app 28 | 29 |
  • 30 |
      31 |
    • 32 | 33 | assets 34 | 35 |
    • 36 |
        37 |
      • 38 | 39 | javascripts 40 | 41 |
      • 42 | 56 | 57 |
      58 | 59 |
    60 | 61 |
62 | 63 |
64 | 65 | -------------------------------------------------------------------------------- /doc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CoffeeScript API Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /doc/mixin_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CoffeeScript API Documentation 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Mixin List

13 | 20 | 24 |
    25 |
  • 26 | 27 | Mixin 28 | 29 | 30 | 31 | 32 |
  • 33 | 59 | 60 |
61 | 62 |
63 | 64 | -------------------------------------------------------------------------------- /doc/server/images/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/add.png -------------------------------------------------------------------------------- /doc/server/images/arrow_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/arrow_up.png -------------------------------------------------------------------------------- /doc/server/images/brick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/brick.png -------------------------------------------------------------------------------- /doc/server/images/brick_link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/brick_link.png -------------------------------------------------------------------------------- /doc/server/images/bug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/bug.png -------------------------------------------------------------------------------- /doc/server/images/bullet_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/bullet_black.png -------------------------------------------------------------------------------- /doc/server/images/bullet_toggle_minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/bullet_toggle_minus.png -------------------------------------------------------------------------------- /doc/server/images/bullet_toggle_plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/bullet_toggle_plus.png -------------------------------------------------------------------------------- /doc/server/images/date.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/date.png -------------------------------------------------------------------------------- /doc/server/images/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/delete.png -------------------------------------------------------------------------------- /doc/server/images/find.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/find.png -------------------------------------------------------------------------------- /doc/server/images/loadingAnimation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/loadingAnimation.gif -------------------------------------------------------------------------------- /doc/server/images/macFFBgHack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/macFFBgHack.png -------------------------------------------------------------------------------- /doc/server/images/package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/package.png -------------------------------------------------------------------------------- /doc/server/images/page_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/page_green.png -------------------------------------------------------------------------------- /doc/server/images/page_white_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/page_white_text.png -------------------------------------------------------------------------------- /doc/server/images/page_white_width.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/page_white_width.png -------------------------------------------------------------------------------- /doc/server/images/plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/plugin.png -------------------------------------------------------------------------------- /doc/server/images/ruby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/ruby.png -------------------------------------------------------------------------------- /doc/server/images/tag_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/tag_blue.png -------------------------------------------------------------------------------- /doc/server/images/tag_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/tag_green.png -------------------------------------------------------------------------------- /doc/server/images/transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/transparent.png -------------------------------------------------------------------------------- /doc/server/images/wrench.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/wrench.png -------------------------------------------------------------------------------- /doc/server/images/wrench_orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/wrench_orange.png -------------------------------------------------------------------------------- /doc/server/images/zoom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/doc/server/images/zoom.png -------------------------------------------------------------------------------- /doc/server/js/search.js: -------------------------------------------------------------------------------- 1 | Search = function(data, input, result) { 2 | this.data = data; 3 | this.$input = $(input); 4 | this.$result = $(result); 5 | 6 | this.$current = null; 7 | this.$view = this.$result.parent(); 8 | this.searcher = new Searcher(data.index); 9 | this.init(); 10 | } 11 | 12 | Search.prototype = $.extend({}, Navigation, new function() { 13 | var suid = 1; 14 | 15 | this.init = function() { 16 | var _this = this; 17 | var observer = function() { 18 | _this.search(_this.$input[0].value); 19 | }; 20 | this.$input.keyup(observer); 21 | this.$input.click(observer); // mac's clear field 22 | 23 | this.searcher.ready(function(results, isLast) { 24 | _this.addResults(results, isLast); 25 | }) 26 | 27 | this.initNavigation(); 28 | this.setNavigationActive(false); 29 | } 30 | 31 | this.search = function(value, selectFirstMatch) { 32 | value = jQuery.trim(value).toLowerCase(); 33 | if (value) { 34 | this.setNavigationActive(true); 35 | } else { 36 | this.setNavigationActive(false); 37 | } 38 | 39 | if (value == '') { 40 | this.lastQuery = value; 41 | this.$result.empty(); 42 | this.setNavigationActive(false); 43 | } else if (value != this.lastQuery) { 44 | this.lastQuery = value; 45 | this.firstRun = true; 46 | this.searcher.find(value); 47 | } 48 | } 49 | 50 | this.addResults = function(results, isLast) { 51 | var target = this.$result.get(0); 52 | if (this.firstRun && (results.length > 0 || isLast)) { 53 | this.$current = null; 54 | this.$result.empty(); 55 | } 56 | 57 | for (var i=0, l = results.length; i < l; i++) { 58 | target.appendChild(this.renderItem.call(this, results[i])); 59 | }; 60 | 61 | if (this.firstRun && results.length > 0) { 62 | this.firstRun = false; 63 | this.$current = $(target.firstChild); 64 | this.$current.addClass('current'); 65 | } 66 | if (jQuery.browser.msie) this.$element[0].className += ''; 67 | } 68 | 69 | this.move = function(isDown) { 70 | if (!this.$current) return; 71 | var $next = this.$current[isDown ? 'next' : 'prev'](); 72 | if ($next.length) { 73 | this.$current.removeClass('current'); 74 | $next.addClass('current'); 75 | this.scrollIntoView($next[0], this.$view[0]); 76 | this.$current = $next; 77 | } 78 | return true; 79 | } 80 | 81 | this.hlt = function(html) { 82 | return this.escapeHTML(html). 83 | replace(/\u0001/g, ''). 84 | replace(/\u0002/g, ''); 85 | } 86 | 87 | this.escapeHTML = function(html) { 88 | return html.replace(/[&<>]/g, function(c) { 89 | return '&#' + c.charCodeAt(0) + ';'; 90 | }); 91 | } 92 | 93 | }); 94 | 95 | -------------------------------------------------------------------------------- /docs/deliverables/cts/DJ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/cts/DJ.png -------------------------------------------------------------------------------- /docs/deliverables/cts/SS.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/cts/SS.jpeg -------------------------------------------------------------------------------- /docs/deliverables/cts/TP.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/cts/TP.jpeg -------------------------------------------------------------------------------- /docs/deliverables/cts/VR.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/cts/VR.jpeg -------------------------------------------------------------------------------- /docs/deliverables/cts/Yoloost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/cts/Yoloost.png -------------------------------------------------------------------------------- /docs/deliverables/ead/EAD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/ead/EAD.png -------------------------------------------------------------------------------- /docs/deliverables/ead/Emergent Architectural Design.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/ead/Emergent Architectural Design.fnt -------------------------------------------------------------------------------- /docs/deliverables/ead/Emergent Architectural Design.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/ead/Emergent Architectural Design.pdf -------------------------------------------------------------------------------- /docs/deliverables/ead/SequenceDiagramLife.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/ead/SequenceDiagramLife.png -------------------------------------------------------------------------------- /docs/deliverables/ead/cell_struct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/ead/cell_struct.png -------------------------------------------------------------------------------- /docs/deliverables/ead/class.vsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/ead/class.vsd -------------------------------------------------------------------------------- /docs/deliverables/ead/controllers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/ead/controllers.png -------------------------------------------------------------------------------- /docs/deliverables/ead/erd.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/ead/erd.pdf -------------------------------------------------------------------------------- /docs/deliverables/ead/helpers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/ead/helpers.png -------------------------------------------------------------------------------- /docs/deliverables/ead/main_struct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/ead/main_struct.png -------------------------------------------------------------------------------- /docs/deliverables/ead/models.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/ead/models.png -------------------------------------------------------------------------------- /docs/deliverables/ead/the-virtual-cell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/ead/the-virtual-cell.png -------------------------------------------------------------------------------- /docs/deliverables/ead/views.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/ead/views.png -------------------------------------------------------------------------------- /docs/deliverables/final-report/personal-reflection-joost.tex: -------------------------------------------------------------------------------- 1 | Let me start off by being honest and admitting that my opinion of this particular context and the assignment was not especially high. I always like to build something that will or could actually be used. The game context would have provided me with a project to create something like that, and for that I listed it as my first choice. The Programming Life context didn’t seem to offer such a chance. However, I still had my reasons for listing this context as my second choice. I find the scientific field of microbiology a very interesting one, even though I never took biology in high school beyond the 3rd grade. \\ 2 | 3 | Also, before being enrolled into a particular context, I had the desire to step away from the web for a change. I have built websites for a living and I wanted a ‘change of scenery’, and I believe that was the case for more members of the team. Interestingly enough, in the first meetings the team held we decided that we were going to build a web app. To keep the assignment a challenge, we decided we decided we would get our kicks by using platforms, tools and languages we hadn’t used before. And that was a blessing. \\ 4 | 5 | The best discovery for me is the language CoffeeScript. It’s an object-oriented, Ruby inspired language that is converted - by the server - into JavaScript which can be run in a normal web browser. It was able to turn my dislike of developing for the web around and made me find again the fun that I have when I really enjoy what I’m doing. Throughout the project I found that the more I understood CoffeeScript, the more fun I had and the more time and effort I put into the project. \\ 6 | 7 | Besides the new tools, this was the first time I - and I believe any of our team - have actually employed the Scrum workflow. It’s a very nice way to do your project planning, although we didn’t put all the effort into it to follow the process it by the letter. We didn’t assign a designated Scrum master but instead rotated the roles so all team members would gain some experience into this process. Also, we didn’t maintain the sprint log an backlog as well as we could have. Estimations for sprint log items also gained a lot of accuracy through the sprints. \\ 8 | 9 | I realize during the project I have grown as a software developer and as a team member. The team was awesome: we were all eager to learn new things, not afraid to ask questions and clever enough to develop out-of-the-box solutions. I’ve also learnt a lot about the context: the provided seminars provided me with a lot of food for thought and have inspired many hours of browsing and clicking through Wikipedia in the hunt for more knowledge. Nature works in incredible ways, and the basic knowledge provided in the seminars have enabled me to further grasp some of the intriguing details. 10 | -------------------------------------------------------------------------------- /docs/deliverables/final-report/personal-reflection-steffan.tex: -------------------------------------------------------------------------------- 1 | This project was really a great part of my life during the past half year. Because I had already completed most lab assignments of the second year courses, I had a lot of time to spare to work on the application. This resulted in many longs nights of debugging, refactoring and more debugging, most of the times along with one or more of my fellow group members. For me, this was basically a fun way to spend my time, because the group is one of the greatest groups I have ever worked with, and their dedication and motivation motivated me to return that favor, creating an in my opinion allround positive experience.\\ 2 | 3 | The context of the project didn't invoke much of a reaction in me at first, mostly because I've never worked much in any area to do with Biology, but the title of the project and the idea of `Programing Life', actually influencing life by programming, did and still does sound quite cool. It's made me wonder about the possibilities that exist with the technoligies we have used and contributed to, and I think I would enjoy a career in Bioinformatics, even though it would never have guessed it would be one of my choices to begin with.\\ 4 | 5 | One peculiar side effect that working on the project seemed to cause, was that I would find myself going to sleep with my head full of ideas on how to create new functionalities for the application or just ideas about cool software in general. This of course threw me into an upwards spiral of spending time working on the project, becoming more excited and as such spending even more time on the project. Overall I think this was a first for me, because usually in projects I get excited about it, but not this much.\\ 6 | 7 | Another effect of the project was that suddenly everything even remotely related to bacterias or cells or products reminded me of our application, resulting in me showing and explaining what we had been working on recently to anybody fortunate enough to share in the conversation. All that explaining made me understand the context of the project better, making my interests in Biology and especially Bioinformatics grow.\\ 8 | 9 | All in all, I have had a great time the past weeks, and I attribute that mostly the project. I learned a lot of new things and I had a lot of fun doing it, not to mention that in my opinion the end result was worth every bit of time put into it. I think it ultimately made me a better programmer and someone who is a little more informed on the inner workings of cells than most people. 10 | -------------------------------------------------------------------------------- /docs/deliverables/final-report/personal-reflection-tung.tex: -------------------------------------------------------------------------------- 1 | Before the project began, I had no idea what would be in store for me. I didn't know what bioinformatics was and, to be fair, it wasn't my first choice either. But I have zero regrets, as I've rediscovered my love for informatics and learned to view it from a different perspective. Thanks to the project, bioinformatics is also something I'll take into account when I'm choosing a master.\\ 2 | 3 | The project taught me my limitations of an undergraduate, as my skills were more on the lacking side that I hoped. And that's okay. I learned to take stuff at my own pace, instead of constantly comparing my capabilities to others. That also reassures me that computer science is still the future for me, as for the past year, I had serious doubts about my choice and skills. I considered it a race, and I was losing it. I was constantly being amazed by other programmers my age, how they were completely out of my league and doubted my future. Due to help from a few team members, I finally realised, even though it sounds obvious, that I'm going to college for my own good. Not for my family, friends or future boss, but for myself. They reached this level of skill by dedication and hard work and not by some funny whim of nature, it's just that some people are quicker on the uptake than others and I'm fine with it.\\ 4 | 5 | After experiencing what bioinformatics can do, I've been curious about the application of informatics in the world, combining different fields and forming a whole new field.\\ 6 | 7 | As we worked with a whole new language in this project, I've learned to work outside my comfort zone, getting used to the new tools and developing environment. It has also urged me to learn more about said language, Ruby (on Rails), and this project made me want to work on personal projects in this language too.\\ 8 | 9 | Lastly, this project has been a confirmation for what I want to do later in life as a computer scientist. I definitely belong in the higher level group of computer scientists: focussing more on developing software than, for example, optimising the programming languages. One of the things I want do to is to be able to develop software to help other fields effectively accomplish their goals. 10 | -------------------------------------------------------------------------------- /docs/deliverables/final-report/teamwork.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/final-report/teamwork.txt -------------------------------------------------------------------------------- /docs/deliverables/img/DJ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/img/DJ.png -------------------------------------------------------------------------------- /docs/deliverables/img/SS.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/img/SS.jpeg -------------------------------------------------------------------------------- /docs/deliverables/img/TP.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/img/TP.jpeg -------------------------------------------------------------------------------- /docs/deliverables/img/VR.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/img/VR.jpeg -------------------------------------------------------------------------------- /docs/deliverables/img/Yoloost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/img/Yoloost.png -------------------------------------------------------------------------------- /docs/deliverables/product-vision/Draft product vision.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/product-vision/Draft product vision.docx -------------------------------------------------------------------------------- /docs/deliverables/product-vision/Initial product vision.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/product-vision/Initial product vision.docx -------------------------------------------------------------------------------- /docs/deliverables/product-vision/Roadmap-template.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/product-vision/Roadmap-template.vsdx -------------------------------------------------------------------------------- /docs/deliverables/product-vision/Roadmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/product-vision/Roadmap.jpg -------------------------------------------------------------------------------- /docs/deliverables/product-vision/Roadmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/product-vision/Roadmap.png -------------------------------------------------------------------------------- /docs/deliverables/product-vision/Roadmap.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/product-vision/Roadmap.vsdx -------------------------------------------------------------------------------- /docs/deliverables/product-vision/mockup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/product-vision/mockup.jpg -------------------------------------------------------------------------------- /docs/deliverables/summaries/Seminar 1/Programming Life 1.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/deliverables/summaries/Seminar 1/Programming Life 1.docx -------------------------------------------------------------------------------- /docs/deliverables/template/template.tex: -------------------------------------------------------------------------------- 1 | \documentclass[10pt,a4paper]{report} 2 | 3 | \usepackage[utf8]{inputenc} 4 | \usepackage{amsmath} 5 | \usepackage{amsfonts} 6 | \usepackage{amssymb} 7 | \usepackage{graphicx} 8 | \usepackage{hyperref} 9 | \usepackage[left=2cm,right=2cm,top=2cm,bottom=2cm]{geometry} 10 | 11 | \title{Title} 12 | \author{Programming Life group 2\\ 13 | \begin{tabular}{c c c} 14 | \hline 15 | Derk-Jan Karrenbeld & 4021967 & \includegraphics[scale=0.2]{../img/DJ.png}\\ 16 | Joost Verdoorn & 1545396 & \includegraphics[scale=0.2]{../img/Yoloost.png}\\ 17 | Steffan Sluis & 4088816 & \includegraphics[scale=0.2]{../img/SS.jpeg}\\ 18 | Tung Phan & 4004868 & \includegraphics[scale=0.2]{../img/TP.jpeg}\\ 19 | Vincent Robbemond & 4174097 & \includegraphics[scale=0.2]{../img/VR.jpeg}\\ 20 | \hline 21 | \end{tabular} 22 | } 23 | \date{\today} 24 | 25 | \begin{document} 26 | \maketitle 27 | 28 | \setcounter{section}{0} 29 | \setcounter{secnumdepth}{3} 30 | \setcounter{tocdepth}{5} 31 | \renewcommand*\thesection{\arabic{section}} 32 | 33 | \pdfbookmark{\contentsname}{toc} 34 | \tableofcontents 35 | 36 | \clearpage 37 | 38 | \section{Introduction} 39 | This is a template that can be used for all Context Project deliverables, unless explicitly stated they shouldn't be in this layout. 40 | \section{Template usage} 41 | Please use proper indentation (tabs, not spaces) and preferably use the sectioning commands used in this document. 42 | \subsection{Example} 43 | \subsubsection{More example} 44 | \paragraph{Eeeeexapmle} 45 | \subparagraph{Heading} 46 | You really shouldn't add subsections if the supersection doesn't contain any text and/or only one subsection. 47 | \section{Language} 48 | English. Also, formal. Also, using the word 'we' or 'us' or anything similar is bad practice, because it's not formal. Just saying. 49 | \section{Conclusion} 50 | That's it. 51 | 52 | \end{document} 53 | -------------------------------------------------------------------------------- /docs/onduidelijkheden.txt: -------------------------------------------------------------------------------- 1 | Moet er bij de synthese van lipide/proteine 1 of meer substraten worden geconsumeerd? 2 | Wanneer deelt de cel? 3 | Moeten we van tijdstip 0 tot de tijdstip van celdeling simuleren? 4 | -------------------------------------------------------------------------------- /docs/planning samenvatten.txt: -------------------------------------------------------------------------------- 1 | | Samenvatters 2 | ----------------------------- 3 | College 2 | DJ, Tung 4 | ----------------------------- 5 | College 3 | Vincent, Steffan 6 | ----------------------------- 7 | College 4 | Joost, DJ 8 | ----------------------------- 9 | College 5 | Tung, Vincent 10 | -------------------------------------------------------------------------------- /docs/resources/Programming life 1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/resources/Programming life 1.pdf -------------------------------------------------------------------------------- /docs/resources/Programming life 2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/docs/resources/Programming life 2.pdf -------------------------------------------------------------------------------- /lib/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/lib/assets/.gitkeep -------------------------------------------------------------------------------- /lib/tasks/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/lib/tasks/.gitkeep -------------------------------------------------------------------------------- /log.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/log.txt -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The page you were looking for doesn't exist.

23 |

You may have mistyped the address or the page may have moved.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was rejected.

23 |

Maybe you tried to change something you didn't have access to.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

We're sorry, but something went wrong.

23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/public/favicon.ico -------------------------------------------------------------------------------- /public/img/cellgrowth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/public/img/cellgrowth.png -------------------------------------------------------------------------------- /public/img/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/public/img/cursor.png -------------------------------------------------------------------------------- /public/img/dna.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/public/img/dna.png -------------------------------------------------------------------------------- /public/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/public/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /public/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/public/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /public/img/icon-chevron-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/public/img/icon-chevron-left.png -------------------------------------------------------------------------------- /public/img/icon-chevron-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/public/img/icon-chevron-right.png -------------------------------------------------------------------------------- /public/img/lipid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/public/img/lipid.png -------------------------------------------------------------------------------- /public/img/protein.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/public/img/protein.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby.exe 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /spec/javascripts/controller_specs/__spec.js: -------------------------------------------------------------------------------- 1 | describe("Base", function() { 2 | var controller, view; 3 | var dummy = function() {}; 4 | dummy.prototype.kill = jasmine.createSpy( 'kill' ); 5 | 6 | beforeEach( function() { 7 | view = new dummy(); 8 | controller = new Controller.Base( view ); 9 | spyOn( controller, 'kill' ).andCallThrough(); 10 | }); 11 | 12 | describe("when initialized", function() { 13 | 14 | it("should contain the view", function() { 15 | expect( controller.view ).toBe( view ); 16 | }); 17 | 18 | it("should have no children", function() { 19 | expect( controller.controllers() ).toMatch( {} ); 20 | }); 21 | 22 | }); 23 | 24 | describe("when child is added", function() { 25 | 26 | var child = new dummy(); 27 | beforeEach( function() { 28 | controller.addChild( 'dummy', child ); 29 | }); 30 | 31 | it("should contain the child", function() { 32 | expect( controller.controller('dummy') ).toBe( child ); 33 | }); 34 | 35 | describe("when child is removed", function() { 36 | 37 | beforeEach( function() { 38 | controller.removeChild( 'dummy' ); 39 | }); 40 | 41 | it("should not contain the child", function() { 42 | expect( controller.controller('dummy') ).not.toBeDefined( ); 43 | }); 44 | 45 | it("should have killed the child", function() { 46 | expect( child.kill.callCount ).toBeGreaterThan( 0 ); 47 | }); 48 | }); 49 | 50 | }); 51 | 52 | describe("when killed", function() { 53 | 54 | var child = new dummy(); 55 | beforeEach( function() { 56 | controller.kill(); 57 | }); 58 | 59 | it("should have killed the controller", function() { 60 | expect( controller.kill.callCount ).toBeGreaterThan( 0 ); 61 | }); 62 | 63 | it("should have killed the view", function() { 64 | expect( controller.view.kill.callCount ).toBeGreaterThan( 0 ); 65 | }); 66 | 67 | }); 68 | 69 | afterEach( function() { 70 | controller.kill() 71 | }); 72 | 73 | }); 74 | -------------------------------------------------------------------------------- /spec/javascripts/helper_specs/mixable___spec.js: -------------------------------------------------------------------------------- 1 | describe("Mixable", function() { 2 | 3 | var mixable; 4 | 5 | beforeEach(function() { 6 | mixable = new Helper.Mixable(); 7 | }); 8 | 9 | it("should have reserved keywords", function() { 10 | expect( Helper.Mixable.ModuleKeyWords ).toBeDefined(); 11 | expect( Helper.Mixable.ModuleKeyWords ).toMatch( [ 'extended', 'included' ] ) 12 | }); 13 | 14 | it("should respond to extend", function() { 15 | expect( Helper.Mixable.extend ).toBeDefined(); 16 | }) 17 | 18 | it("should respond to extend", function() { 19 | expect( Helper.Mixable.include ).toBeDefined(); 20 | }) 21 | 22 | it("should respond to concern", function() { 23 | expect( Helper.Mixable.concern ).toBeDefined(); 24 | }) 25 | 26 | }); -------------------------------------------------------------------------------- /spec/javascripts/helper_specs/mixable_timemachine_spec.js: -------------------------------------------------------------------------------- 1 | describe("Mixin: TimeMachine", function() { 2 | 3 | var mixed; 4 | var methods = Mixin.TimeMachine.InstanceMethods; 5 | beforeEach( function() { 6 | 7 | mixed = _( { } ).extend( methods ); 8 | 9 | }); 10 | 11 | describe("when initialized", function() { 12 | 13 | beforeEach( function() { 14 | mixed._allowTimeMachine(); 15 | }); 16 | 17 | it( "should have set a private variable", function() { 18 | expect( mixed.tree ).toBeDefined(); 19 | }); 20 | 21 | describe("and action is added", function() { 22 | 23 | var action = 'foo'; 24 | 25 | beforeEach( function() { 26 | spyOn( mixed.tree, 'add' ) 27 | mixed.addUndoableEvent( action ); 28 | }); 29 | 30 | it( "should called tree adding", function() { 31 | expect( mixed.tree.add ).toHaveBeenCalledWith( action ); 32 | }); 33 | 34 | describe("and is undone", function() { 35 | 36 | var undo = jasmine.createSpy( 'undo' ); 37 | var action = { undo: undo }; 38 | 39 | beforeEach( function() { 40 | spyOn( mixed.tree, 'undo' ).andReturn( action ); 41 | mixed.undo(); 42 | }); 43 | 44 | it( "should called tree undo", function() { 45 | expect( mixed.tree.undo ).toHaveBeenCalled(); 46 | }); 47 | 48 | it( "should undone the returned action", function() { 49 | expect( undo ).toHaveBeenCalled(); 50 | }); 51 | 52 | describe("and is redone", function() { 53 | 54 | var redo = jasmine.createSpy( 'redo' ); 55 | var action = { redo: redo }; 56 | 57 | beforeEach( function() { 58 | spyOn( mixed.tree, 'redo' ).andReturn( action ); 59 | mixed.redo(); 60 | }); 61 | 62 | it( "should called tree redo", function() { 63 | expect( mixed.tree.redo ).toHaveBeenCalled(); 64 | }); 65 | 66 | it( "should redone the returned action", function() { 67 | expect( redo ).toHaveBeenCalled(); 68 | }); 69 | }); 70 | }); 71 | }); 72 | 73 | }); 74 | 75 | describe("when action is created", function() { 76 | 77 | var result; 78 | var desc = 'foo'; 79 | beforeEach( function() { 80 | result = mixed._createAction( desc ); 81 | }); 82 | 83 | it( "should return a model action", function() { 84 | expect( result instanceof Model.Action ).toBeTruthy(); 85 | }); 86 | }); 87 | }); 88 | -------------------------------------------------------------------------------- /spec/javascripts/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/spec/javascripts/helpers/.gitkeep -------------------------------------------------------------------------------- /spec/javascripts/helpers/SpecHelper.js: -------------------------------------------------------------------------------- 1 | beforeEach(function() { 2 | this.addMatchers({ 3 | toBePlaying: function(expectedSong) { 4 | var player = this.actual; 5 | return player.currentlyPlayingSong === expectedSong 6 | && player.isPlaying; 7 | } 8 | }) 9 | }); 10 | -------------------------------------------------------------------------------- /spec/javascripts/helpers/numeric.js: -------------------------------------------------------------------------------- 1 | beforeEach(function() { 2 | 3 | this.addMatchers({ 4 | 5 | toBeAtMost: function( expected ) { 6 | var actual = this.actual; 7 | var notText = this.isNot ? " not" : ""; 8 | 9 | this.message = function () { 10 | return "Expected " + actual + notText + " to be at most " + expected; 11 | }; 12 | 13 | return actual <= expected; 14 | }, 15 | 16 | toBeAtLeast: function( expected ) { 17 | var actual = this.actual; 18 | var notText = this.isNot ? " not" : ""; 19 | 20 | this.message = function () { 21 | return "Expected " + actual + notText + " to be at least " + expected; 22 | }; 23 | 24 | return actual >= expected; 25 | }, 26 | 27 | toBeBetween: function ( rangeFloor, rangeCeiling, inclusive ) { 28 | 29 | if ( inclusive === undefined ) 30 | inclusive = false 31 | 32 | if (rangeFloor > rangeCeiling) { 33 | var temp = rangeFloor; 34 | rangeFloor = rangeCeiling; 35 | rangeCeiling = temp; 36 | } 37 | return ( this.actual > rangeFloor && this.actual < rangeCeiling ) || ( inclusive && this.actual == rangeFloor ) 38 | }, 39 | 40 | toBeCloseTo: function( value, diff ) { 41 | if ( diff === undefined ) 42 | diff = 1e-6; 43 | 44 | var actual = this.actual; 45 | var notText = this.isNot ? " not" : ""; 46 | var result = ( this.actual > value - diff && this.actual <= value + diff ); 47 | 48 | this.message = function () { 49 | return "Expected " + actual + notText + " to be close to " + value + " +- " + diff; 50 | }; 51 | 52 | return result; 53 | } 54 | }); 55 | }); -------------------------------------------------------------------------------- /spec/javascripts/model_specs/action_spec.js: -------------------------------------------------------------------------------- 1 | describe("Action", function() { 2 | 3 | describe("when constructed", function() { 4 | 5 | var action,func1,func2, context; 6 | 7 | beforeEach( function() { 8 | 9 | func1 = function() { 10 | this.k = 1 11 | }; 12 | 13 | func2 = function() { 14 | this.k = 2 15 | }; 16 | 17 | context = { 18 | k : 0, 19 | f1 : func1, 20 | f2 : func2 21 | } 22 | 23 | action = new Model.Action(context, func1, func2); 24 | }); 25 | 26 | it("should have all the properties", function() { 27 | expect( action._todo ).toBe( func1 ); 28 | expect( action._undo ).toBe( func2 ); 29 | expect( action._context ).toBe( context ); 30 | }); 31 | 32 | describe("when having undone the action", function() { 33 | beforeEach( function() { 34 | action.undo(); 35 | }); 36 | 37 | it("should have executed the function on the context", function() { 38 | expect( context.k ).toBe( 2 ); 39 | }); 40 | }); 41 | 42 | describe("when having redone the action", function() { 43 | beforeEach( function() { 44 | action.redo(); 45 | }); 46 | 47 | it("should have executed the function on the context", function() { 48 | expect( context.k ).toBe( 1 ); 49 | }); 50 | }); 51 | 52 | describe("when set", function() { 53 | beforeEach( function() { 54 | func1 = func1 = function() { 55 | this.foo = 1 56 | }; 57 | 58 | func2 = function() { 59 | this.bar = 2 60 | }; 61 | 62 | action.set( func1, func2 ); 63 | }); 64 | 65 | it("should have the new functions", function() { 66 | expect( action._todo ).toBe( func1 ); 67 | expect( action._undo ).toBe( func2 ); 68 | expect( action._context ).toBe( context ); 69 | }); 70 | }); 71 | 72 | }); 73 | 74 | }); 75 | -------------------------------------------------------------------------------- /spec/javascripts/model_specs/node_spec.js: -------------------------------------------------------------------------------- 1 | xdescribe("Node", function() { 2 | var node; 3 | 4 | beforeEach( function() { 5 | }); 6 | 7 | describe("when a root node with children is constructed", function() { 8 | var left, right; 9 | var children; 10 | 11 | beforeEach( function() { 12 | left = new Model.Node( null, null ); 13 | right = new Model.Node( null, null ); 14 | children = [left, right]; 15 | node = new Model.Node( null, null, children ); 16 | left.parent = node; 17 | right.parent = node; 18 | }); 19 | 20 | it("should contain the children", function() { 21 | expect( node.children ).toBe( children ); 22 | }); 23 | 24 | it("should be the parent of its children", function() { 25 | expect( left.parent ).toBe( node ); 26 | expect( right.parent ).toBe( node ); 27 | }); 28 | 29 | describe("when rebasing a child", function() { 30 | it("should have a new parent", function() { 31 | left.rebase( right ); 32 | expect( left.parent ).toBe( right ); 33 | }); 34 | 35 | it("should no longer be the child of the old parent", function() { 36 | expect( node.children ).toMatch([right]); 37 | }); 38 | 39 | it("should set the branch of the parent to the child", function() { 40 | left.rebase( right ); 41 | expect( right.branch ).toBe( left ); 42 | }); 43 | 44 | }); 45 | }); 46 | 47 | 48 | describe("when a root node is constructed", function() { 49 | var nodeObject; 50 | 51 | beforeEach( function() { 52 | nodeObject = {test: "test"}; 53 | node = new Model.Node(nodeObject, null); 54 | }); 55 | 56 | it("should contain the object", function() { 57 | expect( node.object ).toEqual( nodeObject ); 58 | }); 59 | 60 | it("should have null as a parent", function() { 61 | expect( node.parent ).toEqual( null ); 62 | }); 63 | 64 | it("should have no children", function() { 65 | expect( node.children.length ).toEqual( 0 ); 66 | }); 67 | 68 | describe("when a child node is added", function() { 69 | var child; 70 | 71 | beforeEach( function() { 72 | child = new Model.Node(null, node); 73 | }); 74 | 75 | it("should have the root node as its parent", function() { 76 | expect( child.parent ).toEqual( node ); 77 | }); 78 | 79 | it("should be a child of the root", function() { 80 | expect( node.children[0] ).toEqual( child ); 81 | }); 82 | }); 83 | }); 84 | }); 85 | -------------------------------------------------------------------------------- /spec/javascripts/spec_helper.js: -------------------------------------------------------------------------------- 1 | // Teabag includes some support files, but you can use anything from your own support path too. 2 | // require support/jasmine-jquery 3 | // require support/sinon 4 | // require support/your-support-file 5 | // 6 | // Deferring execution 7 | // If you're using CommonJS, RequireJS or some other asynchronous library you can defer execution. Call Teabag.execute() 8 | // after everything has been loaded. Simple example of a timeout: 9 | // 10 | // Teabag.defer = true 11 | // setTimeout(Teabag.execute, 1000) 12 | // 13 | // Matching files 14 | // By default Teabag will look for files that match _spec.{js,js.coffee,.coffee}. Add a filename_spec.js file in your 15 | // spec path and it'll be included in the default suite automatically. If you want to customize suites, check out the 16 | // configuration in config/initializers/teabag.rb 17 | // 18 | // Manifest 19 | // If you'd rather require your spec files manually (to control order for instance) you can disable the suite matcher in 20 | // the configuration and use this file as a manifest. 21 | // 22 | // For more information: http://github.com/modeset/teabag 23 | // 24 | // You can require javascript files here. A good place to start is by requiring your application.js. 25 | //= require application 26 | //= require_tree ./helpers 27 | 28 | -------------------------------------------------------------------------------- /spec/javascripts/support/jasmine.yml: -------------------------------------------------------------------------------- 1 | # src_files 2 | # 3 | # Return an array of filepaths relative to src_dir to include before jasmine specs. 4 | # Default: [] 5 | # 6 | # EXAMPLE: 7 | # 8 | # src_files: 9 | # - lib/source1.js 10 | # - lib/source2.js 11 | # - dist/**/*.js 12 | # 13 | src_files: 14 | - assets/application.js 15 | 16 | # stylesheets 17 | # 18 | # Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs. 19 | # Default: [] 20 | # 21 | # EXAMPLE: 22 | # 23 | # stylesheets: 24 | # - css/style.css 25 | # - stylesheets/*.css 26 | # 27 | stylesheets: 28 | - stylesheets/**/*.css 29 | 30 | # helpers 31 | # 32 | # Return an array of filepaths relative to spec_dir to include before jasmine specs. 33 | # Default: ["helpers/**/*.js"] 34 | # 35 | # EXAMPLE: 36 | # 37 | # helpers: 38 | # - helpers/**/*.js 39 | # 40 | helpers: 41 | - helpers/**/*.js 42 | - helpers/*.js 43 | 44 | # spec_files 45 | # 46 | # Return an array of filepaths relative to spec_dir to include. 47 | # Default: ["**/*[sS]pec.js"] 48 | # 49 | # EXAMPLE: 50 | # 51 | # spec_files: 52 | # - **/*[sS]pec.js 53 | # 54 | spec_files: 55 | - '**/*[sS]pec.js' 56 | 57 | # src_dir 58 | # 59 | # Source directory path. Your src_files must be returned relative to this path. Will use root if left blank. 60 | # Default: project root 61 | # 62 | # EXAMPLE: 63 | # 64 | # src_dir: public 65 | # 66 | src_dir: 67 | 68 | # spec_dir 69 | # 70 | # Spec directory path. Your spec_files must be returned relative to this path. 71 | # Default: spec/javascripts 72 | # 73 | # EXAMPLE: 74 | # 75 | # spec_dir: spec/javascripts 76 | # 77 | spec_dir: spec/javascripts 78 | -------------------------------------------------------------------------------- /spec/javascripts/support/jasmine_helper.rb: -------------------------------------------------------------------------------- 1 | #Use this file to set/override Jasmine configuration options 2 | #You can remove it if you don't need it. 3 | #This file is loaded *after* jasmine.yml is interpreted. 4 | # 5 | #Example: using a different boot file. 6 | #Jasmine.configure do |config| 7 | # @config.boot_dir = '/absolute/path/to/boot_dir' 8 | # @config.boot_files = lambda { ['/absolute/path/to/boot_dir/file.js'] } 9 | #end 10 | # 11 | 12 | -------------------------------------------------------------------------------- /spec/javascripts/view_specs/modal_confirm_spec.js: -------------------------------------------------------------------------------- 1 | describe("ConfirmModal", function() { 2 | describe("when constructed", function() { 3 | beforeEach( function() { 4 | header = ""; 5 | contents = {}; 6 | id = 1; 7 | classname = ""; 8 | view = new View.ConfirmModal(header, contents, id, classname) 9 | }); 10 | 11 | it("the modal should have a cancel button", function() { 12 | expect( view._elem.find("[data-action=\"cancel\"]").length ).toBe( 1 ); 13 | }); 14 | 15 | it("the modal should have a confirm button", function() { 16 | expect( view._elem.find("[data-action=\"confirm\"]").length ).toBe( 1 ); 17 | }); 18 | 19 | afterEach( function() { 20 | view.kill(); 21 | }); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /spec/javascripts/view_specs/modal_settings_spec.js: -------------------------------------------------------------------------------- 1 | describe("Modal settings", function() { 2 | 3 | describe("when constructed", function() { 4 | 5 | beforeEach( function() { 6 | settings = {}; 7 | id = 1; 8 | classname = ""; 9 | view = new View.SettingsModal(settings, id, classname); 10 | }); 11 | 12 | afterEach( function() { 13 | view.kill() 14 | }) 15 | 16 | it( "should have set all the properties", function() { 17 | expect( view._header ).toBe( 'Settings' ); 18 | expect( view.id ).toBe( id ); 19 | expect( view._elem ).toBeDefined(); 20 | }); 21 | 22 | it( "should be able to get the input fields", function() { 23 | expect( view.getInput() ).toBeDefined(); 24 | }); 25 | 26 | it( "should be able to create a control section", function() { 27 | expect( view._createControlSection() ).toBeDefined(); 28 | }); 29 | 30 | }); 31 | 32 | }); -------------------------------------------------------------------------------- /spec/javascripts/view_specs/pane_spec.js: -------------------------------------------------------------------------------- 1 | describe("Pane", function() { 2 | describe("when constructed", function() { 3 | beforeEach( function() { 4 | position = 0; 5 | view = new View.Pane( position ); 6 | }); 7 | 8 | it("should have set all the properties", function() { 9 | expect( view.position).toBe( position ); 10 | expect( view._extended ).toBe( true ); 11 | expect( view._buttonWidth ).toBe( 40 ); 12 | expect( view._containerOptions ).toEqual( {} ); 13 | expect( view._views ).toEqual( [] ); 14 | }); 15 | 16 | describe("when clearing", function() { 17 | beforeEach( function() { 18 | spy = { 19 | kill: jasmine.createSpy( "kill" ) 20 | } 21 | view._views = [spy, spy, spy]; 22 | view.clear(); 23 | }); 24 | 25 | it("should have called kill for each view in it's view", function() { 26 | expect( spy.kill.callCount ).toBe( view._views.length ); 27 | }); 28 | }); 29 | 30 | describe("when killing", function() { 31 | describe("without drawing", function() { 32 | beforeEach( function() { 33 | view.kill(); 34 | }); 35 | 36 | it("elem should still be undefined", function() { 37 | expect( view._elem ).toBe( undefined ); 38 | }); 39 | }); 40 | 41 | describe("after drawing", function() { 42 | beforeEach( function() { 43 | view.draw(); 44 | view.kill(); 45 | }); 46 | 47 | it("elem should still be undefined", function() { 48 | expect( $(document).find(view._elem).length ).toBe( 0 ); 49 | }); 50 | }); 51 | 52 | }); 53 | 54 | 55 | afterEach( function() { 56 | view.kill(); 57 | }); 58 | }); 59 | }); 60 | -------------------------------------------------------------------------------- /test/fixtures/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/test/fixtures/.gitkeep -------------------------------------------------------------------------------- /test/fixtures/cells.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: cells 4 | # 5 | # id :integer not null, primary key 6 | # name :string(255) 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | 11 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html 12 | 13 | one: 14 | name: MyString 15 | id: 1 16 | 17 | two: 18 | name: MyString2 19 | id: 2 20 | -------------------------------------------------------------------------------- /test/fixtures/module_instances.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: module_instances 4 | # 5 | # id :integer not null, primary key 6 | # created_at :datetime not null 7 | # updated_at :datetime not null 8 | # module_template_id :integer 9 | # cell_id :integer 10 | # amount :float 11 | # name :string(255) 12 | # 13 | 14 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html 15 | 16 | # 17 | one: 18 | id: 1 19 | cell_id: 1 20 | module_template_id: 1 21 | name: 'foo' 22 | 23 | two: 24 | id: 2 25 | cell_id: 1 26 | module_template_id: 2 27 | name: 'bar' 28 | -------------------------------------------------------------------------------- /test/fixtures/module_parameters.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: module_parameters 4 | # 5 | # id :integer not null, primary key 6 | # key :string(255) 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # module_template_id :integer 10 | # 11 | 12 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html 13 | 14 | one: 15 | id: 1 16 | module_template_id: 1 17 | key: k 18 | 19 | two: 20 | id: 2 21 | module_template_id: 2 22 | key: lipsum 23 | -------------------------------------------------------------------------------- /test/fixtures/module_templates.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: module_templates 4 | # 5 | # id :integer not null, primary key 6 | # created_at :datetime not null 7 | # updated_at :datetime not null 8 | # name :string(255) 9 | # step :text 10 | # file :string(255) 11 | # javascript_model :string(255) 12 | # 13 | 14 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html 15 | 16 | # 17 | one: 18 | id: 1 19 | name: ModuleA 20 | file: substrate 21 | 22 | two: 23 | id: 2 24 | name: ModuleB 25 | -------------------------------------------------------------------------------- /test/fixtures/module_values.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: module_values 4 | # 5 | # id :integer not null, primary key 6 | # value :text 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # module_parameter_id :integer 10 | # module_instance_id :integer 11 | # 12 | 13 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html 14 | 15 | one: 16 | value: "[1]" 17 | id: 1 18 | module_instance_id: 1 19 | module_parameter_id: 1 20 | 21 | two: 22 | value: "['dolor']" 23 | id: 2 24 | module_instance_id: 2 25 | module_parameter_id: 2 26 | -------------------------------------------------------------------------------- /test/fixtures/reports.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: reports 4 | # 5 | # id :integer not null, primary key 6 | # cell_id :integer 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | 11 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html 12 | 13 | one: 14 | id: 1 15 | cell_id: 1 16 | 17 | two: 18 | id: 2 19 | cell_id: 1 20 | -------------------------------------------------------------------------------- /test/functional/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/test/functional/.gitkeep -------------------------------------------------------------------------------- /test/functional/cells_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class CellsControllerTest < ActionController::TestCase 4 | setup do 5 | @cell = cells(:one) 6 | end 7 | 8 | test "should get index" do 9 | get :index 10 | assert_response :success 11 | assert_not_nil assigns(:cells) 12 | end 13 | 14 | test "should get new" do 15 | get :new 16 | assert_response :success 17 | end 18 | 19 | test "should create cell" do 20 | assert_difference('Cell.count') do 21 | post :create, cell: { name: @cell.name } 22 | end 23 | 24 | assert_redirected_to cell_path(assigns(:cell)) 25 | end 26 | 27 | test "should show cell" do 28 | get :show, id: @cell 29 | assert_response :success 30 | end 31 | 32 | test "should get edit" do 33 | get :edit, id: @cell 34 | assert_response :success 35 | end 36 | 37 | test "should update cell" do 38 | put :update, id: @cell, cell: { id: @cell.id, name: @cell.name } 39 | assert_redirected_to cell_path(assigns(:cell)) 40 | end 41 | 42 | test "should destroy cell" do 43 | assert_difference('Cell.count', -1) do 44 | delete :destroy, id: @cell 45 | end 46 | 47 | assert_redirected_to cells_path 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /test/functional/hook_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class HookControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/functional/main_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class MainControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/functional/module_instances_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ModuleInstancesControllerTest < ActionController::TestCase 4 | setup do 5 | @module_instance = module_instances(:one) 6 | end 7 | 8 | test "should get index" do 9 | get :index 10 | assert_response :success 11 | assert_not_nil assigns(:module_instances) 12 | end 13 | 14 | test "should get new" do 15 | get :new 16 | assert_response :success 17 | end 18 | 19 | test "should create module_instance" do 20 | assert_difference('ModuleInstance.count') do 21 | post :create, module_instance: { 22 | :module_template_id => @module_instance.module_template_id, 23 | :cell_id => @module_instance.cell_id, 24 | :name => @module_instance.name 25 | } 26 | end 27 | 28 | assert_redirected_to module_instance_path(assigns(:module_instance)) 29 | end 30 | 31 | test "should show module_instance" do 32 | get :show, id: @module_instance 33 | assert_response :success 34 | end 35 | 36 | test "should get edit" do 37 | get :edit, id: @module_instance 38 | assert_response :success 39 | end 40 | 41 | test "should update module_instance" do 42 | put :update, id: @module_instance, module_instance: { :id => @module_instance.id } 43 | assert_redirected_to module_instance_path(assigns(:module_instance)) 44 | end 45 | 46 | test "should destroy module_instance" do 47 | assert_difference('ModuleInstance.count', -1) do 48 | delete :destroy, id: @module_instance 49 | end 50 | 51 | assert_redirected_to module_instances_path 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /test/functional/module_templates_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ModuleTemplatesControllerTest < ActionController::TestCase 4 | setup do 5 | @module_template = module_templates(:one) 6 | end 7 | 8 | test "should get index" do 9 | get :index 10 | assert_response :success 11 | assert_not_nil assigns(:module_templates) 12 | end 13 | 14 | test "should get new" do 15 | get :new 16 | assert_response :success 17 | end 18 | 19 | test "should create module_template" do 20 | assert_difference('ModuleTemplate.count') do 21 | post :create, module_template: { :name => @module_template.name } 22 | end 23 | 24 | assert_redirected_to module_template_path(assigns(:module_template)) 25 | end 26 | 27 | test "should show module_template" do 28 | get :show, id: @module_template 29 | assert_response :success 30 | end 31 | 32 | test "should get edit" do 33 | get :edit, id: @module_template 34 | assert_response :success 35 | end 36 | 37 | test "should update module_template" do 38 | put :update, id: @module_template, module_template: { :id => @module_template.id } 39 | assert_redirected_to module_template_path(assigns(:module_template)) 40 | end 41 | 42 | test "should destroy module_template" do 43 | assert_difference('ModuleTemplate.count', -1) do 44 | delete :destroy, id: @module_template 45 | end 46 | 47 | assert_redirected_to module_templates_path 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /test/functional/reports_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ReportsControllerTest < ActionController::TestCase 4 | setup do 5 | @report = reports(:one) 6 | end 7 | 8 | test "should get index" do 9 | get :index 10 | assert_response :success 11 | assert_not_nil assigns(:reports) 12 | end 13 | 14 | test "should get new" do 15 | get :new 16 | assert_response :success 17 | end 18 | 19 | test "should create report" do 20 | assert_difference('Report.count') do 21 | post :create, report: { cell_id: 3 } 22 | end 23 | 24 | assert_redirected_to report_path(assigns(:report)) 25 | end 26 | 27 | test "should not create a duplicate report of a cell" do 28 | assert_no_difference('Report.count') do 29 | post :create, report: { cell_id: @report.cell_id } 30 | end 31 | 32 | #assert_redirected_to report_path(assigns(:report)) 33 | end 34 | 35 | test "should get show" do 36 | get :show, id: @report 37 | assert_response :success 38 | end 39 | 40 | test "should destroy the report" do 41 | assert_difference('Report.count', -1) do 42 | delete :destroy, id: @report 43 | end 44 | 45 | assert_redirected_to reports_path 46 | end 47 | 48 | end 49 | -------------------------------------------------------------------------------- /test/integration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/test/integration/.gitkeep -------------------------------------------------------------------------------- /test/integration/cells_view_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'selenium-webdriver' 3 | 4 | 5 | class CellsViewTests < ActionDispatch::IntegrationTest 6 | 7 | setup do 8 | @driver = Selenium::WebDriver.for :firefox 9 | @wait = Selenium::WebDriver::Wait.new :timeout => 10 10 | @driver.navigate.to "http://life.jstfy.com/cells" 11 | end 12 | 13 | teardown do 14 | @driver.quit 15 | end 16 | 17 | test "navigate to new-cell view" do 18 | button = @wait.until{ @driver.find_element(:class, "icon-plus-sign") } 19 | button.click 20 | url = @driver.current_url 21 | assert_equal url, "http://life.jstfy.com/cells/new" 22 | end 23 | 24 | end -------------------------------------------------------------------------------- /test/integration/main_view_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'selenium-webdriver' 3 | 4 | 5 | 6 | class MainViewTest < ActionDispatch::IntegrationTest 7 | 8 | setup do 9 | @driver = Selenium::WebDriver.for :firefox 10 | @wait = Selenium::WebDriver::Wait.new :timeout => 10 11 | 12 | # navigate to the main view 13 | @driver.navigate.to "http://life.jstfy.com" 14 | end 15 | 16 | teardown do 17 | @driver.quit 18 | end 19 | 20 | #Mouseover event on class module-hitbox 21 | #Check if popover showed up on mouseover 22 | test "module mouseover" do 23 | el = @wait.until { @driver.find_element(:class, "cellgrowth-hitbox") } 24 | displayed = false 25 | if @wait.until { el.displayed? } 26 | @driver.mouse.move_to(el) 27 | pop = @wait.until { @driver.find_element(:class, "cellgrowth-box") } 28 | displayed = @wait.until { pop.displayed? } 29 | end 30 | assert displayed 31 | end 32 | 33 | =begin 34 | #Click on module 35 | #Check if edit popover showed up 36 | test "open edit popover" do 37 | el = @wait.until { @driver.find_element(:class, "module-hitbox") } 38 | displayed = false 39 | if @wait.until { el.displayed? } 40 | el.click 41 | pop = @wait.until { @driver.find_element(:class, "selected") } 42 | displayed = @wait.until { pop.displayed? } 43 | end 44 | assert displayed 45 | end 46 | 47 | #Click on dummy module 48 | #Check wether a module has been added 49 | test "add a module" do 50 | els = @wait.until { @driver.find_elements(:class, "inactive") } 51 | displayed = false 52 | for el_pot in els 53 | if el_pot.displayed? 54 | el = el_pot 55 | break 56 | end 57 | end 58 | if el and @wait.until { el.displayed? } 59 | el.click 60 | newmodule = @wait.until { @driver.find_element(:class, "module-hitbox") } 61 | displayed = @wait.until { newmodule.displayed? } 62 | end 63 | assert displayed 64 | end 65 | =end 66 | 67 | #Click on Action History Pane 68 | #Check if pane showed up 69 | test "view the actionhistory pane" do 70 | el = @wait.until { @driver.find_element(:class, "pane-button") } 71 | pane = @wait.until { @driver.find_element(:class, "pane-left") } 72 | assert_equal "pane pane-left extended", pane.attribute("class") 73 | el.click 74 | assert_equal "pane pane-left", pane.attribute("class") 75 | end 76 | 77 | end -------------------------------------------------------------------------------- /test/integration/reports_view_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'selenium-webdriver' 3 | 4 | 5 | class ReportsViewTests < ActionDispatch::IntegrationTest 6 | 7 | setup do 8 | @driver = Selenium::WebDriver.for :firefox 9 | @wait = Selenium::WebDriver::Wait.new :timeout => 10 10 | @driver.navigate.to "http://life.jstfy.com/reports" 11 | end 12 | 13 | teardown do 14 | @driver.quit 15 | end 16 | 17 | test "navigate to new-report view" do 18 | button = @wait.until { @driver.find_element(:class, "icon-plus-sign") } 19 | button.click 20 | url = @driver.current_url 21 | assert_equal url, "http://life.jstfy.com/reports/new" 22 | end 23 | 24 | end -------------------------------------------------------------------------------- /test/performance/browsing_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'rails/performance_test_help' 3 | 4 | class BrowsingTest < ActionDispatch::PerformanceTest 5 | # Refer to the documentation for all available options 6 | # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory] 7 | # :output => 'tmp/performance', :formats => [:flat] } 8 | 9 | def test_homepage 10 | get '/' 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require 'coveralls' 2 | Coveralls.wear! 3 | 4 | ENV["RAILS_ENV"] = "test" 5 | require File.expand_path('../../config/environment', __FILE__) 6 | require 'rails/test_help' 7 | 8 | class ActiveSupport::TestCase 9 | # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. 10 | # 11 | # Note: You'll currently still have to declare fixtures explicitly in integration tests 12 | # -- they do not yet inherit this setting 13 | fixtures :all 14 | 15 | # Add more helper methods to be used by all tests here... 16 | end 17 | -------------------------------------------------------------------------------- /test/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/test/unit/.gitkeep -------------------------------------------------------------------------------- /test/unit/cell_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: cells 4 | # 5 | # id :integer not null, primary key 6 | # name :string(255) 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | 11 | require 'test_helper' 12 | 13 | class CellTest < ActiveSupport::TestCase 14 | # test "the truth" do 15 | # assert true 16 | # end 17 | end 18 | -------------------------------------------------------------------------------- /test/unit/helpers/application_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ApplicationHelperTest < ActionView::TestCase 4 | test "listify nothing" do 5 | assert_equal 'none', listify( [] ), 'empty list is not listifyable' 6 | end 7 | test "listify one" do 8 | assert_equal 'lipsum', listify( ['lipsum'] ), 'single item list is not listifyable' 9 | end 10 | test "listify two" do 11 | assert_equal 'lipsum and dolor', listify( ['lipsum', 'dolor'] ), 'two items should be joined by and' 12 | end 13 | test "listify three" do 14 | assert_equal 'lipsum, dolor and sit', listify( ['lipsum', 'dolor', 'sit'] ), 'three items a b c should be like a, b and c' 15 | end 16 | test "listify more" do 17 | assert_equal 'lipsum, dolor, sit and amet', listify( ['lipsum', 'dolor', 'sit', 'amet'] ), 'more than three items a...n should be like a, a+1, ..., n-1 and n' 18 | end 19 | 20 | test "filter_on_key" do 21 | #results = [ {:key => 0 }, {:key => 1} ] 22 | #assert_equal [ results.at(0) ], filter_on_key( results, :key, 0 ), 'should have filtered on key' 23 | #assert_equal [ results.at(1) ], filter_on_key( results, :key, 1 ), 'should have filtered on key' 24 | #assert_equal 2, results.count, 'should not have edited original' 25 | end 26 | 27 | test "filter_on_key!" do 28 | #results = [ {:key => 0 }, {:key => 1} ] 29 | #filter_on_key!( results, :key, 0 ) 30 | #assert_equal 1, results.count, 'should have edited original' 31 | #assert_equal 0, results.at(0)[:key], 'should have filtered on key' 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /test/unit/helpers/cells_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class CellsHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /test/unit/helpers/hook_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class HookHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /test/unit/helpers/main_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class MainHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /test/unit/helpers/module_instances_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ModuleInstancesHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /test/unit/helpers/module_templates_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ModuleTemplatesHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /test/unit/helpers/reports_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ReportsHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /test/unit/module_instance_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: module_instances 4 | # 5 | # id :integer not null, primary key 6 | # created_at :datetime not null 7 | # updated_at :datetime not null 8 | # module_template_id :integer 9 | # cell_id :integer 10 | # amount :float 11 | # name :string(255) 12 | # 13 | 14 | require 'test_helper' 15 | 16 | class ModuleInstanceTest < ActiveSupport::TestCase 17 | # test "the truth" do 18 | # assert true 19 | # end 20 | end 21 | -------------------------------------------------------------------------------- /test/unit/module_parameter_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: module_parameters 4 | # 5 | # id :integer not null, primary key 6 | # key :string(255) 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # module_template_id :integer 10 | # 11 | 12 | require 'test_helper' 13 | 14 | class ModuleParameterTest < ActiveSupport::TestCase 15 | # test "the truth" do 16 | # assert true 17 | # end 18 | end 19 | -------------------------------------------------------------------------------- /test/unit/module_template_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: module_templates 4 | # 5 | # id :integer not null, primary key 6 | # created_at :datetime not null 7 | # updated_at :datetime not null 8 | # name :string(255) 9 | # step :text 10 | # file :string(255) 11 | # javascript_model :string(255) 12 | # 13 | 14 | require 'test_helper' 15 | 16 | class ModuleTemplateTest < ActiveSupport::TestCase 17 | # test "the truth" do 18 | # assert true 19 | # end 20 | end 21 | -------------------------------------------------------------------------------- /test/unit/module_value_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: module_values 4 | # 5 | # id :integer not null, primary key 6 | # value :text 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # module_parameter_id :integer 10 | # module_instance_id :integer 11 | # 12 | 13 | require 'test_helper' 14 | 15 | class ModuleValueTest < ActiveSupport::TestCase 16 | # test "the truth" do 17 | # assert true 18 | # end 19 | end 20 | -------------------------------------------------------------------------------- /test/unit/report_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: reports 4 | # 5 | # id :integer not null, primary key 6 | # cell_id :integer 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | 11 | require 'test_helper' 12 | 13 | class ReportTest < ActiveSupport::TestCase 14 | # test "the truth" do 15 | # assert true 16 | # end 17 | end 18 | -------------------------------------------------------------------------------- /vendor/assets/images/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/vendor/assets/images/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /vendor/assets/images/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/vendor/assets/images/glyphicons-halflings.png -------------------------------------------------------------------------------- /vendor/assets/javascripts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/vendor/assets/javascripts/.gitkeep -------------------------------------------------------------------------------- /vendor/assets/javascripts/g.dot-min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * g.Raphael 0.51 - Charting library, based on Raphaël 3 | * 4 | * Copyright (c) 2009-2012 Dmitry Baranovskiy (http://g.raphaeljs.com) 5 | * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. 6 | */ 7 | (function(){function s(e,n,o,p,g,k,h,r,c){function s(a){+a[0]&&(a[0]=j.axis(n+b,o+b,p-2*b,t,C,c.axisxstep||Math.floor((p-2*b)/20),2,c.axisxlabels||null,c.axisxtype||"t",null,e));+a[1]&&(a[1]=j.axis(n+p-b,o+g-b,g-2*b,u,D,c.axisystep||Math.floor((g-2*b)/20),3,c.axisylabels||null,c.axisytype||"t",null,e));+a[2]&&(a[2]=j.axis(n+b,o+g-b+x,p-2*b,t,C,c.axisxstep||Math.floor((p-2*b)/20),0,c.axisxlabels||null,c.axisxtype||"t",null,e));+a[3]&&(a[3]=j.axis(n+b-x,o+g-b,g-2*b,u,D,c.axisystep||Math.floor((g-2* 8 | b)/20),1,c.axisylabels||null,c.axisytype||"t",null,e))}for(var c=c||{},j=this,l=j.snapEnds(Math.min.apply(Math,k),Math.max.apply(Math,k),k.length-1),t=l.from,C=l.to,b=c.gutter||10,l=j.snapEnds(Math.min.apply(Math,h),Math.max.apply(Math,h),h.length-1),u=l.from,D=l.to,v=Math.max(k.length,h.length,r.length),l=e[c.symbol]||"circle",m=e.set(),y=e.set(),E=c.max||100,a=Math.max.apply(Math,r),q=[],i=2*Math.sqrt(a/Math.PI)/E,a=0;a= steps ) 27 | { 28 | clearInterval( intervalID ); 29 | callback && _.defer( callback() ); 30 | } 31 | }, interval ); 32 | } 33 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/raphael-arrow.js: -------------------------------------------------------------------------------- 1 | /** 2 | * raphael.arrow-set plugin 3 | * Copyright (c) 2011 @author: top-flight 4 | * 5 | * Licensed under the MIT license 6 | */ 7 | 8 | (function() { 9 | 10 | /** 11 | * Create a set that will contain a path for the arrow line and a path for the arrow head. 12 | */ 13 | Raphael.fn.arrowSet = function (x1, y1, x2, y2, r) { 14 | var paper = this; 15 | var arrow = paper.set(); 16 | 17 | arrow.push(paper.path(triangle(x2, y2 - (r / 2), r)).rotate(arrowHeadAngle(x1, y1, x2, y2), x2, y2)); 18 | arrow.push(paper.path(line(x1, y1, x2, y2))); 19 | 20 | return arrow; 21 | 22 | /** 23 | * Calculate angle to rotate arrow head by 24 | * This function was inspired by: http://taitems.tumblr.com/post/549973287/drawing-arrows-in-raphaeljs 25 | */ 26 | function arrowHeadAngle (x1, y1, x2, y2) { 27 | var angle = Math.atan2(x1 - x2, y2 - y1); 28 | angle = ((angle / (2 * Math.PI)) * 360) + 180; 29 | return angle; 30 | } 31 | 32 | /** 33 | * String that represents a line path on canvas 34 | * Adapted from raphael.primitives.js 35 | * For more info visit: https://github.com/DmitryBaranovskiy/raphael 36 | */ 37 | function line (x1, y1, x2, y2) { 38 | return ["M", x1, y1, "L", x2, y2]; 39 | } 40 | 41 | /** 42 | * String that represents a triangle path on canvas 43 | * Adapted from raphael.primitives.js 44 | * For more info visit: https://github.com/DmitryBaranovskiy/raphael 45 | */ 46 | function triangle (cx, cy, r) { 47 | r *= 1.75; 48 | return "M".concat(cx, ",", cy, "m0-", r * .58, "l", r * .5, ",", r * .87, "-", r, ",0z"); 49 | } 50 | }; 51 | })(); 52 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/raphael-triangle.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Stuff that should just come with Raphael 3 | */ 4 | 5 | // Make a triangle 6 | Raphael.fn.triangle = function(x, y, size) { 7 | var path = ["M", x, y]; 8 | path = path.concat(["L", (x + size / 2), (y + size)]); 9 | path = path.concat(["L", (x - size / 2), (y + size)]); 10 | return this.path(path.concat(["z"]).join(" ")); 11 | }; 12 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/vendor/assets/stylesheets/.gitkeep -------------------------------------------------------------------------------- /vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programming-life/programming-life-2013/30639aef54281e933b547252007a4fbf79b52fdc/vendor/plugins/.gitkeep --------------------------------------------------------------------------------