├── .gitignore ├── README.md ├── Screenshot.png ├── assets ├── css │ └── theme.css ├── fonts │ ├── lato-black-webfont.eot │ ├── lato-black-webfont.svg │ ├── lato-black-webfont.ttf │ ├── lato-black-webfont.woff │ ├── lato-italic-webfont.eot │ ├── lato-italic-webfont.svg │ ├── lato-italic-webfont.ttf │ ├── lato-italic-webfont.woff │ ├── lato-light-webfont.eot │ ├── lato-light-webfont.svg │ ├── lato-light-webfont.ttf │ ├── lato-light-webfont.woff │ ├── lato-regular-webfont.eot │ ├── lato-regular-webfont.svg │ ├── lato-regular-webfont.ttf │ └── lato-regular-webfont.woff ├── images │ ├── loading-indicator.svg │ └── october.png ├── javascript │ ├── app.js │ ├── dragscroll.js │ ├── fileupload.js │ ├── jquery.js │ ├── modernizr.js │ ├── mousewheel.js │ ├── sortable.js │ └── typeahead.js ├── less │ ├── controls │ │ └── all.less │ ├── layouts │ │ └── all.less │ ├── pages │ │ ├── all.less │ │ ├── dishes.less │ │ ├── planner.less │ │ └── shopping.less │ ├── theme.less │ └── theme │ │ ├── all.less │ │ ├── boot.less │ │ ├── fonts.less │ │ ├── mixins.less │ │ ├── variables.less │ │ └── vendor.less └── vendor │ ├── bootstrap-select │ ├── bootstrap-select.css │ └── bootstrap-select.js │ ├── bootstrap │ ├── js │ │ ├── affix.js │ │ ├── alert.js │ │ ├── button.js │ │ ├── carousel.js │ │ ├── collapse.js │ │ ├── dropdown.js │ │ ├── modal.js │ │ ├── popover.js │ │ ├── scrollspy.js │ │ ├── tab.js │ │ ├── tooltip.js │ │ └── transition.js │ └── less │ │ ├── alerts.less │ │ ├── badges.less │ │ ├── bootstrap.less │ │ ├── breadcrumbs.less │ │ ├── button-groups.less │ │ ├── buttons.less │ │ ├── carousel.less │ │ ├── close.less │ │ ├── code.less │ │ ├── component-animations.less │ │ ├── dropdowns.less │ │ ├── forms.less │ │ ├── glyphicons.less │ │ ├── grid.less │ │ ├── input-groups.less │ │ ├── jumbotron.less │ │ ├── labels.less │ │ ├── list-group.less │ │ ├── media.less │ │ ├── mixins.less │ │ ├── modals.less │ │ ├── navbar.less │ │ ├── navs.less │ │ ├── normalize.less │ │ ├── pager.less │ │ ├── pagination.less │ │ ├── panels.less │ │ ├── popovers.less │ │ ├── print.less │ │ ├── progress-bars.less │ │ ├── responsive-utilities.less │ │ ├── scaffolding.less │ │ ├── tables.less │ │ ├── theme.less │ │ ├── thumbnails.less │ │ ├── tooltip.less │ │ ├── type.less │ │ ├── utilities.less │ │ ├── variables.less │ │ └── wells.less │ ├── fileupload │ ├── fileupload.js │ ├── iframe-transport.js │ └── ui-widget.js │ └── font-awesome │ ├── css │ └── font-awesome.css │ ├── font │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ └── fontawesome-webfont.woff │ └── less │ ├── bootstrap.less │ ├── core.less │ ├── extras.less │ ├── font-awesome-ie7.less │ ├── font-awesome.less │ ├── icons.less │ ├── mixins.less │ ├── path.less │ └── variables.less ├── layouts ├── blank.htm └── default.htm ├── pages ├── 404.htm ├── dishes.htm ├── error.htm ├── home.htm ├── planner.htm └── shopping.htm └── partials ├── .gitkeep ├── dishes ├── dishes.htm ├── form.htm ├── ingredients.htm └── preview.htm ├── footer.htm ├── menu.htm ├── planner └── dishes.htm └── shopping └── ingredients.htm /.gitignore: -------------------------------------------------------------------------------- 1 | /sftp-config.json 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Dish Smith 2013 2 | ========= 3 | 4 | ![Screenshot](https://raw.githubusercontent.com/daftspunk/dishsmith/master/Screenshot.png) 5 | 6 | For my wife, Becky :-) 7 | 8 | DishSmith is a meal planner created at [HACT 2013](http://hact.org.au) hackathon in a 32 hour programming sprint. 9 | 10 | ## What is it? 11 | 12 | DishSmith lets you organise your life for eating. It is a meal planner based on the premise that eating right requires either **passion** or **planning**. 13 | 14 | You add your favourite Dishes and Ingredients needed for those dishes. DishSmith will *pepper* these dishes in to a weekly timetable. 15 | 16 | You can even print a shopping list to be used at the beginning of each week. 17 | 18 | ## Made in Australia 19 | 20 | DishSmith is made using [October CMS](http://octobercms.com) and [Bootstrap](http://getbootstrap.com). 21 | 22 | ## Plugin dependancy 23 | 24 | DishSmith comes with its own Plugin for October CMS. 25 | You can find this plugin at the [dishsmith-plugin repo](https://github.com/daftspunk/dishsmith-plugin). 26 | 27 | ## Installation 28 | 29 | 1. [Install a copy of October CMS](http://octobercms.com/docs/help/installation). 30 | 2. Download this [Theme archive](https://github.com/daftspunk/dishsmith/archive/master.zip) as a ZIP. 31 | 3. Extract the archive contents to `/themes/dishsmith` in the OctoberCMS application root directory. 32 | 4. Open `/app/config/cms.php` and set the `activeTheme` to **dishsmith**. 33 | 4. Install the [DishSmith Plugin](https://github.com/daftspunk/dishsmith-plugin). 34 | 5. Get cooking! 35 | -------------------------------------------------------------------------------- /Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/Screenshot.png -------------------------------------------------------------------------------- /assets/fonts/lato-black-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/assets/fonts/lato-black-webfont.eot -------------------------------------------------------------------------------- /assets/fonts/lato-black-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/assets/fonts/lato-black-webfont.ttf -------------------------------------------------------------------------------- /assets/fonts/lato-black-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/assets/fonts/lato-black-webfont.woff -------------------------------------------------------------------------------- /assets/fonts/lato-italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/assets/fonts/lato-italic-webfont.eot -------------------------------------------------------------------------------- /assets/fonts/lato-italic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/assets/fonts/lato-italic-webfont.ttf -------------------------------------------------------------------------------- /assets/fonts/lato-italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/assets/fonts/lato-italic-webfont.woff -------------------------------------------------------------------------------- /assets/fonts/lato-light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/assets/fonts/lato-light-webfont.eot -------------------------------------------------------------------------------- /assets/fonts/lato-light-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/assets/fonts/lato-light-webfont.ttf -------------------------------------------------------------------------------- /assets/fonts/lato-light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/assets/fonts/lato-light-webfont.woff -------------------------------------------------------------------------------- /assets/fonts/lato-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/assets/fonts/lato-regular-webfont.eot -------------------------------------------------------------------------------- /assets/fonts/lato-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/assets/fonts/lato-regular-webfont.ttf -------------------------------------------------------------------------------- /assets/fonts/lato-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/assets/fonts/lato-regular-webfont.woff -------------------------------------------------------------------------------- /assets/images/loading-indicator.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | ]> 6 | 9 | 10 | 11 | 12 | 15 | 18 | 20 | 21 | -------------------------------------------------------------------------------- /assets/images/october.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daftspunk/dishsmith/525e6f7399883edda90440b3bec81ef19d571425/assets/images/october.png -------------------------------------------------------------------------------- /assets/javascript/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Application 3 | * 4 | */ 5 | 6 | /* 7 | * Bootstrap 8 | * 9 | =require modernizr 10 | =require mousewheel 11 | =require dragscroll 12 | =require typeahead 13 | =require sortable 14 | =require ../vendor/bootstrap/js/transition 15 | =require ../vendor/bootstrap/js/alert 16 | =require ../vendor/bootstrap/js/button 17 | =require ../vendor/bootstrap/js/carousel 18 | =require ../vendor/bootstrap/js/collapse 19 | =require ../vendor/bootstrap/js/dropdown 20 | =require ../vendor/bootstrap/js/modal 21 | =require ../vendor/bootstrap/js/tooltip 22 | =require ../vendor/bootstrap/js/popover 23 | =require ../vendor/bootstrap/js/scrollspy 24 | =require ../vendor/bootstrap/js/tab 25 | =require ../vendor/bootstrap/js/affix 26 | =require ../vendor/bootstrap-select/bootstrap-select.js 27 | */ 28 | 29 | $(document).tooltip({ 30 | selector: '[data-toggle=tooltip]' 31 | }) 32 | 33 | $(document).ready(function(){ 34 | $(document).render(function(){ 35 | $('[data-toggle=popover]').popover({ 36 | html: true 37 | }) 38 | 39 | $('.selectpicker').selectpicker({ 40 | container: 'body' 41 | }) 42 | }) 43 | }) 44 | 45 | $(document) 46 | .on('ajaxPromise', '[data-request]', function() { 47 | $('#layout-header').addClass('loading') 48 | 49 | // This code will cover instances where the element has been removed 50 | // from the DOM, making the resolution event below an orphan. 51 | var $el = $(this); 52 | $(window).one('ajaxUpdateComplete', function(){ 53 | if ($el.closest('html').length === 0) 54 | $('#layout-header').removeClass('loading') 55 | }) 56 | 57 | }).on('ajaxFail ajaxDone', '[data-request]', function(){ 58 | $('#layout-header').removeClass('loading') 59 | }) -------------------------------------------------------------------------------- /assets/javascript/mousewheel.js: -------------------------------------------------------------------------------- 1 | /*! Copyright (c) 2013 Brandon Aaron (http://brandonaaron.net) 2 | * Licensed under the MIT License (LICENSE.txt). 3 | * 4 | * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 5 | * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 6 | * Thanks to: Seamus Leahy for adding deltaX and deltaY 7 | * 8 | * Version: 3.1.3 9 | * 10 | * Requires: 1.2.2+ 11 | */ 12 | 13 | (function (factory) { 14 | if ( typeof define === 'function' && define.amd ) { 15 | // AMD. Register as an anonymous module. 16 | define(['jquery'], factory); 17 | } else if (typeof exports === 'object') { 18 | // Node/CommonJS style for Browserify 19 | module.exports = factory; 20 | } else { 21 | // Browser globals 22 | factory(jQuery); 23 | } 24 | }(function ($) { 25 | 26 | var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll']; 27 | var toBind = 'onwheel' in document || document.documentMode >= 9 ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll']; 28 | var lowestDelta, lowestDeltaXY; 29 | 30 | if ( $.event.fixHooks ) { 31 | for ( var i = toFix.length; i; ) { 32 | $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks; 33 | } 34 | } 35 | 36 | $.event.special.mousewheel = { 37 | setup: function() { 38 | if ( this.addEventListener ) { 39 | for ( var i = toBind.length; i; ) { 40 | this.addEventListener( toBind[--i], handler, false ); 41 | } 42 | } else { 43 | this.onmousewheel = handler; 44 | } 45 | }, 46 | 47 | teardown: function() { 48 | if ( this.removeEventListener ) { 49 | for ( var i = toBind.length; i; ) { 50 | this.removeEventListener( toBind[--i], handler, false ); 51 | } 52 | } else { 53 | this.onmousewheel = null; 54 | } 55 | } 56 | }; 57 | 58 | $.fn.extend({ 59 | mousewheel: function(fn) { 60 | return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); 61 | }, 62 | 63 | unmousewheel: function(fn) { 64 | return this.unbind("mousewheel", fn); 65 | } 66 | }); 67 | 68 | 69 | function handler(event) { 70 | var orgEvent = event || window.event, 71 | args = [].slice.call(arguments, 1), 72 | delta = 0, 73 | deltaX = 0, 74 | deltaY = 0, 75 | absDelta = 0, 76 | absDeltaXY = 0, 77 | fn; 78 | event = $.event.fix(orgEvent); 79 | event.type = "mousewheel"; 80 | 81 | // Old school scrollwheel delta 82 | if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta; } 83 | if ( orgEvent.detail ) { delta = orgEvent.detail * -1; } 84 | 85 | // New school wheel delta (wheel event) 86 | if ( orgEvent.deltaY ) { 87 | deltaY = orgEvent.deltaY * -1; 88 | delta = deltaY; 89 | } 90 | if ( orgEvent.deltaX ) { 91 | deltaX = orgEvent.deltaX; 92 | delta = deltaX * -1; 93 | } 94 | 95 | // Webkit 96 | if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY; } 97 | if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = orgEvent.wheelDeltaX * -1; } 98 | 99 | // Look for lowest delta to normalize the delta values 100 | absDelta = Math.abs(delta); 101 | if ( !lowestDelta || absDelta < lowestDelta ) { lowestDelta = absDelta; } 102 | absDeltaXY = Math.max(Math.abs(deltaY), Math.abs(deltaX)); 103 | if ( !lowestDeltaXY || absDeltaXY < lowestDeltaXY ) { lowestDeltaXY = absDeltaXY; } 104 | 105 | // Get a whole value for the deltas 106 | fn = delta > 0 ? 'floor' : 'ceil'; 107 | delta = Math[fn](delta / lowestDelta); 108 | deltaX = Math[fn](deltaX / lowestDeltaXY); 109 | deltaY = Math[fn](deltaY / lowestDeltaXY); 110 | 111 | // Add event and delta to the front of the arguments 112 | args.unshift(event, delta, deltaX, deltaY); 113 | 114 | return ($.event.dispatch || $.event.handle).apply(this, args); 115 | } 116 | 117 | })); -------------------------------------------------------------------------------- /assets/less/controls/all.less: -------------------------------------------------------------------------------- 1 | // 2 | // Controls 3 | // 4 | // These are reusable elements used in the site. 5 | // 6 | 7 | // 8 | // Resets 9 | // 10 | 11 | .form-control { 12 | .transition(none); 13 | .box-shadow(none); 14 | &:focus { 15 | .box-shadow(none); 16 | } 17 | } 18 | 19 | .btn { 20 | &:active, &.active { 21 | .box-shadow(none); 22 | outline: none; 23 | } 24 | } 25 | 26 | // 27 | // Callouts 28 | // -------------------------------------------------- 29 | 30 | .callout { 31 | margin-bottom: @line-height-computed; 32 | padding: @callout-padding; 33 | border-left: 3px solid @callout-border; 34 | code, .highlight { 35 | } 36 | h4 { 37 | margin-top: 0; 38 | margin-bottom: 5px; 39 | } 40 | p:last-child { 41 | margin-bottom: 0; 42 | } 43 | } 44 | 45 | .callout-danger { 46 | background-color: @callout-danger-bg; 47 | border-color: @callout-danger-border; 48 | h4 { 49 | color: @callout-danger-text; 50 | } 51 | } 52 | 53 | .callout-warning { 54 | background-color: @callout-warning-bg; 55 | border-color: @callout-warning-border; 56 | h4 { 57 | color: @callout-warning-text; 58 | } 59 | } 60 | 61 | .callout-info { 62 | background-color: @callout-info-bg; 63 | border-color: @callout-info-border; 64 | h4 { 65 | color: @callout-info-text; 66 | } 67 | } 68 | 69 | .callout-success { 70 | background-color: @callout-success-bg; 71 | border-color: @callout-success-border; 72 | h4 { 73 | color: @callout-success-text; 74 | } 75 | } -------------------------------------------------------------------------------- /assets/less/layouts/all.less: -------------------------------------------------------------------------------- 1 | // 2 | // Layouts 3 | // 4 | // Styles specific to different page layouts. 5 | // 6 | 7 | body { 8 | background: #2980B9; 9 | } 10 | 11 | body.drag * { 12 | cursor: drag!important; 13 | cursor: -webkit-grab!important; 14 | cursor: -moz-grab!important; 15 | } 16 | 17 | .attachment-input { 18 | position: absolute; 19 | visibility: hidden; 20 | width: 10px; 21 | opacity: 0; 22 | } 23 | 24 | body.default-layout { 25 | 26 | #layout-header-container { 27 | padding-top: 40px; 28 | padding-bottom: 0; 29 | position: relative; 30 | 31 | .user-menu { 32 | position: absolute; 33 | top: 5px; 34 | right: 0; 35 | } 36 | } 37 | 38 | header#layout-header { 39 | position: relative; 40 | vertical-align: bottom; 41 | 42 | h1.logo { 43 | font-size: 48px; 44 | margin: 0; 45 | color: white; 46 | font-weight: bold; 47 | span { font-style: italic; } 48 | a { 49 | color: white; 50 | text-decoration: none; 51 | display: block; 52 | &:hover i { 53 | .opacity(.8); 54 | } 55 | } 56 | } 57 | 58 | i.icon-food { 59 | width: 40px; 60 | height: 40px; 61 | display: inline-block; 62 | position: relative; 63 | &:before, &:after { 64 | .transition(opacity 0.5s ease); 65 | } 66 | &:after { 67 | .opacity(0); 68 | content: ''; 69 | display: block; 70 | position: absolute; 71 | top: 50%; 72 | left: 50%; 73 | margin-left: -20px; 74 | margin-top: -17px; 75 | width: 40px; 76 | height: 40px; 77 | background-image: url('../images/loading-indicator.svg'); 78 | background-size: 40px 40px; 79 | background-position: 50% 50%; 80 | .animation(spin 1s linear infinite); 81 | } 82 | } 83 | 84 | &.loading { 85 | i.icon-food { 86 | &:before { 87 | .opacity(0); 88 | } 89 | &:after { 90 | .opacity(1); 91 | } 92 | } 93 | } 94 | } 95 | 96 | nav#layout-nav { 97 | * { 98 | border-color: transparent !important; 99 | } 100 | ul { 101 | margin-top: 15px; 102 | } 103 | li { 104 | margin: 0 5px; 105 | 106 | a { 107 | color: white; 108 | font-size: 18px; 109 | 110 | &:hover { 111 | color: #C0392B; 112 | } 113 | } 114 | &.active { 115 | a { 116 | color: #C0392B; 117 | } 118 | } 119 | } 120 | } 121 | 122 | .active-day { 123 | padding: 15px 0 0 10px; 124 | .btn-group { margin:0; } 125 | } 126 | 127 | section#layout-content .container { 128 | background: white; 129 | .border-radius(5px); 130 | border: 1px solid #ddd; 131 | border-top: none; 132 | position: relative; 133 | top: -2px; 134 | } 135 | } 136 | 137 | footer#layout-footer { 138 | padding: 20px 0; 139 | color: #ECF0F1; 140 | 141 | a { color: #ECF0F1; 142 | &:hover { color: #BDC3C7; } 143 | } 144 | } -------------------------------------------------------------------------------- /assets/less/pages/all.less: -------------------------------------------------------------------------------- 1 | // 2 | // Pages 3 | // 4 | // Styles specific to individual pages. 5 | // 6 | 7 | @import "planner"; 8 | @import "dishes"; 9 | @import "shopping"; 10 | 11 | .home-page { 12 | 13 | margin-top: 50px; 14 | 15 | p { 16 | color: white; 17 | } 18 | 19 | a { 20 | color: #ECF0F1; 21 | text-decoration: none; 22 | &:hover { color: white; } 23 | } 24 | 25 | .logo-circle { 26 | display: block; 27 | position: relative; 28 | background: white; 29 | .border-radius(9999px); 30 | width: 200px; 31 | height: 200px; 32 | margin-bottom: 15px; 33 | .transition(background 0.5s ease); 34 | 35 | h1 { 36 | color: #555; 37 | margin: 0 auto; 38 | line-height: 200px; 39 | text-align: center; 40 | white-space: nowrap; 41 | .transition(opacity 0.5s ease); 42 | span { font-style: italic; } 43 | } 44 | 45 | &.loading { 46 | background: rgba(255,255,255,.5); 47 | 48 | &:after { 49 | content: ''; 50 | display: block; 51 | position: absolute; 52 | top: 50%; 53 | left: 50%; 54 | margin-left: -50px; 55 | margin-top: -50px; 56 | width: 100px; 57 | height: 100px; 58 | background-image: url('../images/loading-indicator.svg'); 59 | background-size: 100px 100px; 60 | background-position: 50% 50%; 61 | .animation(spin 1s linear infinite); 62 | } 63 | 64 | h1 { .opacity(.5); } 65 | } 66 | } 67 | 68 | a.help-popover { 69 | margin-left: 3px; 70 | } 71 | 72 | p.lead { 73 | text-align: justify; 74 | display: block; 75 | } 76 | 77 | p.no-spammy { 78 | padding-top: 5px; 79 | color: #ECF0F1; 80 | } 81 | 82 | .alert { 83 | text-align: center; 84 | a { 85 | color: #2980B9; 86 | &:hover { color: #3498DB; } 87 | } 88 | } 89 | 90 | } -------------------------------------------------------------------------------- /assets/less/pages/dishes.less: -------------------------------------------------------------------------------- 1 | // 2 | // Draggable 3 | // 4 | 5 | body.dragging, body.dragging * { 6 | cursor: move !important; 7 | } 8 | 9 | .dragged { 10 | position: absolute !important; 11 | .opacity(.5); 12 | z-index: 2000; 13 | } 14 | 15 | .dish-placeholder { 16 | background: #ECF0F1; 17 | } 18 | 19 | @supports (flex-wrap: wrap) { 20 | .dishes-page { 21 | .dishes { 22 | display: flex; 23 | flex-direction: row; 24 | flex-wrap: wrap; 25 | 26 | > div { 27 | flex: 0 0 auto; 28 | } 29 | } 30 | } 31 | } 32 | 33 | .dishes-page { 34 | 35 | position: relative; 36 | overflow: hidden; 37 | margin: 20px; 38 | 39 | // 40 | // Screens 41 | // 42 | 43 | .dish-form, .dishes { 44 | .transition(all 0.5s ease); 45 | } 46 | 47 | // 48 | // Off screen elements 49 | // 50 | 51 | .dishes { 52 | top: 0; 53 | } 54 | 55 | .typeahead { 56 | z-index: 999; 57 | } 58 | 59 | .dish-form { 60 | width: 100%; 61 | position: relative; 62 | height: 0; 63 | overflow: hidden; 64 | .opacity(0); 65 | top: -50px; 66 | } 67 | 68 | &.edit-mode { 69 | .dishes { 70 | .opacity(0); 71 | height: 0; 72 | overflow: hidden; 73 | top: -50px; 74 | } 75 | .dish-form { 76 | height: auto; 77 | .opacity(1); 78 | top: 0; 79 | } 80 | } 81 | 82 | // 83 | // Dish list 84 | // 85 | 86 | .dishes { 87 | position: relative; 88 | > div { 89 | position: relative; 90 | padding: 0 0 10px 10px; 91 | min-height: 100px; 92 | } 93 | } 94 | 95 | // 96 | // Dish item 97 | // 98 | 99 | .dish-item { 100 | border: 2px solid transparent; 101 | color: #555; 102 | 103 | h3.title { 104 | color: #C0392B; 105 | .text-overflow(); 106 | display: block; 107 | } 108 | 109 | .image { 110 | padding: 10px 0; 111 | img { 112 | width: 90px; 113 | .border-radius(999px); 114 | } 115 | } 116 | 117 | .hover { display: none; } 118 | 119 | &:hover { 120 | border-color: #ECF0F1; 121 | .normal { display: none; } 122 | .hover { display: block; } 123 | } 124 | 125 | &.dragged { 126 | border-color: #ECF0F1; 127 | .normal { display: block; } 128 | .hover { display: none; } 129 | } 130 | } 131 | 132 | // New dish button 133 | 134 | .new-dish { 135 | display: block; 136 | border: 2px dashed #ECF0F1; 137 | 138 | position: absolute; 139 | top: 0; 140 | right: 0; 141 | left: 0; 142 | bottom: 0; 143 | text-decoration: none; 144 | i { 145 | font-size:64px; 146 | color: #ECF0F1; 147 | position: absolute; 148 | left: 20px; 149 | top: 50%; 150 | margin-top: -32px; 151 | } 152 | 153 | p { 154 | color: #ECF0F1; 155 | font-size: 32px; 156 | line-height: 64px; 157 | top: 50%; 158 | left: 100px; 159 | margin-top: -32px; 160 | position: absolute; 161 | } 162 | 163 | &:hover { 164 | border-color: #BDC3C7; 165 | } 166 | } 167 | 168 | // 169 | // Dish Form 170 | // 171 | 172 | .dish-form { 173 | 174 | .dish-item { 175 | border-color: #ECF0F1; 176 | width: 100%; 177 | margin-bottom: 15px; 178 | padding-left: 20px; 179 | } 180 | 181 | button.selectpicker { 182 | .border-left-radius(0); 183 | margin-left: -1px; 184 | } 185 | 186 | .list-group { 187 | p.lead { margin:0; } 188 | button.close { position: relative; top: 5px; } 189 | } 190 | 191 | } 192 | 193 | } -------------------------------------------------------------------------------- /assets/less/pages/planner.less: -------------------------------------------------------------------------------- 1 | .planner-page { 2 | 3 | .dishes-container { 4 | overflow: hidden; 5 | overflow-x: scroll; 6 | } 7 | 8 | ul.dishes { 9 | list-style: none; 10 | margin: 0; 11 | padding: 0; 12 | 13 | display: flex; 14 | flex-direction: row; 15 | 16 | > li { 17 | flex: 0 0 200px; 18 | position: relative; 19 | border: 2px solid #ECF0F1; 20 | min-height: 200px; 21 | 22 | &.start-banner { 23 | flex: 0 0 50px; 24 | background: #E74C3C; 25 | position: relative; 26 | 27 | span { 28 | position: absolute; 29 | margin-top: 25px; 30 | top: 50%; 31 | left: 0; 32 | width: 50px; 33 | line-height: 50px; 34 | text-align: center; 35 | display: block; 36 | color: white; 37 | .rotate(-90deg); 38 | white-space: nowrap; 39 | font-size: 22px; 40 | text-transform: uppercase; 41 | letter-spacing: 10px; 42 | } 43 | } 44 | 45 | h5.day { 46 | margin: 0; 47 | padding: 10px 0; 48 | font-size: 28px; 49 | display: block; 50 | background: #ECF0F1; 51 | text-align: center; 52 | color: #555; 53 | } 54 | 55 | .image { 56 | padding: 10px 0; 57 | text-align: center; 58 | img { 59 | width: 95%; 60 | .border-radius(999px); 61 | } 62 | } 63 | 64 | h3.title { 65 | margin: 0; 66 | padding: 10px 0; 67 | background: #ECF0F1; 68 | color: #C0392B; 69 | text-align: center; 70 | } 71 | 72 | ul.ingredients { 73 | list-style: none; 74 | margin: 0; 75 | padding: 0; 76 | color: #555; 77 | font-size: 16px; 78 | overflow: hidden; 79 | li { 80 | padding: 5px 0; 81 | background: white; 82 | text-align: center; 83 | &:nth-child(even) { 84 | background: #ECF0F1; 85 | } 86 | } 87 | } 88 | 89 | &.active { 90 | border-color: #C0392B; 91 | &:before { 92 | position: absolute; 93 | left: 50%; 94 | margin-left: -15px; 95 | .triangle(down, 30px, 10px, #C0392B); 96 | } 97 | } 98 | 99 | &.today { 100 | h5.day { 101 | background: #F1C40F; 102 | color: white; 103 | } 104 | } 105 | } 106 | 107 | } 108 | 109 | } -------------------------------------------------------------------------------- /assets/less/pages/shopping.less: -------------------------------------------------------------------------------- 1 | .shopping-page { 2 | padding: 20px; 3 | 4 | h1 { 5 | color: #C0392B; 6 | padding-bottom: 10px; 7 | } 8 | 9 | .shopping-list { 10 | .list-item { 11 | border-top: 1px solid #e0e0e0; 12 | padding-top: 5px; 13 | padding-bottom: 5px; 14 | line-height: 1; 15 | i { 16 | font-size: 24px; 17 | position: relative; 18 | top: 2px; 19 | margin-right: 2px; 20 | } 21 | } 22 | } 23 | 24 | // Checkbox item 25 | 26 | .custom-checkbox { 27 | display: inline-block; 28 | 29 | input[type=checkbox] { 30 | display: none; 31 | } 32 | 33 | label { 34 | display: inline-block; 35 | cursor: pointer; 36 | position: relative; 37 | padding-left: 30px; 38 | margin-right: 5px; 39 | margin-left: -20px; 40 | 41 | font-size: 22px; 42 | &:before { 43 | content: ""; 44 | display: inline-block; 45 | text-align: center; 46 | 47 | width: 22px; 48 | height: 22px; 49 | 50 | margin-right: 15px; 51 | position: absolute; 52 | left: 0; 53 | top: 3px; 54 | background-color: #FFFFFF; 55 | border: 1px solid #999; 56 | color: #999; 57 | 58 | } 59 | &:hover:before { 60 | border-color: #333; 61 | color: #333; 62 | } 63 | &:active:before { 64 | border-color: #000; 65 | color: #000; 66 | } 67 | } 68 | input[type=checkbox]:checked + label { 69 | text-decoration: line-through; 70 | color: #999; 71 | &:before { 72 | .icon(@ok); 73 | text-decoration: none; 74 | font-size: 16px; 75 | line-height: 20px; 76 | border-width: 2px; 77 | } 78 | } 79 | } 80 | 81 | 82 | } -------------------------------------------------------------------------------- /assets/less/theme.less: -------------------------------------------------------------------------------- 1 | // 2 | // Display warning notice inside the CSS file to deter any cowboy coding 3 | // 4 | 5 | /* 6 | * 7 | * !! WARNING !! THIS CSS FILE HAS BEEN AUTOMATICALLY GENERATED !! 8 | * 9 | * Any modifications made to this file will be lost next time it is generated. 10 | * Consider modifying the 'theme.less' file found in the 'less' folder instead 11 | * or create a new custom CSS file to override the rules in this one. 12 | * 13 | * !! YOU HAVE BEEN WARNED !! MODIFY THIS FILE AT YOUR OWN RISK !! 14 | * 15 | */ 16 | 17 | // 18 | // Theme Includes 19 | // 20 | 21 | @import "theme/all"; 22 | -------------------------------------------------------------------------------- /assets/less/theme/all.less: -------------------------------------------------------------------------------- 1 | // 2 | // Boot variables and mixins 3 | // 4 | 5 | @import "boot"; 6 | 7 | // 8 | // Vendor and Fonts 9 | // 10 | 11 | @import "vendor"; 12 | @import "fonts"; 13 | 14 | // 15 | // Pages, Layouts and Controls 16 | // 17 | 18 | @import "../pages/all"; 19 | @import "../layouts/all"; 20 | @import "../controls/all"; 21 | -------------------------------------------------------------------------------- /assets/less/theme/boot.less: -------------------------------------------------------------------------------- 1 | // 2 | // Boot file 3 | // 4 | // Includes non-output LESS files such as mixins and variables 5 | // 6 | 7 | @import "../../vendor/bootstrap/less/variables.less"; 8 | @import "../../vendor/bootstrap/less/mixins.less"; 9 | @import "../../vendor/font-awesome/less/variables.less"; 10 | @import "../../vendor/font-awesome/less/mixins.less"; 11 | @import "mixins.less"; 12 | @import "variables.less"; 13 | -------------------------------------------------------------------------------- /assets/less/theme/fonts.less: -------------------------------------------------------------------------------- 1 | // 2 | // Fonts file 3 | // 4 | // Allocated area for font definitions used by this application 5 | // 6 | 7 | @font-face { 8 | font-family: 'lato'; 9 | src: url('../fonts/lato-black-webfont.eot'); 10 | src: url('../fonts/lato-black-webfont.eot?#iefix') format('embedded-opentype'), 11 | url('../fonts/lato-black-webfont.svg#latoblack') format('svg'), 12 | url('../fonts/lato-black-webfont.woff') format('woff'), 13 | url('../fonts/lato-black-webfont.ttf') format('truetype'); 14 | font-weight: 700; 15 | font-style: normal; 16 | } 17 | 18 | @font-face { 19 | font-family: 'lato'; 20 | src: url('../fonts/lato-italic-webfont.eot'); 21 | src: url('../fonts/lato-italic-webfont.eot?#iefix') format('embedded-opentype'), 22 | url('../fonts/lato-italic-webfont.svg#latoitalic') format('svg'), 23 | url('../fonts/lato-italic-webfont.woff') format('woff'), 24 | url('../fonts/lato-italic-webfont.ttf') format('truetype'); 25 | font-weight: 400; 26 | font-style: italic; 27 | } 28 | 29 | @font-face { 30 | font-family: 'lato'; 31 | src: url('../fonts/lato-regular-webfont.eot'); 32 | src: url('../fonts/lato-regular-webfont.eot?#iefix') format('embedded-opentype'), 33 | url('../fonts/lato-regular-webfont.svg#latoregular') format('svg'), 34 | url('../fonts/lato-regular-webfont.woff') format('woff'), 35 | url('../fonts/lato-regular-webfont.ttf') format('truetype'); 36 | font-weight: 400; 37 | font-style: normal; 38 | } 39 | 40 | @font-face { 41 | font-family: 'lato'; 42 | src: url('../fonts/lato-light-webfont.eot'); 43 | src: url('../fonts/lato-light-webfont.eot?#iefix') format('embedded-opentype'), 44 | url('../fonts/lato-light-webfont.svg#latolight') format('svg'), 45 | url('../fonts/lato-light-webfont.woff') format('woff'), 46 | url('../fonts/lato-light-webfont.ttf') format('truetype'); 47 | font-weight: 300; 48 | font-style: normal; 49 | } -------------------------------------------------------------------------------- /assets/less/theme/mixins.less: -------------------------------------------------------------------------------- 1 | // 2 | // Mixins file 3 | // 4 | // Space for any custom mixins used by this application 5 | // 6 | 7 | 8 | // Triangles 9 | // -------------------------------------------------- 10 | 11 | .triangle-base() { 12 | content: ''; 13 | display: block; 14 | width: 0; 15 | height: 0; 16 | } 17 | .triangle(@direction, @width, @height, @color) when (@direction = up) { 18 | .triangle-base(); 19 | border-left: @width/2 solid transparent; 20 | border-right:@width/2 solid transparent; 21 | border-bottom: @height solid @color; 22 | } 23 | .triangle(@direction, @width, @height, @color) when (@direction = down) { 24 | .triangle-base(); 25 | border-left: @width/2 solid transparent; 26 | border-right: @width/2 solid transparent; 27 | border-top: @height solid @color; 28 | } 29 | .triangle(@direction, @width, @height, @color) when (@direction = left) { 30 | .triangle-base(); 31 | border-top: @height/2 solid transparent; 32 | border-bottom: @height/2 solid transparent; 33 | border-right: @width solid @color; 34 | } 35 | .triangle(@direction, @width, @height, @color) when (@direction = right) { 36 | .triangle-base(); 37 | border-top: @height/2 solid transparent; 38 | border-bottom: @height/2 solid transparent; 39 | border-left: @width solid @color; 40 | } 41 | -------------------------------------------------------------------------------- /assets/less/theme/variables.less: -------------------------------------------------------------------------------- 1 | // 2 | // Variables file 3 | // 4 | // Space for any custom variables used by this application 5 | // 6 | 7 | // Icons 8 | // ------------------------- 9 | 10 | @FontAwesomePath: "../vendor/font-awesome/font"; 11 | 12 | // Typography 13 | // ------------------------- 14 | 15 | @font-family-sans-serif: "lato", sans-serif; 16 | @headings-font-family: "Lobster Two", cursive; 17 | 18 | // Callouts 19 | // ------------------------- 20 | @callout-padding: 20px; 21 | @callout-border-radius: @border-radius-base; 22 | @callout-border: @gray-lighter; 23 | 24 | @callout-info-bg: #f4f8fa; 25 | @callout-info-text: @state-info-text; 26 | @callout-info-border: @state-info-border; 27 | 28 | @callout-warning-bg: #faf8f0; 29 | @callout-warning-text: @state-warning-text; 30 | @callout-warning-border: @state-warning-border; 31 | 32 | @callout-danger-bg: #fdf7f7; 33 | @callout-danger-text: @state-danger-text; 34 | @callout-danger-border: @state-danger-border; 35 | 36 | @callout-success-bg: #f9fdf7; 37 | @callout-success-text: @state-success-text; 38 | @callout-success-border: @state-success-border; -------------------------------------------------------------------------------- /assets/less/theme/vendor.less: -------------------------------------------------------------------------------- 1 | // 2 | // Vendor file 3 | // 4 | // Includes all vendor LESS files that contain usable output 5 | // 6 | 7 | // 8 | // Bootstrap 9 | // 10 | 11 | // Reset 12 | @import "../../vendor/bootstrap/less/normalize"; 13 | @import "../../vendor/bootstrap/less/print"; 14 | 15 | // Core CSS 16 | @import "../../vendor/bootstrap/less/scaffolding"; 17 | @import "../../vendor/bootstrap/less/type"; 18 | @import "../../vendor/bootstrap/less/code"; 19 | @import "../../vendor/bootstrap/less/grid"; 20 | @import "../../vendor/bootstrap/less/tables"; 21 | @import "../../vendor/bootstrap/less/forms"; 22 | @import "../../vendor/bootstrap/less/buttons"; 23 | 24 | // Components 25 | @import "../../vendor/bootstrap/less/component-animations"; 26 | @import "../../vendor/bootstrap/less/dropdowns"; 27 | @import "../../vendor/bootstrap/less/button-groups"; 28 | @import "../../vendor/bootstrap/less/input-groups"; 29 | @import "../../vendor/bootstrap/less/navs"; 30 | @import "../../vendor/bootstrap/less/navbar"; 31 | @import "../../vendor/bootstrap/less/breadcrumbs"; 32 | @import "../../vendor/bootstrap/less/pagination"; 33 | @import "../../vendor/bootstrap/less/pager"; 34 | @import "../../vendor/bootstrap/less/labels"; 35 | @import "../../vendor/bootstrap/less/badges"; 36 | @import "../../vendor/bootstrap/less/jumbotron"; 37 | @import "../../vendor/bootstrap/less/thumbnails"; 38 | @import "../../vendor/bootstrap/less/alerts"; 39 | @import "../../vendor/bootstrap/less/progress-bars"; 40 | @import "../../vendor/bootstrap/less/media"; 41 | @import "../../vendor/bootstrap/less/list-group"; 42 | @import "../../vendor/bootstrap/less/panels"; 43 | @import "../../vendor/bootstrap/less/wells"; 44 | @import "../../vendor/bootstrap/less/close"; 45 | 46 | // Components w/ JavaScript 47 | @import "../../vendor/bootstrap/less/modals"; 48 | @import "../../vendor/bootstrap/less/tooltip"; 49 | @import "../../vendor/bootstrap/less/popovers"; 50 | @import "../../vendor/bootstrap/less/carousel"; 51 | 52 | // Utility classes 53 | @import "../../vendor/bootstrap/less/utilities"; 54 | @import "../../vendor/bootstrap/less/responsive-utilities"; 55 | 56 | // 57 | // Font Awesome 58 | // 59 | 60 | @import "../../vendor/font-awesome/less/path"; 61 | @import "../../vendor/font-awesome/less/core"; 62 | @import "../../vendor/font-awesome/less/bootstrap"; 63 | @import "../../vendor/font-awesome/less/extras"; 64 | @import "../../vendor/font-awesome/less/icons"; 65 | -------------------------------------------------------------------------------- /assets/vendor/bootstrap-select/bootstrap-select.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-select v1.3.5 3 | * http://silviomoreto.github.io/bootstrap-select/ 4 | * 5 | * Copyright 2013 bootstrap-select 6 | * Licensed under the MIT license 7 | */ 8 | 9 | .bootstrap-select.btn-group, 10 | .bootstrap-select.btn-group[class*="span"] { 11 | float: none; 12 | display: inline-block; 13 | margin-bottom: 10px; 14 | margin-left: 0; 15 | } 16 | .form-search .bootstrap-select.btn-group, 17 | .form-inline .bootstrap-select.btn-group, 18 | .form-horizontal .bootstrap-select.btn-group { 19 | margin-bottom: 0; 20 | } 21 | 22 | .bootstrap-select.form-control { 23 | padding: 0; 24 | border: none; 25 | } 26 | 27 | .bootstrap-select.btn-group.pull-right, 28 | .bootstrap-select.btn-group[class*="span"].pull-right, 29 | .row-fluid .bootstrap-select.btn-group[class*="span"].pull-right { 30 | float: right; 31 | } 32 | 33 | .input-append .bootstrap-select.btn-group { 34 | margin-left: -1px; 35 | } 36 | 37 | .input-prepend .bootstrap-select.btn-group { 38 | margin-right: -1px; 39 | } 40 | 41 | .bootstrap-select:not([class*="span"]):not([class*="col-"]):not([class*="form-control"]) { 42 | width: 220px; 43 | } 44 | 45 | .bootstrap-select { 46 | /*width: 220px\9; IE8 and below*/ 47 | width: 220px\0; /*IE9 and below*/ 48 | } 49 | 50 | .bootstrap-select.form-control:not([class*="span"]) { 51 | width: 100%; 52 | } 53 | 54 | .bootstrap-select > .btn { 55 | width: 100%; 56 | } 57 | 58 | .error .bootstrap-select .btn { 59 | border: 1px solid #b94a48; 60 | } 61 | 62 | 63 | .dropdown-menu { 64 | z-index: 2000; 65 | } 66 | 67 | .bootstrap-select.show-menu-arrow.open > .btn { 68 | z-index: 2051; 69 | } 70 | 71 | /* 72 | .bootstrap-select .btn:focus { 73 | outline: thin dotted #333333 !important; 74 | outline: 5px auto -webkit-focus-ring-color !important; 75 | outline-offset: -2px; 76 | } 77 | */ 78 | 79 | .bootstrap-select.btn-group .btn .filter-option { 80 | overflow: hidden; 81 | position: absolute; 82 | left: 12px; 83 | right: 25px; 84 | text-align: left; 85 | } 86 | 87 | .bootstrap-select.btn-group .btn .caret { 88 | position: absolute; 89 | top: 50%; 90 | right: 12px; 91 | margin-top: -2px; 92 | vertical-align: middle; 93 | } 94 | 95 | .bootstrap-select.btn-group > .disabled, 96 | .bootstrap-select.btn-group .dropdown-menu li.disabled > a { 97 | cursor: not-allowed; 98 | } 99 | 100 | .bootstrap-select.btn-group > .disabled:focus { 101 | outline: none !important; 102 | } 103 | 104 | .bootstrap-select.btn-group[class*="span"] .btn { 105 | width: 100%; 106 | } 107 | 108 | .bootstrap-select.btn-group .dropdown-menu { 109 | min-width: 100%; 110 | -moz-box-sizing: border-box; 111 | -webkit-box-sizing: border-box; 112 | box-sizing: border-box; 113 | } 114 | 115 | .bootstrap-select.btn-group .dropdown-menu.inner { 116 | position: static; 117 | border: 0; 118 | padding: 0; 119 | margin: 0; 120 | -webkit-border-radius: 0; 121 | -moz-border-radius: 0; 122 | border-radius: 0; 123 | -webkit-box-shadow: none; 124 | -moz-box-shadow: none; 125 | box-shadow: none; 126 | } 127 | 128 | .bootstrap-select.btn-group .dropdown-menu dt { 129 | display: block; 130 | padding: 3px 20px; 131 | cursor: default; 132 | } 133 | 134 | .bootstrap-select.btn-group .div-contain { 135 | overflow: hidden; 136 | } 137 | 138 | .bootstrap-select.btn-group .dropdown-menu li { 139 | position: relative; 140 | } 141 | 142 | .bootstrap-select.btn-group .dropdown-menu li > a.opt { 143 | position: relative; 144 | padding-left: 35px; 145 | } 146 | 147 | .bootstrap-select.btn-group .dropdown-menu li > a { 148 | cursor: pointer; 149 | } 150 | 151 | .bootstrap-select.btn-group .dropdown-menu li > dt small { 152 | font-weight: normal; 153 | } 154 | 155 | .bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a i.check-mark { 156 | display: inline-block; 157 | position: absolute; 158 | right: 15px; 159 | margin-top: 2.5px; 160 | } 161 | 162 | .bootstrap-select.btn-group .dropdown-menu li a i.check-mark { 163 | display: none; 164 | } 165 | 166 | .bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text { 167 | margin-right: 34px; 168 | } 169 | 170 | .bootstrap-select.btn-group .dropdown-menu li small { 171 | padding-left: 0.5em; 172 | } 173 | 174 | .bootstrap-select.btn-group .dropdown-menu li:not(.disabled) > a:hover small, 175 | .bootstrap-select.btn-group .dropdown-menu li:not(.disabled) > a:focus small { 176 | color: #64b1d8; 177 | color: rgba(255,255,255,0.4); 178 | } 179 | 180 | .bootstrap-select.btn-group .dropdown-menu li > dt small { 181 | font-weight: normal; 182 | } 183 | 184 | .bootstrap-select.show-menu-arrow .dropdown-toggle:before { 185 | content: ''; 186 | display: inline-block; 187 | border-left: 7px solid transparent; 188 | border-right: 7px solid transparent; 189 | border-bottom: 7px solid #CCC; 190 | border-bottom-color: rgba(0, 0, 0, 0.2); 191 | position: absolute; 192 | bottom: -4px; 193 | left: 9px; 194 | display: none; 195 | } 196 | 197 | .bootstrap-select.show-menu-arrow .dropdown-toggle:after { 198 | content: ''; 199 | display: inline-block; 200 | border-left: 6px solid transparent; 201 | border-right: 6px solid transparent; 202 | border-bottom: 6px solid white; 203 | position: absolute; 204 | bottom: -4px; 205 | left: 10px; 206 | display: none; 207 | } 208 | 209 | .bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before { 210 | bottom: auto; 211 | top: -3px; 212 | border-top: 7px solid #ccc; 213 | border-bottom: 0; 214 | border-top-color: rgba(0, 0, 0, 0.2); 215 | } 216 | 217 | .bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after { 218 | bottom: auto; 219 | top: -3px; 220 | border-top: 6px solid #ffffff; 221 | border-bottom: 0; 222 | } 223 | 224 | .bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before { 225 | right: 12px; 226 | left: auto; 227 | } 228 | .bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after { 229 | right: 13px; 230 | left: auto; 231 | } 232 | 233 | .bootstrap-select.show-menu-arrow.open > .dropdown-toggle:before, 234 | .bootstrap-select.show-menu-arrow.open > .dropdown-toggle:after { 235 | display: block; 236 | } 237 | 238 | .mobile-device { 239 | position: absolute; 240 | top: 0; 241 | left: 0; 242 | display: block !important; 243 | width: 100%; 244 | height: 100% !important; 245 | opacity: 0; 246 | } 247 | 248 | .bootstrap-select.fit-width { 249 | width: auto !important; 250 | } 251 | 252 | .bootstrap-select.btn-group.fit-width .btn .filter-option { 253 | position: static; 254 | } 255 | 256 | .bootstrap-select.btn-group.fit-width .btn .caret { 257 | position: static; 258 | top: auto; 259 | margin-top: -1px; 260 | } 261 | 262 | .control-group.error .bootstrap-select .dropdown-toggle{ 263 | border-color: #b94a48; 264 | } 265 | 266 | .bootstrap-select-searchbox { 267 | padding: 4px 8px; 268 | } -------------------------------------------------------------------------------- /assets/vendor/bootstrap/js/affix.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: affix.js v3.1.0 3 | * http://getbootstrap.com/javascript/#affix 4 | * ======================================================================== 5 | * Copyright 2011-2014 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // AFFIX CLASS DEFINITION 14 | // ====================== 15 | 16 | var Affix = function (element, options) { 17 | this.options = $.extend({}, Affix.DEFAULTS, options) 18 | this.$window = $(window) 19 | .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) 20 | .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) 21 | 22 | this.$element = $(element) 23 | this.affixed = 24 | this.unpin = 25 | this.pinnedOffset = null 26 | 27 | this.checkPosition() 28 | } 29 | 30 | Affix.RESET = 'affix affix-top affix-bottom' 31 | 32 | Affix.DEFAULTS = { 33 | offset: 0 34 | } 35 | 36 | Affix.prototype.getPinnedOffset = function () { 37 | if (this.pinnedOffset) return this.pinnedOffset 38 | this.$element.removeClass(Affix.RESET).addClass('affix') 39 | var scrollTop = this.$window.scrollTop() 40 | var position = this.$element.offset() 41 | return (this.pinnedOffset = position.top - scrollTop) 42 | } 43 | 44 | Affix.prototype.checkPositionWithEventLoop = function () { 45 | setTimeout($.proxy(this.checkPosition, this), 1) 46 | } 47 | 48 | Affix.prototype.checkPosition = function () { 49 | if (!this.$element.is(':visible')) return 50 | 51 | var scrollHeight = $(document).height() 52 | var scrollTop = this.$window.scrollTop() 53 | var position = this.$element.offset() 54 | var offset = this.options.offset 55 | var offsetTop = offset.top 56 | var offsetBottom = offset.bottom 57 | 58 | if (this.affixed == 'top') position.top += scrollTop 59 | 60 | if (typeof offset != 'object') offsetBottom = offsetTop = offset 61 | if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) 62 | if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) 63 | 64 | var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false : 65 | offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' : 66 | offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false 67 | 68 | if (this.affixed === affix) return 69 | if (this.unpin) this.$element.css('top', '') 70 | 71 | var affixType = 'affix' + (affix ? '-' + affix : '') 72 | var e = $.Event(affixType + '.bs.affix') 73 | 74 | this.$element.trigger(e) 75 | 76 | if (e.isDefaultPrevented()) return 77 | 78 | this.affixed = affix 79 | this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null 80 | 81 | this.$element 82 | .removeClass(Affix.RESET) 83 | .addClass(affixType) 84 | .trigger($.Event(affixType.replace('affix', 'affixed'))) 85 | 86 | if (affix == 'bottom') { 87 | this.$element.offset({ top: scrollHeight - offsetBottom - this.$element.height() }) 88 | } 89 | } 90 | 91 | 92 | // AFFIX PLUGIN DEFINITION 93 | // ======================= 94 | 95 | var old = $.fn.affix 96 | 97 | $.fn.affix = function (option) { 98 | return this.each(function () { 99 | var $this = $(this) 100 | var data = $this.data('bs.affix') 101 | var options = typeof option == 'object' && option 102 | 103 | if (!data) $this.data('bs.affix', (data = new Affix(this, options))) 104 | if (typeof option == 'string') data[option]() 105 | }) 106 | } 107 | 108 | $.fn.affix.Constructor = Affix 109 | 110 | 111 | // AFFIX NO CONFLICT 112 | // ================= 113 | 114 | $.fn.affix.noConflict = function () { 115 | $.fn.affix = old 116 | return this 117 | } 118 | 119 | 120 | // AFFIX DATA-API 121 | // ============== 122 | 123 | $(window).on('load', function () { 124 | $('[data-spy="affix"]').each(function () { 125 | var $spy = $(this) 126 | var data = $spy.data() 127 | 128 | data.offset = data.offset || {} 129 | 130 | if (data.offsetBottom) data.offset.bottom = data.offsetBottom 131 | if (data.offsetTop) data.offset.top = data.offsetTop 132 | 133 | $spy.affix(data) 134 | }) 135 | }) 136 | 137 | }(jQuery); 138 | -------------------------------------------------------------------------------- /assets/vendor/bootstrap/js/alert.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: alert.js v3.1.0 3 | * http://getbootstrap.com/javascript/#alerts 4 | * ======================================================================== 5 | * Copyright 2011-2014 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // ALERT CLASS DEFINITION 14 | // ====================== 15 | 16 | var dismiss = '[data-dismiss="alert"]' 17 | var Alert = function (el) { 18 | $(el).on('click', dismiss, this.close) 19 | } 20 | 21 | Alert.prototype.close = function (e) { 22 | var $this = $(this) 23 | var selector = $this.attr('data-target') 24 | 25 | if (!selector) { 26 | selector = $this.attr('href') 27 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 28 | } 29 | 30 | var $parent = $(selector) 31 | 32 | if (e) e.preventDefault() 33 | 34 | if (!$parent.length) { 35 | $parent = $this.hasClass('alert') ? $this : $this.parent() 36 | } 37 | 38 | $parent.trigger(e = $.Event('close.bs.alert')) 39 | 40 | if (e.isDefaultPrevented()) return 41 | 42 | $parent.removeClass('in') 43 | 44 | function removeElement() { 45 | $parent.trigger('closed.bs.alert').remove() 46 | } 47 | 48 | $.support.transition && $parent.hasClass('fade') ? 49 | $parent 50 | .one($.support.transition.end, removeElement) 51 | .emulateTransitionEnd(150) : 52 | removeElement() 53 | } 54 | 55 | 56 | // ALERT PLUGIN DEFINITION 57 | // ======================= 58 | 59 | var old = $.fn.alert 60 | 61 | $.fn.alert = function (option) { 62 | return this.each(function () { 63 | var $this = $(this) 64 | var data = $this.data('bs.alert') 65 | 66 | if (!data) $this.data('bs.alert', (data = new Alert(this))) 67 | if (typeof option == 'string') data[option].call($this) 68 | }) 69 | } 70 | 71 | $.fn.alert.Constructor = Alert 72 | 73 | 74 | // ALERT NO CONFLICT 75 | // ================= 76 | 77 | $.fn.alert.noConflict = function () { 78 | $.fn.alert = old 79 | return this 80 | } 81 | 82 | 83 | // ALERT DATA-API 84 | // ============== 85 | 86 | $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) 87 | 88 | }(jQuery); 89 | -------------------------------------------------------------------------------- /assets/vendor/bootstrap/js/button.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: button.js v3.1.0 3 | * http://getbootstrap.com/javascript/#buttons 4 | * ======================================================================== 5 | * Copyright 2011-2014 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // BUTTON PUBLIC CLASS DEFINITION 14 | // ============================== 15 | 16 | var Button = function (element, options) { 17 | this.$element = $(element) 18 | this.options = $.extend({}, Button.DEFAULTS, options) 19 | this.isLoading = false 20 | } 21 | 22 | Button.DEFAULTS = { 23 | loadingText: 'loading...' 24 | } 25 | 26 | Button.prototype.setState = function (state) { 27 | var d = 'disabled' 28 | var $el = this.$element 29 | var val = $el.is('input') ? 'val' : 'html' 30 | var data = $el.data() 31 | 32 | state = state + 'Text' 33 | 34 | if (!data.resetText) $el.data('resetText', $el[val]()) 35 | 36 | $el[val](data[state] || this.options[state]) 37 | 38 | // push to event loop to allow forms to submit 39 | setTimeout($.proxy(function () { 40 | if (state == 'loadingText') { 41 | this.isLoading = true 42 | $el.addClass(d).attr(d, d) 43 | } else if (this.isLoading) { 44 | this.isLoading = false 45 | $el.removeClass(d).removeAttr(d) 46 | } 47 | }, this), 0) 48 | } 49 | 50 | Button.prototype.toggle = function () { 51 | var changed = true 52 | var $parent = this.$element.closest('[data-toggle="buttons"]') 53 | 54 | if ($parent.length) { 55 | var $input = this.$element.find('input') 56 | if ($input.prop('type') == 'radio') { 57 | if ($input.prop('checked') && this.$element.hasClass('active')) changed = false 58 | else $parent.find('.active').removeClass('active') 59 | } 60 | if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') 61 | } 62 | 63 | if (changed) this.$element.toggleClass('active') 64 | } 65 | 66 | 67 | // BUTTON PLUGIN DEFINITION 68 | // ======================== 69 | 70 | var old = $.fn.button 71 | 72 | $.fn.button = function (option) { 73 | return this.each(function () { 74 | var $this = $(this) 75 | var data = $this.data('bs.button') 76 | var options = typeof option == 'object' && option 77 | 78 | if (!data) $this.data('bs.button', (data = new Button(this, options))) 79 | 80 | if (option == 'toggle') data.toggle() 81 | else if (option) data.setState(option) 82 | }) 83 | } 84 | 85 | $.fn.button.Constructor = Button 86 | 87 | 88 | // BUTTON NO CONFLICT 89 | // ================== 90 | 91 | $.fn.button.noConflict = function () { 92 | $.fn.button = old 93 | return this 94 | } 95 | 96 | 97 | // BUTTON DATA-API 98 | // =============== 99 | 100 | $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) { 101 | var $btn = $(e.target) 102 | if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') 103 | $btn.button('toggle') 104 | e.preventDefault() 105 | }) 106 | 107 | }(jQuery); 108 | -------------------------------------------------------------------------------- /assets/vendor/bootstrap/js/carousel.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: carousel.js v3.1.0 3 | * http://getbootstrap.com/javascript/#carousel 4 | * ======================================================================== 5 | * Copyright 2011-2014 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // CAROUSEL CLASS DEFINITION 14 | // ========================= 15 | 16 | var Carousel = function (element, options) { 17 | this.$element = $(element) 18 | this.$indicators = this.$element.find('.carousel-indicators') 19 | this.options = options 20 | this.paused = 21 | this.sliding = 22 | this.interval = 23 | this.$active = 24 | this.$items = null 25 | 26 | this.options.pause == 'hover' && this.$element 27 | .on('mouseenter', $.proxy(this.pause, this)) 28 | .on('mouseleave', $.proxy(this.cycle, this)) 29 | } 30 | 31 | Carousel.DEFAULTS = { 32 | interval: 5000, 33 | pause: 'hover', 34 | wrap: true 35 | } 36 | 37 | Carousel.prototype.cycle = function (e) { 38 | e || (this.paused = false) 39 | 40 | this.interval && clearInterval(this.interval) 41 | 42 | this.options.interval 43 | && !this.paused 44 | && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) 45 | 46 | return this 47 | } 48 | 49 | Carousel.prototype.getActiveIndex = function () { 50 | this.$active = this.$element.find('.item.active') 51 | this.$items = this.$active.parent().children() 52 | 53 | return this.$items.index(this.$active) 54 | } 55 | 56 | Carousel.prototype.to = function (pos) { 57 | var that = this 58 | var activeIndex = this.getActiveIndex() 59 | 60 | if (pos > (this.$items.length - 1) || pos < 0) return 61 | 62 | if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) 63 | if (activeIndex == pos) return this.pause().cycle() 64 | 65 | return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) 66 | } 67 | 68 | Carousel.prototype.pause = function (e) { 69 | e || (this.paused = true) 70 | 71 | if (this.$element.find('.next, .prev').length && $.support.transition) { 72 | this.$element.trigger($.support.transition.end) 73 | this.cycle(true) 74 | } 75 | 76 | this.interval = clearInterval(this.interval) 77 | 78 | return this 79 | } 80 | 81 | Carousel.prototype.next = function () { 82 | if (this.sliding) return 83 | return this.slide('next') 84 | } 85 | 86 | Carousel.prototype.prev = function () { 87 | if (this.sliding) return 88 | return this.slide('prev') 89 | } 90 | 91 | Carousel.prototype.slide = function (type, next) { 92 | var $active = this.$element.find('.item.active') 93 | var $next = next || $active[type]() 94 | var isCycling = this.interval 95 | var direction = type == 'next' ? 'left' : 'right' 96 | var fallback = type == 'next' ? 'first' : 'last' 97 | var that = this 98 | 99 | if (!$next.length) { 100 | if (!this.options.wrap) return 101 | $next = this.$element.find('.item')[fallback]() 102 | } 103 | 104 | if ($next.hasClass('active')) return this.sliding = false 105 | 106 | var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction }) 107 | this.$element.trigger(e) 108 | if (e.isDefaultPrevented()) return 109 | 110 | this.sliding = true 111 | 112 | isCycling && this.pause() 113 | 114 | if (this.$indicators.length) { 115 | this.$indicators.find('.active').removeClass('active') 116 | this.$element.one('slid.bs.carousel', function () { 117 | var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) 118 | $nextIndicator && $nextIndicator.addClass('active') 119 | }) 120 | } 121 | 122 | if ($.support.transition && this.$element.hasClass('slide')) { 123 | $next.addClass(type) 124 | $next[0].offsetWidth // force reflow 125 | $active.addClass(direction) 126 | $next.addClass(direction) 127 | $active 128 | .one($.support.transition.end, function () { 129 | $next.removeClass([type, direction].join(' ')).addClass('active') 130 | $active.removeClass(['active', direction].join(' ')) 131 | that.sliding = false 132 | setTimeout(function () { that.$element.trigger('slid.bs.carousel') }, 0) 133 | }) 134 | .emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000) 135 | } else { 136 | $active.removeClass('active') 137 | $next.addClass('active') 138 | this.sliding = false 139 | this.$element.trigger('slid.bs.carousel') 140 | } 141 | 142 | isCycling && this.cycle() 143 | 144 | return this 145 | } 146 | 147 | 148 | // CAROUSEL PLUGIN DEFINITION 149 | // ========================== 150 | 151 | var old = $.fn.carousel 152 | 153 | $.fn.carousel = function (option) { 154 | return this.each(function () { 155 | var $this = $(this) 156 | var data = $this.data('bs.carousel') 157 | var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) 158 | var action = typeof option == 'string' ? option : options.slide 159 | 160 | if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) 161 | if (typeof option == 'number') data.to(option) 162 | else if (action) data[action]() 163 | else if (options.interval) data.pause().cycle() 164 | }) 165 | } 166 | 167 | $.fn.carousel.Constructor = Carousel 168 | 169 | 170 | // CAROUSEL NO CONFLICT 171 | // ==================== 172 | 173 | $.fn.carousel.noConflict = function () { 174 | $.fn.carousel = old 175 | return this 176 | } 177 | 178 | 179 | // CAROUSEL DATA-API 180 | // ================= 181 | 182 | $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { 183 | var $this = $(this), href 184 | var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 185 | var options = $.extend({}, $target.data(), $this.data()) 186 | var slideIndex = $this.attr('data-slide-to') 187 | if (slideIndex) options.interval = false 188 | 189 | $target.carousel(options) 190 | 191 | if (slideIndex = $this.attr('data-slide-to')) { 192 | $target.data('bs.carousel').to(slideIndex) 193 | } 194 | 195 | e.preventDefault() 196 | }) 197 | 198 | $(window).on('load', function () { 199 | $('[data-ride="carousel"]').each(function () { 200 | var $carousel = $(this) 201 | $carousel.carousel($carousel.data()) 202 | }) 203 | }) 204 | 205 | }(jQuery); 206 | -------------------------------------------------------------------------------- /assets/vendor/bootstrap/js/collapse.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: collapse.js v3.1.0 3 | * http://getbootstrap.com/javascript/#collapse 4 | * ======================================================================== 5 | * Copyright 2011-2014 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // COLLAPSE PUBLIC CLASS DEFINITION 14 | // ================================ 15 | 16 | var Collapse = function (element, options) { 17 | this.$element = $(element) 18 | this.options = $.extend({}, Collapse.DEFAULTS, options) 19 | this.transitioning = null 20 | 21 | if (this.options.parent) this.$parent = $(this.options.parent) 22 | if (this.options.toggle) this.toggle() 23 | } 24 | 25 | Collapse.DEFAULTS = { 26 | toggle: true 27 | } 28 | 29 | Collapse.prototype.dimension = function () { 30 | var hasWidth = this.$element.hasClass('width') 31 | return hasWidth ? 'width' : 'height' 32 | } 33 | 34 | Collapse.prototype.show = function () { 35 | if (this.transitioning || this.$element.hasClass('in')) return 36 | 37 | var startEvent = $.Event('show.bs.collapse') 38 | this.$element.trigger(startEvent) 39 | if (startEvent.isDefaultPrevented()) return 40 | 41 | var actives = this.$parent && this.$parent.find('> .panel > .in') 42 | 43 | if (actives && actives.length) { 44 | var hasData = actives.data('bs.collapse') 45 | if (hasData && hasData.transitioning) return 46 | actives.collapse('hide') 47 | hasData || actives.data('bs.collapse', null) 48 | } 49 | 50 | var dimension = this.dimension() 51 | 52 | this.$element 53 | .removeClass('collapse') 54 | .addClass('collapsing') 55 | [dimension](0) 56 | 57 | this.transitioning = 1 58 | 59 | var complete = function () { 60 | this.$element 61 | .removeClass('collapsing') 62 | .addClass('collapse in') 63 | [dimension]('auto') 64 | this.transitioning = 0 65 | this.$element.trigger('shown.bs.collapse') 66 | } 67 | 68 | if (!$.support.transition) return complete.call(this) 69 | 70 | var scrollSize = $.camelCase(['scroll', dimension].join('-')) 71 | 72 | this.$element 73 | .one($.support.transition.end, $.proxy(complete, this)) 74 | .emulateTransitionEnd(350) 75 | [dimension](this.$element[0][scrollSize]) 76 | } 77 | 78 | Collapse.prototype.hide = function () { 79 | if (this.transitioning || !this.$element.hasClass('in')) return 80 | 81 | var startEvent = $.Event('hide.bs.collapse') 82 | this.$element.trigger(startEvent) 83 | if (startEvent.isDefaultPrevented()) return 84 | 85 | var dimension = this.dimension() 86 | 87 | this.$element 88 | [dimension](this.$element[dimension]()) 89 | [0].offsetHeight 90 | 91 | this.$element 92 | .addClass('collapsing') 93 | .removeClass('collapse') 94 | .removeClass('in') 95 | 96 | this.transitioning = 1 97 | 98 | var complete = function () { 99 | this.transitioning = 0 100 | this.$element 101 | .trigger('hidden.bs.collapse') 102 | .removeClass('collapsing') 103 | .addClass('collapse') 104 | } 105 | 106 | if (!$.support.transition) return complete.call(this) 107 | 108 | this.$element 109 | [dimension](0) 110 | .one($.support.transition.end, $.proxy(complete, this)) 111 | .emulateTransitionEnd(350) 112 | } 113 | 114 | Collapse.prototype.toggle = function () { 115 | this[this.$element.hasClass('in') ? 'hide' : 'show']() 116 | } 117 | 118 | 119 | // COLLAPSE PLUGIN DEFINITION 120 | // ========================== 121 | 122 | var old = $.fn.collapse 123 | 124 | $.fn.collapse = function (option) { 125 | return this.each(function () { 126 | var $this = $(this) 127 | var data = $this.data('bs.collapse') 128 | var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 129 | 130 | if (!data && options.toggle && option == 'show') option = !option 131 | if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 132 | if (typeof option == 'string') data[option]() 133 | }) 134 | } 135 | 136 | $.fn.collapse.Constructor = Collapse 137 | 138 | 139 | // COLLAPSE NO CONFLICT 140 | // ==================== 141 | 142 | $.fn.collapse.noConflict = function () { 143 | $.fn.collapse = old 144 | return this 145 | } 146 | 147 | 148 | // COLLAPSE DATA-API 149 | // ================= 150 | 151 | $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) { 152 | var $this = $(this), href 153 | var target = $this.attr('data-target') 154 | || e.preventDefault() 155 | || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 156 | var $target = $(target) 157 | var data = $target.data('bs.collapse') 158 | var option = data ? 'toggle' : $this.data() 159 | var parent = $this.attr('data-parent') 160 | var $parent = parent && $(parent) 161 | 162 | if (!data || !data.transitioning) { 163 | if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed') 164 | $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') 165 | } 166 | 167 | $target.collapse(option) 168 | }) 169 | 170 | }(jQuery); 171 | -------------------------------------------------------------------------------- /assets/vendor/bootstrap/js/dropdown.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: dropdown.js v3.1.0 3 | * http://getbootstrap.com/javascript/#dropdowns 4 | * ======================================================================== 5 | * Copyright 2011-2014 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // DROPDOWN CLASS DEFINITION 14 | // ========================= 15 | 16 | var backdrop = '.dropdown-backdrop' 17 | var toggle = '[data-toggle=dropdown]' 18 | var Dropdown = function (element) { 19 | $(element).on('click.bs.dropdown', this.toggle) 20 | } 21 | 22 | Dropdown.prototype.toggle = function (e) { 23 | var $this = $(this) 24 | 25 | if ($this.is('.disabled, :disabled')) return 26 | 27 | var $parent = getParent($this) 28 | var isActive = $parent.hasClass('open') 29 | 30 | clearMenus() 31 | 32 | if (!isActive) { 33 | if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { 34 | // if mobile we use a backdrop because click events don't delegate 35 | $('