├── img ├── bg.png ├── cloud.png ├── logo.png ├── collab.png ├── organize.png └── logosmall.png ├── css ├── fonts │ ├── Lato-Bold.ttf │ ├── Lato-Light.ttf │ ├── Lato-Regular.ttf │ ├── Flat-UI-Icons.eot │ ├── Flat-UI-Icons.ttf │ ├── Flat-UI-Icons.woff │ ├── Flat-UI-Icons.svg │ └── Flat-UI-Icons.dev.svg ├── img │ ├── splitter │ │ ├── hgrabber.gif │ │ ├── vgrabber.gif │ │ ├── vdockbar-trans.gif │ │ ├── vdockleft-trans.gif │ │ ├── vgrabber2-active.gif │ │ └── vgrabber2-normal.gif │ ├── glyphicons-halflings.png │ └── glyphicons-halflings-white.png ├── show.css ├── vendor │ ├── jquery.maximage.min.css │ ├── jquery.splitter.css │ ├── theme │ │ ├── README.md │ │ └── default.css │ ├── zenburn.css │ └── bootstrap-responsive.min.css └── style.css ├── js ├── mazmurApp.js ├── schedule.js ├── laguEntity.js ├── addEdit.js ├── vendor │ ├── backbone.picky.min.js │ ├── backbone.localStorage-min.js │ ├── backbone.syphon.min.js │ ├── jquery.maximage.min.js │ ├── underscore-min.js │ ├── jquery.splitter.js │ ├── backbone-firebase.js │ ├── backbone-min.js │ └── json2.js ├── previewList.js ├── presenter.js ├── lirikViewer.js └── laguList.js ├── data └── lagu.json ├── README.md ├── index-lama.html ├── show.html └── index.html /img/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/img/bg.png -------------------------------------------------------------------------------- /img/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/img/cloud.png -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/img/logo.png -------------------------------------------------------------------------------- /img/collab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/img/collab.png -------------------------------------------------------------------------------- /img/organize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/img/organize.png -------------------------------------------------------------------------------- /img/logosmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/img/logosmall.png -------------------------------------------------------------------------------- /css/fonts/Lato-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/fonts/Lato-Bold.ttf -------------------------------------------------------------------------------- /css/fonts/Lato-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/fonts/Lato-Light.ttf -------------------------------------------------------------------------------- /css/fonts/Lato-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/fonts/Lato-Regular.ttf -------------------------------------------------------------------------------- /css/fonts/Flat-UI-Icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/fonts/Flat-UI-Icons.eot -------------------------------------------------------------------------------- /css/fonts/Flat-UI-Icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/fonts/Flat-UI-Icons.ttf -------------------------------------------------------------------------------- /css/fonts/Flat-UI-Icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/fonts/Flat-UI-Icons.woff -------------------------------------------------------------------------------- /css/img/splitter/hgrabber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/img/splitter/hgrabber.gif -------------------------------------------------------------------------------- /css/img/splitter/vgrabber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/img/splitter/vgrabber.gif -------------------------------------------------------------------------------- /css/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /css/img/splitter/vdockbar-trans.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/img/splitter/vdockbar-trans.gif -------------------------------------------------------------------------------- /css/img/splitter/vdockleft-trans.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/img/splitter/vdockleft-trans.gif -------------------------------------------------------------------------------- /css/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /css/img/splitter/vgrabber2-active.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/img/splitter/vgrabber2-active.gif -------------------------------------------------------------------------------- /css/img/splitter/vgrabber2-normal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonnylazuardi/mazmur/HEAD/css/img/splitter/vgrabber2-normal.gif -------------------------------------------------------------------------------- /js/mazmurApp.js: -------------------------------------------------------------------------------- 1 | var lirikData = []; 2 | var currentBg; 3 | 4 | var MazmurApp = new Marionette.Application(); 5 | 6 | MazmurApp.addRegions({ 7 | laguList: '#lagu-list', 8 | laguForm: '#lagu-form', 9 | lirikList: '#lirik-list', 10 | previewList: '#preview-list', 11 | scheduleList: '#schedule-list' 12 | }); 13 | 14 | MazmurApp.on('initialize:before', function(options){ 15 | MazmurApp.lagus = new MazmurApp.LaguCollection(); 16 | MazmurApp.lagus.fetch(); 17 | }); -------------------------------------------------------------------------------- /js/schedule.js: -------------------------------------------------------------------------------- 1 | (function(MazmurApp) { 2 | MazmurApp.addInitializer(function() { 3 | MazmurApp.Schedule.init(); 4 | MazmurApp.Schedule.show(MazmurApp.schedules); 5 | }); 6 | 7 | MazmurApp.Schedule = { 8 | init: function() { 9 | MazmurApp.schedules = new MazmurApp.LaguCollection(); 10 | }, 11 | show: function(lagus) { 12 | var scheduleList = new MazmurApp.LaguViewList({ 13 | collection: lagus 14 | }); 15 | MazmurApp.scheduleList.show(scheduleList); 16 | } 17 | }; 18 | })(MazmurApp); -------------------------------------------------------------------------------- /css/show.css: -------------------------------------------------------------------------------- 1 | html {overflow-x:hidden;} 2 | body {margin:0; padding:0} 3 | 4 | video, object { 5 | top:0;left:0; 6 | width: 100%; 7 | height: 100%; 8 | /*background: #000;*/ 9 | position:absolute; 10 | } 11 | #imageWrap, #videoWrap { 12 | display: hidden; 13 | /*width: 100%; 14 | height: 100%;*/ 15 | /*background: #000;*/ 16 | } 17 | 18 | #blackSlide { 19 | z-index: 10; 20 | display: none; 21 | background: #000; 22 | position: absolute; 23 | top:0; 24 | left:0; 25 | width: 100%; 26 | height: 100%; 27 | } -------------------------------------------------------------------------------- /css/vendor/jquery.maximage.min.css: -------------------------------------------------------------------------------- 1 | /*! Version: 2.0.73 (12-Oct-2012) */.mc-hide-scrolls{overflow:hidden}body .mc-cycle{height:100%;left:0;overflow:hidden;position:fixed;top:0;width:100%;z-index:-1}div.mc-image{-webkit-transition:opacity 1s ease-in-out;-moz-transition:opacity 1s ease-in-out;-o-transition:opacity 1s ease-in-out;transition:opacity 1s ease-in-out;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;background-position:center center;background-repeat:no-repeat;height:100%;overflow:hidden;width:100%}.mc-old-browser .mc-image{overflow:hidden} -------------------------------------------------------------------------------- /data/lagu.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "judul": "Sungguh Besar Setia-Mu", 4 | "lirik": "sungguh besar setia-Mu\n\nnyata di sepanjang hidupku\n\nchorus\nKu tinggikan Engkau Tuhan\n\nmelebihi segalanya" 5 | }, 6 | { 7 | "judul": "Anug'rah-Mu Kepadaku", 8 | "lirik": "anugrah-Mu kepadaku\n\ntak pernah berubah\n\nperbauatan-Mu terlukiskan" 9 | }, 10 | { 11 | "judul": "Sungai Sukacita", 12 | "lirik": "sungai sukacitaku mengalir dalam-Mu\n\noh yeah, yes,yes,yes" 13 | }, 14 | { 15 | "judul": "T'rima Sukacita Surga", 16 | "lirik": "t'rima sukacita surga\n\nitulah kekuatan bagi jiwa" 17 | } 18 | ] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | mazmur 2 | ====== 3 | 4 | Church Worship Lyrics Presentation Web Application 5 | 6 | ![mazmur screenshot](https://fbcdn-sphotos-d-a.akamaihd.net/hphotos-ak-prn1/1014013_10201064598689969_1257027394_n.jpg) 7 | 8 | Technology Stack 9 | ---------------- 10 | 11 | 1. Backbone.js 12 | 2. Marionette.js 13 | 3. Reveal.js 14 | 4. jQuery 15 | 16 | Features 17 | -------- 18 | 1. Lyrics input form 19 | 2. Background image and video 20 | 3. Schedule (in progress) 21 | 22 | Usage 23 | ----- 24 | 25 | 1. Install Node.js 26 | 2. Download this repository 27 | 3. Open command prompt, and `cd` to this directory. 28 | 4. `npm install -g pushserve` to install the server 29 | 5. `pushserve` in this directory will serve to localhost 30 | 6. open in your browser `http://localhost:8000/` 31 | 32 | Video Demo 33 | ---------- 34 | https://www.youtube.com/watch?v=7rVbCwQRVYI 35 | -------------------------------------------------------------------------------- /js/laguEntity.js: -------------------------------------------------------------------------------- 1 | (function(MazmurApp) { 2 | 3 | MazmurApp.Lagu = Backbone.Model.extend({ 4 | initialize: function() { 5 | var selectable = new Backbone.Picky.Selectable(this); 6 | _.extend(this, selectable); 7 | }, 8 | selector: null, 9 | match: function(select) { 10 | this.selector = select; 11 | return ( 12 | select.search_text.length == 0 || 13 | (select.search_text.length > 0 && 14 | _.chain( 15 | _.values( 16 | _.pick(this.attributes, 'judul', 'lirik') 17 | ) 18 | ) 19 | .any( 20 | function (s) { 21 | return s.toLowerCase().indexOf(select.search_text.toLowerCase()) > -1; 22 | } 23 | ) 24 | .value() 25 | ) 26 | ); 27 | } 28 | }); 29 | 30 | MazmurApp.LaguCollection = Backbone.Collection.extend({ 31 | model: MazmurApp.Lagu, 32 | // url: '/lagus', 33 | initialize: function(options) { 34 | var singleSelect = new Backbone.Picky.SingleSelect(this); 35 | _.extend(this, singleSelect); 36 | }, 37 | localStorage: new Backbone.LocalStorage("LaguCollection") 38 | }); 39 | 40 | })(MazmurApp); -------------------------------------------------------------------------------- /css/vendor/jquery.splitter.css: -------------------------------------------------------------------------------- 1 | 2 | .splitter { 3 | height-x: 400px; 4 | height-x: 50%; 5 | height: calc(100% - 180px); 6 | height: -moz-calc(100% - 180px); 7 | height: -webkit-calc(100% - 180px); 8 | margin: 1em 3em; 9 | /*border: 4px solid #bdb;*/ 10 | /*background: #f8fff8;*/ 11 | boo: 45px; 12 | } 13 | 14 | .ui-state-default { background-color: #aca } 15 | .ui-state-hover { background-color: #bdb } 16 | .ui-state-highlight { background-color: #add } 17 | .ui-state-error { background-color: #eaa } 18 | 19 | .splitter-pane { 20 | overflow: auto; 21 | } 22 | .splitter-bar-vertical { 23 | width: 6px; 24 | height-x: 100%; 25 | background-image: url(../img/splitter/vgrabber.gif); 26 | background-repeat: no-repeat; 27 | background-position: center; 28 | } 29 | 30 | .splitter-bar-vertical-docked { 31 | width: 10px; 32 | background-image: url(../img/splitter/vdockbar-trans.gif); 33 | background-repeat: no-repeat; 34 | background-position: center; 35 | } 36 | .splitter-bar.ui-state-highlight { 37 | opacity: 0.7; 38 | } 39 | .splitter-iframe-hide { 40 | visibility: hidden; 41 | } 42 | #contentPanel { 43 | padding: 0; 44 | margin: 0; 45 | margin-top: -20px; 46 | } 47 | #livePanel { 48 | margin:0; 49 | padding: 0; 50 | } -------------------------------------------------------------------------------- /js/addEdit.js: -------------------------------------------------------------------------------- 1 | (function(MazmurApp) { 2 | MazmurApp.addInitializer(function() { 3 | MazmurApp.AddEditLagu.init(); 4 | }); 5 | 6 | MazmurApp.AddEditLagu = { 7 | init: function () { 8 | this.mainRegion = MazmurApp.laguForm; 9 | $('a#removeAdd').click(this.removeAdd); 10 | }, 11 | addEditLagu: function(lagu) { 12 | var addEditLaguView = new AddEditLaguView({ 13 | model: lagu 14 | }); 15 | this.mainRegion.show(addEditLaguView); 16 | MazmurApp.laguForm.$el.hide().slideDown('slow'); 17 | } 18 | }; 19 | 20 | var AddEditLaguView = Marionette.ItemView.extend({ 21 | template: '#form-lagu-template', 22 | events: { 23 | 'click #simpan': 'saveLagu', 24 | 'click #removeAdd': 'removeAdd', 25 | }, 26 | saveLagu: function (e) { 27 | e.preventDefault(); 28 | var data = Backbone.Syphon.serialize(this); 29 | this.collection = MazmurApp.lagus; 30 | if (MazmurApp.lagus.selected) { 31 | this.model.set(data); 32 | this.model.save(); 33 | MazmurApp.lagus.deselect(); 34 | MazmurApp.lagus.select(this.model); 35 | } else { 36 | console.log(data); 37 | this.collection.create(data, { 38 | success: function(lagu) { 39 | MazmurApp.lagus.add(lagu); 40 | MazmurApp.lagus.select(lagu); 41 | } 42 | }); 43 | } 44 | MazmurApp.laguForm.reset(); 45 | MazmurApp.laguForm.$el.show().slideUp('slow'); 46 | }, 47 | removeAdd: function() { 48 | MazmurApp.laguForm.$el.show().slideUp('slow'); 49 | } 50 | }); 51 | 52 | 53 | })(MazmurApp); -------------------------------------------------------------------------------- /css/vendor/theme/README.md: -------------------------------------------------------------------------------- 1 | ## Dependencies 2 | 3 | Themes are written using Sass to keep things modular and reduce the need for repeated selectors across files. Make sure that you have the reveal.js development environment including the Grunt dependencies installed before proceding: https://github.com/hakimel/reveal.js#full-setup 4 | 5 | 6 | 7 | ## Creating a Theme 8 | 9 | To create your own theme, start by duplicating any ```.scss``` file in [/css/theme/source](https://github.com/hakimel/reveal.js/blob/master/css/theme/source) and adding it to the compilation list in the [Gruntfile](https://github.com/hakimel/reveal.js/blob/master/Gruntfile.js). 10 | 11 | Each theme file does four things in the following order: 12 | 13 | 1. **Include [/css/theme/template/mixins.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/mixins.scss)** 14 | Shared utility functions. 15 | 16 | 2. **Include [/css/theme/template/settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss)** 17 | Declares a set of custom variables that the template file (step 4) expects. Can be overridden in step 3. 18 | 19 | 3. **Override** 20 | This is where you override the default theme. Either by specifying variables (see [settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss) for reference) or by adding full selectors with hardcoded styles. 21 | 22 | 4. **Include [/css/theme/template/theme.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/theme.scss)** 23 | The template theme file which will generate final CSS output based on the currently defined variables. 24 | -------------------------------------------------------------------------------- /js/vendor/backbone.picky.min.js: -------------------------------------------------------------------------------- 1 | // Backbone.Picky, v0.1.0 2 | // Copyright (c)2012 Derick Bailey, Muted Solutions, LLC. 3 | // Distributed under MIT license 4 | // http://github.com/derickbailey/backbone.picky 5 | Backbone.Picky=function(a,b){var c={};c.SingleSelect=function(a){this.collection=a},b.extend(c.SingleSelect.prototype,{select:function(a){if(a&&this.selected===a)return;this.deselect(),this.selected=a,this.selected.select(),this.trigger("selected",a)},deselect:function(a){if(!this.selected)return;a=a||this.selected;if(this.selected!==a)return;this.selected.deselect(),this.trigger("deselected",this.selected),delete this.selected}}),c.MultiSelect=function(a){this.collection=a,this.selected={}},b.extend(c.MultiSelect.prototype,{select:function(a){if(this.selected[a.cid])return;this.selected[a.cid]=a,a.select(),d(this)},deselect:function(a){if(!this.selected[a.cid])return;delete this.selected[a.cid],a.deselect(),d(this)},selectAll:function(){this.each(function(a){a.select()}),d(this)},selectNone:function(){if(this.selectedLength===0)return;this.each(function(a){a.deselect()}),d(this)},toggleSelectAll:function(){this.selectedLength===this.length?this.selectNone():this.selectAll()}}),c.Selectable=function(a){this.model=a},b.extend(c.Selectable.prototype,{select:function(){if(this.selected)return;this.selected=!0,this.trigger("selected"),this.collection&&this.collection.select(this)},deselect:function(){if(!this.selected)return;this.selected=!1,this.trigger("deselected"),this.collection&&this.collection.deselect(this)},toggleSelected:function(){this.selected?this.deselect():this.select()}});var d=function(a){a.selectedLength=b.size(a.selected);var c=a.selectedLength,d=a.length;if(c===d){a.trigger("select:all",a);return}if(c===0){a.trigger("select:none",a);return}if(c>0&&c 4 | based on dark.css by Ivan Sagalaev 5 | 6 | */ 7 | 8 | pre code { 9 | display: block; padding: 0.5em; 10 | background: #3F3F3F; 11 | color: #DCDCDC; 12 | } 13 | 14 | pre .keyword, 15 | pre .tag, 16 | pre .django .tag, 17 | pre .django .keyword, 18 | pre .css .class, 19 | pre .css .id, 20 | pre .lisp .title { 21 | color: #E3CEAB; 22 | } 23 | 24 | pre .django .template_tag, 25 | pre .django .variable, 26 | pre .django .filter .argument { 27 | color: #DCDCDC; 28 | } 29 | 30 | pre .number, 31 | pre .date { 32 | color: #8CD0D3; 33 | } 34 | 35 | pre .dos .envvar, 36 | pre .dos .stream, 37 | pre .variable, 38 | pre .apache .sqbracket { 39 | color: #EFDCBC; 40 | } 41 | 42 | pre .dos .flow, 43 | pre .diff .change, 44 | pre .python .exception, 45 | pre .python .built_in, 46 | pre .literal, 47 | pre .tex .special { 48 | color: #EFEFAF; 49 | } 50 | 51 | pre .diff .chunk, 52 | pre .ruby .subst { 53 | color: #8F8F8F; 54 | } 55 | 56 | pre .dos .keyword, 57 | pre .python .decorator, 58 | pre .class .title, 59 | pre .haskell .label, 60 | pre .function .title, 61 | pre .ini .title, 62 | pre .diff .header, 63 | pre .ruby .class .parent, 64 | pre .apache .tag, 65 | pre .nginx .built_in, 66 | pre .tex .command, 67 | pre .input_number { 68 | color: #efef8f; 69 | } 70 | 71 | pre .dos .winutils, 72 | pre .ruby .symbol, 73 | pre .ruby .symbol .string, 74 | pre .ruby .symbol .keyword, 75 | pre .ruby .symbol .keymethods, 76 | pre .ruby .string, 77 | pre .ruby .instancevar { 78 | color: #DCA3A3; 79 | } 80 | 81 | pre .diff .deletion, 82 | pre .string, 83 | pre .tag .value, 84 | pre .preprocessor, 85 | pre .built_in, 86 | pre .sql .aggregate, 87 | pre .javadoc, 88 | pre .smalltalk .class, 89 | pre .smalltalk .localvars, 90 | pre .smalltalk .array, 91 | pre .css .rules .value, 92 | pre .attr_selector, 93 | pre .pseudo, 94 | pre .apache .cbracket, 95 | pre .tex .formula { 96 | color: #CC9393; 97 | } 98 | 99 | pre .shebang, 100 | pre .diff .addition, 101 | pre .comment, 102 | pre .java .annotation, 103 | pre .template_comment, 104 | pre .pi, 105 | pre .doctype { 106 | color: #7F9F7F; 107 | } 108 | 109 | pre .xml .css, 110 | pre .xml .javascript, 111 | pre .xml .vbscript, 112 | pre .tex .formula { 113 | opacity: 0.5; 114 | } 115 | 116 | -------------------------------------------------------------------------------- /js/previewList.js: -------------------------------------------------------------------------------- 1 | (function(MazmurApp) { 2 | MazmurApp.addInitializer(function(){ 3 | MazmurApp.PreviewList.init(); 4 | }); 5 | 6 | MazmurApp.PreviewList = { 7 | init: function() { 8 | this.laguList = MazmurApp.laguList; 9 | MazmurApp.previewList.show(new MazmurApp.PreviewListView()); 10 | }, 11 | show: function(lagu) { 12 | var previewText = lagu.get('lirik'); 13 | this.previewTemp = new MazmurApp.LirikCollection(true); 14 | MazmurApp.LirikViewer.parse(previewText, this.previewTemp); 15 | var previewList = new MazmurApp.PreviewListView({ 16 | collection: this.previewTemp 17 | }); 18 | MazmurApp.previewList.show(previewList); 19 | } 20 | }; 21 | 22 | MazmurApp.PreviewView = Marionette.ItemView.extend({ 23 | tagName: 'li', 24 | template: '#lirik-view-template', 25 | events: { 26 | 'click a.lirik-preview': 'lirikClicked', 27 | 'dblclick a.lirik-preview': 'lirikSelect', 28 | }, 29 | initialize: function () { 30 | this.model.bind('selected', this.lirikSelected, this); 31 | this.model.bind('deselected', this.lirikDeselected, this); 32 | this.model.bind('dblclicked', this.lirikSelect, this); 33 | }, 34 | lirikClicked: function(e) { 35 | e.preventDefault(); 36 | this.model.select(); 37 | }, 38 | lirikSelect: function() { 39 | MazmurApp.LirikViewer.show(MazmurApp.lagus.selected); 40 | lirikData.findWhere({ctr: this.model.get('ctr')}).select(); 41 | }, 42 | lirikSelected: function() { 43 | this.$el.addClass('active'); 44 | }, 45 | lirikDeselected: function() { 46 | this.$el.removeClass('active'); 47 | } 48 | }); 49 | 50 | MazmurApp.PreviewListView = Marionette.CompositeView.extend({ 51 | itemView: MazmurApp.PreviewView, 52 | itemViewContainer: "#preview-items", 53 | template: "#preview-template", 54 | events: { 55 | // 'drop #uploadBg': 'dropFile' 56 | 'change #uploadBg': 'dropFile' 57 | }, 58 | dropFile: function(e) { 59 | if (e.currentTarget.files.length) { 60 | e.preventDefault(); 61 | e.stopPropagation(); 62 | var file = e.currentTarget.files[0]; 63 | var type = file.type; 64 | currentBg = file; 65 | $('#bgName').html(file.name); 66 | // windowPreview.changeBg(file); 67 | } 68 | // if(e.originalEvent.dataTransfer){ 69 | // if(e.originalEvent.dataTransfer.files.length) { 70 | // e.preventDefault(); 71 | // e.stopPropagation(); 72 | // var file = e.originalEvent.dataTransfer.files[0]; 73 | // var type = file.type; 74 | // windowPreview.changeBg(file); 75 | // } 76 | // } 77 | } 78 | }); 79 | 80 | })(MazmurApp); 81 | -------------------------------------------------------------------------------- /js/vendor/backbone.localStorage-min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Backbone localStorage Adapter 3 | * Version 1.1.6 4 | * 5 | * https://github.com/jeromegn/Backbone.localStorage 6 | */(function(a,b){typeof exports=="object"&&a.require?module.exports=b(require("underscore"),require("backbone")):typeof define=="function"&&define.amd?define(["underscore","backbone"],function(c,d){return b(c||a._,d||a.Backbone)}):b(_,Backbone)})(this,function(a,b){function c(){return((1+Math.random())*65536|0).toString(16).substring(1)}function d(){return c()+c()+"-"+c()+"-"+c()+"-"+c()+"-"+c()+c()+c()}return b.LocalStorage=window.Store=function(a){if(!this.localStorage)throw"Backbone.localStorage: Environment does not support localStorage.";this.name=a;var b=this.localStorage().getItem(this.name);this.records=b&&b.split(",")||[]},a.extend(b.LocalStorage.prototype,{save:function(){this.localStorage().setItem(this.name,this.records.join(","))},create:function(a){return a.id||(a.id=d(),a.set(a.idAttribute,a.id)),this.localStorage().setItem(this.name+"-"+a.id,JSON.stringify(a)),this.records.push(a.id.toString()),this.save(),this.find(a)},update:function(b){return this.localStorage().setItem(this.name+"-"+b.id,JSON.stringify(b)),a.include(this.records,b.id.toString())||this.records.push(b.id.toString()),this.save(),this.find(b)},find:function(a){return this.jsonData(this.localStorage().getItem(this.name+"-"+a.id))},findAll:function(){return(a.chain||a)(this.records).map(function(a){return this.jsonData(this.localStorage().getItem(this.name+"-"+a))},this).compact().value()},destroy:function(b){return b.isNew()?!1:(this.localStorage().removeItem(this.name+"-"+b.id),this.records=a.reject(this.records,function(a){return a===b.id.toString()}),this.save(),b)},localStorage:function(){return localStorage},jsonData:function(a){return a&&JSON.parse(a)},_clear:function(){var b=this.localStorage(),c=new RegExp("^"+this.name+"-");b.removeItem(this.name),(a.chain||a)(b).keys().filter(function(a){return c.test(a)}).each(function(a){b.removeItem(a)}),this.records.length=0},_storageSize:function(){return this.localStorage().length}}),b.LocalStorage.sync=window.Store.sync=b.localSync=function(a,c,d){var e=c.localStorage||c.collection.localStorage,f,g,h=b.$.Deferred&&b.$.Deferred();try{switch(a){case"read":f=c.id!=undefined?e.find(c):e.findAll();break;case"create":f=e.create(c);break;case"update":f=e.update(c);break;case"delete":f=e.destroy(c)}}catch(i){i.code===22&&e._storageSize()===0?g="Private browsing is unsupported":g=i.message}return f?(d&&d.success&&(b.VERSION==="0.9.10"?d.success(c,f,d):d.success(f)),h&&h.resolve(f)):(g=g?g:"Record Not Found",d&&d.error&&(b.VERSION==="0.9.10"?d.error(c,g,d):d.error(g)),h&&h.reject(g)),d&&d.complete&&d.complete(f),h&&h.promise()},b.ajaxSync=b.sync,b.getSyncMethod=function(a){return a.localStorage||a.collection&&a.collection.localStorage?b.localSync:b.ajaxSync},b.sync=function(a,c,d){return b.getSyncMethod(c).apply(this,[a,c,d])},b.LocalStorage}); -------------------------------------------------------------------------------- /js/presenter.js: -------------------------------------------------------------------------------- 1 | var windowPreview; 2 | 3 | (function(MazmurApp) { 4 | 5 | MazmurApp.addInitializer(function(){ 6 | MazmurApp.Presenter.init(); 7 | }); 8 | 9 | MazmurApp.LirikViewList = Marionette.CompositeView.extend({ 10 | itemView: MazmurApp.LirikView, 11 | itemViewContainer: "#live-items", 12 | template: "#live-template", 13 | events: { 14 | 'click a#livePreview': 'livePreview', 15 | 'click a#clearPreview': 'clearPreview', 16 | 'click a#blankPreview': 'blankPreview', 17 | 18 | }, 19 | livePreview: function(e) { 20 | e.preventDefault(); 21 | if (typeof(windowPreview)!='undefined' && !windowPreview.closed) { 22 | windowPreview.close(); 23 | $(e.currentTarget).find('span').attr('class', 'fui-play'); 24 | } else { 25 | windowPreview = window.open("show.html", "_blank", "channelmode=yes, fullscreen=yes"); 26 | $(e.currentTarget).find('span').attr('class', 'fui-pause'); 27 | } 28 | }, 29 | clearPreview: function(e) { 30 | e.preventDefault(); 31 | if (typeof(windowPreview)!='undefined' && !windowPreview.closed) { 32 | if ($(e.currentTarget).find('span').attr('class') == 'fui-eye') { 33 | windowPreview.clearSlide(true); 34 | $(e.currentTarget).find('span').attr('class', 'fui-cross'); 35 | } else { 36 | windowPreview.clearSlide(false); 37 | $(e.currentTarget).find('span').attr('class', 'fui-eye'); 38 | } 39 | } 40 | }, 41 | blankPreview: function(e) { 42 | e.preventDefault(); 43 | if (typeof(windowPreview)!='undefined' && !windowPreview.closed) { 44 | if ($(e.currentTarget).find('span').attr('class') == 'fui-radio-unchecked') { 45 | windowPreview.blankSlide(true); 46 | $(e.currentTarget).find('span').attr('class', 'fui-radio-checked'); 47 | } else { 48 | windowPreview.blankSlide(false); 49 | $(e.currentTarget).find('span').attr('class', 'fui-radio-unchecked'); 50 | } 51 | } 52 | } 53 | }); 54 | 55 | MazmurApp.Presenter = { 56 | init: function() { 57 | _.bindAll(this, 'keyDown'); 58 | $(document).on('keydown', this.keyDown); 59 | }, 60 | keyDown: function(e) { 61 | // console.log(e.keyCode); 62 | // if (e.target.tagName.toLowerCase() !== 'input' && 63 | // e.target.tagName.toLowerCase() !== 'textarea' && e.which == 46) { 64 | if (e.target.tagName.toLowerCase() != 'input' && e.target.tagName.toLowerCase() != 'textarea') { 65 | if (e.keyCode == 38 || e.keyCode == 33) { 66 | //prev 67 | MazmurApp.vent.trigger('prevSlide'); 68 | } else if (e.keyCode == 40 || e.keyCode == 32 || e.keyCode == 34) { 69 | //next 70 | MazmurApp.vent.trigger('nextSlide'); 71 | } else if (e.keyCode == 37) { 72 | //prevLagu 73 | // MazmurApp.vent.trigger('prevLagu'); 74 | } else if (e.keyCode == 39) { 75 | //nextLagu 76 | // MazmurApp.vent.trigger('nextLagu'); 77 | } 78 | } 79 | // } 80 | } 81 | }; 82 | 83 | })(MazmurApp); 84 | -------------------------------------------------------------------------------- /js/lirikViewer.js: -------------------------------------------------------------------------------- 1 | (function(MazmurApp) { 2 | MazmurApp.addInitializer(function() { 3 | MazmurApp.LirikViewer.init(); 4 | }); 5 | 6 | MazmurApp.LirikViewer = { 7 | init: function() { 8 | lirikData = new MazmurApp.LirikCollection(); 9 | MazmurApp.lirikList.show(new MazmurApp.LirikViewList()); 10 | }, 11 | parse: function(lirikText, lirikData) { 12 | var parsed = lirikText.split('\n\n'); 13 | var ctr = 0; 14 | lirikData.reset(); 15 | _.each(parsed, function(baris) { 16 | baris = $.trim(baris); 17 | var caption = (baris.substring(0, 6).toLowerCase() == 'chorus'); 18 | if (caption) baris = baris.substring(7, baris.length); 19 | baris = baris.replace('\n','
'); 20 | var lirik = new MazmurApp.Lirik({caption: caption, ctr: ctr, lirik: baris}); 21 | lirikData.push(lirik); 22 | ctr++; 23 | }, this); 24 | }, 25 | show: function(lagu) { 26 | var lirikText = lagu.get('lirik'); 27 | this.parse(lirikText, lirikData); 28 | this.lirikViewList = new MazmurApp.LirikViewList({ 29 | collection: lirikData 30 | }); 31 | MazmurApp.lirikList.show(this.lirikViewList); 32 | if (typeof(windowPreview)!='undefined' && !windowPreview.closed) { 33 | windowPreview.PresenterApp.init({lirikData: lirikData.toJSON()}); 34 | if (currentBg) { 35 | console.log(currentBg); 36 | windowPreview.changeBg(currentBg); 37 | } 38 | windowPreview.blankSlide(false); 39 | } 40 | } 41 | }; 42 | 43 | MazmurApp.Lirik = Backbone.Model.extend({ 44 | initialize: function() { 45 | var selectable = new Backbone.Picky.Selectable(this); 46 | _.extend(this, selectable); 47 | }, 48 | }); 49 | 50 | MazmurApp.LirikCollection = Backbone.Collection.extend({ 51 | model: MazmurApp.Lirik, 52 | initialize: function(options) { 53 | var singleSelect = new Backbone.Picky.SingleSelect(this); 54 | _.extend(this, singleSelect); 55 | if (!options) { 56 | MazmurApp.vent.bind("prevSlide", this.prevSlide, this); 57 | MazmurApp.vent.bind("nextSlide", this.nextSlide, this); 58 | } 59 | }, 60 | prevSlide: function() { 61 | var index = this.indexOf(this.selected); 62 | if (index > 0){ 63 | index -= 1; 64 | } else { 65 | index = this.length - 1; 66 | } 67 | var lirik = this.at(index); 68 | lirik.select(); 69 | }, 70 | nextSlide: function() { 71 | var index = this.indexOf(this.selected); 72 | if (index < this.length - 1){ 73 | index += 1; 74 | } else { 75 | index = 0; 76 | } 77 | var lirik = this.at(index); 78 | lirik.select(); 79 | } 80 | }); 81 | 82 | MazmurApp.LirikView = Marionette.ItemView.extend({ 83 | tagName: 'li', 84 | template: '#lirik-view-template', 85 | events: { 86 | 'click a.lirik-preview': 'lirikClicked', 87 | }, 88 | initialize: function () { 89 | this.model.bind('selected', this.lirikSelected, this); 90 | this.model.bind('deselected', this.lirikDeselected, this); 91 | }, 92 | lirikClicked: function(e) { 93 | e.preventDefault(); 94 | this.model.select(); 95 | }, 96 | lirikSelected: function() { 97 | this.$el.addClass('active'); 98 | if (typeof(windowPreview)!='undefined' && !windowPreview.closed) 99 | windowPreview.changeSlide(this.model.get('ctr')); 100 | }, 101 | lirikDeselected: function() { 102 | this.$el.removeClass('active'); 103 | } 104 | }); 105 | 106 | })(MazmurApp); 107 | 108 | -------------------------------------------------------------------------------- /js/vendor/backbone.syphon.min.js: -------------------------------------------------------------------------------- 1 | // Backbone.Syphon, v0.4.1 2 | // Copyright (c)2012 Derick Bailey, Muted Solutions, LLC. 3 | // Distributed under MIT license 4 | // http://github.com/derickbailey/backbone.syphon 5 | Backbone.Syphon=function(a,b,c){var d={};d.ignoredTypes=["button","submit","reset","fieldset"],d.serialize=function(a,d){var g={},j=h(d),k=e(a,j);return c.each(k,function(a){var c=b(a),d=f(c),e=j.keyExtractors.get(d),h=e(c),k=j.inputReaders.get(d),l=k(c),m=j.keyAssignmentValidators.get(d);if(m(c,h,l)){var n=j.keySplitter(h);g=i(g,n,l)}}),g},d.deserialize=function(a,d,g){var i=h(g),k=e(a,i),l=j(i,d);c.each(k,function(a){var c=b(a),d=f(c),e=i.keyExtractors.get(d),g=e(c),h=i.inputWriters.get(d),j=l[g];h(c,j)})};var e=function(a,d){var e=g(a),h=e.elements;return h=c.reject(h,function(a){var e,g=f(a),h=d.keyExtractors.get(g),i=h(b(a)),j=c.include(d.ignoredTypes,g),k=c.include(d.include,i),l=c.include(d.exclude,i);return k?e=!1:d.include?e=!0:e=l||j,e}),h},f=function(a){var c,d=b(a),e=d[0].tagName,f=e;return e.toLowerCase()==="input"&&(c=d.attr("type"),c?f=c:f="text"),f.toLowerCase()},g=function(a){return c.isUndefined(a.$el)&&a.tagName.toLowerCase()==="form"?a:a.$el.is("form")?a.el:a.$("form")[0]},h=function(a){var b=c.clone(a)||{};return b.ignoredTypes=c.clone(d.ignoredTypes),b.inputReaders=b.inputReaders||d.InputReaders,b.inputWriters=b.inputWriters||d.InputWriters,b.keyExtractors=b.keyExtractors||d.KeyExtractors,b.keySplitter=b.keySplitter||d.KeySplitter,b.keyJoiner=b.keyJoiner||d.KeyJoiner,b.keyAssignmentValidators=b.keyAssignmentValidators||d.KeyAssignmentValidators,b},i=function(a,b,d){if(!b)return a;var e=b.shift();return a[e]||(a[e]=c.isArray(e)?[]:{}),b.length===0&&(c.isArray(a[e])?a[e].push(d):a[e]=d),b.length>0&&i(a[e],b,d),a},j=function(a,b,d){var e={};return c.each(b,function(b,f){var g={};d&&(f=a.keyJoiner(d,f)),c.isArray(b)?(f+="[]",g[f]=b):c.isObject(b)?g=j(a,b,f):g[f]=b,c.extend(e,g)}),e};return d}(Backbone,jQuery,_),Backbone.Syphon.TypeRegistry=function(){this.registeredTypes={}},Backbone.Syphon.TypeRegistry.extend=Backbone.Model.extend,_.extend(Backbone.Syphon.TypeRegistry.prototype,{get:function(a){var b=this.registeredTypes[a];return b||(b=this.registeredTypes["default"]),b},register:function(a,b){this.registeredTypes[a]=b},registerDefault:function(a){this.registeredTypes["default"]=a},unregister:function(a){this.registeredTypes[a]&&delete this.registeredTypes[a]}}),Backbone.Syphon.KeyExtractorSet=Backbone.Syphon.TypeRegistry.extend(),Backbone.Syphon.KeyExtractors=new Backbone.Syphon.KeyExtractorSet,Backbone.Syphon.KeyExtractors.registerDefault(function(a){return a.prop("name")}),Backbone.Syphon.InputReaderSet=Backbone.Syphon.TypeRegistry.extend(),Backbone.Syphon.InputReaders=new Backbone.Syphon.InputReaderSet,Backbone.Syphon.InputReaders.registerDefault(function(a){return a.val()}),Backbone.Syphon.InputReaders.register("checkbox",function(a){var b=a.prop("checked");return b}),Backbone.Syphon.InputWriterSet=Backbone.Syphon.TypeRegistry.extend(),Backbone.Syphon.InputWriters=new Backbone.Syphon.InputWriterSet,Backbone.Syphon.InputWriters.registerDefault(function(a,b){a.val(b)}),Backbone.Syphon.InputWriters.register("checkbox",function(a,b){a.prop("checked",b)}),Backbone.Syphon.InputWriters.register("radio",function(a,b){a.prop("checked",a.val()===b)}),Backbone.Syphon.KeyAssignmentValidatorSet=Backbone.Syphon.TypeRegistry.extend(),Backbone.Syphon.KeyAssignmentValidators=new Backbone.Syphon.KeyAssignmentValidatorSet,Backbone.Syphon.KeyAssignmentValidators.registerDefault(function(){return!0}),Backbone.Syphon.KeyAssignmentValidators.register("radio",function(a,b,c){return a.prop("checked")}),Backbone.Syphon.KeySplitter=function(a){var b=a.match(/[^\[\]]+/g);return a.indexOf("[]")===a.length-2&&(lastKey=b.pop(),b.push([lastKey])),b},Backbone.Syphon.KeyJoiner=function(a,b){return a+"["+b+"]"}; -------------------------------------------------------------------------------- /index-lama.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mazmur Online 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 42 |
43 |

