├── .bowerrc
├── .buildpacks
├── .gitignore
├── .travis.yml
├── Gruntfile.js
├── LICENSE
├── Makefile
├── Procfile
├── README.md
├── app.py
├── bower.json
├── configure.py
├── local_settings.py
├── package.json
├── requirements.txt
├── static
├── images
│ ├── boston_strong.jpg
│ ├── boston_strong.png
│ ├── favicon.ico
│ ├── screenshot1.png
│ ├── twilio_logo_white_311x100.png
│ └── twilio_logo_white_73x22.png
├── materialize
│ ├── .bower.json
│ ├── .gitattributes
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── bower.json
│ ├── dist
│ │ ├── css
│ │ │ ├── materialize.css
│ │ │ └── materialize.min.css
│ │ ├── font
│ │ │ ├── material-design-icons
│ │ │ │ ├── Material-Design-Icons.eot
│ │ │ │ ├── Material-Design-Icons.svg
│ │ │ │ ├── Material-Design-Icons.ttf
│ │ │ │ ├── Material-Design-Icons.woff
│ │ │ │ └── Material-Design-Icons.woff2
│ │ │ └── roboto
│ │ │ │ ├── Roboto-Bold.ttf
│ │ │ │ ├── Roboto-Bold.woff
│ │ │ │ ├── Roboto-Bold.woff2
│ │ │ │ ├── Roboto-Light.ttf
│ │ │ │ ├── Roboto-Light.woff
│ │ │ │ ├── Roboto-Light.woff2
│ │ │ │ ├── Roboto-Medium.ttf
│ │ │ │ ├── Roboto-Medium.woff
│ │ │ │ ├── Roboto-Medium.woff2
│ │ │ │ ├── Roboto-Regular.ttf
│ │ │ │ ├── Roboto-Regular.woff
│ │ │ │ ├── Roboto-Regular.woff2
│ │ │ │ ├── Roboto-Thin.ttf
│ │ │ │ ├── Roboto-Thin.woff
│ │ │ │ └── Roboto-Thin.woff2
│ │ └── js
│ │ │ ├── materialize.js
│ │ │ └── materialize.min.js
│ ├── font
│ │ ├── material-design-icons
│ │ │ ├── Material-Design-Icons.eot
│ │ │ ├── Material-Design-Icons.svg
│ │ │ ├── Material-Design-Icons.ttf
│ │ │ ├── Material-Design-Icons.woff
│ │ │ └── Material-Design-Icons.woff2
│ │ └── roboto
│ │ │ ├── Roboto-Bold.ttf
│ │ │ ├── Roboto-Bold.woff
│ │ │ ├── Roboto-Bold.woff2
│ │ │ ├── Roboto-Light.ttf
│ │ │ ├── Roboto-Light.woff
│ │ │ ├── Roboto-Light.woff2
│ │ │ ├── Roboto-Medium.ttf
│ │ │ ├── Roboto-Medium.woff
│ │ │ ├── Roboto-Medium.woff2
│ │ │ ├── Roboto-Regular.ttf
│ │ │ ├── Roboto-Regular.woff
│ │ │ ├── Roboto-Regular.woff2
│ │ │ ├── Roboto-Thin.ttf
│ │ │ ├── Roboto-Thin.woff
│ │ │ └── Roboto-Thin.woff2
│ ├── js
│ │ ├── animation.js
│ │ ├── buttons.js
│ │ ├── cards.js
│ │ ├── character_counter.js
│ │ ├── collapsible.js
│ │ ├── date_picker
│ │ │ ├── picker.date.js
│ │ │ └── picker.js
│ │ ├── dropdown.js
│ │ ├── forms.js
│ │ ├── global.js
│ │ ├── hammer.min.js
│ │ ├── jquery.easing.1.3.js
│ │ ├── jquery.hammer.js
│ │ ├── jquery.timeago.min.js
│ │ ├── leanModal.js
│ │ ├── materialbox.js
│ │ ├── parallax.js
│ │ ├── pushpin.js
│ │ ├── scrollFire.js
│ │ ├── scrollspy.js
│ │ ├── sideNav.js
│ │ ├── slider.js
│ │ ├── tabs.js
│ │ ├── toasts.js
│ │ ├── tooltip.js
│ │ ├── transitions.js
│ │ ├── velocity.min.js
│ │ └── waves.js
│ ├── package.js
│ ├── sass
│ │ ├── components
│ │ │ ├── _buttons.scss
│ │ │ ├── _cards.scss
│ │ │ ├── _collapsible.scss
│ │ │ ├── _color.scss
│ │ │ ├── _dropdown.scss
│ │ │ ├── _form.scss
│ │ │ ├── _global.scss
│ │ │ ├── _grid.scss
│ │ │ ├── _icons-material-design.scss
│ │ │ ├── _materialbox.scss
│ │ │ ├── _mixins.scss
│ │ │ ├── _modal.scss
│ │ │ ├── _navbar.scss
│ │ │ ├── _normalize.scss
│ │ │ ├── _prefixer.scss
│ │ │ ├── _preloader.scss
│ │ │ ├── _roboto.scss
│ │ │ ├── _sideNav.scss
│ │ │ ├── _slider.scss
│ │ │ ├── _table_of_contents.scss
│ │ │ ├── _tabs.scss
│ │ │ ├── _toast.scss
│ │ │ ├── _tooltip.scss
│ │ │ ├── _typography.scss
│ │ │ ├── _variables.scss
│ │ │ ├── _waves.scss
│ │ │ └── date_picker
│ │ │ │ ├── _default.date.scss
│ │ │ │ ├── _default.scss
│ │ │ │ └── _default.time.scss
│ │ └── materialize.scss
│ └── templates
│ │ ├── masonry-template
│ │ ├── LICENSE
│ │ ├── background1.jpg
│ │ ├── background2.jpg
│ │ ├── background3.jpg
│ │ ├── css
│ │ │ └── style.css
│ │ └── js
│ │ │ ├── init.js
│ │ │ └── masonry.pkgd.min.js
│ │ ├── parallax-template
│ │ ├── LICENSE
│ │ ├── background1.jpg
│ │ ├── background2.jpg
│ │ ├── background3.jpg
│ │ ├── css
│ │ │ └── style.css
│ │ └── js
│ │ │ └── init.js
│ │ └── starter-template
│ │ ├── LICENSE
│ │ ├── css
│ │ └── style.css
│ │ └── js
│ │ └── init.js
├── sounds
│ └── inbound.mp3
└── styles
│ ├── index.css
│ ├── source
│ ├── index.scss
│ ├── theme_color.scss
│ └── theme_variables.scss
│ └── theme.css
├── templates
├── base.html
├── index.html
└── thankyou.html
└── tests
├── __init__.py
├── context.py
├── test_assets
├── bad_git_config
└── good_git_config
├── test_configure.py
├── test_twilio.py
└── test_web.py
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory" : "static/components"
3 | }
4 |
--------------------------------------------------------------------------------
/.buildpacks:
--------------------------------------------------------------------------------
1 | https://github.com/heroku/heroku-buildpack-nodejs
2 | https://github.com/ejholmes/heroku-buildpack-bower
3 | https://github.com/heroku/heroku-buildpack-python.git
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin
2 | build
3 | include
4 | lib
5 | node_modules
6 | static/components
7 | .Python
8 | *.pyc
9 | *.project
10 | *.pydevproject
11 | *.pyo
12 | *.swp
13 | *.coverage
14 | npm-debug.log
15 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 | python:
3 | - "2.6"
4 | - "2.7"
5 | install:
6 | - pip install -r requirements.txt --use-mirrors
7 | script: nosetests
8 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 | var port = grunt.option('port') || 8000;
3 | // Project configuration
4 | grunt.initConfig({
5 | sass: {
6 | theme: {
7 | files: {
8 | 'static/styles/index.css': 'static/materialize/sass/materialize.scss'
9 | }
10 | }
11 | },
12 | jshint: {
13 | files: [ 'Gruntfile.js', 'static/jss/*.js'],
14 | options: {
15 | globals: {
16 | jQuery: true,
17 | console: true
18 | }
19 | }
20 | },
21 | open: {
22 | delayed: {
23 | path: 'http://localhost:5000',
24 | options: {
25 | openOn: 'serverListening'
26 | }
27 | }
28 | },
29 | watch: {
30 | options: {
31 | livereload: true
32 | },
33 | js: {
34 | files: [ 'Gruntfile.js', 'static/js/*.js' ],
35 | tasks: 'jshint'
36 | },
37 | theme: {
38 | files: [ 'static/materialize/sass/components/*.scss' ],
39 | tasks: 'sass'
40 | },
41 | html: {
42 | files: [ 'templates/*.html']
43 | }
44 | },
45 | });
46 |
47 | grunt.loadNpmTasks( 'grunt-sass' );
48 | grunt.loadNpmTasks( 'grunt-contrib-watch' );
49 | grunt.loadNpmTasks( 'grunt-contrib-jshint' );
50 | grunt.loadNpmTasks( 'grunt-open' );
51 | grunt.loadNpmTasks( 'grunt-connect' );
52 |
53 | grunt.registerTask( 'default', [ 'sass', 'jshint' ] );
54 |
55 | grunt.registerTask('flask', 'Run flask server.', function() {
56 | var spawn = require('child_process').spawn;
57 | grunt.log.writeln('Starting Flask development server.');
58 | // stdio: 'inherit' let us see flask output in grunt
59 | process.env.FLASK_YEOMAN_DEBUG = 1;
60 | var PIPE = {stdio: 'inherit'};
61 | spawn('python', ['app.py'], PIPE);
62 | grunt.event.emit('serverListening');
63 | });
64 |
65 | grunt.registerTask( 'serve', [ 'open', 'flask', 'watch', 'connect' ] );
66 | };
67 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012 Twilio, Inc.
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | init:
2 | pip install -r requirements.txt --use-mirrors
3 |
4 | test:
5 | nosetests -v tests
6 |
7 | configure:
8 | python configure.py
9 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: gunicorn app:app -b 0.0.0.0:$PORT -w 3
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Call Your Family
2 |
3 | A free Twilio app to let Boston residents call their families while phone
4 | coverage is poor.
5 |
6 | Built following the tragic loss of life during the Boston Marathon, 15 April
7 | 2013.
8 |
9 | [](http://travis-ci.org/RobSpectre/Call-Your-Family)
11 |
12 | ## Summary
13 |
14 | Simple app using [Twilio Client](http://www.twilio.com/client) to let folks
15 | affected by the tragedy at the Boston Marathon to call their family.
16 |
17 | It works like this:
18 |
19 | 1. Put a phone number in the input box on the right.
20 | 1. Click call.
21 | 1. Click "Allow" on the permissions dialog that follows.
22 | 1. Speak into the microphone on your laptop or desktop to talk with your family for
23 | up to ten minutes.
24 |
25 |
26 | ## Usage
27 |
28 | Once you deploy this app, you get a simple web form that asks you to put in your
29 | phone number:
30 |
31 | 
32 |
33 | Call is then placed to the number (if it is valid) using Twilio Client.
34 |
35 |
36 |
37 | ## Installation
38 |
39 | Step-by-step on how to deploy and develop this app.
40 |
41 | ### Deploy
42 |
43 | 1) Grab latest source
44 |
45 | git clone git://github.com/RobSpectre/Call-Your-Family.git
46 |
47 |
48 | 2) Install dependencies
49 |
50 | make init
51 |
52 |
53 | 3) Navigate to folder and create new Heroku Cedar app
54 |
55 | heroku create --stack cedar
56 |
57 |
58 | 4) Deploy to Heroku
59 |
60 | git push heroku master
61 |
62 |
63 | 5) Scale your dynos
64 |
65 | heroku scale web=1
66 |
67 |
68 | 6) Configure Heroku to use your Twilio credentials.
69 |
70 | python configure.py --account_sid ACxxxxxx --auth_token yyyyyyy
71 |
72 |
73 | 7) Open the app in your browser and get an invite!
74 |
75 | heroku open
76 |
77 |
78 |
79 | ### Development
80 |
81 | Be sure to follow the configuration steps above and use this step-by-step
82 | guide to tweak to your heart's content.
83 |
84 | 1) Install the dependencies.
85 |
86 | make init
87 |
88 |
89 | 2) Launch local development webserver
90 |
91 | foreman start
92 |
93 |
94 | 3) Open browser to [http://localhost:5000](http://localhost:5000).
95 |
96 | 4) Tweak away on `app.py`.
97 |
98 |
99 | ## Testing
100 |
101 | This example app comes with a full testing suite with the same kind of form
102 | validation that you would want to use in production. To run the tests, simply
103 | use `nose` with this shortcut command:
104 |
105 |
106 | make test
107 |
108 |
109 |
110 | ## Anatomy
111 |
112 | This app does have a little more complexity than our usual examples in an effort
113 | to be production-ready. Here's a quick rundown of all the important files:
114 |
115 | * `local_settings.py` - Contains all the configuration options for the app,
116 | including Twilio credentials and the URIs you want to which you wish to direct
117 | your mobile users.
118 | * `app.py` - The meat of the app. Contains all the logic for rendering the
119 | form, sending the invites, and redirecting mobile users.
120 | * `tests` - Test suite testing the web, Twilio and form validation functionality
121 | of this example.
122 | * `templates` - The gorgeous interface I surreptitiously from
123 | [Andres](http://twitter.com/enborra).
124 | * `static` - Location of the styles for above.
125 |
126 |
127 | ## Meta
128 |
129 | * No warranty expressed or implied. Software is as is. Diggity.
130 | * [MIT License](http://www.opensource.org/licenses/mit-license.html)
131 | * Lovingly crafted by [Twilio](http://www.twilio.com)
132 |
133 |
134 | Call your folks. They'd like to hear from you.
135 |
136 |
137 | [](http://githalytics.com/RobSpectre/Call-Your-Family)
140 |
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | import os
2 | import signal
3 |
4 |
5 | from flask import Flask
6 | from flask import render_template
7 | from flask import url_for
8 | from flask import request
9 |
10 | from twilio import twiml
11 | from twilio.util import TwilioCapability
12 |
13 |
14 | # Declare and configure application
15 | app = Flask(__name__, static_url_path='/static')
16 | app.config.from_pyfile('local_settings.py')
17 |
18 |
19 | @app.route('/', methods=['GET', 'POST'])
20 | def index():
21 | # Make sure we have this host configured properly.
22 | config_errors = []
23 | for option in ['TWILIO_ACCOUNT_SID', 'TWILIO_AUTH_TOKEN']:
24 | if not app.config[option]:
25 | config_errors.append("%s is not configured for this host."
26 | % option)
27 |
28 | # Create capability token
29 | capability = TwilioCapability(app.config.get('TWILIO_ACCOUNT_SID', None),
30 | app.config.get('TWILIO_AUTH_TOKEN', None))
31 | capability.allow_client_outgoing(app.config.get('TWILIO_APP_SID', None))
32 | token = capability.generate()
33 |
34 | # Define important links
35 | params = {
36 | 'sms_request_url': url_for('.sms', _external=True),
37 | 'token': token,
38 | 'config_errors': config_errors}
39 |
40 | return render_template('index.html', params=params)
41 |
42 |
43 | @app.route('/voice', methods=['POST'])
44 | def voice():
45 | response = twiml.Response()
46 | with response.dial(callerId=app.config['TWILIO_CALLER_ID'],
47 | timeLimit="600") as dial:
48 | dial.number(request.form['PhoneNumber'])
49 | return str(response)
50 |
51 |
52 | @app.route('/inbound', methods=['POST'])
53 | def inbound():
54 | response = twiml.Response()
55 | response.play('/static/sounds/inbound.mp3')
56 | return str(response)
57 |
58 |
59 | @app.route('/sms', methods=['GET', 'POST'])
60 | def sms():
61 | # Respond to any text inbound text message with a link to the app!
62 | response = twiml.Response()
63 | response.sms("This number belongs to the Twilio Call Your Family app " \
64 | "for Boston. Please visit " \
65 | "http://callyourfamily.twilio.ly for more info.")
66 | return str(response)
67 |
68 |
69 | # Handles SIGTERM so that we don't get an error when Heroku wants or needs to
70 | # restart the dyno
71 | def graceful_shutdown(signum, frame):
72 | exit()
73 |
74 | signal.signal(signal.SIGTERM, graceful_shutdown)
75 |
76 |
77 | if __name__ == '__main__':
78 | port = int(os.environ.get("PORT", 5000))
79 | if port == 5000:
80 | app.debug = True
81 | app.run(host='0.0.0.0', port=port)
82 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "twilio-call-your-family",
3 | "version": "1.0.0",
4 | "authors": [
5 | "Rob Spectre "
6 | ],
7 | "description": "A disaster response app for free phone calls in emergencies",
8 | "main": "index.html",
9 | "license": "MIT",
10 | "homepage": "http://www.brooklynhacker.com",
11 | "private": true,
12 | "ignore": [
13 | "**/.*",
14 | "node_modules",
15 | "bower_components",
16 | "test",
17 | "tests"
18 | ],
19 | "dependencies": {
20 | "materialize": "~0.96.1",
21 | "jquery": "~2.1.3",
22 | "intl-tel-input": "~5.8.7"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/local_settings.py:
--------------------------------------------------------------------------------
1 | '''
2 | Configuration Settings
3 | '''
4 |
5 | ''' Uncomment to configure using the file.
6 | WARNING: Be careful not to post your account credentials on GitHub.
7 |
8 | TWILIO_ACCOUNT_SID = "ACxxxxxxxxxxxxx"
9 | TWILIO_AUTH_TOKEN = "yyyyyyyyyyyyyyyy"
10 | TWILIO_APP_SID = "APzzzzzzzzz"
11 | TWILIO_CALLER_ID = "+17778889999"
12 | IOS_URI = "http://phobos.apple.com/whatever"
13 | ANDROID_URI = "http://market.google.com/somethingsomething"
14 | '''
15 |
16 | # Begin Heroku configuration - configured through environment variables.
17 | import os
18 | TWILIO_ACCOUNT_SID = os.environ.get('TWILIO_ACCOUNT_SID', None)
19 | TWILIO_AUTH_TOKEN = os.environ.get('TWILIO_AUTH_TOKEN', None)
20 | TWILIO_CALLER_ID = os.environ.get('TWILIO_CALLER_ID', None)
21 | TWILIO_APP_SID = os.environ.get('TWILIO_APP_SID', None)
22 | IOS_URI = os.environ.get('IOS_URI',
23 | 'http://itunes.apple.com/us/app/plants-vs.-zombies/id350642635?mt=8&uo=4')
24 | ANDROID_URI = os.environ.get('ANDROID_URI',
25 | 'http://market.android.com/details?id=com.popcap.pvz_row')
26 | WEB_URI = os.environ.get('WEB_URI',
27 | 'http://www.popcap.com/games/plants-vs-zombies/pc')
28 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "twilio-call-your-family",
3 | "version": "1.0.0",
4 | "engines": {
5 | "node": "0.10.x"
6 | },
7 | "dependencies": {
8 | "bower": "^1.3.12",
9 | "grunt": "^0.4.5",
10 | "grunt-cli": "^0.1.13",
11 | "grunt-contrib-connect": "^0.9.0",
12 | "grunt-contrib-jshint": "^0.11.0",
13 | "grunt-contrib-watch": "^0.6.1",
14 | "grunt-sass": "^0.18.1"
15 | },
16 | "devDependencies": {
17 | "grunt-connect": "^0.2.0",
18 | "grunt-open": "^0.2.3"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Flask==0.9
2 | twilio>=3.4.5
3 | mock==0.8.0
4 | gunicorn==0.14.2
5 |
--------------------------------------------------------------------------------
/static/images/boston_strong.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/images/boston_strong.jpg
--------------------------------------------------------------------------------
/static/images/boston_strong.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/images/boston_strong.png
--------------------------------------------------------------------------------
/static/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/images/favicon.ico
--------------------------------------------------------------------------------
/static/images/screenshot1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/images/screenshot1.png
--------------------------------------------------------------------------------
/static/images/twilio_logo_white_311x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/images/twilio_logo_white_311x100.png
--------------------------------------------------------------------------------
/static/images/twilio_logo_white_73x22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/images/twilio_logo_white_73x22.png
--------------------------------------------------------------------------------
/static/materialize/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Materialize",
3 | "version": "0.96.1",
4 | "description": "A modern responsive front-end framework based on Material Design",
5 | "keywords": [
6 | "css",
7 | "js",
8 | "sass",
9 | "mobile-first",
10 | "responsive",
11 | "front-end",
12 | "framework",
13 | "ux",
14 | "material",
15 | "design"
16 | ],
17 | "main": [
18 | "bin/materialize.css",
19 | "bin/materialize.js",
20 | "font/material-design-icons/Material-Design-Icons.eot",
21 | "font/material-design-icons/Material-Design-Icons.svg",
22 | "font/material-design-icons/Material-Design-Icons.ttf",
23 | "font/material-design-icons/Material-Design-Icons.woff",
24 | "font/material-design-icons/Material-Design-Icons.woff2",
25 | "font/roboto/Roboto-Bold.ttf",
26 | "font/roboto/Roboto-Bold.woff",
27 | "font/roboto/Roboto-Bold.woff2",
28 | "font/roboto/Roboto-Light.ttf",
29 | "font/roboto/Roboto-Light.woff",
30 | "font/roboto/Roboto-Light.woff2",
31 | "font/roboto/Roboto-Medium.ttf",
32 | "font/roboto/Roboto-Medium.woff",
33 | "font/roboto/Roboto-Medium.woff2",
34 | "font/roboto/Roboto-Regular.ttf",
35 | "font/roboto/Roboto-Regular.woff",
36 | "font/roboto/Roboto-Regular.woff2",
37 | "font/roboto/Roboto-Thin.ttf",
38 | "font/roboto/Roboto-Thin.woff",
39 | "font/roboto/Roboto-Thin.woff2"
40 | ],
41 | "ignore": [
42 | "jade/",
43 | ".gitignore",
44 | "CNAME",
45 | "css/",
46 | "bower.json",
47 | "README.md",
48 | "images/",
49 | "js/jquery.timeago.js",
50 | "js/init.js",
51 | "js/prism.js",
52 | "res/",
53 | "sass/style.scss",
54 | "sass/ghpages-materialize.scss",
55 | "**/*.html",
56 | "**/*.zip",
57 | "**/*.txt",
58 | "sitemap.xml",
59 | "package.json",
60 | "Gruntfile.js"
61 | ],
62 | "dependencies": {
63 | "jquery": ">=2.1.1"
64 | },
65 | "homepage": "https://github.com/Dogfalo/materialize",
66 | "_release": "0.96.1",
67 | "_resolution": {
68 | "type": "version",
69 | "tag": "v0.96.1",
70 | "commit": "7cdf0c8852ed14f81c7ee43eb573d8df8589ad94"
71 | },
72 | "_source": "git://github.com/Dogfalo/materialize.git",
73 | "_target": "~0.96.1",
74 | "_originalSource": "materialize"
75 | }
--------------------------------------------------------------------------------
/static/materialize/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | **/*.html linguist-documentation
3 |
--------------------------------------------------------------------------------
/static/materialize/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | - v0.94.0 (Dec 30, 2014)
2 | - Sidenav supports right edge positioning
3 | - Responsive Embeds
4 | - Image Vertical align classes
5 | - border-box added
6 | - Variable file created
7 | - Pushpin added
8 | - Tooltips support all directions
9 | - Layout helper classes added
10 | - Materialbox Fixes
11 | - Form Element Enhancements
12 | - Navbar supports search bar
13 | - Waves fixes
14 | - Materialbox Captions
15 | - Image Slider Fixes
16 |
17 | - v0.93.1 (Dec 20, 2014)
18 | - Flexbox Sticky Footer removed due to IE incompatibility
19 |
20 | - v0.93.0 (Dec 19, 2014)
21 | - Card Reveal
22 | - Image Slider
23 | - Dynamically loaded forms work correctly
24 | - Badges added
25 | - Circular Image
26 | - Waves Fixes
27 | - Footer Added
28 | - Toast support Custom HTML
29 | - Modals support programmatic opening/closing
30 | - Responsive Image support
31 |
32 | - v0.92.1 (Dec 14, 2014)
33 | - Bower semver fix
34 | - Added new radio button style
35 |
36 | - v0.92.0 (Dec 13, 2014)
37 | - Clicking icon in dropdown in navbar no longer closes dropdown immediately
38 | - Multiple select inputs now work properly
39 | - Mobile navbar no longer extends past screen width
40 | - Parallax improved
41 | - Modal restructured / can be opened programmatically
42 | - Callbacks added to modals
43 | - Added dist folder to repo
44 | - Cards restructured
45 |
46 |
47 | - v0.91 (Dec 3, 2014)
48 | - bug fixes to forms
49 | - added waves color classes
50 | - toast thickened to look better on mobile
51 | - many other bug fixes
52 |
53 |
54 | - v0.9 (Nov 30, 2014)
55 | - Touch interactions added
56 | - tons more...
--------------------------------------------------------------------------------
/static/materialize/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014-2015 Materialize
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/static/materialize/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Materialize",
3 | "version": "0.96.1",
4 | "description": "A modern responsive front-end framework based on Material Design",
5 | "keywords": [
6 | "css",
7 | "js",
8 | "sass",
9 | "mobile-first",
10 | "responsive",
11 | "front-end",
12 | "framework",
13 | "ux",
14 | "material",
15 | "design"
16 | ],
17 | "main": [
18 | "bin/materialize.css",
19 | "bin/materialize.js",
20 | "font/material-design-icons/Material-Design-Icons.eot",
21 | "font/material-design-icons/Material-Design-Icons.svg",
22 | "font/material-design-icons/Material-Design-Icons.ttf",
23 | "font/material-design-icons/Material-Design-Icons.woff",
24 | "font/material-design-icons/Material-Design-Icons.woff2",
25 | "font/roboto/Roboto-Bold.ttf",
26 | "font/roboto/Roboto-Bold.woff",
27 | "font/roboto/Roboto-Bold.woff2",
28 | "font/roboto/Roboto-Light.ttf",
29 | "font/roboto/Roboto-Light.woff",
30 | "font/roboto/Roboto-Light.woff2",
31 | "font/roboto/Roboto-Medium.ttf",
32 | "font/roboto/Roboto-Medium.woff",
33 | "font/roboto/Roboto-Medium.woff2",
34 | "font/roboto/Roboto-Regular.ttf",
35 | "font/roboto/Roboto-Regular.woff",
36 | "font/roboto/Roboto-Regular.woff2",
37 | "font/roboto/Roboto-Thin.ttf",
38 | "font/roboto/Roboto-Thin.woff",
39 | "font/roboto/Roboto-Thin.woff2"
40 | ],
41 | "ignore": [
42 | "jade/",
43 | ".gitignore",
44 | "CNAME",
45 | "css/",
46 | "bower.json",
47 | "README.md",
48 | "images/",
49 | "js/jquery.timeago.js",
50 | "js/init.js",
51 | "js/prism.js",
52 | "res/",
53 | "sass/style.scss",
54 | "sass/ghpages-materialize.scss",
55 | "**/*.html",
56 | "**/*.zip",
57 | "**/*.txt",
58 | "sitemap.xml",
59 | "package.json",
60 | "Gruntfile.js"
61 |
62 | ],
63 | "dependencies": {
64 | "jquery": ">=2.1.1"
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/static/materialize/dist/font/material-design-icons/Material-Design-Icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/material-design-icons/Material-Design-Icons.eot
--------------------------------------------------------------------------------
/static/materialize/dist/font/material-design-icons/Material-Design-Icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/material-design-icons/Material-Design-Icons.ttf
--------------------------------------------------------------------------------
/static/materialize/dist/font/material-design-icons/Material-Design-Icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/material-design-icons/Material-Design-Icons.woff
--------------------------------------------------------------------------------
/static/materialize/dist/font/material-design-icons/Material-Design-Icons.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/material-design-icons/Material-Design-Icons.woff2
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Bold.ttf
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Bold.woff
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Bold.woff2
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Light.ttf
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Light.woff
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Light.woff2
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Medium.ttf
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Medium.woff
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Medium.woff2
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Regular.woff
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Regular.woff2
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Thin.ttf
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Thin.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Thin.woff
--------------------------------------------------------------------------------
/static/materialize/dist/font/roboto/Roboto-Thin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/dist/font/roboto/Roboto-Thin.woff2
--------------------------------------------------------------------------------
/static/materialize/font/material-design-icons/Material-Design-Icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/material-design-icons/Material-Design-Icons.eot
--------------------------------------------------------------------------------
/static/materialize/font/material-design-icons/Material-Design-Icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/material-design-icons/Material-Design-Icons.ttf
--------------------------------------------------------------------------------
/static/materialize/font/material-design-icons/Material-Design-Icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/material-design-icons/Material-Design-Icons.woff
--------------------------------------------------------------------------------
/static/materialize/font/material-design-icons/Material-Design-Icons.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/material-design-icons/Material-Design-Icons.woff2
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Bold.ttf
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Bold.woff
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Bold.woff2
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Light.ttf
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Light.woff
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Light.woff2
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Medium.ttf
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Medium.woff
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Medium.woff2
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Regular.woff
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Regular.woff2
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Thin.ttf
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Thin.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Thin.woff
--------------------------------------------------------------------------------
/static/materialize/font/roboto/Roboto-Thin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/font/roboto/Roboto-Thin.woff2
--------------------------------------------------------------------------------
/static/materialize/js/animation.js:
--------------------------------------------------------------------------------
1 | // Custom Easing
2 | jQuery.extend( jQuery.easing,
3 | {
4 | easeInOutMaterial: function (x, t, b, c, d) {
5 | if ((t/=d/2) < 1) return c/2*t*t + b;
6 | return c/4*((t-=2)*t*t + 2) + b;
7 | }
8 | });
9 |
10 |
--------------------------------------------------------------------------------
/static/materialize/js/buttons.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 | $(document).ready(function() {
3 |
4 | // jQuery reverse
5 | $.fn.reverse = [].reverse;
6 |
7 | $(document).on('mouseenter.fixedActionBtn', '.fixed-action-btn', function(e) {
8 | var $this = $(this);
9 |
10 | $this.find('ul .btn-floating').velocity(
11 | { scaleY: ".4", scaleX: ".4", translateY: "40px"},
12 | { duration: 0 });
13 |
14 | var time = 0;
15 | $this.find('ul .btn-floating').reverse().each(function () {
16 | $(this).velocity(
17 | { opacity: "1", scaleX: "1", scaleY: "1", translateY: "0"},
18 | { duration: 80, delay: time });
19 | time += 40;
20 | });
21 |
22 | });
23 |
24 | $(document).on('mouseleave.fixedActionBtn', '.fixed-action-btn', function(e) {
25 | var $this = $(this);
26 |
27 | var time = 0;
28 | $this.find('ul .btn-floating').velocity("stop", true);
29 | $this.find('ul .btn-floating').velocity(
30 | { opacity: "0", scaleX: ".4", scaleY: ".4", translateY: "40px"},
31 | { duration: 80 });
32 | });
33 |
34 | });
35 | }( jQuery ));
36 |
--------------------------------------------------------------------------------
/static/materialize/js/cards.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 | $(document).ready(function() {
3 |
4 | $(document).on('click.card', '.card', function (e) {
5 | if ($(this).find('.card-reveal').length) {
6 | if ($(e.target).is($('.card-reveal .card-title')) || $(e.target).is($('.card-reveal .card-title i'))) {
7 | // Make Reveal animate down and display none
8 | $(this).find('.card-reveal').velocity(
9 | {translateY: 0}, {
10 | duration: 225,
11 | queue: false,
12 | easing: 'easeInOutQuad',
13 | complete: function() { $(this).css({ display: 'none'}) }
14 | }
15 | );
16 | }
17 | else if ($(e.target).is($('.card .activator')) ||
18 | $(e.target).is($('.card .activator i')) ) {
19 | $(this).find('.card-reveal').css({ display: 'block'}).velocity("stop", false).velocity({translateY: '-100%'}, {duration: 300, queue: false, easing: 'easeInOutQuad'});
20 | }
21 | }
22 |
23 |
24 | });
25 |
26 | });
27 | }( jQuery ));
--------------------------------------------------------------------------------
/static/materialize/js/character_counter.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | $.fn.characterCounter = function(){
4 | return this.each(function(){
5 |
6 | itHasLengthAttribute = $(this).attr('length') != undefined;
7 |
8 | if(itHasLengthAttribute){
9 | $(this).on('input', updateCounter);
10 | $(this).on('focus', updateCounter);
11 | $(this).on('blur', removeCounterElement);
12 |
13 | addCounterElement($(this));
14 | }
15 |
16 | });
17 | };
18 |
19 | function updateCounter(){
20 | var maxLength = +$(this).attr('length'),
21 | actualLength = +$(this).val().length,
22 | isValidLength = actualLength <= maxLength;
23 |
24 | $(this).parent().find('span[class="character-counter"]')
25 | .html( actualLength + '/' + maxLength);
26 |
27 | addInputStyle(isValidLength, $(this));
28 | }
29 |
30 | function addCounterElement($input){
31 | $counterElement = $(' ')
32 | .addClass('character-counter')
33 | .css('float','right')
34 | .css('font-size','12px')
35 | .css('height', 1);
36 |
37 | $input.parent().append($counterElement);
38 | }
39 |
40 | function removeCounterElement(){
41 | $(this).parent().find('span[class="character-counter"]').html('');
42 | }
43 |
44 | function addInputStyle(isValidLength, $input){
45 | inputHasInvalidClass = $input.hasClass('invalid');
46 | if (isValidLength && inputHasInvalidClass) {
47 | $input.removeClass('invalid');
48 | }
49 | else if(!isValidLength && !inputHasInvalidClass){
50 | $input.removeClass('valid');
51 | $input.addClass('invalid');
52 | }
53 | }
54 |
55 | $(document).ready(function(){
56 | $('input, textarea').characterCounter();
57 | });
58 |
59 | }( jQuery ));
60 |
--------------------------------------------------------------------------------
/static/materialize/js/collapsible.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 | $.fn.collapsible = function(options) {
3 | var defaults = {
4 | accordion: undefined
5 | };
6 |
7 | options = $.extend(defaults, options);
8 |
9 |
10 | return this.each(function() {
11 |
12 | var $this = $(this);
13 |
14 | var $panel_headers = $(this).find('> li > .collapsible-header');
15 |
16 | var collapsible_type = $this.data("collapsible");
17 |
18 | // Turn off any existing event handlers
19 | $this.off('click.collapse', '.collapsible-header');
20 | $panel_headers.off('click.collapse');
21 |
22 |
23 | /****************
24 | Helper Functions
25 | ****************/
26 |
27 | // Accordion Open
28 | function accordionOpen(object) {
29 | $panel_headers = $this.find('> li > .collapsible-header');
30 | if (object.hasClass('active')) {
31 | object.parent().addClass('active');
32 | }
33 | else {
34 | object.parent().removeClass('active');
35 | }
36 | if (object.parent().hasClass('active')){
37 | object.siblings('.collapsible-body').stop(true,false).slideDown({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '')}});
38 | }
39 | else{
40 | object.siblings('.collapsible-body').stop(true,false).slideUp({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '')}});
41 | }
42 |
43 | $panel_headers.not(object).removeClass('active').parent().removeClass('active');
44 | $panel_headers.not(object).parent().children('.collapsible-body').stop(true,false).slideUp(
45 | {
46 | duration: 350,
47 | easing: "easeOutQuart",
48 | queue: false,
49 | complete:
50 | function() {
51 | $(this).css('height', '')
52 | }
53 | });
54 | }
55 |
56 | // Expandable Open
57 | function expandableOpen(object) {
58 | if (object.hasClass('active')) {
59 | object.parent().addClass('active');
60 | }
61 | else {
62 | object.parent().removeClass('active');
63 | }
64 | if (object.parent().hasClass('active')){
65 | object.siblings('.collapsible-body').stop(true,false).slideDown({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '')}});
66 | }
67 | else{
68 | object.siblings('.collapsible-body').stop(true,false).slideUp({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '')}});
69 | }
70 | }
71 |
72 | /**
73 | * Check if object is children of panel header
74 | * @param {Object} object Jquery object
75 | * @return {Boolean} true if it is children
76 | */
77 | function isChildrenOfPanelHeader(object) {
78 |
79 | var panelHeader = getPanelHeader(object);
80 |
81 | return panelHeader.length > 0;
82 | }
83 |
84 | /**
85 | * Get panel header from a children element
86 | * @param {Object} object Jquery object
87 | * @return {Object} panel header object
88 | */
89 | function getPanelHeader(object) {
90 |
91 | return object.closest('li > .collapsible-header');
92 | }
93 |
94 | /***** End Helper Functions *****/
95 |
96 |
97 |
98 | if (options.accordion || collapsible_type == "accordion" || collapsible_type == undefined) { // Handle Accordion
99 | // Add click handler to only direct collapsible header children
100 | $panel_headers = $this.find('> li > .collapsible-header');
101 | $panel_headers.on('click.collapse', function (e) {
102 | var element = $(e.target);
103 |
104 | if (isChildrenOfPanelHeader(element)) {
105 | element = getPanelHeader(element);
106 | }
107 |
108 | element.toggleClass('active');
109 | accordionOpen(element);
110 | });
111 | // Open first active
112 | accordionOpen($panel_headers.filter('.active').first());
113 | }
114 | else { // Handle Expandables
115 | $panel_headers.each(function () {
116 | // Add click handler to only direct collapsible header children
117 | $(this).on('click.collapse', function (e) {
118 | var element = $(e.target);
119 | if (isChildrenOfPanelHeader(element)) {
120 | element = getPanelHeader(element);
121 | }
122 | element.toggleClass('active');
123 | expandableOpen(element);
124 | });
125 | // Open any bodies that have the active class
126 | if ($(this).hasClass('active')) {
127 | expandableOpen($(this));
128 | }
129 |
130 | });
131 | }
132 |
133 | });
134 | };
135 |
136 | $(document).ready(function(){
137 | $('.collapsible').collapsible();
138 | });
139 | }( jQuery ));
--------------------------------------------------------------------------------
/static/materialize/js/dropdown.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | // Add posibility to scroll to selected option
4 | // usefull for select for example
5 | $.fn.scrollTo = function(elem) {
6 | $(this).scrollTop($(this).scrollTop() - $(this).offset().top + $(elem).offset().top);
7 | return this;
8 | };
9 |
10 | $.fn.dropdown = function (option) {
11 | var defaults = {
12 | inDuration: 300,
13 | outDuration: 225,
14 | constrain_width: true, // Constrains width of dropdown to the activator
15 | hover: false,
16 | gutter: 0, // Spacing from edge
17 | belowOrigin: false
18 | }
19 |
20 | this.each(function(){
21 | var origin = $(this);
22 | var options = $.extend({}, defaults, option);
23 |
24 | // Dropdown menu
25 | var activates = $("#"+ origin.attr('data-activates'));
26 |
27 | function updateOptions() {
28 | if (origin.data('induration') != undefined)
29 | options.inDuration = origin.data('inDuration');
30 | if (origin.data('outduration') != undefined)
31 | options.outDuration = origin.data('outDuration');
32 | if (origin.data('constrainwidth') != undefined)
33 | options.constrain_width = origin.data('constrainwidth');
34 | if (origin.data('hover') != undefined)
35 | options.hover = origin.data('hover');
36 | if (origin.data('gutter') != undefined)
37 | options.gutter = origin.data('gutter');
38 | if (origin.data('beloworigin') != undefined)
39 | options.belowOrigin = origin.data('beloworigin');
40 | }
41 |
42 | updateOptions();
43 |
44 | // Attach dropdown to its activator
45 | origin.after(activates);
46 |
47 | /*
48 | Helper function to position and resize dropdown.
49 | Used in hover and click handler.
50 | */
51 | function placeDropdown() {
52 | // Check html data attributes
53 | updateOptions();
54 |
55 | // Set Dropdown state
56 | activates.addClass('active');
57 |
58 | // Constrain width
59 | if (options.constrain_width == true) {
60 | activates.css('width', origin.outerWidth());
61 | }
62 | var offset = 0;
63 | if (options.belowOrigin == true) {
64 | offset = origin.height();
65 | }
66 |
67 | // Handle edge alignment
68 | var offsetLeft = origin.offset().left;
69 | var width_difference = 0;
70 | var gutter_spacing = options.gutter;
71 |
72 |
73 | if (offsetLeft + activates.innerWidth() > $(window).width()) {
74 | width_difference = origin.innerWidth() - activates.innerWidth();
75 | gutter_spacing = gutter_spacing * -1;
76 | }
77 |
78 | // Position dropdown
79 | activates.css({
80 | position: 'absolute',
81 | top: origin.position().top + offset,
82 | left: origin.position().left + width_difference + gutter_spacing
83 | });
84 |
85 |
86 |
87 | // Show dropdown
88 | activates.stop(true, true).css('opacity', 0)
89 | .slideDown({
90 | queue: false,
91 | duration: options.inDuration,
92 | easing: 'easeOutCubic',
93 | complete: function() {
94 | $(this).css('height', '');
95 | }
96 | })
97 | .animate( {opacity: 1}, {queue: false, duration: options.inDuration, easing: 'easeOutSine'});
98 | }
99 |
100 | function hideDropdown() {
101 | activates.fadeOut(options.outDuration);
102 | activates.removeClass('active');
103 | }
104 |
105 | // Hover
106 | if (options.hover) {
107 | var open = false;
108 | origin.unbind('click.' + origin.attr('id'));
109 | // Hover handler to show dropdown
110 | origin.on('mouseenter', function(e){ // Mouse over
111 | if (open === false) {
112 | placeDropdown();
113 | open = true
114 | }
115 | });
116 | origin.on('mouseleave', function(e){
117 | // If hover on origin then to something other than dropdown content, then close
118 | if(!$(e.toElement).closest('.dropdown-content').is(activates)) {
119 | activates.stop(true, true);
120 | hideDropdown();
121 | open = false;
122 | }
123 | });
124 |
125 | activates.on('mouseleave', function(e){ // Mouse out
126 | if(!$(e.toElement).closest('.dropdown-button').is(origin)) {
127 | activates.stop(true, true);
128 | hideDropdown();
129 | open = false;
130 | }
131 | });
132 |
133 | // Click
134 | } else {
135 |
136 | // Click handler to show dropdown
137 | origin.unbind('click.' + origin.attr('id'));
138 | origin.bind('click.'+origin.attr('id'), function(e){
139 |
140 | if ( origin[0] == e.currentTarget && ($(e.target).closest('.dropdown-content').length === 0) ) {
141 | e.preventDefault(); // Prevents button click from moving window
142 | placeDropdown();
143 |
144 | }
145 | // If origin is clicked and menu is open, close menu
146 | else {
147 | if (origin.hasClass('active')) {
148 | hideDropdown();
149 | $(document).unbind('click.' + activates.attr('id'));
150 | }
151 | }
152 | // If menu open, add click close handler to document
153 | if (activates.hasClass('active')) {
154 | $(document).bind('click.'+ activates.attr('id'), function (e) {
155 | if (!activates.is(e.target) && !origin.is(e.target) && (!origin.find(e.target).length > 0) ) {
156 | hideDropdown();
157 | $(document).unbind('click.' + activates.attr('id'));
158 | }
159 | });
160 | }
161 | });
162 |
163 | } // End else
164 |
165 | // Listen to open and close event - useful for select component
166 | origin.on('open', placeDropdown);
167 | origin.on('close', hideDropdown);
168 |
169 |
170 | });
171 | }; // End dropdown plugin
172 |
173 | $(document).ready(function(){
174 | $('.dropdown-button').dropdown();
175 | });
176 | }( jQuery ));
177 |
--------------------------------------------------------------------------------
/static/materialize/js/global.js:
--------------------------------------------------------------------------------
1 | Materialize = {};
2 |
3 | // Unique ID
4 | Materialize.guid = (function() {
5 | function s4() {
6 | return Math.floor((1 + Math.random()) * 0x10000)
7 | .toString(16)
8 | .substring(1);
9 | }
10 | return function() {
11 | return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
12 | s4() + '-' + s4() + s4() + s4();
13 | };
14 | })();
15 |
16 | Materialize.elementOrParentIsFixed = function(element) {
17 | var $element = $(element);
18 | var $checkElements = $element.add($element.parents());
19 | var isFixed = false;
20 | $checkElements.each(function(){
21 | if ($(this).css("position") === "fixed") {
22 | isFixed = true;
23 | return false;
24 | }
25 | });
26 | return isFixed;
27 | }
28 |
29 | // Velocity has conflicts when loaded with jQuery, this will check for it
30 | var Vel;
31 | if ($) { Vel = $.Velocity } else { Vel = Velocity};
32 |
--------------------------------------------------------------------------------
/static/materialize/js/jquery.easing.1.3.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
3 | *
4 | * Uses the built in easing capabilities added In jQuery 1.1
5 | * to offer multiple easing options
6 | *
7 | * TERMS OF USE - jQuery Easing
8 | *
9 | * Open source under the BSD License.
10 | *
11 | * Copyright © 2008 George McGinley Smith
12 | * All rights reserved.
13 | *
14 | * Redistribution and use in source and binary forms, with or without modification,
15 | * are permitted provided that the following conditions are met:
16 | *
17 | * Redistributions of source code must retain the above copyright notice, this list of
18 | * conditions and the following disclaimer.
19 | * Redistributions in binary form must reproduce the above copyright notice, this list
20 | * of conditions and the following disclaimer in the documentation and/or other materials
21 | * provided with the distribution.
22 | *
23 | * Neither the name of the author nor the names of contributors may be used to endorse
24 | * or promote products derived from this software without specific prior written permission.
25 | *
26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
27 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
31 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34 | * OF THE POSSIBILITY OF SUCH DAMAGE.
35 | *
36 | */
37 |
38 | // t: current time, b: begInnIng value, c: change In value, d: duration
39 | jQuery.easing['jswing'] = jQuery.easing['swing'];
40 |
41 | jQuery.extend( jQuery.easing,
42 | {
43 | def: 'easeOutQuad',
44 | swing: function (x, t, b, c, d) {
45 | //alert(jQuery.easing.default);
46 | return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
47 | },
48 | easeInQuad: function (x, t, b, c, d) {
49 | return c*(t/=d)*t + b;
50 | },
51 | easeOutQuad: function (x, t, b, c, d) {
52 | return -c *(t/=d)*(t-2) + b;
53 | },
54 | easeInOutQuad: function (x, t, b, c, d) {
55 | if ((t/=d/2) < 1) return c/2*t*t + b;
56 | return -c/2 * ((--t)*(t-2) - 1) + b;
57 | },
58 | easeInCubic: function (x, t, b, c, d) {
59 | return c*(t/=d)*t*t + b;
60 | },
61 | easeOutCubic: function (x, t, b, c, d) {
62 | return c*((t=t/d-1)*t*t + 1) + b;
63 | },
64 | easeInOutCubic: function (x, t, b, c, d) {
65 | if ((t/=d/2) < 1) return c/2*t*t*t + b;
66 | return c/2*((t-=2)*t*t + 2) + b;
67 | },
68 | easeInQuart: function (x, t, b, c, d) {
69 | return c*(t/=d)*t*t*t + b;
70 | },
71 | easeOutQuart: function (x, t, b, c, d) {
72 | return -c * ((t=t/d-1)*t*t*t - 1) + b;
73 | },
74 | easeInOutQuart: function (x, t, b, c, d) {
75 | if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
76 | return -c/2 * ((t-=2)*t*t*t - 2) + b;
77 | },
78 | easeInQuint: function (x, t, b, c, d) {
79 | return c*(t/=d)*t*t*t*t + b;
80 | },
81 | easeOutQuint: function (x, t, b, c, d) {
82 | return c*((t=t/d-1)*t*t*t*t + 1) + b;
83 | },
84 | easeInOutQuint: function (x, t, b, c, d) {
85 | if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
86 | return c/2*((t-=2)*t*t*t*t + 2) + b;
87 | },
88 | easeInSine: function (x, t, b, c, d) {
89 | return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
90 | },
91 | easeOutSine: function (x, t, b, c, d) {
92 | return c * Math.sin(t/d * (Math.PI/2)) + b;
93 | },
94 | easeInOutSine: function (x, t, b, c, d) {
95 | return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
96 | },
97 | easeInExpo: function (x, t, b, c, d) {
98 | return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
99 | },
100 | easeOutExpo: function (x, t, b, c, d) {
101 | return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
102 | },
103 | easeInOutExpo: function (x, t, b, c, d) {
104 | if (t==0) return b;
105 | if (t==d) return b+c;
106 | if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
107 | return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
108 | },
109 | easeInCirc: function (x, t, b, c, d) {
110 | return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
111 | },
112 | easeOutCirc: function (x, t, b, c, d) {
113 | return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
114 | },
115 | easeInOutCirc: function (x, t, b, c, d) {
116 | if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
117 | return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
118 | },
119 | easeInElastic: function (x, t, b, c, d) {
120 | var s=1.70158;var p=0;var a=c;
121 | if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
122 | if (a < Math.abs(c)) { a=c; var s=p/4; }
123 | else var s = p/(2*Math.PI) * Math.asin (c/a);
124 | return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
125 | },
126 | easeOutElastic: function (x, t, b, c, d) {
127 | var s=1.70158;var p=0;var a=c;
128 | if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
129 | if (a < Math.abs(c)) { a=c; var s=p/4; }
130 | else var s = p/(2*Math.PI) * Math.asin (c/a);
131 | return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
132 | },
133 | easeInOutElastic: function (x, t, b, c, d) {
134 | var s=1.70158;var p=0;var a=c;
135 | if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
136 | if (a < Math.abs(c)) { a=c; var s=p/4; }
137 | else var s = p/(2*Math.PI) * Math.asin (c/a);
138 | if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
139 | return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
140 | },
141 | easeInBack: function (x, t, b, c, d, s) {
142 | if (s == undefined) s = 1.70158;
143 | return c*(t/=d)*t*((s+1)*t - s) + b;
144 | },
145 | easeOutBack: function (x, t, b, c, d, s) {
146 | if (s == undefined) s = 1.70158;
147 | return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
148 | },
149 | easeInOutBack: function (x, t, b, c, d, s) {
150 | if (s == undefined) s = 1.70158;
151 | if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
152 | return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
153 | },
154 | easeInBounce: function (x, t, b, c, d) {
155 | return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
156 | },
157 | easeOutBounce: function (x, t, b, c, d) {
158 | if ((t/=d) < (1/2.75)) {
159 | return c*(7.5625*t*t) + b;
160 | } else if (t < (2/2.75)) {
161 | return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
162 | } else if (t < (2.5/2.75)) {
163 | return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
164 | } else {
165 | return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
166 | }
167 | },
168 | easeInOutBounce: function (x, t, b, c, d) {
169 | if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
170 | return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
171 | }
172 | });
173 |
174 | /*
175 | *
176 | * TERMS OF USE - EASING EQUATIONS
177 | *
178 | * Open source under the BSD License.
179 | *
180 | * Copyright © 2001 Robert Penner
181 | * All rights reserved.
182 | *
183 | * Redistribution and use in source and binary forms, with or without modification,
184 | * are permitted provided that the following conditions are met:
185 | *
186 | * Redistributions of source code must retain the above copyright notice, this list of
187 | * conditions and the following disclaimer.
188 | * Redistributions in binary form must reproduce the above copyright notice, this list
189 | * of conditions and the following disclaimer in the documentation and/or other materials
190 | * provided with the distribution.
191 | *
192 | * Neither the name of the author nor the names of contributors may be used to endorse
193 | * or promote products derived from this software without specific prior written permission.
194 | *
195 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
196 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
197 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
198 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
199 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
200 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
201 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
202 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
203 | * OF THE POSSIBILITY OF SUCH DAMAGE.
204 | *
205 | */
--------------------------------------------------------------------------------
/static/materialize/js/jquery.hammer.js:
--------------------------------------------------------------------------------
1 | (function(factory) {
2 | if (typeof define === 'function' && define.amd) {
3 | define(['jquery', 'hammerjs'], factory);
4 | } else if (typeof exports === 'object') {
5 | factory(require('jquery'), require('hammerjs'));
6 | } else {
7 | factory(jQuery, Hammer);
8 | }
9 | }(function($, Hammer) {
10 | function hammerify(el, options) {
11 | var $el = $(el);
12 | if(!$el.data("hammer")) {
13 | $el.data("hammer", new Hammer($el[0], options));
14 | }
15 | }
16 |
17 | $.fn.hammer = function(options) {
18 | return this.each(function() {
19 | hammerify(this, options);
20 | });
21 | };
22 |
23 | // extend the emit method to also trigger jQuery events
24 | Hammer.Manager.prototype.emit = (function(originalEmit) {
25 | return function(type, data) {
26 | originalEmit.call(this, type, data);
27 | $(this.element).trigger({
28 | type: type,
29 | gesture: data
30 | });
31 | };
32 | })(Hammer.Manager.prototype.emit);
33 | }));
34 |
--------------------------------------------------------------------------------
/static/materialize/js/jquery.timeago.min.js:
--------------------------------------------------------------------------------
1 | !function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(t){function e(){var e=a(this),o=r.settings;return isNaN(e.datetime)||(0==o.cutoff||Math.abs(n(e.datetime))0)||r.isTime(e)&&e.attr("title")||e.attr("title",a)}return e.data("timeago")}function i(t){return r.inWords(n(t))}function n(t){return(new Date).getTime()-t.getTime()}t.timeago=function(e){return i(e instanceof Date?e:"string"==typeof e?t.timeago.parse(e):"number"==typeof e?new Date(e):t.timeago.datetime(e))};var r=t.timeago;t.extend(t.timeago,{settings:{refreshMillis:6e4,allowPast:!0,allowFuture:!1,localeTitle:!1,cutoff:0,strings:{prefixAgo:null,prefixFromNow:null,suffixAgo:"ago",suffixFromNow:"from now",inPast:"any moment now",seconds:"less than a minute",minute:"about a minute",minutes:"%d minutes",hour:"about an hour",hours:"about %d hours",day:"a day",days:"%d days",month:"about a month",months:"%d months",year:"about a year",years:"%d years",wordSeparator:" ",numbers:[]}},inWords:function(e){function a(a,n){var r=t.isFunction(a)?a(n,e):a,o=i.numbers&&i.numbers[n]||n;return r.replace(/%d/i,o)}if(!this.settings.allowPast&&!this.settings.allowFuture)throw"timeago allowPast and allowFuture settings can not both be set to false.";var i=this.settings.strings,n=i.prefixAgo,r=i.suffixAgo;if(this.settings.allowFuture&&0>e&&(n=i.prefixFromNow,r=i.suffixFromNow),!this.settings.allowPast&&e>=0)return this.settings.strings.inPast;var o=Math.abs(e)/1e3,s=o/60,u=s/60,m=u/24,l=m/365,d=45>o&&a(i.seconds,Math.round(o))||90>o&&a(i.minute,1)||45>s&&a(i.minutes,Math.round(s))||90>s&&a(i.hour,1)||24>u&&a(i.hours,Math.round(u))||42>u&&a(i.day,1)||30>m&&a(i.days,Math.round(m))||45>m&&a(i.month,1)||365>m&&a(i.months,Math.round(m/30))||1.5>l&&a(i.year,1)||a(i.years,Math.round(l)),f=i.wordSeparator||"";return void 0===i.wordSeparator&&(f=" "),t.trim([n,d,r].join(f))},parse:function(e){var a=t.trim(e);return a=a.replace(/\.\d+/,""),a=a.replace(/-/,"/").replace(/-/,"/"),a=a.replace(/T/," ").replace(/Z/," UTC"),a=a.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"),a=a.replace(/([\+\-]\d\d)$/," $100"),new Date(a)},datetime:function(e){var a=t(e).attr(r.isTime(e)?"datetime":"title");return r.parse(a)},isTime:function(e){return"time"===t(e).get(0).tagName.toLowerCase()}});var o={init:function(){var a=t.proxy(e,this);a();var i=r.settings;i.refreshMillis>0&&(this._timeagoInterval=setInterval(a,i.refreshMillis))},update:function(a){var i=r.parse(a);t(this).data("timeago",{datetime:i}),r.settings.localeTitle&&t(this).attr("title",i.toLocaleString()),e.apply(this)},updateFromDOM:function(){t(this).data("timeago",{datetime:r.parse(t(this).attr(r.isTime(this)?"datetime":"title"))}),e.apply(this)},dispose:function(){this._timeagoInterval&&(window.clearInterval(this._timeagoInterval),this._timeagoInterval=null)}};t.fn.timeago=function(t,e){var a=t?o[t]:o.init;if(!a)throw new Error("Unknown function name '"+t+"' for timeago");return this.each(function(){a.call(this,e)}),this},document.createElement("abbr"),document.createElement("time")});
--------------------------------------------------------------------------------
/static/materialize/js/leanModal.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | $.fn.extend({
3 | openModal: function(options) {
4 | var modal = this;
5 | var overlay = $('
');
6 | $("body").append(overlay);
7 |
8 | var defaults = {
9 | opacity: 0.5,
10 | in_duration: 350,
11 | out_duration: 250,
12 | ready: undefined,
13 | complete: undefined,
14 | dismissible: true
15 | }
16 |
17 | // Override defaults
18 | options = $.extend(defaults, options);
19 |
20 | if (options.dismissible) {
21 | $("#lean-overlay").click(function() {
22 | $(modal).closeModal(options);
23 | });
24 | // Return on ESC
25 | $(document).on('keyup.leanModal', function(e) {
26 | if (e.keyCode === 27) { // ESC key
27 | $(modal).closeModal(options);
28 | }
29 | });
30 | }
31 |
32 | $(modal).find(".modal-close").click(function(e) {
33 | $(modal).closeModal(options);
34 | });
35 |
36 | $("#lean-overlay").css({ display : "block", opacity : 0 });
37 |
38 | $(modal).css({
39 | display : "block",
40 | opacity: 0
41 | });
42 |
43 | $("#lean-overlay").velocity({opacity: options.opacity}, {duration: options.in_duration, queue: false, ease: "easeOutCubic"});
44 |
45 |
46 | // Define Bottom Sheet animation
47 | if ($(modal).hasClass('bottom-sheet')) {
48 | $(modal).velocity({bottom: "0", opacity: 1}, {
49 | duration: options.in_duration,
50 | queue: false,
51 | ease: "easeOutCubic",
52 | // Handle modal ready callback
53 | complete: function() {
54 | if (typeof(options.ready) === "function") {
55 | options.ready();
56 | }
57 | }
58 | });
59 | }
60 | else {
61 | $(modal).css({ top: "4%" });
62 | $(modal).velocity({top: "10%", opacity: 1}, {
63 | duration: options.in_duration,
64 | queue: false,
65 | ease: "easeOutCubic",
66 | // Handle modal ready callback
67 | complete: function() {
68 | if (typeof(options.ready) === "function") {
69 | options.ready();
70 | }
71 | }
72 | });
73 | }
74 |
75 |
76 | }
77 | });
78 |
79 | $.fn.extend({
80 | closeModal: function(options) {
81 | var defaults = {
82 | out_duration: 250,
83 | complete: undefined
84 | }
85 | var options = $.extend(defaults, options);
86 |
87 | $('.modal-close').off();
88 | $(document).off('keyup.leanModal');
89 |
90 | $("#lean-overlay").velocity( { opacity: 0}, {duration: options.out_duration, queue: false, ease: "easeOutQuart"});
91 |
92 |
93 | // Define Bottom Sheet animation
94 | if ($(this).hasClass('bottom-sheet')) {
95 | $(this).velocity({bottom: "-100%", opacity: 0}, {
96 | duration: options.out_duration,
97 | queue: false,
98 | ease: "easeOutCubic",
99 | // Handle modal ready callback
100 | complete: function() {
101 | $("#lean-overlay").css({display:"none"});
102 |
103 | // Call complete callback
104 | if (typeof(options.complete) === "function") {
105 | options.complete();
106 | }
107 | $('#lean-overlay').remove();
108 | }
109 | });
110 | }
111 | else {
112 | $(this).fadeOut(options.out_duration, function() {
113 | $(this).css({ top: 0});
114 | $("#lean-overlay").css({display:"none"});
115 |
116 | // Call complete callback
117 | if (typeof(options.complete) === "function") {
118 | options.complete();
119 | }
120 | $('#lean-overlay').remove();
121 | });
122 | }
123 |
124 | }
125 | })
126 |
127 | $.fn.extend({
128 | leanModal: function(options) {
129 | return this.each(function() {
130 | // Close Handlers
131 | $(this).click(function(e) {
132 | var modal_id = $(this).attr("href") || '#' + $(this).data('target');
133 | $(modal_id).openModal(options);
134 | e.preventDefault();
135 | }); // done set on click
136 | }); // done return
137 | }
138 | });
139 | })(jQuery);
140 |
--------------------------------------------------------------------------------
/static/materialize/js/materialbox.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | $.fn.materialbox = function () {
4 |
5 | return this.each(function() {
6 |
7 | if ($(this).hasClass('intialized')) {
8 | return;
9 | }
10 |
11 | $(this).addClass('intialized');
12 |
13 | var overlayActive = false;
14 | var doneAnimating = true;
15 | var inDuration = 275;
16 | var outDuration = 200;
17 | var origin = $(this);
18 | var placeholder = $('
').addClass('material-placeholder');
19 | var originalWidth = 0;
20 | var originalHeight = 0;
21 | origin.wrap(placeholder);
22 |
23 |
24 | origin.on('click', function(){
25 | var placeholder = origin.parent('.material-placeholder');
26 | var windowWidth = window.innerWidth;
27 | var windowHeight = window.innerHeight;
28 | var originalWidth = origin.width();
29 | var originalHeight = origin.height();
30 |
31 |
32 | // If already modal, return to original
33 | if (doneAnimating === false) {
34 | returnToOriginal();
35 | return false;
36 | }
37 | else if (overlayActive && doneAnimating===true) {
38 | returnToOriginal();
39 | return false;
40 | }
41 |
42 |
43 | // Set states
44 | doneAnimating = false;
45 | origin.addClass('active');
46 | overlayActive = true;
47 |
48 | // Set positioning for placeholder
49 |
50 | placeholder.css({
51 | width: placeholder[0].getBoundingClientRect().width,
52 | height: placeholder[0].getBoundingClientRect().height,
53 | position: 'relative',
54 | top: 0,
55 | left: 0
56 | });
57 |
58 |
59 |
60 | // Set css on origin
61 | origin.css({position: 'absolute', 'z-index': 1000})
62 | .data('width', originalWidth)
63 | .data('height', originalHeight);
64 |
65 | // Add overlay
66 | var overlay = $('
')
67 | .css({
68 | opacity: 0
69 | })
70 | .click(function(){
71 | if (doneAnimating === true)
72 | returnToOriginal();
73 | });
74 | // Animate Overlay
75 | $('body').append(overlay);
76 | overlay.velocity({opacity: 1}, {duration: inDuration, queue: false, easing: 'easeOutQuad'}
77 | );
78 |
79 |
80 | // Add and animate caption if it exists
81 | if (origin.data('caption') !== "") {
82 | var $photo_caption = $('
');
83 | $photo_caption.text(origin.data('caption'));
84 | $('body').append($photo_caption);
85 | $photo_caption.css({ "display": "inline" });
86 | $photo_caption.velocity({opacity: 1}, {duration: inDuration, queue: false, easing: 'easeOutQuad'})
87 | }
88 |
89 |
90 |
91 | // Resize Image
92 | var ratio = 0;
93 | var widthPercent = originalWidth / windowWidth;
94 | var heightPercent = originalHeight / windowHeight;
95 | var newWidth = 0;
96 | var newHeight = 0;
97 |
98 | if (widthPercent > heightPercent) {
99 | ratio = originalHeight / originalWidth;
100 | newWidth = windowWidth * 0.9;
101 | newHeight = windowWidth * 0.9 * ratio;
102 | }
103 | else {
104 | ratio = originalWidth / originalHeight;
105 | newWidth = (windowHeight * 0.9) * ratio;
106 | newHeight = windowHeight * 0.9;
107 | }
108 |
109 | // Animate image + set z-index
110 | if(origin.hasClass('responsive-img')) {
111 | origin.velocity({'max-width': newWidth, 'width': originalWidth}, {duration: 0, queue: false,
112 | complete: function(){
113 | origin.css({left: 0, top: 0})
114 | .velocity(
115 | {
116 | height: newHeight,
117 | width: newWidth,
118 | left: $(document).scrollLeft() + windowWidth/2 - origin.parent('.material-placeholder').offset().left - newWidth/2,
119 | top: $(document).scrollTop() + windowHeight/2 - origin.parent('.material-placeholder').offset().top - newHeight/ 2
120 | },
121 | {
122 | duration: inDuration,
123 | queue: false,
124 | easing: 'easeOutQuad',
125 | complete: function(){doneAnimating = true;}
126 | }
127 | );
128 | } // End Complete
129 | }); // End Velocity
130 | }
131 | else {
132 | origin.css('left', 0)
133 | .css('top', 0)
134 | .velocity(
135 | {
136 | height: newHeight,
137 | width: newWidth,
138 | left: $(document).scrollLeft() + windowWidth/2 - origin.parent('.material-placeholder').offset().left - newWidth/2,
139 | top: $(document).scrollTop() + windowHeight/2 - origin.parent('.material-placeholder').offset().top - newHeight/ 2
140 | },
141 | {
142 | duration: inDuration,
143 | queue: false,
144 | easing: 'easeOutQuad',
145 | complete: function(){doneAnimating = true;}
146 | }
147 | ); // End Velocity
148 | }
149 |
150 | }); // End origin on click
151 |
152 |
153 | // Return on scroll
154 | $(window).scroll(function() {
155 | if (overlayActive ) {
156 | returnToOriginal();
157 | }
158 | });
159 |
160 | // Return on ESC
161 | $(document).keyup(function(e) {
162 |
163 | if (e.keyCode === 27 && doneAnimating === true) { // ESC key
164 | if (overlayActive) {
165 | returnToOriginal();
166 | }
167 | }
168 | });
169 |
170 |
171 | // This function returns the modaled image to the original spot
172 | function returnToOriginal() {
173 |
174 | doneAnimating = false;
175 |
176 | var placeholder = origin.parent('.material-placeholder');
177 | var windowWidth = window.innerWidth;
178 | var windowHeight = window.innerHeight;
179 | var originalWidth = origin.data('width');
180 | var originalHeight = origin.data('height');
181 |
182 | origin.velocity("stop", true);
183 | $('#materialbox-overlay').velocity("stop", true);
184 | $('.materialbox-caption').velocity("stop", true);
185 |
186 |
187 | $('#materialbox-overlay').velocity({opacity: 0}, {
188 | duration: outDuration, // Delay prevents animation overlapping
189 | queue: false, easing: 'easeOutQuad',
190 | complete: function(){
191 | // Remove Overlay
192 | overlayActive = false;
193 | $(this).remove();
194 | }
195 | });
196 |
197 | // Resize Image
198 | origin.velocity(
199 | {
200 | width: originalWidth,
201 | height: originalHeight,
202 | left: 0,
203 | top: 0
204 | },
205 | {
206 | duration: outDuration,
207 | queue: false, easing: 'easeOutQuad'
208 | }
209 | );
210 |
211 | // Remove Caption + reset css settings on image
212 | $('.materialbox-caption').velocity({opacity: 0}, {
213 | duration: outDuration, // Delay prevents animation overlapping
214 | queue: false, easing: 'easeOutQuad',
215 | complete: function(){
216 | placeholder.css({
217 | height: '',
218 | width: '',
219 | position: '',
220 | top: '',
221 | left: ''
222 | });
223 |
224 | origin.css({
225 | height: '',
226 | top: '',
227 | left: '',
228 | width: '',
229 | 'max-width': '',
230 | position: '',
231 | 'z-index': ''
232 | });
233 |
234 | // Remove class
235 | origin.removeClass('active');
236 | doneAnimating = true;
237 | $(this).remove();
238 | }
239 | });
240 |
241 | }
242 | });
243 | };
244 |
245 | $(document).ready(function(){
246 | $('.materialboxed').materialbox();
247 | });
248 |
249 | }( jQuery ));
250 |
--------------------------------------------------------------------------------
/static/materialize/js/parallax.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | $.fn.parallax = function () {
4 | var window_width = $(window).width();
5 | // Parallax Scripts
6 | return this.each(function(i) {
7 | var $this = $(this);
8 | $this.addClass('parallax');
9 |
10 | function updateParallax(initial) {
11 | var container_height;
12 | if (window_width < 601) {
13 | container_height = ($this.height() > 0) ? $this.height() : $this.children("img").height();
14 | }
15 | else {
16 | container_height = ($this.height() > 0) ? $this.height() : 500;
17 | }
18 | var $img = $this.children("img").first();
19 | var img_height = $img.height();
20 | var parallax_dist = img_height - container_height;
21 | var bottom = $this.offset().top + container_height;
22 | var top = $this.offset().top;
23 | var scrollTop = $(window).scrollTop();
24 | var windowHeight = window.innerHeight;
25 | var windowBottom = scrollTop + windowHeight;
26 | var percentScrolled = (windowBottom - top) / (container_height + windowHeight);
27 | var parallax = Math.round((parallax_dist * percentScrolled));
28 |
29 | if (initial) {
30 | $img.css('display', 'block');
31 | }
32 | if ((bottom > scrollTop) && (top < (scrollTop + windowHeight))) {
33 | $img.css('transform', "translate3D(-50%," + parallax + "px, 0)");
34 | }
35 |
36 | }
37 |
38 | // Wait for image load
39 | $this.children("img").one("load", function() {
40 | updateParallax(true);
41 | }).each(function() {
42 | if(this.complete) $(this).load();
43 | });
44 |
45 | $(window).scroll(function() {
46 | window_width = $(window).width();
47 | updateParallax(false);
48 | });
49 |
50 | $(window).resize(function() {
51 | window_width = $(window).width();
52 | updateParallax(false);
53 | });
54 |
55 | });
56 |
57 | };
58 | }( jQuery ));
--------------------------------------------------------------------------------
/static/materialize/js/pushpin.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 | $(document).ready(function() {
3 |
4 | $.fn.pushpin = function (options) {
5 |
6 | var defaults = {
7 | top: 0,
8 | bottom: Infinity,
9 | offset: 0
10 | }
11 | options = $.extend(defaults, options);
12 |
13 | $index = 0;
14 | return this.each(function() {
15 | var $uniqueId = Materialize.guid(),
16 | $this = $(this),
17 | $original_offset = $(this).offset().top;
18 |
19 | function removePinClasses(object) {
20 | object.removeClass('pin-top');
21 | object.removeClass('pinned');
22 | object.removeClass('pin-bottom');
23 | }
24 |
25 | function updateElements(objects, scrolled) {
26 | objects.each(function () {
27 | // Add position fixed (because its between top and bottom)
28 | if (options.top <= scrolled && options.bottom >= scrolled && !$(this).hasClass('pinned')) {
29 | removePinClasses($(this));
30 | $(this).css('top', options.offset);
31 | $(this).addClass('pinned');
32 | }
33 |
34 | // Add pin-top (when scrolled position is above top)
35 | if (scrolled < options.top && !$(this).hasClass('pin-top')) {
36 | removePinClasses($(this));
37 | $(this).css('top', 0);
38 | $(this).addClass('pin-top');
39 | }
40 |
41 | // Add pin-bottom (when scrolled position is below bottom)
42 | if (scrolled > options.bottom && !$(this).hasClass('pin-bottom')) {
43 | removePinClasses($(this));
44 | $(this).addClass('pin-bottom');
45 | $(this).css('top', options.bottom - $original_offset);
46 | }
47 | });
48 | }
49 |
50 | updateElements($this, $(window).scrollTop());
51 | $(window).on('scroll.' + $uniqueId, function () {
52 | var $scrolled = $(window).scrollTop() + options.offset;
53 | updateElements($this, $scrolled);
54 | });
55 |
56 | });
57 |
58 | };
59 |
60 |
61 | });
62 | }( jQuery ));
--------------------------------------------------------------------------------
/static/materialize/js/scrollFire.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 |
3 | // Input: Array of JSON objects {selector, offset, callback}
4 |
5 | Materialize.scrollFire = function(options) {
6 |
7 | var didScroll = false;
8 |
9 | window.addEventListener("scroll", function() {
10 | didScroll = true;
11 | });
12 |
13 | // Rate limit to 100ms
14 | setInterval(function() {
15 | if(didScroll) {
16 | didScroll = false;
17 |
18 | var windowScroll = window.pageYOffset + window.innerHeight;
19 |
20 | for (var i = 0 ; i < options.length; i++) {
21 | // Get options from each line
22 | var value = options[i];
23 | var selector = value.selector,
24 | offset = value.offset,
25 | callback = value.callback;
26 |
27 | var currentElement = document.querySelector(selector);
28 | if ( currentElement !== null) {
29 | var elementOffset = currentElement.getBoundingClientRect().top + document.body.scrollTop;
30 |
31 | if (windowScroll > (elementOffset + offset)) {
32 | if (value.done != true) {
33 | var callbackFunc = new Function(callback);
34 | callbackFunc();
35 | value.done = true;
36 | }
37 | }
38 | }
39 | };
40 | }
41 | }, 100);
42 |
43 |
44 | // $(window).scroll(function () {
45 | // var windowScroll = $(window).scrollTop() + $(window).height();
46 |
47 | // $.each( options, function( i, value ){
48 | // var selector = value.selector,
49 | // offset = value.offset,
50 | // callback = value.callback;
51 |
52 | // if ($(selector).length != 0) {
53 | // var elementOffset = $(selector).offset().top;
54 |
55 | // if (windowScroll > (elementOffset + offset)) {
56 | // if (value.done != true) {
57 | // var callbackFunc = new Function(callback);
58 | // callbackFunc();
59 | // value.done = true;
60 | // }
61 | // }
62 | // }
63 |
64 | // });
65 | // });
66 |
67 | }
68 |
69 | })(jQuery);
--------------------------------------------------------------------------------
/static/materialize/js/scrollspy.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Extend jquery with a scrollspy plugin.
3 | * This watches the window scroll and fires events when elements are scrolled into viewport.
4 | *
5 | * throttle() and getTime() taken from Underscore.js
6 | * https://github.com/jashkenas/underscore
7 | *
8 | * @author Copyright 2013 John Smart
9 | * @license https://raw.github.com/thesmart/jquery-scrollspy/master/LICENSE
10 | * @see https://github.com/thesmart
11 | * @version 0.1.2
12 | */
13 | (function($) {
14 |
15 | var jWindow = $(window);
16 | var elements = [];
17 | var elementsInView = [];
18 | var isSpying = false;
19 | var ticks = 0;
20 | var unique_id = 1;
21 | var offset = {
22 | top : 0,
23 | right : 0,
24 | bottom : 0,
25 | left : 0,
26 | }
27 |
28 | /**
29 | * Find elements that are within the boundary
30 | * @param {number} top
31 | * @param {number} right
32 | * @param {number} bottom
33 | * @param {number} left
34 | * @return {jQuery} A collection of elements
35 | */
36 | function findElements(top, right, bottom, left) {
37 | var hits = $();
38 | $.each(elements, function(i, element) {
39 | if (element.height() > 0) {
40 | var elTop = element.offset().top,
41 | elLeft = element.offset().left,
42 | elRight = elLeft + element.width(),
43 | elBottom = elTop + element.height();
44 |
45 | var isIntersect = !(elLeft > right ||
46 | elRight < left ||
47 | elTop > bottom ||
48 | elBottom < top);
49 |
50 | if (isIntersect) {
51 | hits.push(element);
52 | }
53 | }
54 | });
55 |
56 | return hits;
57 | }
58 |
59 |
60 | /**
61 | * Called when the user scrolls the window
62 | */
63 | function onScroll() {
64 | // unique tick id
65 | ++ticks;
66 |
67 | // viewport rectangle
68 | var top = jWindow.scrollTop(),
69 | left = jWindow.scrollLeft(),
70 | right = left + jWindow.width(),
71 | bottom = top + jWindow.height();
72 |
73 | // determine which elements are in view
74 | // + 60 accounts for fixed nav
75 | var intersections = findElements(top+offset.top + 200, right+offset.right, bottom+offset.bottom, left+offset.left);
76 | $.each(intersections, function(i, element) {
77 |
78 | var lastTick = element.data('scrollSpy:ticks');
79 | if (typeof lastTick != 'number') {
80 | // entered into view
81 | element.triggerHandler('scrollSpy:enter');
82 | }
83 |
84 | // update tick id
85 | element.data('scrollSpy:ticks', ticks);
86 | });
87 |
88 | // determine which elements are no longer in view
89 | $.each(elementsInView, function(i, element) {
90 | var lastTick = element.data('scrollSpy:ticks');
91 | if (typeof lastTick == 'number' && lastTick !== ticks) {
92 | // exited from view
93 | element.triggerHandler('scrollSpy:exit');
94 | element.data('scrollSpy:ticks', null);
95 | }
96 | });
97 |
98 | // remember elements in view for next tick
99 | elementsInView = intersections;
100 | }
101 |
102 | /**
103 | * Called when window is resized
104 | */
105 | function onWinSize() {
106 | jWindow.trigger('scrollSpy:winSize');
107 | }
108 |
109 | /**
110 | * Get time in ms
111 | * @license https://raw.github.com/jashkenas/underscore/master/LICENSE
112 | * @type {function}
113 | * @return {number}
114 | */
115 | var getTime = (Date.now || function () {
116 | return new Date().getTime();
117 | });
118 |
119 | /**
120 | * Returns a function, that, when invoked, will only be triggered at most once
121 | * during a given window of time. Normally, the throttled function will run
122 | * as much as it can, without ever going more than once per `wait` duration;
123 | * but if you'd like to disable the execution on the leading edge, pass
124 | * `{leading: false}`. To disable execution on the trailing edge, ditto.
125 | * @license https://raw.github.com/jashkenas/underscore/master/LICENSE
126 | * @param {function} func
127 | * @param {number} wait
128 | * @param {Object=} options
129 | * @returns {Function}
130 | */
131 | function throttle(func, wait, options) {
132 | var context, args, result;
133 | var timeout = null;
134 | var previous = 0;
135 | options || (options = {});
136 | var later = function () {
137 | previous = options.leading === false ? 0 : getTime();
138 | timeout = null;
139 | result = func.apply(context, args);
140 | context = args = null;
141 | };
142 | return function () {
143 | var now = getTime();
144 | if (!previous && options.leading === false) previous = now;
145 | var remaining = wait - (now - previous);
146 | context = this;
147 | args = arguments;
148 | if (remaining <= 0) {
149 | clearTimeout(timeout);
150 | timeout = null;
151 | previous = now;
152 | result = func.apply(context, args);
153 | context = args = null;
154 | } else if (!timeout && options.trailing !== false) {
155 | timeout = setTimeout(later, remaining);
156 | }
157 | return result;
158 | };
159 | };
160 |
161 | /**
162 | * Enables ScrollSpy using a selector
163 | * @param {jQuery|string} selector The elements collection, or a selector
164 | * @param {Object=} options Optional.
165 | throttle : number -> scrollspy throttling. Default: 100 ms
166 | offsetTop : number -> offset from top. Default: 0
167 | offsetRight : number -> offset from right. Default: 0
168 | offsetBottom : number -> offset from bottom. Default: 0
169 | offsetLeft : number -> offset from left. Default: 0
170 | * @returns {jQuery}
171 | */
172 | $.scrollSpy = function(selector, options) {
173 | var visible = [];
174 | selector = $(selector);
175 | selector.each(function(i, element) {
176 | elements.push($(element));
177 | $(element).data("scrollSpy:id", i);
178 | // Smooth scroll to section
179 | $('a[href=#' + $(element).attr('id') + ']').click(function(e) {
180 | e.preventDefault();
181 | var offset = $(this.hash).offset().top + 1;
182 |
183 | // offset - 200 allows elements near bottom of page to scroll
184 |
185 | $('html, body').animate({ scrollTop: offset - 200 }, {duration: 400, queue: false, easing: 'easeOutCubic'});
186 |
187 | });
188 | });
189 | options = options || {
190 | throttle: 100
191 | };
192 |
193 | offset.top = options.offsetTop || 0;
194 | offset.right = options.offsetRight || 0;
195 | offset.bottom = options.offsetBottom || 0;
196 | offset.left = options.offsetLeft || 0;
197 |
198 | var throttledScroll = throttle(onScroll, options.throttle || 100);
199 | var readyScroll = function(){
200 | $(document).ready(throttledScroll);
201 | };
202 |
203 | if (!isSpying) {
204 | jWindow.on('scroll', readyScroll);
205 | jWindow.on('resize', readyScroll);
206 | isSpying = true;
207 | }
208 |
209 | // perform a scan once, after current execution context, and after dom is ready
210 | setTimeout(readyScroll, 0);
211 |
212 |
213 | selector.on('scrollSpy:enter', function() {
214 | visible = $.grep(visible, function(value) {
215 | return value.height() != 0;
216 | });
217 |
218 | var $this = $(this);
219 |
220 | if (visible[0]) {
221 | $('a[href=#' + visible[0].attr('id') + ']').removeClass('active');
222 | if ($this.data('scrollSpy:id') < visible[0].data('scrollSpy:id')) {
223 | visible.unshift($(this));
224 | }
225 | else {
226 | visible.push($(this));
227 | }
228 | }
229 | else {
230 | visible.push($(this));
231 | }
232 |
233 |
234 | $('a[href=#' + visible[0].attr('id') + ']').addClass('active');
235 | });
236 | selector.on('scrollSpy:exit', function() {
237 | visible = $.grep(visible, function(value) {
238 | return value.height() != 0;
239 | });
240 |
241 | if (visible[0]) {
242 | $('a[href=#' + visible[0].attr('id') + ']').removeClass('active');
243 | var $this = $(this);
244 | visible = $.grep(visible, function(value) {
245 | return value.attr('id') != $this.attr('id');
246 | });
247 | if (visible[0]) { // Check if empty
248 | $('a[href=#' + visible[0].attr('id') + ']').addClass('active');
249 | }
250 | }
251 | });
252 |
253 | return selector;
254 | };
255 |
256 | /**
257 | * Listen for window resize events
258 | * @param {Object=} options Optional. Set { throttle: number } to change throttling. Default: 100 ms
259 | * @returns {jQuery} $(window)
260 | */
261 | $.winSizeSpy = function(options) {
262 | $.winSizeSpy = function() { return jWindow; }; // lock from multiple calls
263 | options = options || {
264 | throttle: 100
265 | };
266 | return jWindow.on('resize', throttle(onWinSize, options.throttle || 100));
267 | };
268 |
269 | /**
270 | * Enables ScrollSpy on a collection of elements
271 | * e.g. $('.scrollSpy').scrollSpy()
272 | * @param {Object=} options Optional.
273 | throttle : number -> scrollspy throttling. Default: 100 ms
274 | offsetTop : number -> offset from top. Default: 0
275 | offsetRight : number -> offset from right. Default: 0
276 | offsetBottom : number -> offset from bottom. Default: 0
277 | offsetLeft : number -> offset from left. Default: 0
278 | * @returns {jQuery}
279 | */
280 | $.fn.scrollSpy = function(options) {
281 | return $.scrollSpy($(this), options);
282 | };
283 |
284 | })(jQuery);
--------------------------------------------------------------------------------
/static/materialize/js/slider.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | $.fn.slider = function (options) {
4 | var defaults = {
5 | indicators: true,
6 | height: 400,
7 | transition: 500,
8 | interval: 6000
9 | }
10 | options = $.extend(defaults, options);
11 |
12 | return this.each(function() {
13 |
14 | // For each slider, we want to keep track of
15 | // which slide is active and its associated content
16 | var $this = $(this);
17 | var $slider = $this.find('ul.slides').first();
18 | var $slides = $slider.find('li');
19 | var $active_index = $slider.find('.active').index();
20 | var $active;
21 | if ($active_index != -1) { $active = $slides.eq($active_index); }
22 |
23 | // Transitions the caption depending on alignment
24 | function captionTransition(caption, duration) {
25 | if (caption.hasClass("center-align")) {
26 | caption.velocity({opacity: 0, translateY: -100}, {duration: duration, queue: false});
27 | }
28 | else if (caption.hasClass("right-align")) {
29 | caption.velocity({opacity: 0, translateX: 100}, {duration: duration, queue: false});
30 | }
31 | else if (caption.hasClass("left-align")) {
32 | caption.velocity({opacity: 0, translateX: -100}, {duration: duration, queue: false});
33 | }
34 | }
35 |
36 | // This function will transition the slide to any index of the next slide
37 | function moveToSlide(index) {
38 | if (index >= $slides.length) index = 0;
39 | else if (index < 0) index = $slides.length -1;
40 |
41 | $active_index = $slider.find('.active').index();
42 |
43 | // Only do if index changes
44 | if ($active_index != index) {
45 | $active = $slides.eq($active_index);
46 | $caption = $active.find('.caption');
47 |
48 | $active.removeClass('active');
49 | $active.velocity({opacity: 0}, {duration: options.transition, queue: false, easing: 'easeOutQuad',
50 | complete: function() {
51 | $slides.not('.active').velocity({opacity: 0, translateX: 0, translateY: 0}, {duration: 0, queue: false});
52 | } });
53 | captionTransition($caption, options.transition);
54 |
55 |
56 | // Update indicators
57 | if (options.indicators) {
58 | $indicators.eq($active_index).removeClass('active');
59 | }
60 |
61 | $slides.eq(index).velocity({opacity: 1}, {duration: options.transition, queue: false, easing: 'easeOutQuad'});
62 | $slides.eq(index).find('.caption').velocity({opacity: 1, translateX: 0, translateY: 0}, {duration: options.transition, delay: options.transition, queue: false, easing: 'easeOutQuad'});
63 | $slides.eq(index).addClass('active');
64 |
65 |
66 | // Update indicators
67 | if (options.indicators) {
68 | $indicators.eq(index).addClass('active');
69 | }
70 | }
71 | }
72 |
73 | // Set height of slider
74 | if (options.height != 400) {
75 | $this.height(options.height + 40);
76 | $slider.height(options.height);
77 | }
78 |
79 | // Set initial positions of captions
80 | $slides.find('.caption').each(function () {
81 | captionTransition($(this), 0);
82 | });
83 |
84 | // Set initial dimensions of images
85 | // $slides.find('img').each(function () {
86 | // $(this).load(function () {
87 | // if ($(this).width() < $(this).parent().width()) {
88 | // $(this).css({width: '100%', height: 'auto'});
89 | // }
90 | // });
91 | // });
92 |
93 | // Move img src into background-image
94 | $slides.find('img').each(function () {
95 | $(this).css('background-image', 'url(' + $(this).attr('src') + ')' );
96 | $(this).attr('src', 'data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==');
97 | });
98 |
99 | // dynamically add indicators
100 | if (options.indicators) {
101 | var $indicators = $('');
102 | $slides.each(function( index ) {
103 | var $indicator = $(' ');
104 |
105 | // Handle clicks on indicators
106 | $indicator.click(function () {
107 | var $parent = $slider.parent();
108 | var curr_index = $parent.find($(this)).index();
109 | moveToSlide(curr_index);
110 |
111 | // reset interval
112 | clearInterval($interval);
113 | $interval = setInterval(
114 | function(){
115 | $active_index = $slider.find('.active').index();
116 | if ($slides.length == $active_index + 1) $active_index = 0; // loop to start
117 | else $active_index += 1;
118 |
119 | moveToSlide($active_index);
120 |
121 | }, options.transition + options.interval
122 | );
123 | });
124 | $indicators.append($indicator);
125 | });
126 | $this.append($indicators);
127 | $indicators = $this.find('ul.indicators').find('li.indicator-item');
128 | }
129 |
130 | if ($active) {
131 | $active.show();
132 | }
133 | else {
134 | $slides.first().addClass('active').velocity({opacity: 1}, {duration: options.transition, queue: false, easing: 'easeOutQuad'});
135 |
136 | $active_index = 0;
137 | $active = $slides.eq($active_index);
138 |
139 | // Update indicators
140 | if (options.indicators) {
141 | $indicators.eq($active_index).addClass('active');
142 | }
143 | }
144 |
145 | // Adjust height to current slide
146 | $active.find('img').each(function() {
147 | $active.find('.caption').velocity({opacity: 1, translateX: 0, translateY: 0}, {duration: options.transition, queue: false, easing: 'easeOutQuad'});
148 | });
149 |
150 | // auto scroll
151 | $interval = setInterval(
152 | function(){
153 | $active_index = $slider.find('.active').index();
154 | moveToSlide($active_index + 1);
155 |
156 | }, options.transition + options.interval
157 | );
158 |
159 |
160 | // HammerJS, Swipe navigation
161 |
162 | // Touch Event
163 | var panning = false;
164 | var swipeLeft = false;
165 | var swipeRight = false;
166 |
167 | $this.hammer({
168 | prevent_default: false
169 | }).bind('pan', function(e) {
170 | if (e.gesture.pointerType === "touch") {
171 |
172 | // reset interval
173 | clearInterval($interval);
174 |
175 | var direction = e.gesture.direction;
176 | var x = e.gesture.deltaX;
177 | var velocityX = e.gesture.velocityX;
178 |
179 | $curr_slide = $slider.find('.active');
180 | $curr_slide.velocity({ translateX: x
181 | }, {duration: 50, queue: false, easing: 'easeOutQuad'});
182 |
183 | // Swipe Left
184 | if (direction === 4 && (x > ($this.innerWidth() / 2) || velocityX < -0.65)) {
185 | swipeRight = true;
186 | }
187 | // Swipe Right
188 | else if (direction === 2 && (x < (-1 * $this.innerWidth() / 2) || velocityX > 0.65)) {
189 | swipeLeft = true;
190 | }
191 |
192 | // Make Slide Behind active slide visible
193 | var next_slide;
194 | if (swipeLeft) {
195 | next_slide = $curr_slide.next();
196 | if (next_slide.length === 0) {
197 | next_slide = $slides.first();
198 | }
199 | next_slide.velocity({ opacity: 1
200 | }, {duration: 300, queue: false, easing: 'easeOutQuad'});
201 | }
202 | if (swipeRight) {
203 | next_slide = $curr_slide.prev();
204 | if (next_slide.length === 0) {
205 | next_slide = $slides.last();
206 | }
207 | next_slide.velocity({ opacity: 1
208 | }, {duration: 300, queue: false, easing: 'easeOutQuad'});
209 | }
210 |
211 |
212 | }
213 |
214 | }).bind('panend', function(e) {
215 | if (e.gesture.pointerType === "touch") {
216 |
217 | $curr_slide = $slider.find('.active');
218 | panning = false;
219 | curr_index = $slider.find('.active').index();
220 |
221 | if (!swipeRight && !swipeLeft) {
222 | // Return to original spot
223 | $curr_slide.velocity({ translateX: 0
224 | }, {duration: 300, queue: false, easing: 'easeOutQuad'});
225 | }
226 | else if (swipeLeft) {
227 | moveToSlide(curr_index + 1);
228 | $curr_slide.velocity({translateX: -1 * $this.innerWidth() }, {duration: 300, queue: false, easing: 'easeOutQuad',
229 | complete: function() {
230 | $curr_slide.velocity({opacity: 0, translateX: 0}, {duration: 0, queue: false});
231 | } });
232 | }
233 | else if (swipeRight) {
234 | moveToSlide(curr_index - 1);
235 | $curr_slide.velocity({translateX: $this.innerWidth() }, {duration: 300, queue: false, easing: 'easeOutQuad',
236 | complete: function() {
237 | $curr_slide.velocity({opacity: 0, translateX: 0}, {duration: 0, queue: false});
238 | } });
239 | }
240 | swipeLeft = false;
241 | swipeRight = false;
242 |
243 | // Restart interval
244 | clearInterval($interval);
245 | $interval = setInterval(
246 | function(){
247 | $active_index = $slider.find('.active').index();
248 | if ($slides.length == $active_index + 1) $active_index = 0; // loop to start
249 | else $active_index += 1;
250 |
251 | moveToSlide($active_index);
252 |
253 | }, options.transition + options.interval
254 | );
255 | }
256 | });
257 |
258 | });
259 |
260 |
261 |
262 | };
263 | }( jQuery ));
264 |
--------------------------------------------------------------------------------
/static/materialize/js/tabs.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | var methods = {
4 | init : function() {
5 | return this.each(function() {
6 |
7 | // For each set of tabs, we want to keep track of
8 | // which tab is active and its associated content
9 | var $this = $(this),
10 | window_width = $(window).width();
11 |
12 | $this.width('100%');
13 | // Set Tab Width for each tab
14 | var $num_tabs = $(this).children('li').length;
15 | $this.children('li').each(function() {
16 | $(this).width((100/$num_tabs)+'%');
17 | });
18 | var $active, $content, $links = $this.find('li.tab a'),
19 | $tabs_width = $this.width(),
20 | $tab_width = $this.find('li').first().outerWidth(),
21 | $index = 0;
22 |
23 | // If the location.hash matches one of the links, use that as the active tab.
24 | $active = $($links.filter('[href="'+location.hash+'"]'));
25 |
26 | // If no match is found, use the first link or any with class 'active' as the initial active tab.
27 | if ($active.length === 0) {
28 | $active = $(this).find('li.tab a.active').first();
29 | }
30 | if ($active.length === 0) {
31 | $active = $(this).find('li.tab a').first();
32 | }
33 |
34 | $active.addClass('active');
35 | $index = $links.index($active);
36 | if ($index < 0) {
37 | $index = 0;
38 | }
39 |
40 | $content = $($active[0].hash);
41 |
42 | // append indicator then set indicator width to tab width
43 | $this.append('
');
44 | var $indicator = $this.find('.indicator');
45 | if ($this.is(":visible")) {
46 | $indicator.css({"right": $tabs_width - (($index + 1) * $tab_width)});
47 | $indicator.css({"left": $index * $tab_width});
48 | }
49 | $(window).resize(function () {
50 | $tabs_width = $this.width();
51 | $tab_width = $this.find('li').first().outerWidth();
52 | if ($index < 0) {
53 | $index = 0;
54 | }
55 | if ($tab_width !== 0 && $tabs_width !== 0) {
56 | $indicator.css({"right": $tabs_width - (($index + 1) * $tab_width)});
57 | $indicator.css({"left": $index * $tab_width});
58 | }
59 | });
60 |
61 | // Hide the remaining content
62 | $links.not($active).each(function () {
63 | $(this.hash).hide();
64 | });
65 |
66 |
67 | // Bind the click event handler
68 | $this.on('click', 'a', function(e){
69 | $tabs_width = $this.width();
70 | $tab_width = $this.find('li').first().outerWidth();
71 |
72 | // Make the old tab inactive.
73 | $active.removeClass('active');
74 | $content.hide();
75 |
76 | // Update the variables with the new link and content
77 | $active = $(this);
78 | $content = $(this.hash);
79 | $links = $this.find('li.tab a');
80 |
81 | // Make the tab active.
82 | $active.addClass('active');
83 | var $prev_index = $index;
84 | $index = $links.index($(this));
85 | if ($index < 0) {
86 | $index = 0;
87 | }
88 | // Change url to current tab
89 | // window.location.hash = $active.attr('href');
90 |
91 | $content.show();
92 |
93 | // Update indicator
94 | if (($index - $prev_index) >= 0) {
95 | $indicator.velocity({"right": $tabs_width - (($index + 1) * $tab_width)}, { duration: 300, queue: false, easing: 'easeOutQuad'});
96 | $indicator.velocity({"left": $index * $tab_width}, {duration: 300, queue: false, easing: 'easeOutQuad', delay: 90});
97 |
98 | }
99 | else {
100 | $indicator.velocity({"left": $index * $tab_width}, { duration: 300, queue: false, easing: 'easeOutQuad'});
101 | $indicator.velocity({"right": $tabs_width - (($index + 1) * $tab_width)}, {duration: 300, queue: false, easing: 'easeOutQuad', delay: 90});
102 | }
103 |
104 | // Prevent the anchor's default click action
105 | e.preventDefault();
106 | });
107 | });
108 |
109 | },
110 | select_tab : function( id ) {
111 | this.find('a[href="#' + id + '"]').trigger('click');
112 | }
113 | };
114 |
115 | $.fn.tabs = function(methodOrOptions) {
116 | if ( methods[methodOrOptions] ) {
117 | return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 ));
118 | } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) {
119 | // Default to "init"
120 | return methods.init.apply( this, arguments );
121 | } else {
122 | $.error( 'Method ' + methodOrOptions + ' does not exist on jQuery.tooltip' );
123 | }
124 | };
125 |
126 | $(document).ready(function(){
127 | $('ul.tabs').tabs();
128 | });
129 | }( jQuery ));
130 |
--------------------------------------------------------------------------------
/static/materialize/js/toasts.js:
--------------------------------------------------------------------------------
1 | Materialize.toast = function (message, displayLength, className, completeCallback) {
2 | className = className || "";
3 |
4 | var container = document.getElementById('toast-container');
5 |
6 | // Create toast container if it does not exist
7 | if (container === null) {
8 | // create notification container
9 | var container = document.createElement('div');
10 | container.id = 'toast-container';
11 | document.body.appendChild(container);
12 | }
13 |
14 | // Select and append toast
15 | var newToast = createToast(message);
16 | container.appendChild(newToast);
17 |
18 | newToast.style.top = '35px';
19 | newToast.style.opacity = 0;
20 |
21 | // Animate toast in
22 | Vel(newToast, { "top" : "0px", opacity: 1 }, {duration: 300,
23 | easing: 'easeOutCubic',
24 | queue: false});
25 |
26 | // Allows timer to be pause while being panned
27 | var timeLeft = displayLength;
28 | var counterInterval = setInterval (function(){
29 |
30 |
31 | if (newToast.parentNode === null)
32 | window.clearInterval(counterInterval);
33 |
34 | // If toast is not being dragged, decrease its time remaining
35 | if (!newToast.classList.contains('panning')) {
36 | timeLeft -= 20;
37 | }
38 |
39 | if (timeLeft <= 0) {
40 | // Animate toast out
41 | Vel(newToast, {"opacity": 0, marginTop: '-40px'}, { duration: 375,
42 | easing: 'easeOutExpo',
43 | queue: false,
44 | complete: function(){
45 | // Call the optional callback
46 | if(typeof(completeCallback) === "function")
47 | completeCallback();
48 | // Remove toast after it times out
49 | this[0].parentNode.removeChild(this[0]);
50 | }
51 | });
52 | window.clearInterval(counterInterval);
53 | }
54 | }, 20);
55 |
56 |
57 |
58 | function createToast(html) {
59 |
60 | // Create toast
61 | var toast = document.createElement('div');
62 | toast.classList.add('toast');
63 | if (className) {
64 | var classes = className.split(' ');
65 |
66 | for (var i = 0, count = classes.length; i < count; i++) {
67 | toast.classList.add(classes[i]);
68 | }
69 | }
70 | toast.innerHTML = html;
71 |
72 | // Bind hammer
73 | var hammerHandler = new Hammer(toast, {prevent_default: false});
74 | hammerHandler.on('pan', function(e) {
75 | var deltaX = e.deltaX;
76 | var activationDistance = 80;
77 |
78 | // Change toast state
79 | if (!toast.classList.contains('panning')){
80 | toast.classList.add('panning');
81 | }
82 |
83 | var opacityPercent = 1-Math.abs(deltaX / activationDistance);
84 | if (opacityPercent < 0)
85 | opacityPercent = 0;
86 |
87 | Vel(toast, {left: deltaX, opacity: opacityPercent }, {duration: 50, queue: false, easing: 'easeOutQuad'});
88 |
89 | });
90 |
91 | hammerHandler.on('panend', function(e) {
92 | var deltaX = e.deltaX;
93 | var activationDistance = 80;
94 |
95 | // If toast dragged past activation point
96 | if (Math.abs(deltaX) > activationDistance) {
97 | Vel(toast, {marginTop: '-40px'}, { duration: 375,
98 | easing: 'easeOutExpo',
99 | queue: false,
100 | complete: function(){
101 | if(typeof(completeCallback) === "function") {
102 | completeCallback();
103 | }
104 | toast.parentNode.removeChild(toast);
105 | }
106 | });
107 |
108 | } else {
109 | toast.classList.remove('panning');
110 | // Put toast back into original position
111 | Vel(toast, { left: 0, opacity: 1 }, { duration: 300,
112 | easing: 'easeOutExpo',
113 | queue: false
114 | });
115 |
116 | }
117 | });
118 |
119 | return toast;
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/static/materialize/js/tooltip.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 | $.fn.tooltip = function (options) {
3 | var timeout = null,
4 | counter = null,
5 | started = false,
6 | counterInterval = null,
7 | margin = 5;
8 |
9 | // Defaults
10 | var defaults = {
11 | delay: 350
12 | };
13 | options = $.extend(defaults, options);
14 |
15 | //Remove previously created html
16 | $('.material-tooltip').remove();
17 |
18 | return this.each(function(){
19 | var origin = $(this);
20 |
21 | // Create Text span
22 | var tooltip_text = $(' ').text(origin.attr('data-tooltip'));
23 |
24 | // Create tooltip
25 | var newTooltip = $('
');
26 | newTooltip.addClass('material-tooltip').append(tooltip_text);
27 | newTooltip.appendTo($('body'));
28 |
29 | var backdrop = $('
').addClass('backdrop');
30 | backdrop.appendTo(newTooltip);
31 | backdrop.css({ top: 0, left:0 });
32 |
33 |
34 | //Destroy previously binded events
35 | $(this).off('mouseenter mouseleave');
36 | // Mouse In
37 | $(this).on({
38 | mouseenter: function(e) {
39 | var tooltip_delay = origin.data("delay");
40 | tooltip_delay = (tooltip_delay == undefined || tooltip_delay == "") ? options.delay : tooltip_delay;
41 | counter = 0;
42 | counterInterval = setInterval(function(){
43 | counter += 10;
44 | if (counter >= tooltip_delay && started == false) {
45 | started = true
46 | newTooltip.css({ display: 'block', left: '0px', top: '0px' });
47 |
48 | // Set Tooltip text
49 | newTooltip.children('span').text(origin.attr('data-tooltip'));
50 |
51 | // Tooltip positioning
52 | var originWidth = origin.outerWidth();
53 | var originHeight = origin.outerHeight();
54 | var tooltipPosition = origin.attr('data-position');
55 | var tooltipHeight = newTooltip.outerHeight();
56 | var tooltipWidth = newTooltip.outerWidth();
57 | var tooltipVerticalMovement = '0px';
58 | var tooltipHorizontalMovement = '0px';
59 | var scale_factor = 8;
60 |
61 | if (tooltipPosition === "top") {
62 | // Top Position
63 | newTooltip.css({
64 | top: origin.offset().top - tooltipHeight - margin,
65 | left: origin.offset().left + originWidth/2 - tooltipWidth/2
66 | });
67 | tooltipVerticalMovement = '-10px';
68 | backdrop.css({
69 | borderRadius: '14px 14px 0 0',
70 | transformOrigin: '50% 90%',
71 | marginTop: tooltipHeight,
72 | marginLeft: (tooltipWidth/2) - (backdrop.width()/2)
73 |
74 | });
75 | }
76 | // Left Position
77 | else if (tooltipPosition === "left") {
78 | newTooltip.css({
79 | top: origin.offset().top + originHeight/2 - tooltipHeight/2,
80 | left: origin.offset().left - tooltipWidth - margin
81 | });
82 | tooltipHorizontalMovement = '-10px';
83 | backdrop.css({
84 | width: '14px',
85 | height: '14px',
86 | borderRadius: '14px 0 0 14px',
87 | transformOrigin: '95% 50%',
88 | marginTop: tooltipHeight/2,
89 | marginLeft: tooltipWidth
90 | });
91 | }
92 | // Right Position
93 | else if (tooltipPosition === "right") {
94 | newTooltip.css({
95 | top: origin.offset().top + originHeight/2 - tooltipHeight/2,
96 | left: origin.offset().left + originWidth + margin
97 | });
98 | tooltipHorizontalMovement = '+10px';
99 | backdrop.css({
100 | width: '14px',
101 | height: '14px',
102 | borderRadius: '0 14px 14px 0',
103 | transformOrigin: '5% 50%',
104 | marginTop: tooltipHeight/2,
105 | marginLeft: '0px'
106 | });
107 | }
108 | else {
109 | // Bottom Position
110 | newTooltip.css({
111 | top: origin.offset().top + origin.outerHeight() + margin,
112 | left: origin.offset().left + originWidth/2 - tooltipWidth/2
113 | });
114 | tooltipVerticalMovement = '+10px';
115 | backdrop.css({
116 | marginLeft: (tooltipWidth/2) - (backdrop.width()/2)
117 | });
118 | }
119 |
120 | // Calculate Scale to fill
121 | scale_factor = tooltipWidth / 8;
122 | if (scale_factor < 8) {
123 | scale_factor = 8;
124 | }
125 | if (tooltipPosition === "right" || tooltipPosition === "left") {
126 | scale_factor = tooltipWidth / 10;
127 | if (scale_factor < 6)
128 | scale_factor = 6;
129 | }
130 |
131 | newTooltip.velocity({ opacity: 1, marginTop: tooltipVerticalMovement, marginLeft: tooltipHorizontalMovement}, { duration: 350, queue: false });
132 | backdrop.css({ display: 'block' })
133 | .velocity({opacity:1},{duration: 55, delay: 0, queue: false})
134 | .velocity({scale: scale_factor}, {duration: 300, delay: 0, queue: false, easing: 'easeInOutQuad'});
135 |
136 | }
137 | }, 10); // End Interval
138 |
139 | // Mouse Out
140 | },
141 | mouseleave: function(){
142 | // Reset State
143 | clearInterval(counterInterval);
144 | counter = 0;
145 |
146 | // Animate back
147 | newTooltip.velocity({
148 | opacity: 0, marginTop: 0, marginLeft: 0}, { duration: 225, queue: false, delay: 275 }
149 | );
150 | backdrop.velocity({opacity: 0, scale: 1}, {
151 | duration:225,
152 | delay: 275, queue: false,
153 | complete: function(){
154 | backdrop.css('display', 'none');
155 | newTooltip.css('display', 'none');
156 | started = false;}
157 | });
158 | }
159 | });
160 | });
161 | };
162 |
163 | $(document).ready(function(){
164 | $('.tooltipped').tooltip();
165 | });
166 | }( jQuery ));
167 |
--------------------------------------------------------------------------------
/static/materialize/js/transitions.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 | // Image transition function
3 | Materialize.fadeInImage = function(selector){
4 | var element = $(selector);
5 | element.css({opacity: 0});
6 | $(element).velocity({opacity: 1}, {
7 | duration: 650,
8 | queue: false,
9 | easing: 'easeOutSine'
10 | });
11 | $(element).velocity({opacity: 1}, {
12 | duration: 1300,
13 | queue: false,
14 | easing: 'swing',
15 | step: function(now, fx) {
16 | fx.start = 100;
17 | var grayscale_setting = now/100;
18 | var brightness_setting = 150 - (100 - now)/1.75;
19 |
20 | if (brightness_setting < 100) {
21 | brightness_setting = 100;
22 | }
23 | if (now >= 0) {
24 | $(this).css({
25 | "-webkit-filter": "grayscale("+grayscale_setting+")" + "brightness("+brightness_setting+"%)",
26 | "filter": "grayscale("+grayscale_setting+")" + "brightness("+brightness_setting+"%)"
27 | });
28 | }
29 | }
30 | });
31 | };
32 |
33 | // Horizontal staggered list
34 | Materialize.showStaggeredList = function(selector) {
35 | var time = 0;
36 | $(selector).find('li').velocity(
37 | { translateX: "-100px"},
38 | { duration: 0 });
39 |
40 | $(selector).find('li').each(function() {
41 | $(this).velocity(
42 | { opacity: "1", translateX: "0"},
43 | { duration: 800, delay: time, easing: [60, 10] });
44 | time += 120;
45 | });
46 | };
47 |
48 |
49 | $(document).ready(function() {
50 | // Hardcoded .staggered-list scrollFire
51 | // var staggeredListOptions = [];
52 | // $('ul.staggered-list').each(function (i) {
53 |
54 | // var label = 'scrollFire-' + i;
55 | // $(this).addClass(label);
56 | // staggeredListOptions.push(
57 | // {selector: 'ul.staggered-list.' + label,
58 | // offset: 200,
59 | // callback: 'showStaggeredList("ul.staggered-list.' + label + '")'});
60 | // });
61 | // scrollFire(staggeredListOptions);
62 |
63 | // HammerJS, Swipe navigation
64 |
65 | // Touch Event
66 | var swipeLeft = false;
67 | var swipeRight = false;
68 |
69 | $('.dismissable').each(function() {
70 | $(this).hammer({
71 | prevent_default: false
72 | }).bind('pan', function(e) {
73 | if (e.gesture.pointerType === "touch") {
74 | var $this = $(this);
75 | var direction = e.gesture.direction;
76 | var x = e.gesture.deltaX;
77 | var velocityX = e.gesture.velocityX;
78 |
79 | $this.velocity({ translateX: x
80 | }, {duration: 50, queue: false, easing: 'easeOutQuad'});
81 |
82 | // Swipe Left
83 | if (direction === 4 && (x > ($this.innerWidth() / 2) || velocityX < -0.75)) {
84 | swipeLeft = true;
85 | }
86 | // Swipe Right
87 | else if (direction === 2 && (x < (-1 * $this.innerWidth() / 2) || velocityX > 0.75)) {
88 | swipeRight = true;
89 | }
90 | }
91 | }).bind('panend', function(e) {
92 | if (e.gesture.pointerType === "touch") {
93 | var $this = $(this);
94 | if (swipeLeft || swipeRight) {
95 | var fullWidth;
96 | if (swipeLeft) { fullWidth = $this.innerWidth() }
97 | else { fullWidth = -1 * $this.innerWidth() }
98 |
99 | $this.velocity({ translateX: fullWidth,
100 | }, {duration: 100, queue: false, easing: 'easeOutQuad', complete:
101 | function() {
102 | $this.css('border', 'none');
103 | $this.velocity({ height: 0, padding: 0,
104 | }, {duration: 200, queue: false, easing: 'easeOutQuad', complete:
105 | function() { $this.remove(); }
106 | });
107 | }
108 | });
109 | }
110 | else {
111 | $this.velocity({ translateX: 0,
112 | }, {duration: 100, queue: false, easing: 'easeOutQuad'});
113 | }
114 | swipeLeft = false;
115 | swipeRight = false;
116 | }
117 | });
118 |
119 | });
120 |
121 |
122 | // time = 0
123 | // // Vertical Staggered list
124 | // $('ul.staggered-list.vertical li').velocity(
125 | // { translateY: "100px"},
126 | // { duration: 0 });
127 |
128 | // $('ul.staggered-list.vertical li').each(function() {
129 | // $(this).velocity(
130 | // { opacity: "1", translateY: "0"},
131 | // { duration: 800, delay: time, easing: [60, 25] });
132 | // time += 120;
133 | // });
134 |
135 | // // Fade in and Scale
136 | // $('.fade-in.scale').velocity(
137 | // { scaleX: .4, scaleY: .4, translateX: -600},
138 | // { duration: 0});
139 | // $('.fade-in').each(function() {
140 | // $(this).velocity(
141 | // { opacity: "1", scaleX: 1, scaleY: 1, translateX: 0},
142 | // { duration: 800, easing: [60, 10] });
143 | // });
144 | });
145 | }( jQuery ));
146 |
--------------------------------------------------------------------------------
/static/materialize/package.js:
--------------------------------------------------------------------------------
1 | // package metadata file for Meteor.js
2 |
3 | Package.describe({
4 | name: 'materialize:materialize', // http://atmospherejs.com/materialize/materialize
5 | summary: 'Materialize (official): A modern responsive front-end framework based on Material Design',
6 | version: '0.96.1',
7 | git: 'https://github.com/Dogfalo/materialize.git'
8 | });
9 |
10 | Package.onUse(function (api) {
11 | api.versionsFrom('METEOR@1.0');
12 |
13 | api.use('jquery', 'client');
14 |
15 | api.export('Materialize', 'client');
16 |
17 | api.addFiles([
18 | 'font/material-design-icons/Material-Design-Icons.eot',
19 | 'font/material-design-icons/Material-Design-Icons.svg',
20 | 'font/material-design-icons/Material-Design-Icons.ttf',
21 | 'font/material-design-icons/Material-Design-Icons.woff',
22 | 'font/material-design-icons/Material-Design-Icons.woff2',
23 | 'font/roboto/Roboto-Bold.ttf',
24 | 'font/roboto/Roboto-Bold.woff',
25 | 'font/roboto/Roboto-Bold.woff2',
26 | 'font/roboto/Roboto-Light.ttf',
27 | 'font/roboto/Roboto-Light.woff',
28 | 'font/roboto/Roboto-Light.woff2',
29 | 'font/roboto/Roboto-Medium.ttf',
30 | 'font/roboto/Roboto-Medium.woff',
31 | 'font/roboto/Roboto-Medium.woff2',
32 | 'font/roboto/Roboto-Regular.ttf',
33 | 'font/roboto/Roboto-Regular.woff',
34 | 'font/roboto/Roboto-Regular.woff2',
35 | 'font/roboto/Roboto-Thin.ttf',
36 | 'font/roboto/Roboto-Thin.woff',
37 | 'font/roboto/Roboto-Thin.woff2',
38 | 'bin/materialize.css',
39 | 'bin/materialize.js',
40 | ], 'client');
41 | });
42 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_buttons.scss:
--------------------------------------------------------------------------------
1 | // shared styles
2 | .btn, .btn-flat {
3 | border: none;
4 | border-radius: 2px;
5 | display: inline-block;
6 | height: $button-height;
7 | line-height: $button-line-height;
8 | // margin-bottom: 15px;
9 | outline: 0;
10 | padding: 0 2rem;
11 | text-transform: uppercase;
12 | vertical-align: middle;
13 | // Gets rid of tap active state
14 | -webkit-tap-highlight-color: transparent;
15 | }
16 | // Disabled shared style
17 | .btn.disabled, .btn-floating.disabled, .btn-large.disabled, .btn:disabled, .btn-large:disabled, .btn-floating:disabled {
18 | background-color: $button-bg-color-disabled;
19 | box-shadow: none;
20 | color: $button-color-disabled;
21 | cursor: default;
22 | * {
23 | pointer-events: none;
24 | }
25 |
26 | &:hover {
27 | background-color: $button-bg-color-disabled;
28 | color: $button-color-disabled;
29 | }
30 | }
31 | // Shared icon styles
32 | .btn, .btn-floating, .btn-large, .btn-flat {
33 | i {
34 | font-size: $button-font-size-shared;
35 | line-height: inherit;
36 | }
37 | }
38 |
39 | // Raised Button
40 | .btn {
41 | text-decoration:none;
42 | color: $button-color-raised;
43 | background-color: $button-color;
44 | text-align: center;
45 | letter-spacing: .5px;
46 | @extend .z-depth-1;
47 | @include transition(.2s ease-out);
48 | cursor: pointer;
49 |
50 | &:hover {
51 | background-color: lighten($button-color, 5%);
52 | @extend .z-depth-1-half;
53 | }
54 | }
55 |
56 | // Floating button
57 | .btn-floating {
58 | display: inline-block;
59 | color: $button-color-raised;
60 | position: relative;
61 | overflow: hidden;
62 | z-index: 1;
63 | width: $button-floating-size;
64 | height: $button-floating-size;
65 | line-height: $button-floating-size;
66 | padding: 0;
67 | background-color: $button-color;
68 | border-radius: 50%;
69 | @extend .z-depth-1;
70 | transition: .3s;
71 | cursor: pointer;
72 | vertical-align: middle;
73 |
74 | i {
75 | width: inherit;
76 | display: inline-block;
77 | text-align: center;
78 | color: $button-color-raised;
79 | font-size: 1.6rem;
80 | line-height: $button-floating-size;
81 | }
82 |
83 | &:hover {
84 | @extend .z-depth-1-half;
85 | }
86 | &:before {
87 | border-radius: 0;
88 | }
89 | &.btn-large {
90 | width: $button-floating-size * 1.5;
91 | height: $button-floating-size * 1.5;
92 | i{
93 | line-height: $button-floating-size * 1.5;
94 | }
95 | }
96 |
97 | }
98 | // button fix
99 | button.btn-floating {
100 | border: none;
101 | }
102 |
103 | // Fixed Action Button
104 | .fixed-action-btn {
105 | position: fixed;
106 | right: 23px;
107 | bottom: 23px;
108 | padding-top: 15px;
109 | margin-bottom: 0;
110 | z-index: 998;
111 |
112 | ul {
113 | left: 0;
114 | right: 0;
115 | text-align: center;
116 | position: absolute;
117 | bottom: 64px;
118 |
119 | li {
120 | margin-bottom: 15px;
121 | }
122 |
123 | a.btn-floating {
124 | opacity: 0;
125 | }
126 | }
127 | }
128 |
129 | // Flat button
130 | .btn-flat {
131 | box-shadow: none;
132 | background-color: transparent;
133 | color: $button-color-flat;
134 | cursor: pointer;
135 |
136 | &.disabled {
137 | color: lighten(#999, 10%);
138 | cursor: default;
139 | }
140 | }
141 |
142 | // Large button
143 | .btn-large {
144 | @extend .btn;
145 | height: $button-height * 1.5;
146 | line-height: 56px;
147 |
148 | i {
149 | font-size: 1.6rem;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_cards.scss:
--------------------------------------------------------------------------------
1 |
2 |
3 | .card-panel {
4 | padding: $card-padding;
5 | margin: $element-top-margin 0 $element-bottom-margin 0;
6 | border-radius: 2px;
7 | @extend .z-depth-1;
8 | background-color: $card-bg-color;
9 | }
10 |
11 | .card {
12 | position: relative;
13 | overflow: hidden;
14 | margin: $element-top-margin 0 $element-bottom-margin 0;
15 | background-color: $card-bg-color;
16 | border-radius: 2px;
17 | @extend .z-depth-1;
18 |
19 |
20 | .card-title {
21 | color: #fff;
22 | font-size: 24px;
23 | font-weight: 300;
24 | &.activator {
25 | cursor: pointer;
26 | }
27 | }
28 |
29 | // Card Sizes
30 | &.small, &.medium, &.large {
31 | position: relative;
32 |
33 | .card-image {
34 | overflow: hidden;
35 | }
36 | .card-content {
37 | overflow: hidden;
38 | }
39 | .card-action {
40 | position: absolute;
41 | bottom: 0;
42 | left: 0;
43 | right: 0;
44 | }
45 | }
46 |
47 | &.small {
48 | height: 300px;
49 |
50 | .card-image {
51 | height: 150px;
52 | }
53 | .card-content {
54 | height: 150px;
55 | }
56 |
57 | }
58 |
59 | &.medium {
60 | height: 400px;
61 |
62 | .card-image {
63 | height: 250px;
64 | }
65 | .card-content {
66 | height: 150px;
67 | }
68 | }
69 |
70 | &.large {
71 | height: 500px;
72 |
73 | .card-image {
74 | height: 330px;
75 | }
76 | .card-content {
77 | height: 170px;
78 | }
79 | }
80 |
81 |
82 | .card-image {
83 | position: relative;
84 |
85 | // Image background for content
86 | img {
87 | border-radius: 2px 2px 0 0;
88 | position: relative;
89 | left: 0;
90 | right: 0;
91 | top: 0;
92 | bottom: 0;
93 | width: 100%;
94 | }
95 |
96 | .card-title {
97 | position: absolute;
98 | bottom: 0;
99 | left: 0;
100 | padding: $card-padding;
101 | }
102 |
103 | }
104 |
105 | .card-content {
106 | padding: $card-padding;
107 | border-radius: 0 0 2px 2px;
108 |
109 |
110 | p {
111 | margin: 0;
112 | color: inherit;
113 | }
114 | .card-title {
115 | line-height: 48px;
116 | }
117 | }
118 |
119 | .card-action {
120 | border-top: 1px solid rgba(160,160,160,.2);
121 | padding: $card-padding;
122 |
123 | a {
124 | color: color("orange", "accent-2");
125 | margin-right: $card-padding;
126 | @include transition(color .3s ease);
127 | text-transform: uppercase;
128 |
129 | &:hover { color: lighten(color("orange", "accent-2"), 20%); }
130 | }
131 | }
132 |
133 | .card-reveal {
134 | padding: $card-padding;
135 | position: absolute;
136 | background-color: #FFF;
137 | width: 100%;
138 | overflow-y: auto;
139 | top: 100%;
140 | height: 100%;
141 | z-index: 1;
142 | display: none;
143 |
144 | .card-title {
145 | cursor: pointer;
146 | display: block;
147 | }
148 |
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_collapsible.scss:
--------------------------------------------------------------------------------
1 | .collapsible {
2 | border-top: 1px solid $collapsible-border-color;
3 | border-right: 1px solid $collapsible-border-color;
4 | border-left: 1px solid $collapsible-border-color;
5 | margin: $element-top-margin 0 $element-bottom-margin 0;
6 | @extend .z-depth-1;
7 | }
8 |
9 | .collapsible-header {
10 | display: block;
11 | cursor: pointer;
12 | height: $collapsible-height;
13 | line-height: $collapsible-height;
14 | padding: 0 1rem;
15 | background-color: $collapsible-header-color;
16 | border-bottom: 1px solid $collapsible-border-color;
17 |
18 | i {
19 | width: 2rem;
20 | font-size: 1.6rem;
21 | line-height: $collapsible-height;
22 | display: block;
23 | float: left;
24 | text-align: center;
25 | margin-right: 1rem;
26 | }
27 | }
28 |
29 | .collapsible-body {
30 | overflow: hidden;
31 | display: none;
32 | border-bottom: 1px solid $collapsible-border-color;
33 | @include box-sizing(border-box);
34 |
35 | p {
36 | margin: 0;
37 | padding: 2rem;
38 | }
39 | }
40 |
41 | // sideNav collapsible styling
42 | .side-nav {
43 |
44 | .collapsible {
45 | border: none;
46 | box-shadow: none;
47 |
48 | li { padding: 0; }
49 | }
50 |
51 | .collapsible-header {
52 | background-color: transparent;
53 | border: none;
54 | line-height: inherit;
55 | height: inherit;
56 | margin: 0 1rem;
57 |
58 | i { line-height: inherit; }
59 | }
60 |
61 | .collapsible-body {
62 | border: 0;
63 | background-color: #FFF;
64 |
65 | li a { margin: 0 1rem 0 2rem; }
66 | }
67 |
68 | }
69 |
70 | // Popout Collapsible
71 |
72 | .collapsible.popout {
73 | border: none;
74 | box-shadow: none;
75 | > li {
76 | &:hover {
77 | will-change: margin, transform;
78 | }
79 | box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
80 | transform: scaleX(.92) translate3d(0,0,0);
81 | transition: margin .35s cubic-bezier(0.250, 0.460, 0.450, 0.940), transform .35s cubic-bezier(0.250, 0.460, 0.450, 0.940);
82 | }
83 | > li.active {
84 | box-shadow: 0 5px 11px 0 rgba(0, 0, 0, 0.18), 0 4px 15px 0 rgba(0, 0, 0, 0.15);
85 | margin: 16px 0;
86 | transform: scaleX(1) translate3d(0,0,0);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_dropdown.scss:
--------------------------------------------------------------------------------
1 | .dropdown-content {
2 | @extend .z-depth-1;
3 | background-color: #FFFFFF;
4 | margin: 0;
5 | display: none;
6 | min-width: 100px;
7 | max-height: 650px;
8 | overflow-y: auto;
9 | opacity: 0;
10 | position: absolute;
11 | white-space: nowrap; // Force one line
12 | z-index: 1;
13 | will-change: width, height;
14 |
15 | li {
16 | clear: both;
17 | color: $off-black;
18 | cursor: pointer;
19 | line-height: 1.5rem;
20 | width: 100%;
21 | text-align: left;
22 | text-transform: none;
23 |
24 | &:hover, &.active {
25 | background-color: #eee;
26 | }
27 |
28 | & > a, & > span {
29 | font-size: 1.2rem;
30 | color: $dropdown-color;
31 | display: block;
32 | padding: 1rem 1rem;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_grid.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | padding: 0 $gutter-width;
3 | margin: 0 auto;
4 | max-width: 1280px;
5 | width: 90%;
6 | }
7 | @media #{$medium-and-up} {
8 | .container {
9 | width: 85%;
10 | }
11 | }
12 | @media #{$large-and-up} {
13 | .container {
14 | width: 70%;
15 | }
16 | }
17 | .container .row {
18 | margin-left: (-1 * $gutter-width / 2);
19 | margin-right: (-1 * $gutter-width / 2);
20 | }
21 |
22 | .section {
23 | padding-top: 1rem;
24 | padding-bottom: 1rem;
25 |
26 | &.no-pad {
27 | padding: 0;
28 | }
29 | &.no-pad-bot {
30 | padding-bottom: 0;
31 | }
32 | &.no-pad-top {
33 | padding-top: 0;
34 | }
35 | }
36 |
37 |
38 | .row {
39 | margin-left: auto;
40 | margin-right: auto;
41 | margin-bottom: 20px;
42 |
43 | // Clear floating children
44 | &:after {
45 | content: "";
46 | display: table;
47 | clear: both;
48 | }
49 |
50 | .col {
51 | float: left;
52 | @include box-sizing(border-box);
53 | padding: 0 $gutter-width / 2;
54 |
55 | $i: 1;
56 | @while $i <= $num-cols {
57 | $perc: unquote((100 / ($num-cols / $i)) + "%");
58 | &.s#{$i} {
59 | width: $perc;
60 | margin-left: 0;
61 | }
62 | $i: $i + 1;
63 | }
64 | $i: 1;
65 | @while $i <= $num-cols {
66 | $perc: unquote((100 / ($num-cols / $i)) + "%");
67 | &.offset-s#{$i} {
68 | margin-left: $perc;
69 | }
70 | $i: $i + 1;
71 | }
72 |
73 | @media #{$medium-and-up} {
74 |
75 | $i: 1;
76 | @while $i <= $num-cols {
77 | $perc: unquote((100 / ($num-cols / $i)) + "%");
78 | &.m#{$i} {
79 | width: $perc;
80 | margin-left: 0;
81 | }
82 | $i: $i + 1;
83 | }
84 | $i: 1;
85 | @while $i <= $num-cols {
86 | $perc: unquote((100 / ($num-cols / $i)) + "%");
87 | &.offset-m#{$i} {
88 | margin-left: $perc;
89 | }
90 | $i: $i + 1;
91 | }
92 |
93 | }
94 |
95 | @media #{$large-and-up} {
96 |
97 | $i: 1;
98 | @while $i <= $num-cols {
99 | $perc: unquote((100 / ($num-cols / $i)) + "%");
100 | &.l#{$i} {
101 | width: $perc;
102 | margin-left: 0;
103 | }
104 | $i: $i + 1;
105 | }
106 | $i: 1;
107 | @while $i <= $num-cols {
108 | $perc: unquote((100 / ($num-cols / $i)) + "%");
109 | &.offset-l#{$i} {
110 | margin-left: $perc;
111 | }
112 | $i: $i + 1;
113 | }
114 |
115 | }
116 |
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_materialbox.scss:
--------------------------------------------------------------------------------
1 | .materialboxed {
2 | cursor: zoom-in;
3 | position: relative;
4 | @include transition(opacity .4s);
5 |
6 | &:hover {
7 | &:not(.active) {
8 | opacity: .8;
9 | }
10 | will-change: left, top, width, height;
11 | }
12 | }
13 |
14 | .materialboxed.active {
15 | cursor: zoom-out;
16 | }
17 |
18 | #materialbox-overlay {
19 | position:fixed;
20 | top:0;
21 | left:0;
22 | right: 0;
23 | bottom: 0;
24 | background-color: #292929;
25 | z-index: 999;
26 |
27 | will-change: opacity;
28 | }
29 | .materialbox-caption {
30 | position: fixed;
31 | display: none;
32 | color: #fff;
33 | line-height: 50px;
34 | bottom: 0;
35 | width: 100%;
36 | text-align: center;
37 | padding: 0% 15%;
38 | height: 50px;
39 | z-index: 1000;
40 | -webkit-font-smoothing: antialiased;
41 | }
--------------------------------------------------------------------------------
/static/materialize/sass/components/_mixins.scss:
--------------------------------------------------------------------------------
1 | @mixin box-shadow-2($args1, $args2) {
2 | -webkit-box-shadow: $args1, $args2;
3 | -moz-box-shadow: $args1, $args2;
4 | box-shadow: $args1, $args2;
5 | }
--------------------------------------------------------------------------------
/static/materialize/sass/components/_modal.scss:
--------------------------------------------------------------------------------
1 | .modal {
2 | @extend .z-depth-4;
3 |
4 | display: none;
5 | position: fixed;
6 | left: 0;
7 | right: 0;
8 | background-color: #fafafa;
9 | padding: 0;
10 | max-height: 70%;
11 | width: 55%;
12 | margin: auto;
13 | overflow-y: auto;
14 | z-index: 1000;
15 |
16 | border-radius: 2px;
17 | @include transform(translate(0));
18 | will-change: top, opacity;
19 |
20 | @media #{$medium-and-down} {
21 | width: 80%;
22 | }
23 |
24 | h1,h2,h3,h4 {
25 | margin-top: 0;
26 | }
27 |
28 | .modal-content {
29 | padding: 24px;
30 | }
31 |
32 | .modal-footer {
33 | border-radius: 0 0 2px 2px;
34 | background-color: #fafafa;
35 | padding: 4px 6px;
36 | height: 56px;
37 | width: 100%;
38 |
39 | .btn, .btn-flat {
40 | float: right;
41 | margin: 6px 0;
42 | }
43 | }
44 | }
45 | #lean-overlay {
46 | position: fixed;
47 | z-index:999;
48 | top: 0;
49 | left: 0;
50 | bottom: 0;
51 | right: 0;
52 | height: 115%;
53 | width: 100%;
54 | background: #000;
55 | display: none;
56 |
57 | will-change: opacity;
58 | }
59 |
60 | // Modal with fixed action footer
61 | .modal.modal-fixed-footer {
62 | padding: 0;
63 | height: 70%;
64 |
65 | .modal-content {
66 | position: fixed;
67 | max-height: 100%;
68 | padding-bottom: 64px;
69 | width: 100%;
70 | overflow-y: auto;
71 | }
72 |
73 | .modal-footer {
74 | border-top: 1px solid rgba(0,0,0,.1);
75 | position: fixed;
76 | bottom: 0;
77 | }
78 | }
79 |
80 | // Modal Bottom Sheet Style
81 | .modal.bottom-sheet {
82 | top: auto;
83 | bottom: -100%;
84 | margin: 0;
85 | width: 100%;
86 | max-height: 45%;
87 | border-radius: 0;
88 | will-change: bottom, opacity;
89 | }
--------------------------------------------------------------------------------
/static/materialize/sass/components/_navbar.scss:
--------------------------------------------------------------------------------
1 | nav {
2 | color: #fff;
3 | @extend .z-depth-1;
4 | background-color: $primary-color;
5 | width: 100%;
6 | height: $navbar-height-mobile;
7 | line-height: $navbar-height-mobile;
8 |
9 | a { color: #fff; }
10 |
11 | .nav-wrapper {
12 | position: relative;
13 | height: 100%;
14 |
15 | i {
16 | display: block;
17 | font-size: 2rem;
18 | }
19 | }
20 |
21 | @media #{$large-and-up} {
22 | a.button-collapse { display: none; }
23 | }
24 |
25 |
26 | // Collapse button
27 | .button-collapse {
28 | float: left;
29 | position: relative;
30 | z-index: 1;
31 | height: $navbar-height-mobile;
32 |
33 | i {
34 | font-size: 2.7rem;
35 | height: $navbar-height-mobile;
36 | line-height: $navbar-height-mobile;
37 | }
38 | }
39 |
40 |
41 | // Logo
42 | .brand-logo {
43 | position: absolute;
44 | color: #fff;
45 | display: inline-block;
46 | font-size: 2.1rem;
47 | padding: 0;
48 |
49 | &.center {
50 | left: 50%;
51 | @include transform(translateX(-50%));
52 | }
53 |
54 | @media #{$medium-and-down} {
55 | left: 50%;
56 | @include transform(translateX(-50%));
57 | }
58 |
59 | &.right {
60 | right: 0.5rem;
61 | padding: 0;
62 | }
63 | }
64 |
65 |
66 | // Navbar Links
67 | ul {
68 | margin: 0;
69 |
70 | li {
71 | @include transition(background-color .3s);
72 | float: left;
73 | padding: 0;
74 |
75 | &:hover, &.active {
76 | background-color: rgba(0,0,0,.1);
77 | }
78 | }
79 | a {
80 | font-size: 1rem;
81 | color: #fff;
82 | display: block;
83 | padding: 0 15px;
84 | }
85 |
86 | &.left {
87 | float: left;
88 | }
89 | }
90 |
91 | // Navbar Search Form
92 | .input-field {
93 | margin: 0;
94 |
95 | input {
96 | height: 100%;
97 | font-size: 1.2rem;
98 | border: none;
99 | padding-left: 2rem;
100 |
101 | &:focus, &[type=text]:valid, &[type=password]:valid,
102 | &[type=email]:valid, &[type=url]:valid, &[type=date]:valid {
103 | border: none;
104 | box-shadow: none;
105 | }
106 | }
107 | label {
108 | top: 0;
109 | left: 0;
110 |
111 | i {
112 | color: rgba(255,255,255,.7);
113 | @include transition(color .3s);
114 | }
115 | &.active i { color: #fff; }
116 | &.active {
117 | @include transform(translateY(0));
118 | }
119 | }
120 |
121 | }
122 |
123 | }
124 |
125 | // Fixed Navbar
126 | .navbar-fixed {
127 | position: relative;
128 | height: $navbar-height-mobile;
129 | z-index: 998;
130 |
131 | nav {
132 | position: fixed;
133 | }
134 | }
135 | @media #{$medium-and-up} {
136 | nav, nav .nav-wrapper i, nav a.button-collapse, nav a.button-collapse i {
137 | height: $navbar-height;
138 | line-height: $navbar-height;
139 | }
140 | .navbar-fixed {
141 | height: $navbar-height;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_normalize.scss:
--------------------------------------------------------------------------------
1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */
2 |
3 | /**
4 | * 1. Set default font family to sans-serif.
5 | * 2. Prevent iOS text size adjust after orientation change, without disabling
6 | * user zoom.
7 | */
8 |
9 | html {
10 | font-family: sans-serif; /* 1 */
11 | -ms-text-size-adjust: 100%; /* 2 */
12 | -webkit-text-size-adjust: 100%; /* 2 */
13 | }
14 |
15 | /**
16 | * Remove default margin.
17 | */
18 |
19 | body {
20 | margin: 0;
21 | }
22 |
23 | /* HTML5 display definitions
24 | ========================================================================== */
25 |
26 | /**
27 | * Correct `block` display not defined for any HTML5 element in IE 8/9.
28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11
29 | * and Firefox.
30 | * Correct `block` display not defined for `main` in IE 11.
31 | */
32 |
33 | article,
34 | aside,
35 | details,
36 | figcaption,
37 | figure,
38 | footer,
39 | header,
40 | hgroup,
41 | main,
42 | menu,
43 | nav,
44 | section,
45 | summary {
46 | display: block;
47 | }
48 |
49 | /**
50 | * 1. Correct `inline-block` display not defined in IE 8/9.
51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
52 | */
53 |
54 | audio,
55 | canvas,
56 | progress,
57 | video {
58 | display: inline-block; /* 1 */
59 | vertical-align: baseline; /* 2 */
60 | }
61 |
62 | /**
63 | * Prevent modern browsers from displaying `audio` without controls.
64 | * Remove excess height in iOS 5 devices.
65 | */
66 |
67 | audio:not([controls]) {
68 | display: none;
69 | height: 0;
70 | }
71 |
72 | /**
73 | * Address `[hidden]` styling not present in IE 8/9/10.
74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
75 | */
76 |
77 | [hidden],
78 | template {
79 | display: none;
80 | }
81 |
82 | /* Links
83 | ========================================================================== */
84 |
85 | /**
86 | * Remove the gray background color from active links in IE 10.
87 | */
88 |
89 | a {
90 | background-color: transparent;
91 | }
92 |
93 | /**
94 | * Improve readability when focused and also mouse hovered in all browsers.
95 | */
96 |
97 | a:active,
98 | a:hover {
99 | outline: 0;
100 | }
101 |
102 | /* Text-level semantics
103 | ========================================================================== */
104 |
105 | /**
106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
107 | */
108 |
109 | abbr[title] {
110 | border-bottom: 1px dotted;
111 | }
112 |
113 | /**
114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
115 | */
116 |
117 | b,
118 | strong {
119 | font-weight: bold;
120 | }
121 |
122 | /**
123 | * Address styling not present in Safari and Chrome.
124 | */
125 |
126 | dfn {
127 | font-style: italic;
128 | }
129 |
130 | /**
131 | * Address variable `h1` font-size and margin within `section` and `article`
132 | * contexts in Firefox 4+, Safari, and Chrome.
133 | */
134 |
135 | h1 {
136 | font-size: 2em;
137 | margin: 0.67em 0;
138 | }
139 |
140 | /**
141 | * Address styling not present in IE 8/9.
142 | */
143 |
144 | mark {
145 | background: #ff0;
146 | color: #000;
147 | }
148 |
149 | /**
150 | * Address inconsistent and variable font size in all browsers.
151 | */
152 |
153 | small {
154 | font-size: 80%;
155 | }
156 |
157 | /**
158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers.
159 | */
160 |
161 | sub,
162 | sup {
163 | font-size: 75%;
164 | line-height: 0;
165 | position: relative;
166 | vertical-align: baseline;
167 | }
168 |
169 | sup {
170 | top: -0.5em;
171 | }
172 |
173 | sub {
174 | bottom: -0.25em;
175 | }
176 |
177 | /* Embedded content
178 | ========================================================================== */
179 |
180 | /**
181 | * Remove border when inside `a` element in IE 8/9/10.
182 | */
183 |
184 | img {
185 | border: 0;
186 | }
187 |
188 | /**
189 | * Correct overflow not hidden in IE 9/10/11.
190 | */
191 |
192 | svg:not(:root) {
193 | overflow: hidden;
194 | }
195 |
196 | /* Grouping content
197 | ========================================================================== */
198 |
199 | /**
200 | * Address margin not present in IE 8/9 and Safari.
201 | */
202 |
203 | figure {
204 | margin: 1em 40px;
205 | }
206 |
207 | /**
208 | * Address differences between Firefox and other browsers.
209 | */
210 |
211 | hr {
212 | -moz-box-sizing: content-box;
213 | box-sizing: content-box;
214 | height: 0;
215 | }
216 |
217 | /**
218 | * Contain overflow in all browsers.
219 | */
220 |
221 | pre {
222 | overflow: auto;
223 | }
224 |
225 | /**
226 | * Address odd `em`-unit font size rendering in all browsers.
227 | */
228 |
229 | code,
230 | kbd,
231 | pre,
232 | samp {
233 | font-family: monospace, monospace;
234 | font-size: 1em;
235 | }
236 |
237 | /* Forms
238 | ========================================================================== */
239 |
240 | /**
241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited
242 | * styling of `select`, unless a `border` property is set.
243 | */
244 |
245 | /**
246 | * 1. Correct color not being inherited.
247 | * Known issue: affects color of disabled elements.
248 | * 2. Correct font properties not being inherited.
249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
250 | */
251 |
252 | button,
253 | input,
254 | optgroup,
255 | select,
256 | textarea {
257 | color: inherit; /* 1 */
258 | font: inherit; /* 2 */
259 | margin: 0; /* 3 */
260 | }
261 |
262 | /**
263 | * Address `overflow` set to `hidden` in IE 8/9/10/11.
264 | */
265 |
266 | button {
267 | overflow: visible;
268 | }
269 |
270 | /**
271 | * Address inconsistent `text-transform` inheritance for `button` and `select`.
272 | * All other form control elements do not inherit `text-transform` values.
273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
274 | * Correct `select` style inheritance in Firefox.
275 | */
276 |
277 | button,
278 | select {
279 | text-transform: none;
280 | }
281 |
282 | /**
283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
284 | * and `video` controls.
285 | * 2. Correct inability to style clickable `input` types in iOS.
286 | * 3. Improve usability and consistency of cursor style between image-type
287 | * `input` and others.
288 | */
289 |
290 | /* 1 */ html input[type="button"],
291 | button,
292 | input[type="reset"],
293 | input[type="submit"] {
294 | -webkit-appearance: button; /* 2 */
295 | cursor: pointer; /* 3 */
296 | }
297 |
298 | /**
299 | * Re-set default cursor for disabled elements.
300 | */
301 |
302 | button[disabled],
303 | html input[disabled] {
304 | cursor: default;
305 | }
306 |
307 | /**
308 | * Remove inner padding and border in Firefox 4+.
309 | */
310 |
311 | button::-moz-focus-inner,
312 | input::-moz-focus-inner {
313 | border: 0;
314 | padding: 0;
315 | }
316 |
317 | /**
318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in
319 | * the UA stylesheet.
320 | */
321 |
322 | input {
323 | line-height: normal;
324 | }
325 |
326 | /**
327 | * It's recommended that you don't attempt to style these elements.
328 | * Firefox's implementation doesn't respect box-sizing, padding, or width.
329 | *
330 | * 1. Address box sizing set to `content-box` in IE 8/9/10.
331 | * 2. Remove excess padding in IE 8/9/10.
332 | */
333 |
334 | input[type="checkbox"],
335 | input[type="radio"] {
336 | box-sizing: border-box; /* 1 */
337 | padding: 0; /* 2 */
338 | }
339 |
340 | /**
341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain
342 | * `font-size` values of the `input`, it causes the cursor style of the
343 | * decrement button to change from `default` to `text`.
344 | */
345 |
346 | input[type="number"]::-webkit-inner-spin-button,
347 | input[type="number"]::-webkit-outer-spin-button {
348 | height: auto;
349 | }
350 |
351 | /**
352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
354 | * (include `-moz` to future-proof).
355 | */
356 |
357 | input[type="search"] {
358 | -webkit-appearance: textfield; /* 1 */
359 | -moz-box-sizing: content-box;
360 | -webkit-box-sizing: content-box; /* 2 */
361 | box-sizing: content-box;
362 | }
363 |
364 | /**
365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X.
366 | * Safari (but not Chrome) clips the cancel button when the search input has
367 | * padding (and `textfield` appearance).
368 | */
369 |
370 | input[type="search"]::-webkit-search-cancel-button,
371 | input[type="search"]::-webkit-search-decoration {
372 | -webkit-appearance: none;
373 | }
374 |
375 | /**
376 | * Define consistent border, margin, and padding.
377 | */
378 |
379 | fieldset {
380 | border: 1px solid #c0c0c0;
381 | margin: 0 2px;
382 | padding: 0.35em 0.625em 0.75em;
383 | }
384 |
385 | /**
386 | * 1. Correct `color` not being inherited in IE 8/9/10/11.
387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets.
388 | */
389 |
390 | legend {
391 | border: 0; /* 1 */
392 | padding: 0; /* 2 */
393 | }
394 |
395 | /**
396 | * Remove default vertical scrollbar in IE 8/9/10/11.
397 | */
398 |
399 | textarea {
400 | overflow: auto;
401 | }
402 |
403 | /**
404 | * Don't inherit the `font-weight` (applied by a rule above).
405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
406 | */
407 |
408 | optgroup {
409 | font-weight: bold;
410 | }
411 |
412 | /* Tables
413 | ========================================================================== */
414 |
415 | /**
416 | * Remove most spacing between table cells.
417 | */
418 |
419 | table {
420 | border-collapse: collapse;
421 | border-spacing: 0;
422 | }
423 |
424 | td,
425 | th {
426 | padding: 0;
427 | }
428 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_roboto.scss:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: "Roboto";
3 | src: url("#{$roboto-font-path}Roboto-Thin.woff2") format("woff2"),
4 | url("#{$roboto-font-path}Roboto-Thin.woff") format("woff"),
5 | url("#{$roboto-font-path}Roboto-Thin.ttf") format("truetype");
6 | font-weight: 200;
7 | }
8 | @font-face {
9 | font-family: "Roboto";
10 | src: url("#{$roboto-font-path}Roboto-Light.woff2") format("woff2"),
11 | url("#{$roboto-font-path}Roboto-Light.woff") format("woff"),
12 | url("#{$roboto-font-path}Roboto-Light.ttf") format("truetype");
13 | font-weight: 300;
14 | }
15 |
16 | @font-face {
17 | font-family: "Roboto";
18 | src: url("#{$roboto-font-path}Roboto-Regular.woff2") format("woff2"),
19 | url("#{$roboto-font-path}Roboto-Regular.woff") format("woff"),
20 | url("#{$roboto-font-path}Roboto-Regular.ttf") format("truetype");
21 | font-weight: 400;
22 | }
23 |
24 | @font-face {
25 | font-family: "Roboto";
26 | src: url("#{$roboto-font-path}Roboto-Medium.woff2") format("woff2"),
27 | url("#{$roboto-font-path}Roboto-Medium.woff") format("woff"),
28 | url("#{$roboto-font-path}Roboto-Medium.ttf") format("truetype");
29 | font-weight: 500;
30 | }
31 |
32 | @font-face {
33 | font-family: "Roboto";
34 | src: url("#{$roboto-font-path}Roboto-Bold.woff2") format("woff2"),
35 | url("#{$roboto-font-path}Roboto-Bold.woff") format("woff"),
36 | url("#{$roboto-font-path}Roboto-Bold.ttf") format("truetype");
37 | font-weight: 700;
38 | }
--------------------------------------------------------------------------------
/static/materialize/sass/components/_sideNav.scss:
--------------------------------------------------------------------------------
1 | .side-nav {
2 | position: fixed;
3 | width: 240px;
4 | left: -105%;
5 | top: 0;
6 | margin: 0;
7 | height: 100%;
8 | height: calc(100% + 60px);
9 | height: -moz-calc(100%); //Temporary Firefox Fix
10 | padding-bottom: 60px;
11 | background-color: #FFF;
12 | z-index: 999;
13 | overflow-y: auto;
14 |
15 | @extend .z-depth-1;
16 | will-change: left;
17 |
18 | // Right Align
19 | &.right-aligned {
20 | will-change: right;
21 | right: -105%;
22 | left: auto;
23 | }
24 |
25 | .collapsible{
26 | margin: 0;
27 | }
28 |
29 |
30 | li {
31 | float: none;
32 | padding: 0 15px;
33 | &:hover, &.active { background-color: #ddd; }
34 | }
35 | a {
36 | color: #444;
37 | display: block;
38 | font-size: 1rem;
39 | height: 64px;
40 | line-height: 64px;
41 | padding: 0 15px;
42 | }
43 | }
44 |
45 |
46 | // Touch interaction
47 | .drag-target {
48 | height: 100%;
49 | width: 10px;
50 | position: fixed;
51 | top: 0;
52 | z-index: 998;
53 | }
54 |
55 |
56 | // Hidden side-nav for all sizes
57 | .side-nav.fixed {
58 | a {
59 | display: block;
60 | padding: 0 15px;
61 | color: #444;
62 | }
63 | }
64 |
65 |
66 | // Fixed side-nav shown
67 | .side-nav.fixed {
68 | left: 0;
69 | position: fixed;
70 |
71 | // Right Align
72 | &.right-aligned {
73 | right: 0;
74 | left: auto;
75 | }
76 | }
77 |
78 | // Fixed sideNav hide on smaller
79 | @media #{$medium-and-down} {
80 | .side-nav.fixed {
81 | left: -105%;
82 |
83 | &.right-aligned {
84 | right: -105%;
85 | left: auto;
86 | }
87 | }
88 | }
89 |
90 |
91 | .side-nav .collapsible-body li.active,
92 | .side-nav.fixed .collapsible-body li.active {
93 | background-color: $primary-color;
94 | a {
95 | color: #fff;
96 | }
97 | }
98 |
99 |
100 | #sidenav-overlay {
101 | position: fixed;
102 | top: 0;
103 | left: 0;
104 | right: 0;
105 |
106 | height: 120vh;
107 | background-color: rgba(0,0,0,.5);
108 | z-index: 997;
109 |
110 | will-change: opacity;
111 | }
112 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_slider.scss:
--------------------------------------------------------------------------------
1 | .slider {
2 | position: relative;
3 | height: 440px;
4 | width: 100%;
5 |
6 | // Fullscreen slider
7 | &.fullscreen {
8 | height: 100%;
9 | width: 100%;
10 | position: absolute;
11 | top: 0;
12 | left: 0;
13 | right: 0;
14 | bottom: 0;
15 |
16 | ul.slides {
17 | height: 100%;
18 | }
19 |
20 | ul.indicators {
21 | z-index: 2;
22 | bottom: 30px;
23 | }
24 | }
25 |
26 | .slides {
27 | background-color: color('grey', 'base');
28 | margin: 0;
29 | height: 400px;
30 |
31 | li {
32 | opacity: 0;
33 | position: absolute;
34 | top: 0;
35 | left: 0;
36 | z-index: 1;
37 | width: 100%;
38 | height: inherit;
39 | overflow: hidden;
40 |
41 | img {
42 | height: 100%;
43 | width: 100%;
44 | background-size: cover;
45 | background-position: center;
46 | }
47 |
48 | .caption {
49 | color: #fff;
50 | position: absolute;
51 | top: 15%;
52 | left: 15%;
53 | width: 70%;
54 | opacity: 0;
55 |
56 | p { color: color('grey', 'lighten-2'); }
57 | }
58 |
59 | &.active {
60 | z-index: 2;
61 | }
62 | }
63 | }
64 |
65 |
66 | .indicators {
67 | position: absolute;
68 | text-align: center;
69 | left: 0;
70 | right: 0;
71 | bottom: 0;
72 | margin: 0;
73 |
74 | .indicator-item {
75 | display: inline-block;
76 | position: relative;
77 | cursor: pointer;
78 | height: 16px;
79 | width: 16px;
80 | margin: 0 12px;
81 | background-color: color('grey', 'lighten-2');
82 |
83 | @include transition(background-color .3s);
84 | border-radius: 50%;
85 |
86 | &.active {
87 | background-color: color('green', 'base');
88 | }
89 | }
90 | }
91 |
92 | }
--------------------------------------------------------------------------------
/static/materialize/sass/components/_table_of_contents.scss:
--------------------------------------------------------------------------------
1 | /***************
2 | Nav List
3 | ***************/
4 | .table-of-contents {
5 | &.fixed {
6 | position: fixed;
7 | }
8 |
9 | li {
10 | padding: 2px 0;
11 | }
12 | a {
13 | display: inline-block;
14 | font-weight: 300;
15 | color: #757575;
16 | padding-left: 20px;
17 | height: 1.5rem;
18 | line-height: 1.5rem;
19 | letter-spacing: .4;
20 | display: inline-block;
21 |
22 | &:hover {
23 | color: lighten(#757575, 20%);
24 | padding-left: 19px;
25 | border-left: 1px solid lighten(color("materialize-red", "base"),10%);
26 | }
27 | &.active {
28 | font-weight: 500;
29 | padding-left: 18px;
30 | border-left: 2px solid lighten(color("materialize-red", "base"),10%);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_tabs.scss:
--------------------------------------------------------------------------------
1 | .tabs {
2 | position: relative;
3 | height: 48px;
4 | background-color: $tabs-bg-color;
5 | margin: 0 auto;
6 | width: 100%;
7 | white-space: nowrap;
8 |
9 | .tab {
10 | display: block;
11 | float: left;
12 | text-align: center;
13 | line-height: 48px;
14 | height: 48px;
15 | padding: 0 20px;
16 | margin: 0;
17 | text-transform: uppercase;
18 | letter-spacing: .8px;
19 | width: 15%;
20 |
21 | a {
22 | color: $tabs-text-color;
23 | display: block;
24 | width: 100%;
25 | height: 100%;
26 | @include transition( color .28s ease);
27 | &:hover {
28 | color: lighten($tabs-text-color, 20%);
29 | }
30 | }
31 | }
32 | .indicator {
33 | position: absolute;
34 | bottom: 0;
35 | height: 2px;
36 | background-color: $tabs-underline-color;
37 | will-change: left, right;
38 | }
39 | }
40 |
41 | .tabs .tab { padding: 0; }
42 |
43 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_toast.scss:
--------------------------------------------------------------------------------
1 | #toast-container {
2 | display:block;
3 | position: fixed;
4 | z-index: 1001;
5 |
6 | @media #{$small-and-down} {
7 | min-width: 100%;
8 | bottom: 0%;
9 | }
10 | @media #{$medium-only} {
11 | min-width: 30%;
12 | left: 5%;
13 | bottom: 7%;
14 | }
15 | @media #{$large-and-up} {
16 | min-width: 8%;
17 | top: 10%;
18 | right: 7%;
19 | }
20 | }
21 |
22 | .toast {
23 | @extend .z-depth-1;
24 | border-radius: 2px;
25 | top: 0;
26 | width: auto;
27 | clear: both;
28 | margin-top: 10px;
29 | position: relative;
30 | max-width:100%;
31 | height: $toast-height;
32 | line-height: $toast-height;
33 | background-color: $toast-color;
34 | padding: 0 25px;
35 | font-size: 1.1rem;
36 | font-weight: 300;
37 | color: $toast-text-color;
38 |
39 | @include flexbox();
40 | @include align(center);
41 | @include justify-content(space-between);
42 |
43 | .btn, .btn-flat {
44 | margin: 0;
45 | margin-left: 3rem;
46 | }
47 |
48 | &.rounded{
49 | border-radius: 24px;
50 | }
51 |
52 | @media #{$small-and-down} {
53 | width:100%;
54 | border-radius: 0;
55 | }
56 | @media #{$medium-only} {
57 | float: left;
58 | }
59 | @media #{$large-and-up} {
60 | float: right;
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_tooltip.scss:
--------------------------------------------------------------------------------
1 | .material-tooltip {
2 | padding: 10px 8px;
3 | font-size: 1rem;
4 | z-index: 1000;
5 | background-color: transparent;
6 | border-radius: 2px;
7 | color: #fff;
8 | min-height: 36px;
9 | line-height: 1rem;
10 | // max-width: 350px;
11 | opacity: 0;
12 | display: none;
13 | position: absolute;
14 | text-align: center;
15 | overflow: hidden;
16 | left:0;
17 | top:0;
18 |
19 | will-change: top, left;
20 | }
21 |
22 | .backdrop {
23 | position: absolute;
24 | opacity: 0;
25 | display: none;
26 | height: 7px;
27 | width: 14px;
28 | border-radius: 0 0 14px 14px;
29 | background-color: #323232;
30 | z-index: -1;
31 | @include transform-origin( 50% 10%);
32 |
33 | will-change: transform, opacity;
34 | }
35 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_typography.scss:
--------------------------------------------------------------------------------
1 | a {
2 | text-decoration: none;
3 | }
4 |
5 | html{
6 | line-height: 1.5;
7 |
8 | @media only screen and (min-width: 0) {
9 | font-size: 14px;
10 | }
11 |
12 | @media only screen and (min-width: $medium-screen) {
13 | font-size: 14.5px;
14 | }
15 |
16 | @media only screen and (min-width: $large-screen) {
17 | font-size: 15px;
18 | }
19 |
20 | font-family: "Roboto", sans-serif;
21 | font-weight: normal;
22 | color: $off-black;
23 | }
24 | h1, h2, h3, h4, h5, h6 {
25 | font-weight: 400;
26 | }
27 |
28 | // Header Styles
29 | h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; }
30 | h1 { font-size: $h1-fontsize; line-height: 1.1*$h1-fontsize; margin: ($h1-fontsize / 2) 0 ($h1-fontsize / 2.5) 0;}
31 | h2 { font-size: $h2-fontsize; line-height: 1.1*$h2-fontsize; margin: ($h2-fontsize / 2) 0 ($h2-fontsize / 2.5) 0;}
32 | h3 { font-size: $h3-fontsize; line-height: 1.1*$h3-fontsize; margin: ($h3-fontsize / 2) 0 ($h3-fontsize / 2.5) 0;}
33 | h4 { font-size: $h4-fontsize; line-height: 1.1*$h4-fontsize; margin: ($h4-fontsize / 2) 0 ($h4-fontsize / 2.5) 0;}
34 | h5 { font-size: $h5-fontsize; line-height: 1.1*$h5-fontsize; margin: ($h5-fontsize / 2) 0 ($h5-fontsize / 2.5) 0;}
35 | h6 { font-size: $h6-fontsize; line-height: 1.1*$h6-fontsize; margin: ($h6-fontsize / 2) 0 ($h6-fontsize / 2.5) 0;}
36 |
37 | // Text Styles
38 | em { font-style: italic; }
39 | strong { font-weight: 500; }
40 | small { font-size: 75%; }
41 | .light { font-weight: 300; }
42 | .thin { font-weight: 200; }
43 |
44 | .flow-text{
45 | font-weight: 300;
46 | $i: 0;
47 | @while $i <= $intervals {
48 | @media only screen and (min-width : 360 + ($i * $interval-size)) {
49 | font-size: 1.2rem * (1 + (.02 * $i));
50 | }
51 | @media only screen and (min-width : 0 + ($i * $interval-size)) {
52 | line-height: .8rem * (1 + (.13 * $i));
53 | }
54 | $i: $i + 1;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_variables.scss:
--------------------------------------------------------------------------------
1 | /*** Colors ***/
2 | $primary-color: color("materialize-red", "lighten-2") !default;
3 | $primary-color-light: lighten($primary-color, 15%) !default;
4 | $primary-color-dark: darken($primary-color, 15%) !default;
5 |
6 | $secondary-color: color("teal", "lighten-1") !default;
7 | $success-color: color("green", "base") !default;
8 | $error-color: color("red", "base") !default;
9 | $link-color: color("blue", "base") !default;
10 |
11 | /*** Badges ***/
12 | $badge-bg-color: $secondary-color !default;
13 |
14 | /*** Buttons ***/
15 | $button-bg-color-disabled: #DFDFDF !default;
16 | $button-color: $secondary-color !default;
17 | $button-color-disabled: #9F9F9F !default;
18 | $button-color-flat: #343434 !default;
19 | $button-color-raised: #FFF !default;
20 | $button-floating-size: 37px !default;
21 | $button-height: 36px !default;
22 | $button-font-size-shared: 1.3rem !default;
23 | $button-line-height: 36px !default;
24 |
25 |
26 | /*** Cards ***/
27 | $card-padding: 20px !default;
28 | $card-bg-color: #fff !default;
29 |
30 | /*** Collapsible ***/
31 | $collapsible-height: 3rem !default;
32 | $collapsible-header-color: #fff !default;
33 | $collapsible-border-color: #ddd !default;
34 |
35 |
36 | /*** Dropdown ***/
37 | $dropdown-color: $secondary-color !default;
38 |
39 | /*** Fonts ***/
40 | $roboto-font-path: "../materialize/font/roboto/" !default;
41 | $icons-font-path: "../materialize/font/material-design-icons/" !default;
42 |
43 | /*** Forms ***/
44 | // Text Inputs + Textarea
45 | $input-border-color: color("grey", "base") !default;
46 | $input-error-color: $error-color !default;
47 | $input-success-color: $success-color !default;
48 | $input-focus-color: $secondary-color !default;
49 | $label-font-size: .8rem !default;
50 | $input-disabled-color: rgba(0,0,0, .26) !default;
51 | $input-disabled-solid-color: #BDBDBD !default;
52 |
53 |
54 | // Radio Buttons
55 | $radio-fill-color: $secondary-color !default;
56 | $radio-empty-color: #5a5a5a !default;
57 |
58 | // Switches
59 | $switch-bg-color: $secondary-color !default;
60 | $switch-checked-lever-bg: desaturate(lighten($secondary-color, 25%), 25%) !default;
61 | $switch-unchecked-bg: #F1F1F1 !default;
62 | $switch-unchecked-lever-bg: #818181 !default;
63 |
64 | // Date Picker
65 | $datepicker-weekday-bg: darken($secondary_color, 7%) !default;
66 | $datepicker-date-bg: $secondary_color !default;
67 | $datepicker-year: rgba(255, 255, 255, .4) !default;
68 | $datepicker-focus: rgba(0,0,0, .05) !default;
69 | $datepicker-selected: $secondary-color !default;
70 | $datepicker-selected-outfocus: desaturate(lighten($secondary-color, 35%), 15%) !default;
71 |
72 |
73 | /*** Global ***/
74 | // Media Query Ranges
75 | $small-screen-up: 601px !default;
76 | $medium-screen-up: 993px !default;
77 | $large-screen-up: 1201px !default;
78 | $small-screen: 600px !default;
79 | $medium-screen: 992px !default;
80 | $large-screen: 1200px !default;
81 |
82 | $medium-and-up: "only screen and (min-width : #{$small-screen-up})" !default;
83 | $large-and-up: "only screen and (min-width : #{$medium-screen-up})" !default;
84 | $small-and-down: "only screen and (max-width : #{$small-screen})" !default;
85 | $medium-and-down: "only screen and (max-width : #{$medium-screen})" !default;
86 | $medium-only: "only screen and (min-width : #{$small-screen-up}) and (max-width : #{$medium-screen})" !default;
87 |
88 | // Grid Variables
89 | $num-cols: 12 !default;
90 | $gutter-width: 1.5rem !default;
91 | $element-top-margin: $gutter-width/3 !default;
92 | $element-bottom-margin: ($gutter-width*2)/3 !default;
93 |
94 | /*** Navbar ***/
95 | $navbar-height: 64px !default;
96 | $navbar-height-mobile: 56px !default;
97 |
98 |
99 | /*** SideNav ***/
100 |
101 |
102 |
103 | /*** Tabs ***/
104 | $tabs-underline-color: $primary-color-light !default;
105 | $tabs-text-color: $primary-color !default;
106 | $tabs-bg-color: #fff !default;
107 |
108 | /*** Tables ***/
109 | $table-border-color: #d0d0d0 !default;
110 | $table-striped-color: #f2f2f2 !default;
111 |
112 | /*** Toasts ***/
113 | $toast-height: 48px !default;
114 | $toast-color: #323232 !default;
115 | $toast-text-color: #fff !default;
116 |
117 | /*** Typography ***/
118 | $off-black: rgba(0, 0, 0, 0.87) !default;
119 | // Header Styles
120 | $h1-fontsize: 4.2rem !default;
121 | $h2-fontsize: 3.56rem !default;
122 | $h3-fontsize: 2.92rem !default;
123 | $h4-fontsize: 2.28rem !default;
124 | $h5-fontsize: 1.64rem !default;
125 | $h6-fontsize: 1rem !default;
126 |
127 | // Footer
128 | $footer-bg-color: $primary-color !default;
129 |
130 | // Flowtext
131 | $range : $large-screen - $small-screen !default;
132 | $intervals: 20 !default;
133 | $interval-size: $range / $intervals !default;
134 |
135 | /*** Collections ***/
136 | $collection-border-color: #e0e0e0 !default;
137 | $collection-bg-color: #fff !default;
138 | $collection-active-bg-color: $secondary-color !default;
139 | $collection-active-color: lighten($secondary-color, 55%) !default;
140 | $collection-hover-bg-color: #ddd !default;
141 |
142 | /* Progress Bar */
143 | $progress-bar-color: $secondary-color !default;
144 |
--------------------------------------------------------------------------------
/static/materialize/sass/components/_waves.scss:
--------------------------------------------------------------------------------
1 |
2 | /*!
3 | * Waves v0.6.0
4 | * http://fian.my.id/Waves
5 | *
6 | * Copyright 2014 Alfiana E. Sibuea and other contributors
7 | * Released under the MIT license
8 | * https://github.com/fians/Waves/blob/master/LICENSE
9 | */
10 |
11 |
12 | .waves-effect {
13 | position: relative;
14 | cursor: pointer;
15 | display: inline-block;
16 | overflow: hidden;
17 | -webkit-user-select: none;
18 | -moz-user-select: none;
19 | -ms-user-select: none;
20 | user-select: none;
21 | -webkit-tap-highlight-color: transparent;
22 | // white-space: nowrap;
23 | // outline: 0;
24 |
25 | vertical-align: middle;
26 | // cursor: pointer;
27 | // border: none;
28 | // outline: none;
29 | // color: inherit;
30 | // background-color: rgba(0, 0, 0, 0);
31 | // font-size: 1em;
32 | // line-height:1em;
33 | // text-align: center;
34 | // text-decoration: none;
35 | z-index: 1;
36 | will-change: opacity, transform;
37 | @include transition(all .3s ease-out);
38 |
39 | .waves-ripple {
40 | position: absolute;
41 | border-radius: 50%;
42 | width: 20px;
43 | height: 20px;
44 | margin-top:-10px;
45 | margin-left:-10px;
46 | opacity: 0;
47 |
48 | background: rgba(0,0,0,0.2);
49 | // $gradient: rgba(0,0,0,0.2) 0,rgba(0,0,0,.3) 40%,rgba(0,0,0,.4) 50%,rgba(0,0,0,.5) 60%,rgba(255,255,255,0) 70%;
50 | // background: -webkit-radial-gradient($gradient);
51 | // background: -o-radial-gradient($gradient);
52 | // background: -moz-radial-gradient($gradient);
53 | // background: radial-gradient($gradient);
54 | @include transition(all 0.7s ease-out);
55 | -webkit-transition-property: -webkit-transform, opacity;
56 | -moz-transition-property: -moz-transform, opacity;
57 | -o-transition-property: -o-transform, opacity;
58 | transition-property: transform, opacity;
59 | @include transform(scale(0));
60 | pointer-events: none;
61 | }
62 |
63 | // Waves Colors
64 | &.waves-light .waves-ripple {
65 | background-color: rgba(255, 255, 255, 0.45);
66 | }
67 |
68 | &.waves-red .waves-ripple {
69 | background-color: rgba(244, 67, 54, .70);
70 | }
71 | &.waves-yellow .waves-ripple {
72 | background-color: rgba(255, 235, 59, .70);
73 | }
74 | &.waves-orange .waves-ripple {
75 | background-color: rgba(255, 152, 0, .70);
76 | }
77 | &.waves-purple .waves-ripple {
78 | background-color: rgba(156, 39, 176, 0.70);
79 | }
80 | &.waves-green .waves-ripple {
81 | background-color: rgba(76, 175, 80, 0.70);
82 | }
83 | &.waves-teal .waves-ripple {
84 | background-color: rgba(0, 150, 136, 0.70);
85 | }
86 |
87 | }
88 |
89 | .waves-notransition {
90 | @include transition(none #{"!important"});
91 | }
92 |
93 | .waves-circle {
94 | @include transform(translateZ(0));
95 | -webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%);
96 | }
97 |
98 | // .waves-button,
99 | // .waves-button:hover,
100 | // .waves-button:visited,
101 | // .waves-button-input {
102 | // white-space: nowrap;
103 | // vertical-align: middle;
104 | // cursor: pointer;
105 | // border: none;
106 | // outline: none;
107 | // color: inherit;
108 | // background-color: rgba(0, 0, 0, 0);
109 | // font-size: 1em;
110 | // line-height:1em;
111 | // text-align: center;
112 | // text-decoration: none;
113 | // z-index: 1;
114 | // }
115 |
116 | // .waves-button {
117 | // padding: 0.85em 1.1em;
118 | // border-radius: 0.2em;
119 | // }
120 |
121 | // .waves-button-input {
122 | // margin: 0;
123 | // padding: 0.85em 1.1em;
124 | // }
125 |
126 | .waves-input-wrapper {
127 | border-radius: 0.2em;
128 | vertical-align: bottom;
129 |
130 | // &.waves-button {
131 | // padding: 0;
132 | // }
133 |
134 | .waves-button-input {
135 | position: relative;
136 | top: 0;
137 | left: 0;
138 | z-index: 1;
139 | }
140 | }
141 |
142 | .waves-circle {
143 | text-align: center;
144 | width: 2.5em;
145 | height: 2.5em;
146 | line-height: 2.5em;
147 | border-radius: 50%;
148 | -webkit-mask-image: none;
149 | }
150 |
151 | // .waves-float {
152 | // -webkit-mask-image: none;
153 | // @include box-shadow(0px 1px 1.5px 1px rgba(0, 0, 0, 0.12));
154 |
155 | // &:active {
156 | // @include box-shadow(0px 8px 20px 1px rgba(0, 0, 0, 0.30));
157 | // }
158 | // }
159 |
160 | .waves-block {
161 | display: block;
162 | }
163 |
164 | /* Firefox Bug: link not triggered */
165 | a.waves-effect .waves-ripple {
166 | z-index: -1;
167 | }
--------------------------------------------------------------------------------
/static/materialize/sass/components/date_picker/_default.scss:
--------------------------------------------------------------------------------
1 | /* ==========================================================================
2 | $BASE-PICKER
3 | ========================================================================== */
4 | /**
5 | * Note: the root picker element should *NOT* be styled more than what's here.
6 | */
7 | .picker {
8 | font-size: 16px;
9 | text-align: left;
10 | line-height: 1.2;
11 | color: #000000;
12 | position: absolute;
13 | z-index: 10000;
14 | -webkit-user-select: none;
15 | -moz-user-select: none;
16 | -ms-user-select: none;
17 | user-select: none;
18 | }
19 | /**
20 | * The picker input element.
21 | */
22 | .picker__input {
23 | cursor: default;
24 | }
25 | /**
26 | * When the picker is opened, the input element is "activated".
27 | */
28 | .picker__input.picker__input--active {
29 | border-color: #0089ec;
30 | }
31 | /**
32 | * The holder is the only "scrollable" top-level container element.
33 | */
34 | .picker__holder {
35 | width: 100%;
36 | overflow-y: auto;
37 | -webkit-overflow-scrolling: touch;
38 | }
39 |
40 | /*!
41 | * Default mobile-first, responsive styling for pickadate.js
42 | * Demo: http://amsul.github.io/pickadate.js
43 | */
44 | /**
45 | * Note: the root picker element should *NOT* be styled more than what's here.
46 | */
47 | /**
48 | * Make the holder and frame fullscreen.
49 | */
50 | .picker__holder,
51 | .picker__frame {
52 | bottom: 0;
53 | left: 0;
54 | right: 0;
55 | top: 100%;
56 | }
57 | /**
58 | * The holder should overlay the entire screen.
59 | */
60 | .picker__holder {
61 | position: fixed;
62 | -webkit-transition: background 0.15s ease-out, top 0s 0.15s;
63 | -moz-transition: background 0.15s ease-out, top 0s 0.15s;
64 | transition: background 0.15s ease-out, top 0s 0.15s;
65 | -webkit-backface-visibility: hidden;
66 | }
67 | /**
68 | * The frame that bounds the box contents of the picker.
69 | */
70 | .picker__frame {
71 | position: absolute;
72 | margin: 0 auto;
73 | min-width: 256px;
74 |
75 | // picker width
76 | max-width: 300px;
77 | max-height: 350px;
78 |
79 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
80 | filter: alpha(opacity=0);
81 | -moz-opacity: 0;
82 | opacity: 0;
83 | -webkit-transition: all 0.15s ease-out;
84 | -moz-transition: all 0.15s ease-out;
85 | transition: all 0.15s ease-out;
86 | }
87 | @media (min-height: 28.875em) {
88 | .picker__frame {
89 | overflow: visible;
90 | top: auto;
91 | bottom: -100%;
92 | max-height: 80%;
93 | }
94 | }
95 | @media (min-height: 40.125em) {
96 | .picker__frame {
97 | margin-bottom: 7.5%;
98 | }
99 | }
100 | /**
101 | * The wrapper sets the stage to vertically align the box contents.
102 | */
103 | .picker__wrap {
104 | display: table;
105 | width: 100%;
106 | height: 100%;
107 | }
108 | @media (min-height: 28.875em) {
109 | .picker__wrap {
110 | display: block;
111 | }
112 | }
113 | /**
114 | * The box contains all the picker contents.
115 | */
116 | .picker__box {
117 | background: #ffffff;
118 | display: table-cell;
119 | vertical-align: middle;
120 | }
121 | //@media (min-height: 26.5em) {
122 | // .picker__box {
123 | //// font-size: 1.25em;
124 | // }
125 | //}
126 | @media (min-height: 28.875em) {
127 | .picker__box {
128 | display: block;
129 |
130 | // picker header font-size
131 | // font-size: 1rem;
132 |
133 | border: 1px solid #777777;
134 | border-top-color: #898989;
135 | border-bottom-width: 0;
136 | -webkit-border-radius: 5px 5px 0 0;
137 | -moz-border-radius: 5px 5px 0 0;
138 | border-radius: 5px 5px 0 0;
139 | -webkit-box-shadow: 0 12px 36px 16px rgba(0, 0, 0, 0.24);
140 | -moz-box-shadow: 0 12px 36px 16px rgba(0, 0, 0, 0.24);
141 | box-shadow: 0 12px 36px 16px rgba(0, 0, 0, 0.24);
142 | }
143 | }
144 | //@media (min-height: 40.125em) {
145 | // .picker__box {
146 | // font-size: 1.1rem;
147 | // border-bottom-width: 1px;
148 | // -webkit-border-radius: 5px;
149 | // -moz-border-radius: 5px;
150 | // border-radius: 5px;
151 | // }
152 | //}
153 | /**
154 | * When the picker opens...
155 | */
156 | .picker--opened .picker__holder {
157 | top: 0;
158 | background: transparent;
159 | -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#1E000000,endColorstr=#1E000000)";
160 | zoom: 1;
161 | background: rgba(0, 0, 0, 0.32);
162 | -webkit-transition: background 0.15s ease-out;
163 | -moz-transition: background 0.15s ease-out;
164 | transition: background 0.15s ease-out;
165 | }
166 | .picker--opened .picker__frame {
167 | top: 0;
168 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
169 | filter: alpha(opacity=100);
170 | -moz-opacity: 1;
171 | opacity: 1;
172 | }
173 | @media (min-height: 35.875em) {
174 | .picker--opened .picker__frame {
175 | top: 10%;
176 | bottom: 20%auto;
177 | }
178 | }
179 | /**
180 | * For `large` screens, transform into an inline picker.
181 | */
182 |
183 | /* ==========================================================================
184 | CUSTOM MATERIALIZE STYLES
185 | ========================================================================== */
186 |
187 | .picker__input.picker__input--active {
188 | border-color: color("blue", "lighten-5");
189 | }
190 |
191 | .picker__frame {
192 | margin: 0 auto;
193 | max-width: 325px;
194 | }
195 |
196 | @media (min-height: 38.875em) {
197 | .picker--opened .picker__frame {
198 | top: 10%;
199 | bottom: auto;
200 | }
201 | }
--------------------------------------------------------------------------------
/static/materialize/sass/components/date_picker/_default.time.scss:
--------------------------------------------------------------------------------
1 | /* ==========================================================================
2 | $BASE-TIME-PICKER
3 | ========================================================================== */
4 | /**
5 | * The list of times.
6 | */
7 | .picker__list {
8 | list-style: none;
9 | padding: 0.75em 0 4.2em;
10 | margin: 0;
11 | }
12 | /**
13 | * The times on the clock.
14 | */
15 | .picker__list-item {
16 | border-bottom: 1px solid #dddddd;
17 | border-top: 1px solid #dddddd;
18 | margin-bottom: -1px;
19 | position: relative;
20 | background: #ffffff;
21 | padding: .75em 1.25em;
22 | }
23 | @media (min-height: 46.75em) {
24 | .picker__list-item {
25 | padding: .5em 1em;
26 | }
27 | }
28 | /* Hovered time */
29 | .picker__list-item:hover {
30 | cursor: pointer;
31 | color: #000000;
32 | background: #b1dcfb;
33 | border-color: #0089ec;
34 | z-index: 10;
35 | }
36 | /* Highlighted and hovered/focused time */
37 | .picker__list-item--highlighted {
38 | border-color: #0089ec;
39 | z-index: 10;
40 | }
41 | .picker__list-item--highlighted:hover,
42 | .picker--focused .picker__list-item--highlighted {
43 | cursor: pointer;
44 | color: #000000;
45 | background: #b1dcfb;
46 | }
47 | /* Selected and hovered/focused time */
48 | .picker__list-item--selected,
49 | .picker__list-item--selected:hover,
50 | .picker--focused .picker__list-item--selected {
51 | background: #0089ec;
52 | color: #ffffff;
53 | z-index: 10;
54 | }
55 | /* Disabled time */
56 | .picker__list-item--disabled,
57 | .picker__list-item--disabled:hover,
58 | .picker--focused .picker__list-item--disabled {
59 | background: #f5f5f5;
60 | border-color: #f5f5f5;
61 | color: #dddddd;
62 | cursor: default;
63 | border-color: #dddddd;
64 | z-index: auto;
65 | }
66 | /**
67 | * The clear button
68 | */
69 | .picker--time .picker__button--clear {
70 | display: block;
71 | width: 80%;
72 | margin: 1em auto 0;
73 | padding: 1em 1.25em;
74 | background: none;
75 | border: 0;
76 | font-weight: 500;
77 | font-size: .67em;
78 | text-align: center;
79 | text-transform: uppercase;
80 | color: #666;
81 | }
82 | .picker--time .picker__button--clear:hover,
83 | .picker--time .picker__button--clear:focus {
84 | color: #000000;
85 | background: #b1dcfb;
86 | background: #ee2200;
87 | border-color: #ee2200;
88 | cursor: pointer;
89 | color: #ffffff;
90 | outline: none;
91 | }
92 | .picker--time .picker__button--clear:before {
93 | top: -0.25em;
94 | color: #666;
95 | font-size: 1.25em;
96 | font-weight: bold;
97 | }
98 | .picker--time .picker__button--clear:hover:before,
99 | .picker--time .picker__button--clear:focus:before {
100 | color: #ffffff;
101 | }
102 |
103 | /* ==========================================================================
104 | $DEFAULT-TIME-PICKER
105 | ========================================================================== */
106 | /**
107 | * The frame the bounds the time picker.
108 | */
109 | .picker--time .picker__frame {
110 | min-width: 256px;
111 | max-width: 320px;
112 | }
113 | /**
114 | * The picker box.
115 | */
116 | .picker--time .picker__box {
117 | font-size: 1em;
118 | background: #f2f2f2;
119 | padding: 0;
120 | }
121 | @media (min-height: 40.125em) {
122 | .picker--time .picker__box {
123 | margin-bottom: 5em;
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/static/materialize/sass/materialize.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | // Mixins
4 | @import "components/prefixer";
5 | @import "components/mixins";
6 | @import "components/color";
7 |
8 | // Variables;
9 | @import "components/variables";
10 |
11 | // Reset
12 | @import "components/normalize";
13 |
14 | // components
15 | @import "components/global";
16 | @import "components/icons-material-design";
17 | @import "components/grid";
18 | @import "components/navbar";
19 | @import "components/roboto";
20 | @import "components/typography";
21 | @import "components/cards";
22 | @import "components/toast";
23 | @import "components/tabs";
24 | @import "components/tooltip";
25 | @import "components/buttons";
26 | @import "components/dropdown";
27 | @import "components/waves";
28 | @import "components/modal";
29 | @import "components/collapsible";
30 | @import "components/materialbox";
31 | @import "components/form";
32 | @import "components/table_of_contents";
33 | @import "components/sideNav";
34 | @import "components/preloader";
35 | @import "components/slider";
36 | @import "components/date_picker/default.scss";
37 | @import "components/date_picker/default.date.scss";
38 | @import "components/date_picker/default.time.scss";
--------------------------------------------------------------------------------
/static/materialize/templates/masonry-template/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Materialize
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/static/materialize/templates/masonry-template/background1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/templates/masonry-template/background1.jpg
--------------------------------------------------------------------------------
/static/materialize/templates/masonry-template/background2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/templates/masonry-template/background2.jpg
--------------------------------------------------------------------------------
/static/materialize/templates/masonry-template/background3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/templates/masonry-template/background3.jpg
--------------------------------------------------------------------------------
/static/materialize/templates/masonry-template/css/style.css:
--------------------------------------------------------------------------------
1 | /* Custom Stylesheet */
2 | /**
3 | * Use this file to override Materialize files so you can update
4 | * the core Materialize files in the future
5 | *
6 | * Made By MaterializeCSS.com
7 | */
8 |
9 | nav ul a,
10 | nav .brand-logo {
11 | color: #444;
12 | }
13 |
14 | p {
15 | line-height: 2rem;
16 | }
17 |
18 | .button-collapse {
19 | color: #26a69a;
20 | }
21 |
22 | .parallax-container {
23 | min-height: 380px;
24 | line-height: 0;
25 | height: auto;
26 | color: rgba(255,255,255,.9);
27 | }
28 | .parallax-container .section {
29 | width: 100%;
30 | }
31 |
32 | @media only screen and (max-width : 992px) {
33 | .parallax-container .section {
34 | position: absolute;
35 | top: 40%;
36 | }
37 | #index-banner .section {
38 | top: 10%;
39 | }
40 | }
41 |
42 | @media only screen and (max-width : 600px) {
43 | #index-banner .section {
44 | top: 0;
45 | }
46 | }
47 |
48 |
49 | .icon-block {
50 | padding: 0 15px;
51 | }
52 |
53 | footer.page-footer {
54 | margin: 0;
55 | }
--------------------------------------------------------------------------------
/static/materialize/templates/masonry-template/js/init.js:
--------------------------------------------------------------------------------
1 | (function($){
2 | $(function(){
3 |
4 | $('.button-collapse').sideNav();
5 |
6 |
7 | var $container = $('#masonry-grid');
8 | // initialize
9 | $container.masonry({
10 | columnWidth: '.col',
11 | itemSelector: '.col',
12 | });
13 |
14 |
15 | }); // end of document ready
16 | })(jQuery); // end of jQuery name space
--------------------------------------------------------------------------------
/static/materialize/templates/parallax-template/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Materialize
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/static/materialize/templates/parallax-template/background1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/templates/parallax-template/background1.jpg
--------------------------------------------------------------------------------
/static/materialize/templates/parallax-template/background2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/templates/parallax-template/background2.jpg
--------------------------------------------------------------------------------
/static/materialize/templates/parallax-template/background3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/materialize/templates/parallax-template/background3.jpg
--------------------------------------------------------------------------------
/static/materialize/templates/parallax-template/css/style.css:
--------------------------------------------------------------------------------
1 | /* Custom Stylesheet */
2 | /**
3 | * Use this file to override Materialize files so you can update
4 | * the core Materialize files in the future
5 | *
6 | * Made By MaterializeCSS.com
7 | */
8 |
9 | nav ul a,
10 | nav .brand-logo {
11 | color: #444;
12 | }
13 |
14 | p {
15 | line-height: 2rem;
16 | }
17 |
18 | .button-collapse {
19 | color: #26a69a;
20 | }
21 |
22 | .parallax-container {
23 | min-height: 380px;
24 | line-height: 0;
25 | height: auto;
26 | color: rgba(255,255,255,.9);
27 | }
28 | .parallax-container .section {
29 | width: 100%;
30 | }
31 |
32 | @media only screen and (max-width : 992px) {
33 | .parallax-container .section {
34 | position: absolute;
35 | top: 40%;
36 | }
37 | #index-banner .section {
38 | top: 10%;
39 | }
40 | }
41 |
42 | @media only screen and (max-width : 600px) {
43 | #index-banner .section {
44 | top: 0;
45 | }
46 | }
47 |
48 |
49 | .icon-block {
50 | padding: 0 15px;
51 | }
52 |
53 | footer.page-footer {
54 | margin: 0;
55 | }
--------------------------------------------------------------------------------
/static/materialize/templates/parallax-template/js/init.js:
--------------------------------------------------------------------------------
1 | (function($){
2 | $(function(){
3 |
4 | $('.button-collapse').sideNav();
5 | $('.parallax').parallax();
6 |
7 | }); // end of document ready
8 | })(jQuery); // end of jQuery name space
--------------------------------------------------------------------------------
/static/materialize/templates/starter-template/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Materialize
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/static/materialize/templates/starter-template/css/style.css:
--------------------------------------------------------------------------------
1 | /* Custom Stylesheet */
2 | /**
3 | * Use this file to override Materialize files so you can update
4 | * the core Materialize files in the future
5 | *
6 | * Made By MaterializeCSS.com
7 | */
8 |
9 | .icon-block {
10 | padding: 0 15px;
11 | }
--------------------------------------------------------------------------------
/static/materialize/templates/starter-template/js/init.js:
--------------------------------------------------------------------------------
1 | (function($){
2 | $(function(){
3 |
4 | $('.button-collapse').sideNav();
5 |
6 | }); // end of document ready
7 | })(jQuery); // end of jQuery name space
--------------------------------------------------------------------------------
/static/sounds/inbound.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/sounds/inbound.mp3
--------------------------------------------------------------------------------
/static/styles/source/index.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | // Mixins
4 | @import "../../components/materialize/sass/components/prefixer";
5 | @import "../../components/materialize/sass/components/mixins";
6 | @import "../../components/materialize/sass/components/color";
7 | @import "theme_color";
8 |
9 | // Variables;
10 | @import "../../components/materialize/sass/components/variables";
11 | @import "theme_variables";
12 |
13 | // Reset
14 | @import "../../components/materialize/sass/components/normalize";
15 |
16 | // components
17 | @import "../../components/materialize/sass/components/global";
18 | @import "../../components/materialize/sass/components/icons-material-design";
19 | @import "../../components/materialize/sass/components/grid";
20 | @import "../../components/materialize/sass/components/navbar";
21 | @import "../../components/materialize/sass/components/roboto";
22 | @import "../../components/materialize/sass/components/typography";
23 | @import "../../components/materialize/sass/components/cards";
24 | @import "../../components/materialize/sass/components/toast";
25 | @import "../../components/materialize/sass/components/tabs";
26 | @import "../../components/materialize/sass/components/tooltip";
27 | @import "../../components/materialize/sass/components/buttons";
28 | @import "../../components/materialize/sass/components/dropdown";
29 | @import "../../components/materialize/sass/components/waves";
30 | @import "../../components/materialize/sass/components/modal";
31 | @import "../../components/materialize/sass/components/collapsible";
32 | @import "../../components/materialize/sass/components/materialbox";
33 | @import "../../components/materialize/sass/components/form";
34 | @import "../../components/materialize/sass/components/table_of_contents";
35 | @import "../../components/materialize/sass/components/sideNav";
36 | @import "../../components/materialize/sass/components/preloader";
37 | @import "../../components/materialize/sass/components/slider";
38 | @import "../../components/materialize/sass/components/date_picker/default.scss";
39 | @import "../../components/materialize/sass/components/date_picker/default.date.scss";
40 | @import "../../components/materialize/sass/components/date_picker/default.time.scss";
41 |
--------------------------------------------------------------------------------
/static/styles/source/theme_color.scss:
--------------------------------------------------------------------------------
1 | // Twilio Colors
2 | $red: (
3 | );
4 |
5 | $twilioMaroon: (
6 | "base": #971d1f,
7 | );
8 |
9 | $twilioGray: (
10 | "base": #2c2c2a,
11 | );
12 |
13 | $twilioBlack: (
14 | "base": #231f20,
15 | );
16 |
17 | $twilioBrown: (
18 | "base": #b1aca0,
19 | );
20 |
21 | $twilioBeige: (
22 | "base": #dbddd7,
23 | );
24 |
25 | $twilioBlue: (
26 | "base": #54c3c2,
27 | );
28 |
29 | // Theme colors
30 | $colors: (
31 | "materialize-red": $twilioRed,
32 | "red": $twilioRed,
33 | "blue": $twilioBlue,
34 | "grey": $twilioGray,
35 | ) !default;
36 |
--------------------------------------------------------------------------------
/static/styles/source/theme_variables.scss:
--------------------------------------------------------------------------------
1 | $primary-color: color("purple") !default;
2 | $link-color: color("teal", "darken-1") !default;
3 |
--------------------------------------------------------------------------------
/static/styles/theme.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/static/styles/theme.css
--------------------------------------------------------------------------------
/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% block title %}{% endblock %}
5 |
6 |
7 |
9 | {% block head %}{% endblock %}
10 |
11 |
12 | {% block content %}{% endblock %}
13 |
15 |
17 |
26 |
27 |
28 | {% block javascript %}{% endblock %}
29 |
30 |
31 |
--------------------------------------------------------------------------------
/templates/index.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block title %}Call Your Family - Nepal Earthquake{% endblock %}
4 |
5 | {% block head %}
6 |
8 |
9 | {% endblock %}
10 |
11 | {% block content %}
12 |
13 |
14 |
15 | Free Calls for Survivors of Nepalese Earthquake
16 |
17 |
18 |
19 | Free Calls for Survivors of Nepalese Earthquake
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | {% if params['config_errors'] %}
28 |
29 | {% else %}
30 |
31 | {% endif %}
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | {% if params['config_errors'] %}
43 |
There was an error configuring this app.
44 | {% for error in params['config_errors'] %}
45 |
{{ error }}
46 | {% endfor %}
47 | {% else %}
48 |
Powered By Twilio
49 |
1. Select the country you wish to call.
50 |
2. Input the number.
51 |
3. Press Call button.
52 |
4. Click "Allow" in your browser or dialog.
53 |
5. Talk through your browser for ten minutes.
54 | {% endif %}
55 |
56 |
57 |
58 |
59 |
60 | {% if not params['config_errors'] %}
61 |
Input the phone number to call below:
62 |
63 | Loading
64 |
66 | ✓ Valid
67 | Invalid number
68 |
69 | {% endif %}
70 |
71 |
72 |
73 |
74 |
75 |
94 |
95 |
96 |
Calling...
97 |
Click "Allow" to authorize the browser's use of your microphone.
98 |
Make sure your microphone is turned on.
99 |
100 |
103 |
104 |
105 | {% endblock %}
106 |
107 | {% block javascript %}
108 |
110 |
194 | {% endblock %}
195 |
--------------------------------------------------------------------------------
/templates/thankyou.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block title %}Call Your Family - Boston Marathon{% endblock %}
4 |
5 | {% block head %}
6 |
8 |
10 | {% endblock %}
11 |
12 | {% block content %}
13 |
14 |
23 |
24 |
25 | {% if params['config_errors'] %}
26 |
We just need to set a few more
27 | configuration options.
28 |
Check your local_settings.py to set these missing
29 | options:
30 |
31 | {% for error in params['config_errors'] %}
32 | Error
33 | {{ error }}
34 | {% endfor %}
35 |
36 | {% else %}
37 |
Our hearts and heads are with
38 | Boston.
39 |
40 | {% endif %}
41 |
42 |
43 |
55 |
56 | {% endblock %}
57 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobSpectre/Call-Your-Family/9f41bda1fab9368b32332c678874f27c943311ff/tests/__init__.py
--------------------------------------------------------------------------------
/tests/context.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | sys.path.insert(0, os.path.abspath('..'))
4 |
5 | import configure
6 | from app import app
7 |
--------------------------------------------------------------------------------
/tests/test_assets/bad_git_config:
--------------------------------------------------------------------------------
1 | [core]
2 | repositoryformatversion = 0
3 | filemode = true
4 | bare = false
5 | logallrefupdates = true
6 |
--------------------------------------------------------------------------------
/tests/test_assets/good_git_config:
--------------------------------------------------------------------------------
1 | [core]
2 | repositoryformatversion = 0
3 | filemode = true
4 | bare = false
5 | logallrefupdates = true
6 | [remote "heroku"]
7 | url = git@heroku.com:look-here-snacky-11211.git
8 | fetch = +refs/heads/*:refs/remotes/heroku/*
9 |
--------------------------------------------------------------------------------
/tests/test_twilio.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from .context import app
3 |
4 |
5 | class TwiMLTest(unittest.TestCase):
6 | def setUp(self):
7 | self.app = app.test_client()
8 |
9 | def assertTwiML(self, response):
10 | self.assertTrue("" in response.data, "Did not find " \
11 | ": %s" % response.data)
12 | self.assertTrue(" " in response.data, "Did not find " \
13 | " : %s" % response.data)
14 | self.assertEqual("200 OK", response.status)
15 |
16 | def sms(self, body, path='/sms', number='+15555555555'):
17 | params = {
18 | 'SmsSid': 'SMtesting',
19 | 'AccountSid': 'ACtesting',
20 | 'From': number,
21 | 'To': '+16666666666',
22 | 'Body': body,
23 | 'ApiVersion': '2010-04-01',
24 | 'Direction': 'inbound'}
25 | return self.app.post(path, data=params)
26 |
27 | def call(self, path='/voice', caller_id='+15555555555', digits=None,
28 | phone_number=None):
29 | params = {
30 | 'CallSid': 'CAtesting',
31 | 'AccountSid': 'ACtesting',
32 | 'From': caller_id,
33 | 'To': '+16666666666',
34 | 'CallStatus': 'ringing',
35 | 'ApiVersion': '2010-04-01',
36 | 'Direction': 'inbound'}
37 | if digits:
38 | params['Digits'] = digits
39 | if phone_number:
40 | params['PhoneNumber'] = phone_number
41 | return self.app.post(path, data=params)
42 |
43 |
44 | class TwilioTests(TwiMLTest):
45 | def test_voice(self):
46 | response = self.call(phone_number="+15557778888")
47 | self.assertTwiML(response)
48 |
49 | def test_inbound(self):
50 | response = self.call(path='/inbound')
51 | self.assertTwiML(response)
52 |
53 | def test_sms(self):
54 | response = self.sms("Test")
55 | self.assertTwiML(response)
56 |
--------------------------------------------------------------------------------
/tests/test_web.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | from .context import app
4 |
5 | app.config['TWILIO_ACCOUNT_SID'] = 'ACxxxxxx'
6 | app.config['TWILIO_AUTH_TOKEN'] = 'yyyyyyyyy'
7 | app.config['TWILIO_CALLER_ID'] = '+15558675309'
8 | app.config['IOS_URI'] = \
9 | 'http://itunes.apple.com/us/app/plants-vs.-zombies/id350642635?mt=8&uo=4'
10 | app.config['ANDROID_URI'] = \
11 | 'http://market.android.com/details?id=com.popcap.pvz_row'
12 | app.config['WEB_URI'] = 'http://www.popcap.com/games/plants-vs-zombies/pc'
13 |
14 |
15 | class WebTest(unittest.TestCase):
16 | def setUp(self):
17 | self.app = app.test_client()
18 |
19 |
20 | class IndexTests(WebTest):
21 | def test_index(self):
22 | response = self.app.get('/')
23 | self.assertEqual("200 OK", response.status)
24 |
--------------------------------------------------------------------------------