44 | 45 | Church Presentation Online 46 |

47 | Try Mazmur Online Now! 48 |
49 |
50 |
51 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Officia, porro, modi, quo incidunt cupiditate
doloremque voluptates ea repellendus odit enim dolorum consequatur a distinctio deleniti vel officiis ut omnis ipsa.

52 |
53 |
54 |
55 |
56 |
57 | 58 |

Organized

59 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Esse, nam obcaecati beatae quibusdam recusandae nihil a! Vero, beatae dolorum exercitationem itaque fugit facilis magnam pariatur ipsam quibusdam repellat officia quidem.

60 |
61 |
62 | 63 |

Cloudy

64 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolores, fugiat, repellendus, aliquam, adipisci ipsa illo accusantium ipsam optio molestias nihil incidunt obcaecati possimus non error eos aspernatur deserunt iure nisi?

65 |
66 |
67 | 68 |

Collaborative

69 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos, veritatis, rem, modi laudantium repellat incidunt earum voluptatum quas praesentium illo accusantium magnam dolorum quidem magni temporibus tempore totam nisi similique?

70 |
71 |
72 |
73 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: url(../img/bg.png); 3 | padding-top: 0; 4 | /*height: 100%;*/ 5 | /*font-size: 16px;*/ 6 | } 7 | @media (min-width:979px) { 8 | body { 9 | position: relative; 10 | padding-top: 70px; 11 | } 12 | } 13 | a { 14 | text-decoration: none; 15 | } 16 | #hover-items, #live-items, #lagu-list{ 17 | /*max-height: 480px;*/ 18 | height: 10%; 19 | overflow: auto; 20 | } 21 | #uploadBg{ 22 | border:3px dashed #2c3e50; 23 | border-radius: 8px; 24 | float:right; 25 | padding: 4px; 26 | margin-right: 10px; 27 | width: 90px; 28 | cursor: pointer; 29 | } 30 | /* Flat Box */ 31 | .box { 32 | background-color: #2c3e50; 33 | color: #798795; 34 | margin-bottom: 20px; 35 | -webkit-border-radius: 8px 8px 6px 6px; 36 | -moz-border-radius: 8px 8px 6px 6px; 37 | border-radius: 8px 8px 6px 6px; 38 | } 39 | .box ul { 40 | margin: 0; 41 | list-style-type: none; 42 | } 43 | .box li { 44 | background: #34495e 92% center no-repeat; 45 | cursor: pointer; 46 | margin-top: 2px; 47 | /*padding: 18px 42px 17px 25px;*/ 48 | position: relative; 49 | -webkit-transition: 0.25s; 50 | -moz-transition: 0.25s; 51 | -o-transition: 0.25s; 52 | transition: 0.25s; 53 | -webkit-backface-visibility: hidden; 54 | } 55 | .box li a.lagu-preview, .box li a.lirik-preview { 56 | display: block; 57 | padding: 10px 20px; 58 | } 59 | .menu-lagu { 60 | /*display: none;*/ 61 | opacity: 0; 62 | position: absolute; 63 | bottom: 0; 64 | right: 0; 65 | } 66 | /*a.lagu-preview:hover + .menu-lagu { 67 | display: block; 68 | opacity: 1; 69 | }*/ 70 | .menu-lagu:hover { 71 | opacity: 1; 72 | } 73 | .box li:hover { 74 | background: #2c3e50 92% center no-repeat; 75 | padding-left: 5px; 76 | } 77 | .box li:first-child { 78 | margin-top: 0; 79 | } 80 | .box li:last-child { 81 | -webkit-border-radius: 0 0 6px 6px; 82 | -moz-border-radius: 0 0 6px 6px; 83 | border-radius: 0 0 6px 6px; 84 | /*padding-bottom: 18px;*/ 85 | } 86 | .box li.active { 87 | background: #1abc9c 92% center no-repeat; 88 | color: #2c3e50; 89 | } 90 | .box li.active .box-name { 91 | color: #2c3e50; 92 | } 93 | .box-content { 94 | /*padding-top: 1px;*/ 95 | padding: 20px; 96 | overflow: hidden; 97 | } 98 | .box-name { 99 | color: #ffffff; 100 | font-size: 15px; 101 | margin: 1px 0 3px; 102 | } 103 | .box-icon { 104 | float: left; 105 | font-size: 20px; 106 | padding: 0px 10px 0 0; 107 | } 108 | .box-header { 109 | position: relative; 110 | background: #1abc9c; 111 | background-size: 16px 16px; 112 | border-radius: 6px 6px 0 0; 113 | color: #34495e; 114 | padding: 10px; 115 | } 116 | .box-header h4{ 117 | font-weight: bold; 118 | padding: 5px 0; 119 | margin: 0; 120 | line-height: 30px; 121 | } 122 | .box-search { 123 | position: relative; 124 | background: #1abc9c; 125 | background-size: 16px 16px; 126 | border-radius: 6px 6px 0 0; 127 | color: #34495e; 128 | padding: 19px 25px 20px; 129 | } 130 | input.box-search-field { 131 | background: #16A085; 132 | display: inline; 133 | border: none; 134 | color: #34495e; 135 | font-size: 19px; 136 | font-weight: 700; 137 | margin: 0; 138 | padding: 10px; 139 | line-height: 23px; 140 | /*padding: 5px 0;*/ 141 | text-indent: 0; 142 | -webkit-box-shadow: none; 143 | -moz-box-shadow: none; 144 | box-shadow: none; 145 | } 146 | input.box-search-field:-moz-placeholder { 147 | color: #34495e; 148 | } 149 | input.box-search-field::-webkit-input-placeholder { 150 | color: #34495e; 151 | } 152 | input.box-search-field.placeholder { 153 | color: #34495e; 154 | } 155 | 156 | /* Logo */ 157 | .demo-headline { 158 | padding: 40px 0; 159 | margin-top: -20px; 160 | text-align: center; 161 | background: #1abc9c; 162 | } 163 | .demo-description { 164 | padding: 30px 0; 165 | color: #fff; 166 | text-align: center; 167 | background: #2C3E50; 168 | } 169 | .demo-logo .logo { 170 | background: url(../img/logo.png) center 0 no-repeat; 171 | background-size: 550px 386px; 172 | height: 386px; 173 | overflow: hidden; 174 | /*padding-left: 550px; 175 | padding-right: -550px;*/ 176 | text-indent: -9999em; 177 | width: 550px; 178 | margin-bottom: 0; 179 | } 180 | .demo-logo small { 181 | color: #11866f; 182 | margin-top: -100px; 183 | margin-bottom: 0; 184 | } 185 | 186 | .mainmenu { 187 | background:url(../img/logosmall.png) no-repeat center; 188 | } 189 | 190 | .footer p{ 191 | padding: 30px; 192 | text-align: center; 193 | font-size: small; 194 | } 195 | 196 | .center{ 197 | text-align: center; 198 | padding: 30px; 199 | } -------------------------------------------------------------------------------- /js/laguList.js: -------------------------------------------------------------------------------- 1 | (function(MazmurApp) { 2 | MazmurApp.addInitializer(function(){ 3 | MazmurApp.LaguList.init(); 4 | MazmurApp.LaguList.show(MazmurApp.lagus); 5 | }); 6 | 7 | MazmurApp.LaguList = { 8 | init: function() { 9 | _.bindAll(this, 'addLagu', 'searchLagu'); 10 | this.laguList = MazmurApp.laguList; 11 | $('a#add-lagu').click(this.addLagu); 12 | $('a#load-lagu').click(this.loadLagu); 13 | $('input#search-lagu').on('input', this.searchLagu); 14 | }, 15 | show: function(lagus) { 16 | var laguList = new MazmurApp.LaguViewList({ 17 | collection: lagus 18 | }); 19 | this.laguList.show(laguList); 20 | }, 21 | addLagu: function(e) { 22 | e.preventDefault(); 23 | MazmurApp.lagus.deselect(); 24 | MazmurApp.AddEditLagu.addEditLagu(new MazmurApp.Lagu()); 25 | }, 26 | loadLagu: function(e) { 27 | e.preventDefault(); 28 | // var Lagu = Backbone.Model.extend({ 29 | // defaults: function() { 30 | // return { 31 | // title: "judul baru...", 32 | // content: "lirik baru..." 33 | // }; 34 | // }, 35 | // initialize: function() { 36 | // if (!this.get("title")) { 37 | // this.set({"title": this.defaults().title}); 38 | // } 39 | // }, 40 | // }); 41 | // var LaguList = Backbone.Firebase.Collection.extend({ 42 | // model: Lagu, 43 | // firebase: "https://kidung.firebaseio.com/songs", 44 | // done: function() { 45 | // console.log('finish'); 46 | // }, 47 | // }); 48 | // var Lagus = new LaguList(); 49 | // MazmurApp.lagus.reset(); 50 | // Lagus.on('add', function(e) { 51 | // var str = e.get('content'); 52 | // var regex = /]*>/gi; 53 | // console.log(str.replace(regex, "\n\n\n")); 54 | // // MazmurApp.lagus.create({judul: e.get('title'), lirik: str.replace(regex, "\n\n")}, { 55 | // // success: function(lagu) { 56 | // // // MazmurApp.lagus.select(lagu); 57 | // // } 58 | // // }) 59 | // }); 60 | // console.log(Lagus); 61 | 62 | // $.get('data/lagu.json', function (data) { 63 | // data.forEach(function(item) { 64 | // MazmurApp.lagus.create(item, { 65 | // success: function(lagu) { 66 | // MazmurApp.lagus.select(lagu); 67 | // } 68 | // }); 69 | // }); 70 | // }); 71 | }, 72 | searchLagu: function(e) { 73 | var search_text = $(e.currentTarget).val(); 74 | var selector = {search_text: $(e.currentTarget).val()}; 75 | var filtered = new MazmurApp.LaguCollection(); 76 | filtered.reset( MazmurApp.lagus.filter(function ( model ) { 77 | return model.match( selector ); 78 | })); 79 | if (search_text.length > 1) { 80 | $.get('http://smoothie.cloudapp.net/kidung/public/index.php/api/song/'+search_text, function(data) { 81 | data.forEach(function (item) { 82 | filtered.create(item, { 83 | success: function(lagu) { 84 | //success add lagu 85 | } 86 | }); 87 | }); 88 | }); 89 | } 90 | MazmurApp.LaguList.show(filtered); 91 | filtered.at(0).select(); 92 | } 93 | }; 94 | 95 | MazmurApp.LaguView = Marionette.ItemView.extend({ 96 | tagName: 'li', 97 | template: '#lagu-preview-template', 98 | events: { 99 | 'click a.lagu-preview': 'selectLagu', 100 | 'dblclick a.lagu-preview': 'lirikLagu', 101 | 'click a#edit-lagu': 'editLagu', 102 | 'click a#delete-lagu': 'deleteLagu', 103 | }, 104 | initialize: function() { 105 | this.model.bind('selected', this.laguSelected, this); 106 | this.model.bind('deselected', this.laguDeselected, this); 107 | }, 108 | selectLagu: function(e) { 109 | e.preventDefault(); 110 | this.model.select(); 111 | }, 112 | editLagu: function(e) { 113 | e.preventDefault(); 114 | MazmurApp.AddEditLagu.addEditLagu(this.model); 115 | }, 116 | deleteLagu: function(e) { 117 | e.preventDefault(); 118 | console.log('delete'); 119 | this.model.destroy(); 120 | }, 121 | laguSelected: function() { 122 | this.$el.addClass('active'); 123 | MazmurApp.PreviewList.show(this.model); 124 | MazmurApp.PreviewList.previewTemp.at(0).select(); 125 | }, 126 | lirikLagu: function() { 127 | MazmurApp.PreviewList.previewTemp.at(0).trigger('dblclicked'); 128 | }, 129 | laguDeselected: function() { 130 | this.$el.removeClass('active'); 131 | } 132 | }); 133 | 134 | MazmurApp.LaguViewList = Marionette.CollectionView.extend({ 135 | tagName: 'ul', 136 | itemView: MazmurApp.LaguView, 137 | initialize: function() { 138 | this.collection.on('change', this.render, this); 139 | } 140 | }); 141 | 142 | })(MazmurApp); 143 | -------------------------------------------------------------------------------- /css/vendor/theme/default.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); 2 | /** 3 | * Default theme for reveal.js. 4 | * 5 | * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 6 | */ 7 | @font-face { 8 | font-family: 'League Gothic'; 9 | src: url("../../lib/font/league_gothic-webfont.eot"); 10 | src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg"); 11 | font-weight: normal; 12 | font-style: normal; } 13 | 14 | /********************************************* 15 | * GLOBAL STYLES 16 | *********************************************/ 17 | body { 18 | background: #1c1e20; 19 | background: -moz-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); 20 | background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #555a5f), color-stop(100%, #1c1e20)); 21 | background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); 22 | background: -o-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); 23 | background: -ms-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); 24 | background: radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); 25 | background-color: #2b2b2b; } 26 | 27 | .reveal { 28 | font-family: "Lato", sans-serif; 29 | font-size: 36px; 30 | font-weight: 200; 31 | letter-spacing: -0.02em; 32 | color: #eeeeee; } 33 | 34 | ::selection { 35 | color: white; 36 | background: #ff5e99; 37 | text-shadow: none; } 38 | 39 | /********************************************* 40 | * HEADERS 41 | *********************************************/ 42 | .reveal h1, 43 | .reveal h2, 44 | .reveal h3, 45 | .reveal h4, 46 | .reveal h5, 47 | .reveal h6 { 48 | margin: 0 0 20px 0; 49 | color: #eeeeee; 50 | font-family: "League Gothic", Impact, sans-serif; 51 | line-height: 0.9em; 52 | letter-spacing: 0.02em; 53 | text-transform: uppercase; 54 | text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); } 55 | 56 | .reveal h1 { 57 | text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); } 58 | 59 | /********************************************* 60 | * LINKS 61 | *********************************************/ 62 | .reveal a:not(.image) { 63 | color: #13daec; 64 | text-decoration: none; 65 | -webkit-transition: color .15s ease; 66 | -moz-transition: color .15s ease; 67 | -ms-transition: color .15s ease; 68 | -o-transition: color .15s ease; 69 | transition: color .15s ease; } 70 | 71 | .reveal a:not(.image):hover { 72 | color: #71e9f4; 73 | text-shadow: none; 74 | border: none; } 75 | 76 | .reveal .roll span:after { 77 | color: #fff; 78 | background: #0d99a5; } 79 | 80 | /********************************************* 81 | * IMAGES 82 | *********************************************/ 83 | .reveal section img { 84 | margin: 15px 0px; 85 | background: rgba(255, 255, 255, 0.12); 86 | border: 4px solid #eeeeee; 87 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); 88 | -webkit-transition: all .2s linear; 89 | -moz-transition: all .2s linear; 90 | -ms-transition: all .2s linear; 91 | -o-transition: all .2s linear; 92 | transition: all .2s linear; } 93 | 94 | .reveal a:hover img { 95 | background: rgba(255, 255, 255, 0.2); 96 | border-color: #13daec; 97 | box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } 98 | 99 | /********************************************* 100 | * NAVIGATION CONTROLS 101 | *********************************************/ 102 | .reveal .controls div.navigate-left, 103 | .reveal .controls div.navigate-left.enabled { 104 | border-right-color: #13daec; } 105 | 106 | .reveal .controls div.navigate-right, 107 | .reveal .controls div.navigate-right.enabled { 108 | border-left-color: #13daec; } 109 | 110 | .reveal .controls div.navigate-up, 111 | .reveal .controls div.navigate-up.enabled { 112 | border-bottom-color: #13daec; } 113 | 114 | .reveal .controls div.navigate-down, 115 | .reveal .controls div.navigate-down.enabled { 116 | border-top-color: #13daec; } 117 | 118 | .reveal .controls div.navigate-left.enabled:hover { 119 | border-right-color: #71e9f4; } 120 | 121 | .reveal .controls div.navigate-right.enabled:hover { 122 | border-left-color: #71e9f4; } 123 | 124 | .reveal .controls div.navigate-up.enabled:hover { 125 | border-bottom-color: #71e9f4; } 126 | 127 | .reveal .controls div.navigate-down.enabled:hover { 128 | border-top-color: #71e9f4; } 129 | 130 | /********************************************* 131 | * PROGRESS BAR 132 | *********************************************/ 133 | .reveal .progress { 134 | background: rgba(0, 0, 0, 0.2); } 135 | 136 | .reveal .progress span { 137 | background: #13daec; 138 | -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 139 | -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 140 | -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 141 | -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 142 | transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } 143 | -------------------------------------------------------------------------------- /show.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Sungguh Besar Setia-Mu 6 | 7 | 8 | 9 | 10 | 11 | 18 | 19 | 20 | 21 |
22 | 23 |
24 | 25 |
26 |
27 | 28 |
29 | 31 | 33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 174 | 175 | -------------------------------------------------------------------------------- /js/vendor/jquery.maximage.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Maximage Version: 2.0.8 (16-Jan-2012) - http://www.aaronvanderzwan.com/maximage/2.0/ 3 | */ 4 | (function(a){a.fn.maximage=function(d,e){var c;if(typeof d=="object"||d===undefined){c=a.extend(a.fn.maximage.defaults,d||{})}if(typeof d=="string"){c=a.fn.maximage.defaults}a.Body=a("body");a.Window=a(window);a.Scroll=a("html, body");a.Events={RESIZE:"resize"};this.each(function(){var m=a(this),f=0,j=[];var i={setup:function(){if(a.Slides.length>0){var r,p=a.Slides.length;for(r=0;r'+q.content+"")}i.preload(0);i.resize()}},preload:function(q){var p=a("");p.load(function(){if(f==0){g.setup();c.onFirstImageLoaded()}if(f==(a.Slides.length-1)){c.onImagesLoaded(m)}else{f++;i.preload(f)}});p[0].src=a.Slides[q].url;j.push(p[0])},resize:function(){a.Window.bind(a.Events.RESIZE,function(){a.Scroll.addClass("mc-hide-scrolls");a.Window.data("h",k.sizes().h).data("w",k.sizes().w);m.height(a.Window.data("h")).width(a.Window.data("w")).children().height(a.Window.data("h")).width(a.Window.data("w"));m.children().each(function(){this.cycleH=a.Window.data("h");this.cycleW=a.Window.data("w")});a(a.Scroll).removeClass("mc-hide-scrolls")})}};var h={setup:function(){var u,s,q,r,p=a.Slides.length;if(a.BrowserTests.msie&&!c.overrideMSIEStop){document.execCommand("Stop",false)}m.html("");a.Body.addClass("mc-old-browser");if(a.Slides.length>0){a.Scroll.addClass("mc-hide-scrolls");a.Window.data("h",k.sizes().h).data("w",k.sizes().w);a("body").append(a("
").attr("class","mc-loader").css({position:"absolute",left:"-9999px"}));for(r=0;r'}else{u=a.Slides[r].content}q=a("
"+u+"
").attr("class","mc-image mc-image-n"+r+" "+a.Slides[r].theclass);m.append(q);if(a(".mc-image-n"+r).children("img").length==0){}else{a("div.mc-loader").append(a(".mc-image-n"+r).children("img").first().clone().addClass("not-loaded"))}}h.preload();h.windowResize()}},preload:function(){var p=setInterval(function(){a(".mc-loader").children("img").each(function(r){var q=a(this);if(q.hasClass("not-loaded")){if(q.height()>0){a(this).removeClass("not-loaded");var s=a("div.mc-image-n"+r).children("img").first();s.data("h",q.height()).data("w",q.width()).data("ar",(q.width()/q.height()));h.onceLoaded(r)}}});if(a(".not-loaded").length==0){a(".mc-loader").remove();clearInterval(p)}},1000)},onceLoaded:function(p){h.maximage(p);if(p==0){m.css({visibility:"visible"});c.onFirstImageLoaded()}else{if(p==a.Slides.length-1){g.setup();a(a.Scroll).removeClass("mc-hide-scrolls");c.onImagesLoaded(m);if(c.debug){b(" - Final Maximage - ");b(m)}}}},maximage:function(q){a("div.mc-image-n"+q).height(a.Window.data("h")).width(a.Window.data("w")).children("img").first().each(function(){n.maxcover(a(this))})},windowResize:function(){a.Window.bind(a.Events.RESIZE,function(){clearTimeout(this.id);this.id=setTimeout(h.doneResizing,200)})},doneResizing:function(){a(a.Scroll).addClass("mc-hide-scrolls");a.Window.data("h",k.sizes().h).data("w",k.sizes().w);m.height(a.Window.data("h")).width(a.Window.data("w"));m.find(".mc-image").each(function(q){h.maximage(q)});var p=m.data("cycle.opts");if(p!=undefined){p.height=a.Window.data("h");p.width=a.Window.data("w");jQuery.each(p.elements,function(q,r){r.cycleW=a.Window.data("w");r.cycleH=a.Window.data("h")})}a(a.Scroll).removeClass("mc-hide-scrolls")}};var g={setup:function(){var q,p;m.addClass("mc-cycle");a.Window.data("h",k.sizes().h).data("w",k.sizes().w);jQuery.easing.easeForCSSTransition=function(v,w,u,A,z,y){return u+A};var r=a.extend({fit:1,containerResize:0,height:a.Window.data("h"),width:a.Window.data("w"),slideResize:false,easing:(a.BrowserTests.cssTransitions&&c.cssTransitions?"easeForCSSTransition":"swing")},c.cycleOptions);m.cycle(r)}};var n={center:function(p){if(c.verticalCenter){p.css({marginTop:((p.height()-a.Window.data("h"))/2)*-1})}if(c.horizontalCenter){p.css({marginLeft:((p.width()-a.Window.data("w"))/2)*-1})}},fill:function(p){var q=p.is("object")?p.parent().first():p;if(typeof c.backgroundSize=="function"){c.backgroundSize(p)}else{if(c.backgroundSize=="cover"){if(a.Window.data("w")/a.Window.data("h")")[0],u=["Moz","Webkit","Khtml","O","ms"],t="transition",s={cssTransitions:false,cssBackgroundSize:("backgroundSize" in q.style&&c.cssBackgroundSize),html5Video:false,msie:false};if(c.cssTransitions){if(typeof q.style[t]=="string"){s.cssTransitions=true}t=t.charAt(0).toUpperCase()+t.substr(1);for(var r=0;r0){if(a.BrowserTests.cssBackgroundSize){a(this).find("img").first().remove()}r.content=a(this).html()}s[0].src="";if(a.BrowserTests.cssBackgroundSize){a(this).remove()}p.push(r)});if(c.debug){b(" - Slide Object - ");b(p)}return p},msie:function(){var r,p=3,s=document.createElement("div"),q=s.getElementsByTagName("i");while(s.innerHTML="",q[0]){}return p>4?p:r},sizes:function(){var p={h:0,w:0};if(c.fillElement=="window"){p.h=a.Window.height();p.w=a.Window.width()}else{var q=m.parents(c.fillElement).first();if(q.height()==0||q.data("windowHeight")==true){q.data("windowHeight",true);p.h=a.Window.height()}else{p.h=q.height()}if(q.width()==0||q.data("windowWidth")==true){q.data("windowWidth",true);p.w=a.Window.width()}else{p.w=q.width()}}return p}};a.BrowserTests=k.browser_tests();if(typeof d=="string"){if(a.BrowserTests.html5Video||!m.is("video")){var l,o=m.is("object")?m.parent().first():m;if(!a.Body.hasClass("mc-old-browser")){a.Body.addClass("mc-old-browser")}a.Window.data("h",k.sizes().h).data("w",k.sizes().w);o.data("h",m.height()).data("w",m.width()).data("ar",m.width()/m.height());a.Window.bind(a.Events.RESIZE,function(){a.Window.data("h",k.sizes().h).data("w",k.sizes().w);l=m.data("resizer");clearTimeout(l);l=setTimeout(n[d](m),200);m.data("resizer",l)});n[d](m)}}else{a.Slides=k.construct_slide_object();if(a.BrowserTests.cssBackgroundSize){if(c.debug){b(" - Using Modern - ")}i.setup()}else{if(c.debug){b(" - Using Old - ")}h.setup()}}});function b(f){if(window.console&&window.console.log){window.console.log(f)}}};a.fn.maximage.defaults={debug:false,cssBackgroundSize:true,cssTransitions:true,verticalCenter:true,horizontalCenter:true,scaleInterval:20,backgroundSize:"cover",fillElement:"window",overrideMSIEStop:false,onFirstImageLoaded:function(){},onImagesLoaded:function(){}}})(jQuery); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mazmur Online 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 | 35 | 51 | 52 | 59 | 60 | 71 | 72 | 92 | 93 | 126 | 127 | 128 | 129 | 149 |
150 |
151 |
152 |
153 | 154 |
155 | 156 | 157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 | 169 |
170 |
171 | 172 |
173 |
174 |
175 |
176 | 177 |
178 |
179 |
180 |
181 | 186 | 187 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /js/vendor/underscore-min.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.5.1 2 | // http://underscorejs.org 3 | // (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 4 | // Underscore may be freely distributed under the MIT license. 5 | !function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,v=e.reduce,h=e.reduceRight,d=e.filter,g=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,w=i.bind,j=function(n){return n instanceof j?n:this instanceof j?(this._wrapped=n,void 0):new j(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=j),exports._=j):n._=j,j.VERSION="1.5.1";var A=j.each=j.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(j.has(n,a)&&t.call(e,n[a],a,n)===r)return};j.map=j.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e.push(t.call(r,n,u,i))}),e)};var E="Reduce of empty array with no initial value";j.reduce=j.foldl=j.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduce===v)return e&&(t=j.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(E);return r},j.reduceRight=j.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduceRight===h)return e&&(t=j.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=j.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(E);return r},j.find=j.detect=function(n,t,r){var e;return O(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},j.filter=j.select=function(n,t,r){var e=[];return null==n?e:d&&n.filter===d?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&e.push(n)}),e)},j.reject=function(n,t,r){return j.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},j.every=j.all=function(n,t,e){t||(t=j.identity);var u=!0;return null==n?u:g&&n.every===g?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var O=j.some=j.any=function(n,t,e){t||(t=j.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};j.contains=j.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:O(n,function(n){return n===t})},j.invoke=function(n,t){var r=o.call(arguments,2),e=j.isFunction(t);return j.map(n,function(n){return(e?t:n[t]).apply(n,r)})},j.pluck=function(n,t){return j.map(n,function(n){return n[t]})},j.where=function(n,t,r){return j.isEmpty(t)?r?void 0:[]:j[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},j.findWhere=function(n,t){return j.where(n,t,!0)},j.max=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.max.apply(Math,n);if(!t&&j.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>e.computed&&(e={value:n,computed:a})}),e.value},j.min=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.min.apply(Math,n);if(!t&&j.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;ae||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.indexi;){var o=i+a>>>1;r.call(e,n[o])=0})})},j.difference=function(n){var t=c.apply(e,o.call(arguments,1));return j.filter(n,function(n){return!j.contains(t,n)})},j.zip=function(){for(var n=j.max(j.pluck(arguments,"length").concat(0)),t=new Array(n),r=0;n>r;r++)t[r]=j.pluck(arguments,""+r);return t},j.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},j.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=j.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},j.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},j.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=new Array(e);e>u;)i[u++]=n,n+=r;return i};var M=function(){};j.bind=function(n,t){var r,e;if(w&&n.bind===w)return w.apply(n,o.call(arguments,1));if(!j.isFunction(n))throw new TypeError;return r=o.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(o.call(arguments)));M.prototype=n.prototype;var u=new M;M.prototype=null;var i=n.apply(u,r.concat(o.call(arguments)));return Object(i)===i?i:u}},j.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},j.bindAll=function(n){var t=o.call(arguments,1);if(0===t.length)throw new Error("bindAll must be passed function names");return A(t,function(t){n[t]=j.bind(n[t],n)}),n},j.memoize=function(n,t){var r={};return t||(t=j.identity),function(){var e=t.apply(this,arguments);return j.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},j.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},j.defer=function(n){return j.delay.apply(j,[n,1].concat(o.call(arguments,1)))},j.throttle=function(n,t,r){var e,u,i,a=null,o=0;r||(r={});var c=function(){o=r.leading===!1?0:new Date,a=null,i=n.apply(e,u)};return function(){var l=new Date;o||r.leading!==!1||(o=l);var f=t-(l-o);return e=this,u=arguments,0>=f?(clearTimeout(a),a=null,o=l,i=n.apply(e,u)):a||r.trailing===!1||(a=setTimeout(c,f)),i}},j.debounce=function(n,t,r){var e,u=null;return function(){var i=this,a=arguments,o=function(){u=null,r||(e=n.apply(i,a))},c=r&&!u;return clearTimeout(u),u=setTimeout(o,t),c&&(e=n.apply(i,a)),e}},j.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},j.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},j.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},j.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},j.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)j.has(n,r)&&t.push(r);return t},j.values=function(n){var t=[];for(var r in n)j.has(n,r)&&t.push(n[r]);return t},j.pairs=function(n){var t=[];for(var r in n)j.has(n,r)&&t.push([r,n[r]]);return t},j.invert=function(n){var t={};for(var r in n)j.has(n,r)&&(t[n[r]]=r);return t},j.functions=j.methods=function(n){var t=[];for(var r in n)j.isFunction(n[r])&&t.push(r);return t.sort()},j.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},j.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},j.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)j.contains(r,u)||(t[u]=n[u]);return t},j.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]===void 0&&(n[r]=t[r])}),n},j.clone=function(n){return j.isObject(n)?j.isArray(n)?n.slice():j.extend({},n):n},j.tap=function(n,t){return t(n),n};var S=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof j&&(n=n._wrapped),t instanceof j&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==String(t);case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;var a=n.constructor,o=t.constructor;if(a!==o&&!(j.isFunction(a)&&a instanceof a&&j.isFunction(o)&&o instanceof o))return!1;r.push(n),e.push(t);var c=0,f=!0;if("[object Array]"==u){if(c=n.length,f=c==t.length)for(;c--&&(f=S(n[c],t[c],r,e)););}else{for(var s in n)if(j.has(n,s)&&(c++,!(f=j.has(t,s)&&S(n[s],t[s],r,e))))break;if(f){for(s in t)if(j.has(t,s)&&!c--)break;f=!c}}return r.pop(),e.pop(),f};j.isEqual=function(n,t){return S(n,t,[],[])},j.isEmpty=function(n){if(null==n)return!0;if(j.isArray(n)||j.isString(n))return 0===n.length;for(var t in n)if(j.has(n,t))return!1;return!0},j.isElement=function(n){return!(!n||1!==n.nodeType)},j.isArray=x||function(n){return"[object Array]"==l.call(n)},j.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){j["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),j.isArguments(arguments)||(j.isArguments=function(n){return!(!n||!j.has(n,"callee"))}),"function"!=typeof/./&&(j.isFunction=function(n){return"function"==typeof n}),j.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},j.isNaN=function(n){return j.isNumber(n)&&n!=+n},j.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},j.isNull=function(n){return null===n},j.isUndefined=function(n){return n===void 0},j.has=function(n,t){return f.call(n,t)},j.noConflict=function(){return n._=t,this},j.identity=function(n){return n},j.times=function(n,t,r){for(var e=Array(Math.max(0,n)),u=0;n>u;u++)e[u]=t.call(r,u);return e},j.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var I={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};I.unescape=j.invert(I.escape);var T={escape:new RegExp("["+j.keys(I.escape).join("")+"]","g"),unescape:new RegExp("("+j.keys(I.unescape).join("|")+")","g")};j.each(["escape","unescape"],function(n){j[n]=function(t){return null==t?"":(""+t).replace(T[n],function(t){return I[n][t]})}}),j.result=function(n,t){if(null==n)return void 0;var r=n[t];return j.isFunction(r)?r.call(n):r},j.mixin=function(n){A(j.functions(n),function(t){var r=j[t]=n[t];j.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),z.call(this,r.apply(j,n))}})};var N=0;j.uniqueId=function(n){var t=++N+"";return n?n+t:t},j.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var q=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\t|\u2028|\u2029/g;j.template=function(n,t,r){var e;r=j.defaults({},r,j.templateSettings);var u=new RegExp([(r.escape||q).source,(r.interpolate||q).source,(r.evaluate||q).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(D,function(n){return"\\"+B[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=new Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,j);var c=function(n){return e.call(this,n,j)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},j.chain=function(n){return j(n).chain()};var z=function(n){return this._chain?j(n).chain():n};j.mixin(j),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];j.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],z.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];j.prototype[n]=function(){return z.call(this,t.apply(this._wrapped,arguments))}}),j.extend(j.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}.call(this); 6 | //# sourceMappingURL=underscore-min.map -------------------------------------------------------------------------------- /css/vendor/bootstrap-responsive.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.3.2 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} 10 | -------------------------------------------------------------------------------- /js/vendor/jquery.splitter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery.splitter.js - two-pane splitter window plugin 3 | * 4 | * version 1.63 (2012/12/06) 5 | * 6 | * Dual licensed under the MIT and GPL licenses: 7 | * http://www.opensource.org/licenses/mit-license.php 8 | * http://www.gnu.org/licenses/gpl.html 9 | */ 10 | 11 | /** 12 | * The splitter() plugin implements a two-pane resizable splitter window. 13 | * The selected elements in the jQuery object are converted to a splitter; 14 | * each selected element should have two child elements, used for the panes 15 | * of the splitter. The plugin adds a third child element for the splitbar. 16 | * 17 | * For more details see: http://methvin.com/jquery/splitter/ 18 | * 19 | * 20 | * @example $('#MySplitter').splitter(); 21 | * @desc Create a vertical splitter with default settings 22 | * 23 | * @example $('#MySplitter').splitter({type: 'h', accessKey: 'M'}); 24 | * @desc Create a horizontal splitter resizable via Alt+Shift+M 25 | * 26 | * @name splitter 27 | * @type jQuery 28 | * @param Object options Options for the splitter (not required) 29 | * @cat Plugins/Splitter 30 | * @return jQuery 31 | * @author Dave Methvin (dave.methvin@gmail.com) 32 | */ 33 | ;(function($){ 34 | 35 | var splitterCounter = 0; 36 | 37 | $.fn.splitter = function(args){ 38 | args = args || {}; 39 | return this.each(function() { 40 | //if ( $(this).is(".splitter") ) return; // already a splitter 41 | if ( $(this).attr("data-splitter-initialized") ) return 42 | var zombie; // left-behind splitbar for outline resizes 43 | function resize_auto_fired() { 44 | // Returns true when the browser natively fires the resize 45 | // event attached to the panes elements 46 | // return ($.browser.msie && (parseInt($.browser.version) < 9)); 47 | } 48 | function setBarState(state) { 49 | bar.removeClass(opts.barStateClasses).addClass(state); 50 | } 51 | function startSplitMouse(evt) { 52 | if ( evt.which != 1 ) 53 | return; // left button only 54 | bar.removeClass(opts.barHoverClass); 55 | if ( opts.outline ) { 56 | zombie = zombie || bar.clone(false).insertAfter(A); 57 | bar.removeClass(opts.barDockedClass); 58 | } 59 | setBarState(opts.barActiveClass) 60 | // Safari selects A/B text on a move; iframes capture mouse events so hide them 61 | panes.css("-webkit-user-select", "none").find("iframe").addClass(opts.iframeClass); 62 | A._posSplit = A[0][opts.pxSplit] - evt[opts.eventPos]; 63 | $(document) 64 | .bind("mousemove"+opts.eventNamespace, doSplitMouse) 65 | .bind("mouseup"+opts.eventNamespace, endSplitMouse); 66 | } 67 | function doSplitMouse(evt) { 68 | var pos = A._posSplit+evt[opts.eventPos], 69 | range = Math.max(0, Math.min(pos, splitter._DA - bar._DA)), 70 | limit = Math.max(A._min, splitter._DA - B._max, 71 | Math.min(pos, A._max, splitter._DA - bar._DA - B._min)); 72 | if ( opts.outline ) { 73 | // Let docking splitbar be dragged to the dock position, even if min width applies 74 | if ( (opts.dockPane == A && pos < Math.max(A._min, bar._DA)) || 75 | (opts.dockPane == B && pos > Math.min(pos, A._max, splitter._DA - bar._DA - B._min)) ) { 76 | bar.addClass(opts.barDockedClass).css(opts.origin, range); 77 | } 78 | else { 79 | bar.removeClass(opts.barDockedClass).css(opts.origin, limit); 80 | } 81 | bar._DA = bar[0][opts.pxSplit]; 82 | } else 83 | resplit(pos); 84 | setBarState(pos == limit? opts.barActiveClass : opts.barLimitClass); 85 | } 86 | function endSplitMouse(evt) { 87 | setBarState(opts.barNormalClass); 88 | bar.addClass(opts.barHoverClass); 89 | var pos = A._posSplit+evt[opts.eventPos]; 90 | if ( opts.outline ) { 91 | zombie && zombie.remove(); zombie = null; 92 | resplit(pos); 93 | } 94 | panes.css("-webkit-user-select", "text").find("iframe").removeClass(opts.iframeClass); 95 | $(document) 96 | .unbind("mousemove"+opts.eventNamespace+" mouseup"+opts.eventNamespace); 97 | } 98 | function resplit(pos) { 99 | bar._DA = bar[0][opts.pxSplit]; // bar size may change during dock 100 | // Constrain new splitbar position to fit pane size and docking limits 101 | if ( (opts.dockPane == A && pos < Math.max(A._min, bar._DA)) || 102 | (opts.dockPane == B && pos > Math.min(pos, A._max, splitter._DA - bar._DA - B._min)) ) { 103 | bar.addClass(opts.barDockedClass); 104 | bar._DA = bar[0][opts.pxSplit]; 105 | pos = opts.dockPane == A? 0 : splitter._DA - bar._DA; 106 | if ( bar._pos == null ) 107 | bar._pos = A[0][opts.pxSplit]; 108 | } 109 | else { 110 | bar.removeClass(opts.barDockedClass); 111 | bar._DA = bar[0][opts.pxSplit]; 112 | bar._pos = null; 113 | pos = Math.max(A._min, splitter._DA - B._max, 114 | Math.min(pos, A._max, splitter._DA - bar._DA - B._min)); 115 | } 116 | // Resize/position the two panes 117 | bar.css(opts.origin, pos).css(opts.fixed, splitter._DF); 118 | A.css(opts.origin, 0).css(opts.split, pos).css(opts.fixed, splitter._DF); 119 | B.css(opts.origin, pos+bar._DA) 120 | .css(opts.split, splitter._DA-bar._DA-pos).css(opts.fixed, splitter._DF); 121 | // IE fires resize for us; all others pay cash 122 | if ( !resize_auto_fired() ) panes.trigger("resize"); 123 | } 124 | function dimSum(jq, dims) { 125 | // Opera returns -1 for missing min/max width, turn into 0 126 | var sum = 0; 127 | for ( var i=1; i < arguments.length; i++ ) 128 | sum += Math.max(parseInt(jq.css(arguments[i]),10) || 0, 0); 129 | return sum; 130 | } 131 | function resize(size){ 132 | // Determine new width/height of splitter container 133 | splitter._DF = splitter[0][opts.pxFixed] - splitter._PBF; 134 | splitter._DA = splitter[0][opts.pxSplit] - splitter._PBA; 135 | // Bail if splitter isn't visible or content isn't there yet 136 | if ( splitter._DF <= 0 || splitter._DA <= 0 ) return; 137 | 138 | // if nothing changed, no need to resize 139 | if (splitter._oldW == splitter.width() && splitter._oldH == splitter.height()) 140 | return; // nothing changed 141 | splitter._oldW = splitter.width(); 142 | splitter._oldH = splitter.height(); 143 | 144 | // Re-divvy the adjustable dimension; maintain size of the preferred pane 145 | resplit(!isNaN(size)? size : (!(opts.sizeRight||opts.sizeBottom)? A[0][opts.pxSplit] : 146 | splitter._DA-B[0][opts.pxSplit]-bar._DA)); 147 | setBarState(opts.barNormalClass); 148 | } 149 | 150 | // Determine settings based on incoming opts, element classes, and defaults 151 | var vh = (args.splitHorizontal? 'h' : args.splitVertical? 'v' : args.type) || 'v'; 152 | var opts = $.extend({ 153 | // Defaults here allow easy use with ThemeRoller 154 | splitterClass: "splitter ui-widget ui-widget-content", 155 | paneClass: "splitter-pane", 156 | barClass: "splitter-bar", 157 | barNormalClass: "ui-state-default", // splitbar normal 158 | barHoverClass: "ui-state-hover", // splitbar mouse hover 159 | barActiveClass: "ui-state-highlight", // splitbar being moved 160 | barLimitClass: "ui-state-error", // splitbar at limit 161 | iframeClass: "splitter-iframe-hide", // hide iframes during split 162 | eventNamespace: ".splitter"+(++splitterCounter), 163 | pxPerKey: 8, // splitter px moved per keypress 164 | tabIndex: 0, // tab order indicator 165 | accessKey: '' // accessKey for splitbar 166 | },{ 167 | // user can override 168 | v: { // Vertical splitters: 169 | keyLeft: 39, keyRight: 37, cursor: "e-resize", 170 | barStateClass: "splitter-bar-vertical", 171 | barDockedClass: "splitter-bar-vertical-docked" 172 | }, 173 | h: { // Horizontal splitters: 174 | keyTop: 40, keyBottom: 38, cursor: "n-resize", 175 | barStateClass: "splitter-bar-horizontal", 176 | barDockedClass: "splitter-bar-horizontal-docked" 177 | } 178 | }[vh], args, { 179 | // user cannot override 180 | v: { // Vertical splitters: 181 | type: 'v', eventPos: "pageX", origin: "left", 182 | split: "width", pxSplit: "offsetWidth", side1: "Left", side2: "Right", 183 | fixed: "height", pxFixed: "offsetHeight", side3: "Top", side4: "Bottom" 184 | }, 185 | h: { // Horizontal splitters: 186 | type: 'h', eventPos: "pageY", origin: "top", 187 | split: "height", pxSplit: "offsetHeight", side1: "Top", side2: "Bottom", 188 | fixed: "width", pxFixed: "offsetWidth", side3: "Left", side4: "Right" 189 | } 190 | }[vh]); 191 | opts.barStateClasses = [opts.barNormalClass, opts.barHoverClass, opts.barActiveClass, opts.barLimitClass].join(' '); 192 | 193 | // Create jQuery object closures for splitter and both panes 194 | var splitter = $(this).css({position: "relative"}).addClass(opts.splitterClass).attr("data-splitter-initialized",true) 195 | var panes = $(">*", splitter[0]).addClass(opts.paneClass).css({ 196 | position: "absolute", // positioned inside splitter container 197 | "z-index": "1", // splitbar is positioned above 198 | "-moz-outline-style": "none" // don't show dotted outline 199 | }); 200 | var A = $(panes[0]), B = $(panes[1]); // A = left/top, B = right/bottom 201 | opts.dockPane = opts.dock && (/right|bottom/.test(opts.dock)? B:A); 202 | 203 | // Focuser element, provides keyboard support; title is shown by Opera accessKeys 204 | var focuser = $('') 205 | .attr({accessKey: opts.accessKey, tabIndex: opts.tabIndex, title: opts.splitbarClass}) 206 | // .bind(($.browser.opera?"click":"focus")+opts.eventNamespace, 207 | // function(){ this.focus(); bar.addClass(opts.barActiveClass) }) 208 | .bind("keydown"+opts.eventNamespace, function(e){ 209 | var key = e.which || e.keyCode; 210 | var dir = key==opts["key"+opts.side1]? 1 : key==opts["key"+opts.side2]? -1 : 0; 211 | if ( dir ) 212 | resplit(A[0][opts.pxSplit]+dir*opts.pxPerKey, false); 213 | }) 214 | .bind("blur"+opts.eventNamespace, 215 | function(){ bar.removeClass(opts.barActiveClass) }); 216 | 217 | // Splitbar element 218 | var bar = $('
') 219 | .insertAfter(A).addClass(opts.barClass).addClass(opts.barStateClass) 220 | .append(focuser).attr({unselectable: "on"}) 221 | .css({position: "absolute", "user-select": "none", "-webkit-user-select": "none", 222 | "-khtml-user-select": "none", "-moz-user-select": "none", "z-index": "100"}) 223 | .bind("mousedown"+opts.eventNamespace, startSplitMouse) 224 | .bind("mouseover"+opts.eventNamespace, function(){ 225 | $(this).addClass(opts.barHoverClass); 226 | }) 227 | .bind("mouseout"+opts.eventNamespace, function(){ 228 | $(this).removeClass(opts.barHoverClass); 229 | }); 230 | // Use our cursor unless the style specifies a non-default cursor 231 | if ( /^(auto|default|)$/.test(bar.css("cursor")) ) 232 | bar.css("cursor", opts.cursor); 233 | 234 | // Cache several dimensions for speed, rather than re-querying constantly 235 | // These are saved on the A/B/bar/splitter jQuery vars, which are themselves cached 236 | // DA=dimension adjustable direction, PBF=padding/border fixed, PBA=padding/border adjustable 237 | bar._DA = bar[0][opts.pxSplit]; 238 | splitter._PBF = dimSum(splitter, "border"+opts.side3+"Width", "border"+opts.side4+"Width"); 239 | splitter._PBA = dimSum(splitter, "border"+opts.side1+"Width", "border"+opts.side2+"Width"); 240 | A._pane = opts.side1; 241 | B._pane = opts.side2; 242 | $.each([A,B], function(){ 243 | this._splitter_style = this.style; 244 | this._min = opts["min"+this._pane] || dimSum(this, "min-"+opts.split); 245 | this._max = opts["max"+this._pane] || dimSum(this, "max-"+opts.split) || 9999; 246 | this._init = opts["size"+this._pane]===true ? 247 | parseInt($.css(this[0],opts.split),10) : opts["size"+this._pane]; 248 | }); 249 | 250 | // Determine initial position, get from cookie if specified 251 | var initPos = A._init; 252 | if ( !isNaN(B._init) ) // recalc initial B size as an offset from the top or left side 253 | initPos = splitter[0][opts.pxSplit] - splitter._PBA - B._init - bar._DA; 254 | if ( opts.cookie ) { 255 | if ( !$.cookie ) 256 | alert('jQuery.splitter(): jQuery cookie plugin required'); 257 | initPos = parseInt($.cookie(opts.cookie),10); 258 | $(window).bind("unload"+opts.eventNamespace, function(){ 259 | var state = String(bar.css(opts.origin)); // current location of splitbar 260 | $.cookie(opts.cookie, state, {expires: opts.cookieExpires || 365, 261 | path: opts.cookiePath || document.location.pathname}); 262 | }); 263 | } 264 | if ( isNaN(initPos) ) // King Solomon's algorithm 265 | initPos = Math.round((splitter[0][opts.pxSplit] - splitter._PBA - bar._DA)/2); 266 | 267 | // Resize event propagation and splitter sizing 268 | if ( opts.anchorToWindow ) 269 | opts.resizeTo = window; 270 | if ( opts.resizeTo ) { 271 | splitter._hadjust = dimSum(splitter, "borderTopWidth", "borderBottomWidth", "marginBottom"); 272 | splitter._hmin = Math.max(dimSum(splitter, "minHeight"), 20); 273 | $(window).bind("resize"+opts.eventNamespace, function(){ 274 | var top = splitter.offset().top; 275 | var eh = $(opts.resizeTo).height(); 276 | splitter.css("height", Math.max(eh-top-splitter._hadjust, splitter._hmin)+"px"); 277 | if ( !resize_auto_fired() ) splitter.triggerHandler("resize"); 278 | }).triggerHandler("resize"+opts.eventNamespace); 279 | } 280 | else if ( opts.resizeToWidth && !resize_auto_fired() ) { 281 | $(window).bind("resize"+opts.eventNamespace, function(){ 282 | // splitter.triggerHandler("resize"); 283 | resize(); 284 | }); 285 | } 286 | 287 | // Docking support 288 | if ( opts.dock ) { 289 | splitter 290 | .bind("toggleDock"+opts.eventNamespace, function() { 291 | var pw = opts.dockPane[0][opts.pxSplit]; 292 | splitter.triggerHandler(pw?"dock":"undock"); 293 | }) 294 | .bind("dock"+opts.eventNamespace, function(){ 295 | var pw = A[0][opts.pxSplit]; 296 | if ( !pw ) return; 297 | bar._pos = pw; 298 | var x={}; 299 | x[opts.origin] = opts.dockPane==A? 0 : 300 | splitter[0][opts.pxSplit] - splitter._PBA - bar[0][opts.pxSplit]; 301 | bar.animate(x, opts.dockSpeed||1, opts.dockEasing, function(){ 302 | bar.addClass(opts.barDockedClass); 303 | resplit(x[opts.origin]); 304 | }); 305 | }) 306 | .bind("undock"+opts.eventNamespace, function(){ 307 | var pw = opts.dockPane[0][opts.pxSplit]; 308 | if ( pw ) return; 309 | var x={}; x[opts.origin]=bar._pos+"px"; 310 | bar.removeClass(opts.barDockedClass) 311 | .animate(x, opts.undockSpeed||opts.dockSpeed||1, opts.undockEasing||opts.dockEasing, function(){ 312 | resplit(bar._pos); 313 | bar._pos = null; 314 | }); 315 | }); 316 | if ( opts.dockKey ) 317 | $('') 318 | .attr({accessKey: opts.dockKey, tabIndex: -1}).appendTo(bar) 319 | .bind($.browser.opera?"click":"focus", function(){ 320 | splitter.triggerHandler("toggleDock"); this.blur(); 321 | }); 322 | bar.bind("dblclick", function(){ splitter.triggerHandler("toggleDock"); }) 323 | } 324 | 325 | // Resize event handler; triggered immediately to set initial position 326 | splitter 327 | .bind("destroy"+opts.eventNamespace, function(){ 328 | $([window, document]).unbind(opts.eventNamespace); 329 | bar.unbind().remove(); 330 | panes.removeClass(opts.paneClass); 331 | splitter 332 | .removeClass(opts.splitterClass) 333 | .add(panes) 334 | .unbind(opts.eventNamespace) 335 | .attr("style", function(el){ 336 | return this._splitter_style||""; //TODO: save style 337 | }); 338 | splitter = bar = focuser = panes = A = B = opts = args = null; 339 | }) 340 | .bind("resize"+opts.eventNamespace, function(e,size) { resize( size ); } ) 341 | .trigger("resize" , [initPos]); 342 | }); 343 | }; 344 | 345 | })(jQuery); 346 | -------------------------------------------------------------------------------- /js/vendor/backbone-firebase.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Backbone Firebase Adapter. 3 | */ 4 | 5 | "use strict"; 6 | 7 | (function() { 8 | 9 | var _ = window._; 10 | var Backbone = window.Backbone; 11 | 12 | Backbone.Firebase = function(ref) { 13 | this._fbref = ref; 14 | this._children = []; 15 | if (typeof ref == "string") { 16 | this._fbref = new Firebase(ref); 17 | } 18 | 19 | this._fbref.on("child_added", this._childAdded, this); 20 | this._fbref.on("child_moved", this._childMoved, this); 21 | this._fbref.on("child_changed", this._childChanged, this); 22 | this._fbref.on("child_removed", this._childRemoved, this); 23 | }; 24 | 25 | _.extend(Backbone.Firebase.prototype, { 26 | _childAdded: function(childSnap, prevChild) { 27 | var model = childSnap.val(); 28 | model.id = childSnap.name(); 29 | if (prevChild) { 30 | var item = _.find(this._children, function(child) { 31 | return child.id == prevChild; 32 | }); 33 | this._children.splice(this._children.indexOf(item) + 1, 0, model); 34 | } else { 35 | this._children.unshift(model); 36 | } 37 | }, 38 | 39 | _childMoved: function(childSnap, prevChild) { 40 | var model = childSnap.val(); 41 | this._children = _.reject(this._children, function(child) { 42 | return child.id == model.id; 43 | }); 44 | this._childAdded(childSnap, prevChild); 45 | }, 46 | 47 | _childChanged: function(childSnap) { 48 | var model = childSnap.val(); 49 | model.id = childSnap.name(); 50 | var item = _.find(this._children, function(child) { 51 | return child.id == model.id; 52 | }); 53 | this._children[this._children.indexOf(item)] = model; 54 | }, 55 | 56 | _childRemoved: function(oldChildSnap) { 57 | var model = oldChildSnap.val(); 58 | this._children = _.reject(this._children, function(child) { 59 | return child.id == model.id; 60 | }); 61 | }, 62 | 63 | create: function(model, cb) { 64 | if (!model.id) { 65 | model.id = this._fbref.ref().push().name(); 66 | } 67 | 68 | var val = model.toJSON(); 69 | this._fbref.ref().child(model.id).set(val, _.bind(function(err) { 70 | if (!err) { 71 | cb(null, val); 72 | } else { 73 | cb("Could not create model " + model.id); 74 | } 75 | }, this)); 76 | }, 77 | 78 | read: function(model, cb) { 79 | if (!model.id) { 80 | _.defer(cb, "Invalid model ID provided to read"); 81 | return; 82 | } 83 | 84 | var index = _.find(this._children, function(child) { 85 | return child.id == model.id; 86 | }); 87 | 88 | _.defer(cb, null, this._children[index]); 89 | }, 90 | 91 | readAll: function(model, cb) { 92 | _.defer(cb, null, this._children); 93 | }, 94 | 95 | update: function(model, cb) { 96 | var val = model.toJSON(); 97 | this._fbref.ref().child(model.id).update(val, function(err) { 98 | if (!err) { 99 | cb(null, val); 100 | } else { 101 | cb("Could not update model " + model.id, null); 102 | } 103 | }); 104 | }, 105 | 106 | "delete": function(model, cb) { 107 | this._fbref.ref().child(model.id).remove(function(err) { 108 | if (!err) { 109 | cb(null, model); 110 | } else { 111 | cb("Could not delete model " + model.id); 112 | } 113 | }); 114 | }, 115 | 116 | ref: function() { 117 | return this._fbref; 118 | } 119 | }); 120 | 121 | 122 | Backbone.Firebase.sync = function(method, model, options, error) { 123 | var store = model.firebase || model.collection.firebase; 124 | 125 | // Backwards compatibility with Backbone <= 0.3.3 126 | if (typeof options == "function") { 127 | options = { 128 | success: options, 129 | error: error 130 | }; 131 | } 132 | 133 | if (method == "read" && model.id === undefined) { 134 | method = "readAll"; 135 | } 136 | 137 | store[method].apply(store, [model, function(err, val) { 138 | if (err) { 139 | model.trigger("error", model, err, options); 140 | if (Backbone.VERSION === "0.9.10") { 141 | options.error(model, err, options); 142 | } else { 143 | options.error(err); 144 | } 145 | } else { 146 | model.trigger("sync", model, val, options); 147 | if (Backbone.VERSION === "0.9.10") { 148 | options.success(model, val, options); 149 | } else { 150 | options.success(val); 151 | } 152 | } 153 | }]); 154 | }; 155 | 156 | Backbone.oldSync = Backbone.sync; 157 | 158 | // Override "Backbone.sync" to default to Firebase sync. 159 | // the original "Backbone.sync" is still available in "Backbone.oldSync" 160 | Backbone.sync = function(method, model, options, error) { 161 | var syncMethod = Backbone.oldSync; 162 | if (model.firebase || (model.collection && model.collection.firebase)) { 163 | syncMethod = Backbone.Firebase.sync; 164 | } 165 | return syncMethod.apply(this, [method, model, options, error]); 166 | }; 167 | 168 | // Custom Firebase Collection. 169 | Backbone.Firebase.Collection = Backbone.Collection.extend({ 170 | sync: function() { 171 | this._log("Sync called on a Firebase collection, ignoring."); 172 | }, 173 | 174 | fetch: function() { 175 | this._log("Fetch called on a Firebase collection, ignoring."); 176 | }, 177 | 178 | constructor: function(models, options) { 179 | // Apply parent constructor (this will also call initialize). 180 | Backbone.Collection.apply(this, arguments); 181 | 182 | if (options && options.firebase) { 183 | this.firebase = options.firebase; 184 | } 185 | switch (typeof this.firebase) { 186 | case "object": 187 | break; 188 | case "string": 189 | this.firebase = new Firebase(this.firebase); 190 | break; 191 | case "function": 192 | this.firebase = this.firebase(); 193 | break; 194 | default: 195 | throw new Error("Invalid firebase reference created"); 196 | } 197 | 198 | // Add handlers for remote events. 199 | this.firebase.on("child_added", _.bind(this._childAdded, this)); 200 | this.firebase.on("child_moved", _.bind(this._childMoved, this)); 201 | this.firebase.on("child_changed", _.bind(this._childChanged, this)); 202 | this.firebase.on("child_removed", _.bind(this._childRemoved, this)); 203 | 204 | // Once handler to emit "sync" event. 205 | this.firebase.once("value", _.bind(function() { 206 | this.trigger("sync", this, null, null); 207 | }, this)); 208 | 209 | // Handle changes in any local models. 210 | this.listenTo(this, "change", this._updateModel, this); 211 | // Listen for destroy event to remove models. 212 | this.listenTo(this, "destroy", this._removeModel, this); 213 | 214 | // Don't suppress local events by default. 215 | this._suppressEvent = false; 216 | }, 217 | 218 | comparator: function(model) { 219 | return model.id; 220 | }, 221 | 222 | add: function(models, options) { 223 | var parsed = this._parseModels(models); 224 | options = options ? _.clone(options) : {}; 225 | options.success = 226 | _.isFunction(options.success) ? options.success : function() {}; 227 | 228 | for (var i = 0; i < parsed.length; i++) { 229 | var model = parsed[i]; 230 | var childRef = this.firebase.ref().child(model.id); 231 | if (options.silent === true) { 232 | this._suppressEvent = true; 233 | } 234 | childRef.set(model, _.bind(options.success, model)); 235 | } 236 | 237 | return parsed; 238 | }, 239 | 240 | remove: function(models, options) { 241 | var parsed = this._parseModels(models); 242 | options = options ? _.clone(options) : {}; 243 | options.success = 244 | _.isFunction(options.success) ? options.success : function() {}; 245 | 246 | for (var i = 0; i < parsed.length; i++) { 247 | var model = parsed[i]; 248 | var childRef = this.firebase.ref().child(model.id); 249 | if (options.silent === true) { 250 | this._suppressEvent = true; 251 | } 252 | childRef.set(null, _.bind(options.success, model)); 253 | } 254 | 255 | return parsed; 256 | }, 257 | 258 | create: function(model, options) { 259 | options = options ? _.clone(options) : {}; 260 | if (options.wait) { 261 | this._log("Wait option provided to create, ignoring."); 262 | } 263 | model = Backbone.Collection.prototype._prepareModel.apply( 264 | this, [model, options] 265 | ); 266 | if (!model) { 267 | return false; 268 | } 269 | var set = this.add([model], options); 270 | return set[0]; 271 | }, 272 | 273 | reset: function(models, options) { 274 | options = options ? _.clone(options) : {}; 275 | // Remove all models remotely. 276 | this.remove(this.models, {silent: true}); 277 | // Add new models. 278 | var ret = this.add(models, {silent: true}); 279 | // Trigger "reset" event. 280 | if (!options.silent) { 281 | this.trigger("reset", this, options); 282 | } 283 | return ret; 284 | }, 285 | 286 | _log: function(msg) { 287 | if (console && console.log) { 288 | console.log(msg); 289 | } 290 | }, 291 | 292 | // TODO: Options will be ignored for add & remove, document this! 293 | _parseModels: function(models) { 294 | var ret = []; 295 | models = _.isArray(models) ? models.slice() : [models]; 296 | for (var i = 0; i < models.length; i++) { 297 | var model = models[i]; 298 | if (model.toJSON && typeof model.toJSON == "function") { 299 | model = model.toJSON(); 300 | } 301 | if (!model.id) { 302 | model.id = this.firebase.ref().push().name(); 303 | } 304 | ret.push(model); 305 | } 306 | return ret; 307 | }, 308 | 309 | _childAdded: function(snap) { 310 | var model = snap.val(); 311 | if (!model.id) { 312 | if (!_.isObject(model)) { 313 | model = {}; 314 | } 315 | model.id = snap.name(); 316 | } 317 | if (this._suppressEvent === true) { 318 | this._suppressEvent = false; 319 | Backbone.Collection.prototype.add.apply(this, [model], {silent: true}); 320 | } else { 321 | Backbone.Collection.prototype.add.apply(this, [model]); 322 | } 323 | this.get(model.id)._remoteAttributes = model; 324 | }, 325 | 326 | _childMoved: function(snap) { 327 | // TODO: Investigate: can this occur without the ID changing? 328 | this._log("_childMoved called with " + snap.val()); 329 | }, 330 | 331 | _childChanged: function(snap) { 332 | var model = snap.val(); 333 | if (!model.id) { 334 | model.id = snap.name(); 335 | } 336 | 337 | var item = _.find(this.models, function(child) { 338 | return child.id == model.id; 339 | }); 340 | 341 | if (!item) { 342 | // TODO: Investigate: what is the right way to handle this case? 343 | throw new Error("Could not find model with ID " + model.id); 344 | } 345 | 346 | this._preventSync(item, true); 347 | item._remoteAttributes = model; 348 | 349 | var diff = _.difference(_.keys(item.attributes), _.keys(model)); 350 | _.each(diff, function(key) { 351 | item.unset(key); 352 | }); 353 | 354 | item.set(model); 355 | this._preventSync(item, false); 356 | }, 357 | 358 | _childRemoved: function(snap) { 359 | var model = snap.val(); 360 | if (!model.id) { 361 | model.id = snap.name(); 362 | } 363 | if (this._suppressEvent === true) { 364 | this._suppressEvent = false; 365 | Backbone.Collection.prototype.remove.apply( 366 | this, [model], {silent: true} 367 | ); 368 | } else { 369 | Backbone.Collection.prototype.remove.apply(this, [model]); 370 | } 371 | }, 372 | 373 | // Add handlers for all models in this collection, and any future ones 374 | // that may be added. 375 | _updateModel: function(model) { 376 | if (model._remoteChanging) { 377 | return; 378 | } 379 | 380 | var remoteAttributes = model._remoteAttributes || {}; 381 | var localAttributes = model.toJSON(); 382 | var updateAttributes = {}; 383 | 384 | var union = _.union(_.keys(remoteAttributes), _.keys(localAttributes)); 385 | _.each(union, function(key) { 386 | if (!_.has(localAttributes, key)) { 387 | updateAttributes[key] = null; 388 | } else if (localAttributes[key] != remoteAttributes[key]) { 389 | updateAttributes[key] = localAttributes[key]; 390 | } 391 | }); 392 | 393 | if (_.size(updateAttributes)) { 394 | // Special case if ".priority" was updated - a merge is not 395 | // allowed so we'll have to do a full setWithPriority. 396 | if (_.has(updateAttributes, ".priority")) { 397 | var ref = this.firebase.ref().child(model.id); 398 | var priority = localAttributes[".priority"]; 399 | delete localAttributes[".priority"]; 400 | ref.setWithPriority(localAttributes, priority); 401 | } else { 402 | this.firebase.ref().child(model.id).update(updateAttributes); 403 | } 404 | } 405 | }, 406 | 407 | // Triggered when model.destroy() is called on one of the children. 408 | _removeModel: function(model, collection, options) { 409 | options = options ? _.clone(options) : {}; 410 | options.success = 411 | _.isFunction(options.success) ? options.success : function() {}; 412 | var childRef = this.firebase.ref().child(model.id); 413 | childRef.set(null, _.bind(options.success, model)); 414 | }, 415 | 416 | _preventSync: function(model, state) { 417 | model._remoteChanging = state; 418 | } 419 | }); 420 | 421 | // Custom Firebase Model. 422 | Backbone.Firebase.Model = Backbone.Model.extend({ 423 | save: function() { 424 | this._log("Save called on a Firebase model, ignoring."); 425 | }, 426 | 427 | destroy: function(options) { 428 | // TODO: Fix naive success callback. Add error callback. 429 | this.firebase.ref().set(null, this._log); 430 | this.trigger("destroy", this, this.collection, options); 431 | if (options.success) { 432 | options.success(this, null, options); 433 | } 434 | }, 435 | 436 | constructor: function(model, options) { 437 | // Store defaults so they don't get applied immediately. 438 | var defaults = _.result(this, "defaults"); 439 | 440 | // Apply defaults only after first sync. 441 | this.once("sync", function() { 442 | this.set(_.defaults(this.toJSON(), defaults)); 443 | }); 444 | 445 | // Apply parent constructor (this will also call initialize). 446 | Backbone.Model.apply(this, arguments); 447 | 448 | if (options && options.firebase) { 449 | this.firebase = options.firebase; 450 | } 451 | switch (typeof this.firebase) { 452 | case "object": 453 | break; 454 | case "string": 455 | this.firebase = new Firebase(this.firebase); 456 | break; 457 | case "function": 458 | this.firebase = this.firebase(); 459 | break; 460 | default: 461 | throw new Error("Invalid firebase reference created"); 462 | } 463 | 464 | // Add handlers for remote events. 465 | this.firebase.on("value", _.bind(this._modelChanged, this)); 466 | 467 | this._listenLocalChange(true); 468 | }, 469 | 470 | _listenLocalChange: function(state) { 471 | if (state) { 472 | this.on("change", this._updateModel, this); 473 | } else { 474 | this.off("change", this._updateModel, this); 475 | } 476 | }, 477 | 478 | _updateModel: function(model) { 479 | // Find the deleted keys and set their values to null 480 | // so Firebase properly deletes them. 481 | var modelObj = model.changedAttributes(); 482 | _.each(model.changed, function(value, key) { 483 | if (typeof value === "undefined" || value === null) { 484 | if (key == "id") { 485 | delete modelObj[key]; 486 | } else { 487 | modelObj[key] = null; 488 | } 489 | } 490 | }); 491 | if (_.size(modelObj)) { 492 | this.firebase.ref().update(modelObj, this._log); 493 | } 494 | }, 495 | 496 | _modelChanged: function(snap) { 497 | // Unset attributes that have been deleted from the server 498 | // by comparing the keys that have been removed. 499 | var newModel = snap.val(); 500 | if (typeof newModel === "object" && newModel !== null) { 501 | var diff = _.difference(_.keys(this.attributes), _.keys(newModel)); 502 | var self = this; 503 | _.each(diff, function(key) { 504 | self.unset(key); 505 | }); 506 | } 507 | this._listenLocalChange(false); 508 | this.set(newModel); 509 | this._listenLocalChange(true); 510 | this.trigger("sync", this, null, null); 511 | }, 512 | 513 | _log: function(msg) { 514 | if (typeof msg === "undefined" || msg === null) { 515 | return; 516 | } 517 | if (console && console.log) { 518 | console.log(msg); 519 | } 520 | } 521 | 522 | }); 523 | 524 | })(); 525 | -------------------------------------------------------------------------------- /js/vendor/backbone-min.js: -------------------------------------------------------------------------------- 1 | (function(){var t=this;var e=t.Backbone;var i=[];var r=i.push;var s=i.slice;var n=i.splice;var a;if(typeof exports!=="undefined"){a=exports}else{a=t.Backbone={}}a.VERSION="1.0.0";var h=t._;if(!h&&typeof require!=="undefined")h=require("underscore");a.$=t.jQuery||t.Zepto||t.ender||t.$;a.noConflict=function(){t.Backbone=e;return this};a.emulateHTTP=false;a.emulateJSON=false;var o=a.Events={on:function(t,e,i){if(!l(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,i){if(!l(this,"once",t,[e,i])||!e)return this;var r=this;var s=h.once(function(){r.off(t,s);e.apply(this,arguments)});s._callback=e;return this.on(t,s,i)},off:function(t,e,i){var r,s,n,a,o,u,c,f;if(!this._events||!l(this,"off",t,[e,i]))return this;if(!t&&!e&&!i){this._events={};return this}a=t?[t]:h.keys(this._events);for(o=0,u=a.length;o").attr(t);this.setElement(e,false)}else{this.setElement(h.result(this,"el"),false)}}});a.sync=function(t,e,i){var r=k[t];h.defaults(i||(i={}),{emulateHTTP:a.emulateHTTP,emulateJSON:a.emulateJSON});var s={type:r,dataType:"json"};if(!i.url){s.url=h.result(e,"url")||U()}if(i.data==null&&e&&(t==="create"||t==="update"||t==="patch")){s.contentType="application/json";s.data=JSON.stringify(i.attrs||e.toJSON(i))}if(i.emulateJSON){s.contentType="application/x-www-form-urlencoded";s.data=s.data?{model:s.data}:{}}if(i.emulateHTTP&&(r==="PUT"||r==="DELETE"||r==="PATCH")){s.type="POST";if(i.emulateJSON)s.data._method=r;var n=i.beforeSend;i.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",r);if(n)return n.apply(this,arguments)}}if(s.type!=="GET"&&!i.emulateJSON){s.processData=false}if(s.type==="PATCH"&&window.ActiveXObject&&!(window.external&&window.external.msActiveXFilteringEnabled)){s.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var o=i.xhr=a.ajax(h.extend(s,i));e.trigger("request",e,o,i);return o};var k={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};a.ajax=function(){return a.$.ajax.apply(a.$,arguments)};var S=a.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var $=/\((.*?)\)/g;var T=/(\(\?)?:\w+/g;var H=/\*\w+/g;var A=/[\-{}\[\]+?.,\\\^$|#\s]/g;h.extend(S.prototype,o,{initialize:function(){},route:function(t,e,i){if(!h.isRegExp(t))t=this._routeToRegExp(t);if(h.isFunction(e)){i=e;e=""}if(!i)i=this[e];var r=this;a.history.route(t,function(s){var n=r._extractParameters(t,s);i&&i.apply(r,n);r.trigger.apply(r,["route:"+e].concat(n));r.trigger("route",e,n);a.history.trigger("route",r,e,n)});return this},navigate:function(t,e){a.history.navigate(t,e);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=h.result(this,"routes");var t,e=h.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(A,"\\$&").replace($,"(?:$1)?").replace(T,function(t,e){return e?t:"([^/]+)"}).replace(H,"(.*?)");return new RegExp("^"+t+"$")},_extractParameters:function(t,e){var i=t.exec(e).slice(1);return h.map(i,function(t){return t?decodeURIComponent(t):null})}});var I=a.History=function(){this.handlers=[];h.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var N=/^[#\/]|\s+$/g;var P=/^\/+|\/+$/g;var O=/msie [\w.]+/;var C=/\/$/;I.started=false;h.extend(I.prototype,o,{interval:50,getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=this.location.pathname;var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.substr(i.length)}else{t=this.getHash()}}return t.replace(N,"")},start:function(t){if(I.started)throw new Error("Backbone.history has already been started");I.started=true;this.options=h.extend({},{root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var e=this.getFragment();var i=document.documentMode;var r=O.exec(navigator.userAgent.toLowerCase())&&(!i||i<=7);this.root=("/"+this.root+"/").replace(P,"/");if(r&&this._wantsHashChange){this.iframe=a.$('