├── .gitignore
├── LICENSE
├── Procfile
├── README.md
├── auth.py
├── create-db.py
├── gmail_flask.py
├── main.py
├── models.py
├── params_central.json
├── readme
├── requirements.txt
├── src
├── analysis_amazon.py
├── analysis_curefit.py
├── analysis_flipkart.py
├── analysis_myntra.py
├── analysis_ola.py
├── analysis_uber.py
├── fetch_uber.py
└── utils.py
├── static
├── css
│ ├── main.css
│ └── util.css
├── fonts
│ ├── font-awesome-4.7.0
│ │ ├── HELP-US-OUT.txt
│ │ ├── css
│ │ │ ├── font-awesome.css
│ │ │ └── font-awesome.min.css
│ │ ├── fonts
│ │ │ ├── FontAwesome.otf
│ │ │ ├── fontawesome-webfont.eot
│ │ │ ├── fontawesome-webfont.svg
│ │ │ ├── fontawesome-webfont.ttf
│ │ │ ├── fontawesome-webfont.woff
│ │ │ └── fontawesome-webfont.woff2
│ │ ├── less
│ │ │ ├── animated.less
│ │ │ ├── bordered-pulled.less
│ │ │ ├── core.less
│ │ │ ├── fixed-width.less
│ │ │ ├── font-awesome.less
│ │ │ ├── icons.less
│ │ │ ├── larger.less
│ │ │ ├── list.less
│ │ │ ├── mixins.less
│ │ │ ├── path.less
│ │ │ ├── rotated-flipped.less
│ │ │ ├── screen-reader.less
│ │ │ ├── stacked.less
│ │ │ └── variables.less
│ │ └── scss
│ │ │ ├── _animated.scss
│ │ │ ├── _bordered-pulled.scss
│ │ │ ├── _core.scss
│ │ │ ├── _fixed-width.scss
│ │ │ ├── _icons.scss
│ │ │ ├── _larger.scss
│ │ │ ├── _list.scss
│ │ │ ├── _mixins.scss
│ │ │ ├── _path.scss
│ │ │ ├── _rotated-flipped.scss
│ │ │ ├── _screen-reader.scss
│ │ │ ├── _stacked.scss
│ │ │ ├── _variables.scss
│ │ │ └── font-awesome.scss
│ ├── montserrat
│ │ ├── Montserrat-Black.ttf
│ │ ├── Montserrat-BlackItalic.ttf
│ │ ├── Montserrat-Bold.ttf
│ │ ├── Montserrat-BoldItalic.ttf
│ │ ├── Montserrat-ExtraBold.ttf
│ │ ├── Montserrat-ExtraBoldItalic.ttf
│ │ ├── Montserrat-ExtraLight.ttf
│ │ ├── Montserrat-ExtraLightItalic.ttf
│ │ ├── Montserrat-Italic.ttf
│ │ ├── Montserrat-Light.ttf
│ │ ├── Montserrat-LightItalic.ttf
│ │ ├── Montserrat-Medium.ttf
│ │ ├── Montserrat-MediumItalic.ttf
│ │ ├── Montserrat-Regular.ttf
│ │ ├── Montserrat-SemiBold.ttf
│ │ ├── Montserrat-SemiBoldItalic.ttf
│ │ ├── Montserrat-Thin.ttf
│ │ ├── Montserrat-ThinItalic.ttf
│ │ └── OFL.txt
│ └── poppins
│ │ ├── Poppins-Black.ttf
│ │ ├── Poppins-BlackItalic.ttf
│ │ ├── Poppins-Bold.ttf
│ │ ├── Poppins-BoldItalic.ttf
│ │ ├── Poppins-ExtraBold.ttf
│ │ ├── Poppins-ExtraBoldItalic.ttf
│ │ ├── Poppins-ExtraLight.ttf
│ │ ├── Poppins-ExtraLightItalic.ttf
│ │ ├── Poppins-Italic.ttf
│ │ ├── Poppins-Light.ttf
│ │ ├── Poppins-LightItalic.ttf
│ │ ├── Poppins-Medium.ttf
│ │ ├── Poppins-MediumItalic.ttf
│ │ ├── Poppins-Regular.ttf
│ │ ├── Poppins-SemiBold.ttf
│ │ ├── Poppins-SemiBoldItalic.ttf
│ │ ├── Poppins-Thin.ttf
│ │ └── Poppins-ThinItalic.ttf
├── images
│ ├── bahi_khata.png
│ ├── icons
│ │ ├── favicon.ico
│ │ └── icon-google.png
│ ├── landing-page.png
│ ├── sample_report.png
│ └── usage.gif
├── js
│ └── main.js
└── vendor
│ ├── animate
│ ├── animate.css
│ └── checkmark.css
│ ├── bootstrap
│ ├── css
│ │ ├── bootstrap-grid.css
│ │ ├── bootstrap-grid.css.map
│ │ ├── bootstrap-grid.min.css
│ │ ├── bootstrap-grid.min.css.map
│ │ ├── bootstrap-reboot.css
│ │ ├── bootstrap-reboot.css.map
│ │ ├── bootstrap-reboot.min.css
│ │ ├── bootstrap-reboot.min.css.map
│ │ ├── bootstrap.css
│ │ ├── bootstrap.css.map
│ │ ├── bootstrap.min.css
│ │ └── bootstrap.min.css.map
│ └── js
│ │ ├── bootstrap.js
│ │ ├── bootstrap.min.js
│ │ ├── popper.js
│ │ ├── popper.min.js
│ │ └── tooltip.js
│ ├── css-hamburgers
│ ├── hamburgers.css
│ └── hamburgers.min.css
│ ├── jquery
│ └── jquery-3.2.1.min.js
│ ├── select2
│ ├── select2.css
│ ├── select2.js
│ ├── select2.min.css
│ └── select2.min.js
│ └── tilt
│ └── tilt.jquery.min.js
├── templates
├── base.html
├── index.html
├── login.html
├── profile.html
├── report.html
├── signup.html
└── thankyou.html
└── wsgi.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pickle
2 | *__pycache__*
3 | *.log
4 | .vscode
5 | data/*.json*
6 | data/*.png
7 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: gunicorn wsgi:app
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
बही खाता
8 |
9 |
19 |
20 |
21 |
22 |
23 |
24 | ## Table of Contents
25 |
26 | - [Table of Contents](#table-of-contents)
27 | - [About The Project](#about-the-project)
28 | - [Supported Receipts](#supported-receipts)
29 | - [Built With](#built-with)
30 | - [Getting Started](#getting-started)
31 | - [Prerequisites](#prerequisites)
32 | - [Installation](#installation)
33 | - [Usage](#usage)
34 | - [Deployment](#deployment)
35 | - [Roadmap](#roadmap)
36 | - [Contributing](#contributing)
37 | - [License](#license)
38 | - [Authors](#authors)
39 | - [Acknowledgements](#acknowledgements)
40 |
41 |
42 | 
43 |
44 |
45 |
46 | ## About The Project
47 |
48 | > Where does all my money go?
49 |
50 | If you have been asking this question to yourself frequently, you are not alone. Handling finances can be tricky. This project is an attempt to help you plan right, so that you worry less while living from paycheck to paycheck.
51 |
52 |
53 | ## Supported Receipts
54 |
55 | - [x] Amazon
56 |
57 | - [x] Flipkart
58 |
59 | - [x] Myntra
60 |
61 | - [x] Ola
62 |
63 | - [x] Uber
64 |
65 | - [ ] Zomato
66 |
67 | - [ ] Swiggy
68 |
69 | - [ ] Curefit
70 |
71 |
72 | ## Built With
73 |
74 | * [Flask](https://flask.palletsprojects.com/en/1.1.x)
75 | * [Heroku](http://heroku.com)
76 | * [Gmail API](https://developers.google.com/gmail/api)
77 | * [Beautiful Soup](https://www.crummy.com/software/BeautifulSoup)
78 | * [Altair](https://altair-viz.github.io)
79 | * [SendGrid](https://sendgrid.com)
80 |
81 |
82 |
83 |
84 | ## Getting Started
85 |
86 | These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See [deployment](#deployment) for notes on how to deploy the project on a live system.
87 |
88 | ### Prerequisites
89 |
90 | * python `>=3.6`
91 | * pip
92 | * [Chrome](https://www.google.com/chrome)
93 | * [ChromeDriver](https://chromedriver.chromium.org)
94 |
95 |
96 | ### Installation
97 |
98 | 1. Clone the repo
99 | ```sh
100 | git clone https://github.com/Bahi-Khata-App/Bahi-Khata
101 | ```
102 | 2. Install the dependencies
103 | ```sh
104 | pip install -r requirements.txt
105 | ```
106 | 3. Setup Gmail API
107 | 1. Check `gmail.readonly` scope in your Gmail API OAuth consent page
108 | 2. Add `http://localhost:5000/push` as redirect URI while generating credentials
109 | 3. Download and place your Gmail API credentials in `data/credentials.json`
110 | 4. Place your SendGrid API credentials in `data/sendgrid.json`
111 | 5. (Optional) Place your analytics tracking script in `base.html`
112 |
113 |
114 |
115 | ## Usage
116 |
117 | 1. Set flask environment variable
118 | ```sh
119 | export FLASK_APP="gmail_flask.py"
120 | ```
121 | 2. Set `LOCAL_DEV = True` in `gmail_flask.py`
122 | 3. `flask run`
123 | 4. Complete the one time app verification
124 |
125 | 
126 |
127 | 5. If any relevant data is found, you'll receive an email report similar as below
128 |
129 | 
130 |
131 |
132 |
133 | ## Deployment
134 |
135 | 1. Set up [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli).
136 | 2. Add redirect URI `/push` in Gmail API console.
137 | 3. Add the [chromedriver](https://github.com/heroku/heroku-buildpack-chromedriver) and [google-chrome](https://github.com/heroku/heroku-buildpack-google-chrome) buildpacks in app settings on your Heroku dashboard.
138 | 4. Configure environment variables for your app in the dashboard.
139 |
140 | | KEY | VALUE |
141 | | ------------------- | ------------------------------------- |
142 | | `CHROMEDRIVER_PATH` | `/app/.chromedriver/bin/chromedriver` |
143 | | `GOOGLE_CHROME_BIN` | `/app/.apt/usr/bin/google-chrome` |
144 |
145 |
146 |
147 | ## Roadmap
148 |
149 | See the [open issues](https://github.com/Bahi-Khata-App/Bahi-Khata/issues) for a list of proposed features (and known issues).
150 |
151 |
152 |
153 |
154 | ## Contributing
155 |
156 | Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.
157 |
158 | 1. Fork the Project
159 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
160 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
161 | 4. Push to the Branch (`git push origin feature/AmazingFeature`)
162 | 5. Open a Pull Request
163 |
164 |
165 |
166 |
167 | ## License
168 |
169 | Distributed under the GPLv3 License. See `LICENSE` for more information.
170 |
171 |
172 |
173 | ## Authors
174 |
175 | * [Rohit Ner](https://github.com/rohitner)
176 | * [Nishant Nikhil](https://github.com/nishnik)
177 |
178 |
179 |
180 | ## Acknowledgements
181 |
182 | * Hat tip to anyone whose code was used
183 |
--------------------------------------------------------------------------------
/auth.py:
--------------------------------------------------------------------------------
1 | from flask import (
2 | Blueprint, render_template, redirect,
3 | url_for, request, flash)
4 | from flask_login import login_user, logout_user, login_required
5 | from werkzeug.security import generate_password_hash, check_password_hash
6 | from models import User
7 | from gmail_flask import db
8 |
9 | auth = Blueprint('auth', __name__)
10 |
11 |
12 | @auth.route('/login', methods=['GET'])
13 | def login():
14 | return render_template('login.html')
15 |
16 |
17 | @auth.route('/signup', methods=['GET'])
18 | def signup():
19 | return render_template('signup.html')
20 |
21 |
22 | @auth.route('/logout')
23 | @login_required
24 | def logout():
25 | logout_user()
26 | return redirect(url_for('main.index'))
27 |
28 |
29 | @auth.route('/signup', methods=['POST'])
30 | def signup_post():
31 | email = request.form.get('email')
32 | name = request.form.get('name')
33 | password = request.form.get('password')
34 |
35 | # if this returns a user, then the email already exists in database
36 | user = User.query.filter_by(email=email).first()
37 |
38 | if user: # if a user is found, we want to redirect back to signup page so user can try again
39 | flash('Email address already exists')
40 | return redirect(url_for('auth.signup'))
41 |
42 | # create new user with the form data. Hash the password so plaintext version isn't saved.
43 | new_user = User(email=email, name=name,
44 | password=generate_password_hash(password, method='sha256'))
45 |
46 | # add the new user to the database
47 | db.session.add(new_user)
48 | db.session.commit()
49 |
50 | return redirect(url_for('auth.login'))
51 |
52 |
53 | @auth.route('/login', methods=['POST'])
54 | def login_post():
55 | email = request.form.get('email')
56 | password = request.form.get('password')
57 | remember = True if request.form.get('remember') else False
58 |
59 | user = User.query.filter_by(email=email).first()
60 |
61 | # check if user actually exists
62 | # take the user supplied password, hash it, and compare it to the hashed password in database
63 | if not user or not check_password_hash(user.password, password):
64 | flash('Please check your login details and try again.')
65 | # if user doesn't exist or password is wrong, reload the page
66 | return redirect(url_for('auth.login'))
67 |
68 | # if the above check passes, then we know the user has the right credentials
69 | login_user(user, remember=remember)
70 | return redirect(url_for('main.profile'))
71 |
--------------------------------------------------------------------------------
/create-db.py:
--------------------------------------------------------------------------------
1 | from gmail_flask import db, create_app
2 | db.create_all(app=create_app())
3 |
--------------------------------------------------------------------------------
/gmail_flask.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | import base64
3 |
4 | from flask import *
5 | import pickle
6 | import os.path
7 | import base64
8 | from googleapiclient.discovery import build
9 | from google_auth_oauthlib.flow import InstalledAppFlow
10 | from google.auth.transport.requests import Request
11 | import pickle
12 | import datetime
13 | import sys
14 | import importlib
15 | from threading import Thread
16 | import sendgrid
17 | from sendgrid import SendGridAPIClient
18 | from sendgrid.helpers.mail import (
19 | Mail, Attachment, FileContent, FileName,
20 | FileType, Disposition, ContentId)
21 |
22 | import pandas as pd
23 | from pandas.plotting import register_matplotlib_converters
24 | import numpy as np
25 | from flask_sqlalchemy import SQLAlchemy
26 | from flask_login import LoginManager
27 | import altair as alt
28 | from altair_saver import save
29 |
30 | LOCAL_DEV = False
31 | PARAMS_FILE = 'params_central.json'
32 | IGNORE_LIST = ['curefit']
33 |
34 | with open(PARAMS_FILE) as params_file:
35 | params = json.load(params_file)
36 |
37 | SCOPES = ['https://www.googleapis.com/auth/gmail.readonly', 'https://www.googleapis.com/auth/userinfo.email', 'openid', 'https://www.googleapis.com/auth/userinfo.profile']
38 |
39 | if LOCAL_DEV:
40 | credentials_filename = 'data/credentials.json.bak'
41 | REDIRECT_URL = "http://localhost:5000/push"
42 | else:
43 | credentials_filename = 'data/credentials.json'
44 | REDIRECT_URL = "https://bahi-khata-app.herokuapp.com/push"
45 |
46 |
47 | flow = InstalledAppFlow.from_client_secrets_file(
48 | credentials_filename, SCOPES)
49 | flow.redirect_uri = REDIRECT_URL
50 | authorization_url, state = flow.authorization_url(access_type='offline', include_granted_scopes='true')
51 | credentials = None
52 |
53 | db = SQLAlchemy()
54 |
55 |
56 | def create_app():
57 | app = Flask(__name__)
58 |
59 | app.config['SECRET_KEY'] = '9OLWxND4o83j4K4iuopO'
60 | app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
61 | app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
62 |
63 | db.init_app(app)
64 |
65 | login_manager = LoginManager()
66 | login_manager.login_view = 'auth.login'
67 | login_manager.init_app(app)
68 |
69 | from models import User
70 |
71 | @login_manager.user_loader
72 | def load_user(user_id):
73 | # since the user_id is just the primary key of our user table, use it in the query for the user
74 | return User.query.get(int(user_id))
75 |
76 | # blueprint for auth routes in our app
77 | from auth import auth as auth_blueprint
78 | app.register_blueprint(auth_blueprint)
79 |
80 | # blueprint for non-auth parts of app
81 | from main import main as main_blueprint
82 | app.register_blueprint(main_blueprint)
83 |
84 | return app
85 |
86 |
87 | app = create_app()
88 |
89 | # Use this for getting form authenticating with GMail
90 | @app.route('/auth', methods=['GET', 'POST'])
91 | def start_auth():
92 | global authorization_url
93 | return redirect(authorization_url)
94 |
95 | @app.route('/push')
96 | def build_service():
97 | print ("Done")
98 | print (request)
99 | print (request.args.get("code"))
100 | flow.fetch_token(code=request.args.get("code"))
101 | credentials = flow.credentials # write it to file
102 | service = build('gmail', 'v1', credentials=credentials)
103 | thread = Thread(target=push_report, args=(service,))
104 | thread.daemon = True
105 | thread.start()
106 | return redirect(url_for('display_thankyou'))
107 |
108 | @app.route('/thankyou', methods=['GET'])
109 | def display_thankyou():
110 | return render_template('thankyou.html')
111 |
112 | def push_report(service):
113 | user_email = service.users().getProfile(userId='me').execute()['emailAddress']
114 | print(user_email)
115 | global params
116 | y_bottom = np.zeros(12)
117 | charts = []
118 | df1 = pd.DataFrame()
119 | for company_name in params:
120 | company = params[company_name]
121 | if company_name in IGNORE_LIST or not create_dump(service, company):
122 | continue
123 | # if company_name in IGNORE_LIST:
124 | # continue
125 | try:
126 | x, y = getData(company_name, company['fname'])
127 | x, y = coerceData(x, y)
128 | except Exception as e:
129 | print(e)
130 | continue
131 | print(company_name, y)
132 | y_bottom = np.add(y_bottom, y)
133 | source = pd.DataFrame({
134 | 'month': x,
135 | 'spent': y,
136 | 'company': [company_name] * 12
137 | })
138 | chart = alt.Chart(source).mark_bar(size=15).encode(
139 | x=alt.X('month', title=''),
140 | y=alt.Y('spent', title='Amount spent (₹)')
141 | ).properties(
142 | title=company_name,
143 | )
144 | charts.append(chart)
145 | source.set_index('month')
146 | if not df1.size:
147 | df1 = source
148 | else:
149 | df1 = df1.append(source)
150 | if not df1.size:
151 | print('No data found for ' + user_email)
152 | return
153 | stackedchart = alt.Chart(df1).mark_bar(size=15).encode(
154 | alt.X('month', title=''),
155 | y=alt.Y('sum(spent)', title='Amount spent (₹)'),
156 | color='company'
157 | ).properties(
158 | title='Aggregate Monthly Spending'
159 | )
160 | charts.insert(0, stackedchart)
161 | repchart = alt.VConcatChart(vconcat=charts)
162 | save(repchart, os.path.dirname(os.path.abspath(__file__)) + '/data/report.png', scale_factor=1.5)
163 | with app.app_context():
164 | context = {'amount': np.sum(y_bottom)}
165 | email_content = render_template('report.html', **context)
166 | push_email(email_content, user_email)
167 |
168 | def create_dump(service, company):
169 | query = company['query']
170 | after_time = company['after']
171 | filename_to_dump = company['fname']
172 | message_ids = []
173 |
174 | returned_request = service.users().messages().list(userId='me', q=query).execute()
175 | if 'messages' not in returned_request:
176 | return False
177 |
178 | message_ids += returned_request['messages']
179 |
180 | while 'nextPageToken' in returned_request:
181 | next_page_token = returned_request['nextPageToken']
182 | returned_request = service.users().messages().list(userId='me', q=query, pageToken = next_page_token).execute()
183 | message_ids += returned_request['messages']
184 |
185 | list_all_messages = []
186 | for i in range(len(message_ids)):
187 | msg_id = message_ids[i]['id']
188 | message = service.users().messages().get(userId='me', id=msg_id, format = 'full').execute()
189 | try:
190 | if (datetime.datetime.fromtimestamp(int(message['internalDate'])/1000).strftime('%Y-%m-%d %H:%M:%S') > after_time):
191 | list_all_messages.append(message)
192 | print ('Message snippet: %s' % message['snippet'])
193 | else:
194 | break
195 | except Exception as e:
196 | print (e)
197 | print ("Index", i, message['snippet'])
198 |
199 | with open(filename_to_dump, 'wb') as handle:
200 | pickle.dump(list_all_messages, handle)
201 | return True
202 |
203 |
204 | def push_email(email_content, user_email):
205 | message = Mail(
206 | from_email='admin@bahikhata.com',
207 | to_emails=user_email,
208 | subject='Bahi Khata Report',
209 | html_content= email_content)
210 | file_path = './static/images/bahi_khata.png'
211 | with open(file_path, 'rb') as f:
212 | data = f.read()
213 | encoded = base64.b64encode(data).decode()
214 | attachment = Attachment()
215 | attachment.file_content = FileContent(encoded)
216 | attachment.file_type = FileType('image/png')
217 | attachment.file_name = FileName('bahi_khata.png')
218 | attachment.disposition = Disposition('inline')
219 | attachment.content_id = ContentId('bahikhatalogo')
220 | message.attachment = attachment
221 | file_path = './data/report.png'
222 | with open(file_path, 'rb') as f:
223 | data = f.read()
224 | encoded = base64.b64encode(data).decode()
225 | attachment = Attachment()
226 | attachment.file_content = FileContent(encoded)
227 | attachment.file_type = FileType('image/png')
228 | attachment.file_name = FileName('report.png')
229 | attachment.disposition = Disposition('inline')
230 | attachment.content_id = ContentId('report')
231 | message.attachment = attachment
232 | with open('data/sendgrid.json') as f:
233 | SG_API_KEY = f.readline()
234 | try:
235 | sg = SendGridAPIClient(SG_API_KEY)
236 | response = sg.send(message)
237 | print(response.status_code)
238 | print(response.body)
239 | print(response.headers)
240 | except Exception as e:
241 | print(e.to_dict)
242 | return "sent email"
243 |
244 |
245 | def getData(company_name, filename_to_dump):
246 | sys.path.append('src')
247 | return importlib.import_module('src.analysis_' + company_name).getData(filename_to_dump)
248 |
249 |
250 | def coerceData(x, y):
251 | df = pd.DataFrame({'Amount': y}, index=x)
252 | df.index = pd.to_datetime(df.index.strftime('%Y-%m-%d'))
253 | df = df['Amount'].resample('M').sum()
254 | df = df.reindex(pd.date_range('2019-07-01', periods=12, freq='M')).fillna(0.0)
255 | # print(df.index)
256 | # print(df)
257 | x = df.index.tolist()
258 | y = df.values
259 | return x, y
260 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | from flask import Blueprint, render_template
2 | from flask_login import login_required, current_user
3 | from gmail_flask import db
4 |
5 | main = Blueprint('main', __name__)
6 |
7 |
8 | @main.route('/')
9 | def index():
10 | return render_template('index.html')
11 |
12 |
13 | @main.route('/profile')
14 | @login_required
15 | def profile():
16 | return render_template('profile.html', name=current_user.name)
17 |
--------------------------------------------------------------------------------
/models.py:
--------------------------------------------------------------------------------
1 | from flask_login import UserMixin
2 | from gmail_flask import db
3 |
4 | # Models created in Flask-SQLAlchemy are represented by classes
5 | # which then translate to tables in a database
6 |
7 |
8 | class User(UserMixin, db.Model):
9 | # primary keys are required by SQLAlchemy
10 | id = db.Column(db.Integer, primary_key=True)
11 | email = db.Column(db.String(100), unique=True)
12 | password = db.Column(db.String(100))
13 | name = db.Column(db.String(1000))
14 |
--------------------------------------------------------------------------------
/params_central.json:
--------------------------------------------------------------------------------
1 | {
2 | "amazon": {
3 | "query": "from:(Amazon.in) subject:(amazon.in your order) -{update been} ",
4 | "after": "2019-05",
5 | "fname": "data/0617_one_year_dump_amazon.pickle"
6 | },
7 | "curefit": {
8 | "query": "from:noreply@cure.fit Confirmation for ",
9 | "after": "2019-05",
10 | "fname": "data/0617_one_year_dump_curefit.pickle"
11 | },
12 | "flipkart": {
13 | "query": "from:(Flipkart.com) Your order has been successfully placed ",
14 | "after": "2019-05",
15 | "fname": "data/0617_one_year_dump_flipkart.pickle"
16 | },
17 | "myntra": {
18 | "query": "from:(Myntra Updates) Your Myntra Order Confirmation -{item} ",
19 | "after": "2019-05",
20 | "fname": "data/0617_one_year_dump_myntra.pickle"
21 | },
22 | "ola": {
23 | "query": "ola your ride to",
24 | "after": "2019-05",
25 | "fname": "data/0617_one_year_dump_ola.pickle"
26 | },
27 | "uber": {
28 | "query": "uber receipts trip with uber",
29 | "after": "2019-05",
30 | "fname": "data/0617_one_year_dump_uber.pickle"
31 | }
32 | }
--------------------------------------------------------------------------------
/readme:
--------------------------------------------------------------------------------
1 | At 6:08 PM, March 14
2 | gmail_flask.py queries mail for all the cure fit related transaction mails
3 | `dump_cure_fit.pickle` is the lists of htmls for the messages
4 |
5 |
6 | TO RUN:
7 | export FLASK_APP=gmail_flask.py
8 | python3 -m flask run
9 |
10 |
11 | First make changes to gmail_flask.py to include the desired query.
12 | Dump the output in a .pickel format in data/
13 | Write an analysis file in src/
14 |
15 |
16 | Selenium needed by altair to export to png
17 | Add chromedriver, google-chrome build-packages on heroku
18 | to make selenium work, also add config vars in heroku settings
19 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | altair==4.0.1
2 | altair_saver==0.5.0
3 | beautifulsoup4==4.9.1
4 | cachetools==4.1.0
5 | certifi==2020.6.20
6 | chardet==3.0.4
7 | click==7.1.2
8 | cycler==0.10.0
9 | Flask==1.1.2
10 | Flask-Login==0.5.0
11 | Flask-SQLAlchemy==2.4.3
12 | google-api-core==1.21.0
13 | google-api-python-client==1.9.3
14 | google-auth==1.18.0
15 | google-auth-httplib2==0.0.3
16 | google-auth-oauthlib==0.4.1
17 | googleapis-common-protos==1.52.0
18 | gunicorn==20.0.4
19 | httplib2==0.18.1
20 | idna==2.9
21 | itsdangerous==1.1.0
22 | Jinja2==2.11.2
23 | kiwisolver==1.1.0
24 | MarkupSafe==1.1.1
25 | matplotlib==3.0.3
26 | numpy==1.18.5
27 | oauthlib==3.1.0
28 | pandas==1.0.5
29 | protobuf==3.12.2
30 | pyasn1==0.4.8
31 | pyasn1-modules==0.2.8
32 | pyparsing==2.4.7
33 | python-dateutil==2.8.1
34 | python-http-client==3.2.7
35 | pytz==2020.1
36 | requests==2.24.0
37 | requests-oauthlib==1.3.0
38 | rsa==4.6
39 | sendgrid==6.3.1
40 | sendgrid-python==0.1.1
41 | six==1.15.0
42 | soupsieve==2.0.1
43 | uritemplate==3.0.1
44 | urllib3==1.25.9
45 | Werkzeug==1.0.1
46 |
--------------------------------------------------------------------------------
/src/analysis_amazon.py:
--------------------------------------------------------------------------------
1 | import pickle
2 | import matplotlib.pyplot as plt
3 | import numpy as np
4 | import matplotlib.dates as mdates
5 | from utils import parse_mail
6 | from bs4 import BeautifulSoup
7 | import datetime
8 | import re
9 | import os
10 |
11 |
12 | def getData(dumpfile):
13 | with open(dumpfile, 'rb') as handle:
14 | data_dump = pickle.load(handle)
15 |
16 | parsed_data = parse_mail(data_dump)
17 |
18 | x = []
19 | y = []
20 | for parsed_row in parsed_data:
21 | date_this = parsed_row['date']
22 | snippet = parsed_row['snippet']
23 | subject_this = parsed_row['subject']
24 | if 'Your Amazon.in order' in subject_this:
25 | soup = BeautifulSoup(parsed_row['str'], features="html.parser")
26 | list_amt = soup.findAll("strong", text=re.compile("Rs."))
27 | if not len(list_amt):
28 | continue
29 | amount_parsed = float(str(list_amt[-1]).split(".")[1].replace(',',''))
30 | date_parsed = datetime.datetime.strptime(date_this, '%a, %d %b %Y %H:%M:%S %z')
31 | x.append(date_parsed)
32 | y.append(amount_parsed)
33 |
34 | return x[::-1], y[::-1]
35 |
--------------------------------------------------------------------------------
/src/analysis_curefit.py:
--------------------------------------------------------------------------------
1 | import pickle
2 | import matplotlib.pyplot as plt
3 | import numpy as np
4 | import matplotlib.dates as mdates
5 | from bs4 import BeautifulSoup
6 | import os
7 |
8 | # This is old now, the way we dump now has changed so would have to modify it accordingly.
9 | # TODO: Nishant
10 | def getData(dumpfile):
11 | with open(dumpfile, 'rb') as handle:
12 | data_cure_fit = pickle.load(handle)
13 | for i in range(len(data_cure_fit)):
14 | sample_data = data_cure_fit[i]
15 | soup=BeautifulSoup(sample_data[0])
16 | elements = soup.findAll(attrs = {"style": "padding-left: 20px; width: 55%"})
17 | assert(len(elements) >= 2)
18 | i = -1
19 | total_sales = []
20 | for i in range(len(data_cure_fit)):
21 | sample_data = data_cure_fit[i]
22 | soup=BeautifulSoup(sample_data[0])
23 | elements = soup.findAll(attrs = {"style": "padding-left: 20px; width: 55%"})
24 | item_list = []
25 | for item in elements[1:]:
26 | item_name = item.text.strip()
27 | attrs = item.fetchNextSiblings()
28 | ind_price = attrs[0].text
29 | quantity = attrs[1].text
30 | total_price = attrs[2].text
31 | item_list.append([item_name, ind_price, quantity, total_price])
32 | attributes_of_sale = {}
33 | elements_of_total_bill = soup.findAll("td", attrs = {"style": "padding-left: 20px; width: 85%"})
34 | for element in elements_of_total_bill:
35 | attributes_of_sale[element.text] = element.fetchNextSiblings()[0].text
36 | attributes_of_sale["item_list"] = item_list
37 | attributes_of_sale["date"] = sample_data[-1]
38 | attributes_of_sale["subject"] = sample_data[-2]
39 | attributes_of_sale["snippet"] = sample_data[-3]
40 | total_sales.append(attributes_of_sale)
41 | num_orders = []
42 | cumulative = 0
43 | for a in total_sales:
44 | # num_orders.append([int(a['subject'].split(" ")[-1]), datetime.datetime.strptime(a['date'], "%a, %d %b %Y %H:%M:%S %z").date()])
45 | # num_orders.append([float(a['Total Payable']), datetime.datetime.strptime(a['date'], "%a, %d %b %Y %H:%M:%S %z").date()])
46 | cumulative += float(a['Total Payable'])
47 | num_orders.append([cumulative, datetime.datetime.strptime(a['date'], "%a, %d %b %Y %H:%M:%S %z").date()])
48 | total_sales.reverse()
49 | num_orders = []
50 | cumulative = 0
51 | for a in total_sales:
52 | # num_orders.append([int(a['subject'].split(" ")[-1]), datetime.datetime.strptime(a['date'], "%a, %d %b %Y %H:%M:%S %z").date()])
53 | # num_orders.append([float(a['Total Payable']), datetime.datetime.strptime(a['date'], "%a, %d %b %Y %H:%M:%S %z").date()])
54 | cumulative += float(a['Total Payable'])
55 | num_orders.append([cumulative, datetime.datetime.strptime(a['date'], "%a, %d %b %Y %H:%M:%S %z").strftime("%Y%m%d")])
56 | num_orders = np.array(num_orders)
57 | x = num_orders[:,1]
58 | y = num_orders[:,0]
59 | uniqueValues, indicesList = np.unique(x, return_index=True)
60 | x_uni = np.array(x[indicesList], dtype=float)
61 | y_uni = np.array(y[indicesList], dtype=float)
62 | return x_uni, y_uni
63 |
64 | getData("")
--------------------------------------------------------------------------------
/src/analysis_flipkart.py:
--------------------------------------------------------------------------------
1 | import pickle
2 | import matplotlib.pyplot as plt
3 | import numpy as np
4 | import matplotlib.dates as mdates
5 | from utils import parse_mail
6 | from bs4 import BeautifulSoup
7 | import datetime
8 | import re
9 | import os
10 |
11 |
12 | def getData(dumpfile):
13 | with open(dumpfile, 'rb') as handle:
14 | data_dump = pickle.load(handle)
15 |
16 | parsed_data = parse_mail(data_dump)
17 |
18 | x = []
19 | y = []
20 | for parsed_row in parsed_data:
21 | date_this = parsed_row['date']
22 | snippet = parsed_row['snippet']
23 | subject_this = parsed_row['subject']
24 | soup = BeautifulSoup(parsed_row['str'], features='html.parser')
25 | amount_parsed = float(str(soup.findAll('span', text=re.compile('₨.'))[-1]).split('₨.')[1].split('<')[0])
26 | try:
27 | date_parsed = datetime.datetime.strptime(date_this, '%a, %d %b %Y %H:%M:%S %z (UTC)')
28 | except Exception as e:
29 | date_parsed = datetime.datetime.strptime(date_this, '%a, %d %b %Y %H:%M:%S %z')
30 | print(e, 'another date format used')
31 | x.append(date_parsed)
32 | y.append(amount_parsed)
33 | return x[::-1], y[::-1]
34 |
--------------------------------------------------------------------------------
/src/analysis_myntra.py:
--------------------------------------------------------------------------------
1 | import pickle
2 | import matplotlib.pyplot as plt
3 | import numpy as np
4 | import matplotlib.dates as mdates
5 | from utils import parse_mail
6 | from bs4 import BeautifulSoup
7 | import datetime
8 | import re
9 | import os
10 |
11 |
12 | def getData(dumpfile):
13 | with open(dumpfile, 'rb') as handle:
14 | data_dump = pickle.load(handle)
15 |
16 | parsed_data = parse_mail(data_dump)
17 |
18 | x = []
19 | y = []
20 | for parsed_row in parsed_data:
21 | date_this = parsed_row['date']
22 | snippet = parsed_row['snippet']
23 | subject_this = parsed_row['subject']
24 | soup = BeautifulSoup(parsed_row['str'], features='html.parser')
25 | amount_parsed = float(str(soup.findAll('td', text=re.compile('₹'))[-1]).split('₹')[1].split('<')[0])
26 | date_parsed = datetime.datetime.strptime(date_this, '%a, %d %b %Y %H:%M:%S %z')
27 | x.append(date_parsed)
28 | y.append(amount_parsed)
29 | return x[::-1], y[::-1]
30 |
--------------------------------------------------------------------------------
/src/analysis_ola.py:
--------------------------------------------------------------------------------
1 | import pickle
2 | import matplotlib.pyplot as plt
3 | import numpy as np
4 | import matplotlib.dates as mdates
5 | from utils import parse_mail
6 | from bs4 import BeautifulSoup
7 | import datetime
8 | import re
9 | import os
10 |
11 |
12 | def getData(dumpfile):
13 | with open(dumpfile, 'rb') as handle:
14 | data_dump = pickle.load(handle)
15 |
16 | parsed_data = parse_mail(data_dump)
17 |
18 | x = []
19 | y = []
20 | for parsed_row in parsed_data:
21 | date_this = parsed_row['date']
22 | snippet = parsed_row['snippet']
23 | subject_this = parsed_row['subject']
24 | if 'ride to' in subject_this:
25 | amount_parsed = float(snippet.split('₹')[1].split(' ')[0])
26 | date_parsed = datetime.datetime.strptime(date_this, '%a, %d %b %Y %H:%M:%S %z')
27 | x.append(date_parsed)
28 | y.append(amount_parsed)
29 | return x[::-1], y[::-1]
30 |
--------------------------------------------------------------------------------
/src/analysis_uber.py:
--------------------------------------------------------------------------------
1 | import pickle
2 | import matplotlib.pyplot as plt
3 | import numpy as np
4 | import matplotlib.dates as mdates
5 | from utils import parse_mail
6 | from bs4 import BeautifulSoup
7 | import pandas as pd
8 | import datetime
9 | import re
10 | import os
11 |
12 |
13 | def getData(dumpfile):
14 | with open(dumpfile, 'rb') as handle:
15 | data_dump = pickle.load(handle)
16 |
17 | parsed_data = parse_mail(data_dump)
18 |
19 | x = []
20 | y = []
21 | for parsed_row in parsed_data:
22 | date_this = parsed_row['date']
23 | snippet = parsed_row['snippet']
24 | subject_this = parsed_row['subject']
25 | if 'trip with Uber' in subject_this and not 'We were unable to charge' in snippet:
26 | amount_parsed = float(snippet.split('₹')[1].split(" ")[0])
27 | date_parsed = ""
28 | try:
29 | date_parsed = datetime.datetime.strptime(date_this[:-6], '%a, %d %b %Y %H:%M:%S %z')
30 | except ValueError:
31 | date_parsed = datetime.datetime.strptime(date_this, '%a, %d %b %Y %H:%M:%S %z')
32 | x.append(date_parsed)
33 | y.append(amount_parsed)
34 |
35 | return x[::-1], y[::-1]
--------------------------------------------------------------------------------
/src/fetch_uber.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | import pickle
3 | import os.path
4 | from googleapiclient.discovery import build
5 | from google_auth_oauthlib.flow import InstalledAppFlow
6 | from google.auth.transport.requests import Request
7 | import base64
8 | from utils import authenticate
9 | import datetime
10 |
11 |
12 | #### PARAMS
13 | ### You will mostly need to change these:
14 | query = 'uber receipts trip with uber'
15 | # 'from:noreply@cure.fit Confirmation for ' # for cure.fit
16 | after_time = '2019-05' # only messages after this time period gets their content
17 | filename_to_dump = '../data/0617_one_year_dump_uber.pickle' # should be as verbose as we can so that we don't have difficulty later on
18 | #### END of parmas
19 |
20 |
21 | service = authenticate()
22 |
23 | #### Firstly we will fetch message ids, then we will fetch the content of it
24 | message_ids = []
25 |
26 | ### Fetch Message Ids
27 | ### This is more like a do while because we need to know if the first query has a nextPageToken or not
28 | returned_request = service.users().messages().list(userId='me', q= query).execute()
29 | message_ids += returned_request['messages']
30 | next_page_token = returned_request['nextPageToken']
31 |
32 | while True:
33 | returned_request = service.users().messages().list(userId='me', q= query, pageToken = next_page_token).execute()
34 | message_ids += returned_request['messages']
35 | if 'nextPageToken' in returned_request:
36 | next_page_token = returned_request['nextPageToken']
37 | else:
38 | break
39 | #### Fetched Message Ids
40 |
41 | #### Fetch Message Content
42 |
43 | list_all_messages = []
44 | for i in range(len(message_ids)):
45 | msg_id = message_ids[i]['id']
46 | message = service.users().messages().get(userId='me', id=msg_id, format = 'full').execute()
47 | try:
48 | if (datetime.datetime.fromtimestamp(int(message['internalDate'])/1000).strftime('%Y-%m-%d %H:%M:%S') > after_time):
49 | list_all_messages.append(message)
50 | print ('Message snippet: %s' % message['snippet'])
51 | else:
52 | break
53 | except Exception as e:
54 | print (e)
55 | print ("Index", i, message['snippet'])
56 |
57 |
58 | #### Dump message content
59 | with open(filename_to_dump, 'wb') as handle:
60 | pickle.dump(list_all_messages, handle)
61 |
62 |
63 |
64 |
65 | # lists['']
66 |
67 | # message = service.users().messages().get(userId='me', id=msg_id, format = 'full').execute()
68 |
69 | # msg_str = ""
70 | # for j in range(len(message['payload']['parts'])):
71 | # if message['payload']['parts'][j]['mimeType'] == 'text/html':
72 | # msg_str = base64.urlsafe_b64decode(message['payload']['parts'][j]['body']['data'])
73 |
74 |
75 | # msg_str = msg_str.decode("utf-8")
76 | # print ('Message snippet: %s' % message['snippet'])
77 | # print (message)
78 | # f = open('out.html', 'w')
79 | # f.write(msg_str.decode("utf=8"))
80 | # f.close()
81 | # labels = results.get('labels', [])
82 |
83 | # if not labels:
84 | # print('No labels found.')
85 | # else:
86 | # print('Labels:')
87 | # for label in labels:
88 | # print(label['name'])
89 |
90 | # i = 0
91 | # msg_id = message_ids[i]['id']
92 | # message = service.users().messages().get(userId='me', id=msg_id, format = 'full').execute()
93 | # try:
94 | # msg_str = ""
95 | # for j in range(len(message['payload']['parts'])):
96 | # if message['payload']['parts'][j]['mimeType'] == 'text/html':
97 | # msg_str = base64.urlsafe_b64decode(message['payload']['parts'][j]['body']['data'])
98 | # all_messages += (msg_str.decode("utf-8") + "\n\n\n")
99 | # list_all_messages.append([msg_str.decode("utf-8"), message['snippet'], message['payload']['headers'][16]['value'], message['payload']['headers'][18]['value']])
100 | # print ('Message snippet: %s' % message['snippet'])
101 | # except Exception as e:
102 | # print (e)
103 | # print ("Index", i)
104 |
--------------------------------------------------------------------------------
/src/utils.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | import pickle
3 | import os.path
4 | from googleapiclient.discovery import build
5 | from google_auth_oauthlib.flow import InstalledAppFlow
6 | from google.auth.transport.requests import Request
7 | import base64
8 |
9 | def authenticate():
10 | # If modifying these scopes, delete the file token.pickle.
11 | SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
12 |
13 | """Shows basic usage of the Gmail API.
14 | Lists the user's Gmail labels.
15 | """
16 | creds = None
17 | # The file token.pickle stores the user's access and refresh tokens, and is
18 | # created automatically when the authorization flow completes for the first
19 | # time.
20 | if os.path.exists('../data/token.pickle'):
21 | with open('../data/token.pickle', 'rb') as token:
22 | creds = pickle.load(token)
23 |
24 |
25 | # If there are no (valid) credentials available, let the user log in.
26 | if not creds or not creds.valid:
27 | if creds and creds.expired and creds.refresh_token:
28 | creds.refresh(Request())
29 | else:
30 | flow = InstalledAppFlow.from_client_secrets_file(
31 | '../data/credentials.json', SCOPES)
32 | creds = flow.run_local_server(port=0)
33 | # Save the credentials for the next run
34 | with open('../data/token.pickle', 'wb') as token:
35 | pickle.dump(creds, token)
36 |
37 | service = build('gmail', 'v1', credentials=creds)
38 | return service
39 |
40 | def parse_mail(data_dump):
41 | # subject, from, date, snippet, email_html
42 | data_arr = []
43 | for message in data_dump:
44 | if 'multipart' in message['payload']['mimeType']:
45 | for j in range(len(message['payload']['parts'])):
46 | if message['payload']['parts'][j]['mimeType'] == 'text/html':
47 | if "data" in message['payload']['parts'][j]['body']:
48 | this_str = base64.urlsafe_b64decode(message['payload']['parts'][j]['body']['data'])
49 | else:
50 | this_str = b"[attachment here]"
51 | this_str = (this_str.decode("utf-8") + "\n\n\n")
52 | else:
53 | this_str = base64.urlsafe_b64decode(message['payload']['body']['data'])
54 | this_str = (this_str.decode("utf-8") + "\n\n\n")
55 | this_snippet = message['snippet']
56 | this_subject = -1
57 | this_from = -1
58 | this_date = -1
59 | for i in range(len(message['payload']['headers'])):
60 | # print (message['payload']['headers'][i]['name'])
61 | # print (message['payload']['headers'][i]['value'], "\n\n\n")
62 | if message['payload']['headers'][i]['name'] == 'Subject':
63 | this_subject = message['payload']['headers'][i]['value']
64 | elif message['payload']['headers'][i]['name'] == 'From':
65 | this_from = message['payload']['headers'][i]['value']
66 | elif message['payload']['headers'][i]['name'] == 'Date':
67 | this_date = message['payload']['headers'][i]['value']
68 | this_dict= {}
69 | this_dict['subject'] = this_subject
70 | this_dict['from'] = this_from
71 | this_dict['date'] = this_date
72 | this_dict['snippet'] = this_snippet
73 | this_dict['str'] = this_str
74 | data_arr.append(this_dict)
75 | return data_arr
76 |
77 |
78 |
--------------------------------------------------------------------------------
/static/css/main.css:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | /*//////////////////////////////////////////////////////////////////
6 | [ FONT ]*/
7 |
8 | @font-face {
9 | font-family: Poppins-Regular;
10 | src: url('../fonts/poppins/Poppins-Regular.ttf');
11 | }
12 |
13 | @font-face {
14 | font-family: Poppins-Bold;
15 | src: url('../fonts/poppins/Poppins-Bold.ttf');
16 | }
17 |
18 | @font-face {
19 | font-family: Poppins-Medium;
20 | src: url('../fonts/poppins/Poppins-Medium.ttf');
21 | }
22 |
23 | @font-face {
24 | font-family: Montserrat-Bold;
25 | src: url('../fonts/montserrat/Montserrat-Bold.ttf');
26 | }
27 |
28 | /*//////////////////////////////////////////////////////////////////
29 | [ RESTYLE TAG ]*/
30 |
31 | * {
32 | margin: 0px;
33 | padding: 0px;
34 | box-sizing: border-box;
35 | }
36 |
37 | body, html {
38 | height: 100%;
39 | font-family: Poppins-Regular, sans-serif;
40 | }
41 |
42 | /*---------------------------------------------*/
43 | a {
44 | font-family: Poppins-Regular;
45 | font-size: 14px;
46 | line-height: 1.7;
47 | color: #666666;
48 | margin: 0px;
49 | transition: all 0.4s;
50 | -webkit-transition: all 0.4s;
51 | -o-transition: all 0.4s;
52 | -moz-transition: all 0.4s;
53 | }
54 |
55 | a:focus {
56 | outline: none !important;
57 | }
58 |
59 | a:hover {
60 | text-decoration: none;
61 | color: #57b846;
62 | }
63 |
64 | /*---------------------------------------------*/
65 | h1,h2,h3,h4,h5,h6 {
66 | margin: 0px;
67 | }
68 |
69 | p {
70 | font-family: Poppins-Regular;
71 | font-size: 14px;
72 | line-height: 1.7;
73 | color: #666666;
74 | margin: 0px;
75 | }
76 |
77 | ul, li {
78 | margin: 0px;
79 | list-style-type: none;
80 | }
81 |
82 |
83 | /*---------------------------------------------*/
84 | input {
85 | outline: none;
86 | border: none;
87 | }
88 |
89 | textarea {
90 | outline: none;
91 | border: none;
92 | }
93 |
94 | textarea:focus, input:focus {
95 | border-color: transparent !important;
96 | }
97 |
98 | input:focus::-webkit-input-placeholder { color:transparent; }
99 | input:focus:-moz-placeholder { color:transparent; }
100 | input:focus::-moz-placeholder { color:transparent; }
101 | input:focus:-ms-input-placeholder { color:transparent; }
102 |
103 | textarea:focus::-webkit-input-placeholder { color:transparent; }
104 | textarea:focus:-moz-placeholder { color:transparent; }
105 | textarea:focus::-moz-placeholder { color:transparent; }
106 | textarea:focus:-ms-input-placeholder { color:transparent; }
107 |
108 | input::-webkit-input-placeholder { color: #999999; }
109 | input:-moz-placeholder { color: #999999; }
110 | input::-moz-placeholder { color: #999999; }
111 | input:-ms-input-placeholder { color: #999999; }
112 |
113 | textarea::-webkit-input-placeholder { color: #999999; }
114 | textarea:-moz-placeholder { color: #999999; }
115 | textarea::-moz-placeholder { color: #999999; }
116 | textarea:-ms-input-placeholder { color: #999999; }
117 |
118 | /*---------------------------------------------*/
119 | button {
120 | outline: none !important;
121 | border: none;
122 | background: transparent;
123 | }
124 |
125 | button:hover {
126 | cursor: pointer;
127 | }
128 |
129 | iframe {
130 | border: none !important;
131 | }
132 |
133 |
134 | /*//////////////////////////////////////////////////////////////////
135 | [ Utility ]*/
136 | .txt1 {
137 | font-family: Poppins-Regular;
138 | font-size: 13px;
139 | line-height: 1.5;
140 | color: #999999;
141 | }
142 |
143 | .txt2 {
144 | font-family: Poppins-Regular;
145 | font-size: 13px;
146 | line-height: 1.5;
147 | color: #666666;
148 | }
149 |
150 |
151 | /*//////////////////////////////////////////////////////////////////
152 | [ login ]*/
153 |
154 | .limiter {
155 | width: 100%;
156 | margin: 0 auto;
157 | }
158 |
159 | .container-login100 {
160 | width: 100%;
161 | min-height: 100vh;
162 | display: -webkit-box;
163 | display: -webkit-flex;
164 | display: -moz-box;
165 | display: -ms-flexbox;
166 | display: flex;
167 | flex-wrap: wrap;
168 | justify-content: center;
169 | align-items: center;
170 | padding: 15px;
171 | background: #9053c7;
172 | background: -webkit-linear-gradient(-135deg, #c850c0, #4158d0);
173 | background: -o-linear-gradient(-135deg, #c850c0, #4158d0);
174 | background: -moz-linear-gradient(-135deg, #c850c0, #4158d0);
175 | background: linear-gradient(-135deg, #c850c0, #4158d0);
176 | }
177 |
178 | .wrap-login100 {
179 | width: 960px;
180 | background: #fff;
181 | border-radius: 10px;
182 | overflow: hidden;
183 |
184 | display: -webkit-box;
185 | display: -webkit-flex;
186 | display: -moz-box;
187 | display: -ms-flexbox;
188 | display: flex;
189 | flex-wrap: wrap;
190 | justify-content: space-between;
191 | padding: 90px 130px 33px 95px;
192 | }
193 |
194 | /*------------------------------------------------------------------
195 | [ ]*/
196 | .login100-pic {
197 | width: 316px;
198 | }
199 |
200 | .login100-pic img {
201 | max-width: 100%;
202 | }
203 |
204 |
205 | /*------------------------------------------------------------------
206 | [ ]*/
207 | .login100-form {
208 | width: 290px;
209 | }
210 |
211 | .login100-form-title {
212 | font-family: Poppins-Bold;
213 | font-size: 24px;
214 | color: #333333;
215 | line-height: 1.2;
216 | text-align: center;
217 |
218 | width: 100%;
219 | display: block;
220 | padding-bottom: 54px;
221 | }
222 |
223 | #login200 {
224 | font-family: Poppins-Bold;
225 | font-size: 24px;
226 | color: #ffffff;
227 | line-height: 1.2;
228 | text-align: center;
229 |
230 | width: 100%;
231 | display: block;
232 | padding-bottom: 54px;
233 | }
234 |
235 | #login201 {
236 | font-family: Poppins-Bold;
237 | font-size: 24px;
238 | color: #000000;
239 | line-height: 1.2;
240 | text-align: center;
241 |
242 | width: 100%;
243 | display: block;
244 | padding-bottom: 54px;
245 | }
246 |
247 | #navbar100 {
248 | font-family: Poppins-Bold;
249 | font-size: 20px;
250 | color: #ffffff;
251 | line-height: 1.2;
252 | text-align: right;
253 | }
254 |
255 | /*---------------------------------------------*/
256 | .wrap-input100 {
257 | position: relative;
258 | width: 100%;
259 | z-index: 1;
260 | margin-bottom: 10px;
261 | }
262 |
263 | .input100 {
264 | font-family: Poppins-Medium;
265 | font-size: 15px;
266 | line-height: 1.5;
267 | color: #666666;
268 |
269 | display: block;
270 | width: 100%;
271 | background: #e6e6e6;
272 | height: 50px;
273 | border-radius: 25px;
274 | padding: 0 30px 0 68px;
275 | }
276 |
277 |
278 | /*------------------------------------------------------------------
279 | [ Button sign in with ]*/
280 | .btn-face,
281 | .btn-google {
282 | font-family: Montserrat-Bold;
283 | font-size: 15px;
284 | line-height: 1.5;
285 | display: -webkit-box;
286 | display: -webkit-flex;
287 | display: -moz-box;
288 | display: -ms-flexbox;
289 | display: flex;
290 | justify-content: center;
291 | align-items: center;
292 | padding: 15px;
293 | width: 100%;
294 | height: 50px;
295 | border-radius: 25px;
296 | box-shadow: 0 1px 5px 0px rgba(0, 0, 0, 0.2);
297 | -moz-box-shadow: 0 1px 5px 0px rgba(0, 0, 0, 0.2);
298 | -webkit-box-shadow: 0 1px 5px 0px rgba(0, 0, 0, 0.2);
299 | -o-box-shadow: 0 1px 5px 0px rgba(0, 0, 0, 0.2);
300 | -ms-box-shadow: 0 1px 5px 0px rgba(0, 0, 0, 0.2);
301 | -webkit-transition: all 0.4s;
302 | -o-transition: all 0.4s;
303 | -moz-transition: all 0.4s;
304 | transition: all 0.4s;
305 | position: relative;
306 | z-index: 1;
307 | }
308 |
309 | .btn-google::before,
310 | .btn-face::before {
311 | content: "";
312 | display: block;
313 | position: absolute;
314 | z-index: -1;
315 | width: 100%;
316 | height: 100%;
317 | border-radius: 25px;
318 | top: 0;
319 | left: 0;
320 | background: #a64bf4;
321 | background: -webkit-linear-gradient(45deg, #00dbde, #fc00ff);
322 | background: -o-linear-gradient(45deg, #00dbde, #fc00ff);
323 | background: -moz-linear-gradient(45deg, #00dbde, #fc00ff);
324 | background: linear-gradient(45deg, #00dbde, #fc00ff);
325 | opacity: 0;
326 | -webkit-transition: all 0.4s;
327 | -o-transition: all 0.4s;
328 | -moz-transition: all 0.4s;
329 | transition: all 0.4s;
330 | }
331 |
332 | .btn-face {
333 | color: #fff;
334 | background-color: #3b5998;
335 | }
336 |
337 | .btn-face i {
338 | font-size: 30px;
339 | margin-right: 17px;
340 | padding-bottom: 3px;
341 | }
342 |
343 | .btn-google {
344 | color: #555555;
345 | background-color: #fff;
346 | }
347 |
348 | .btn-google img {
349 | width: 30px;
350 | margin-right: 15px;
351 | padding-bottom: 3px;
352 | }
353 |
354 | .btn-face:hover:before,
355 | .btn-google:hover:before {
356 | opacity: 1;
357 | }
358 |
359 | .btn-face:hover,
360 | .btn-google:hover {
361 | color: #fff;
362 | }
363 |
364 | /*------------------------------------------------------------------
365 | [ Focus ]*/
366 | .focus-input100 {
367 | display: block;
368 | position: absolute;
369 | border-radius: 25px;
370 | bottom: 0;
371 | left: 0;
372 | z-index: -1;
373 | width: 100%;
374 | height: 100%;
375 | box-shadow: 0px 0px 0px 0px;
376 | color: rgba(87,184,70, 0.8);
377 | }
378 |
379 | .input100:focus + .focus-input100 {
380 | -webkit-animation: anim-shadow 0.5s ease-in-out forwards;
381 | animation: anim-shadow 0.5s ease-in-out forwards;
382 | }
383 |
384 | @-webkit-keyframes anim-shadow {
385 | to {
386 | box-shadow: 0px 0px 70px 25px;
387 | opacity: 0;
388 | }
389 | }
390 |
391 | @keyframes anim-shadow {
392 | to {
393 | box-shadow: 0px 0px 70px 25px;
394 | opacity: 0;
395 | }
396 | }
397 |
398 | .symbol-input100 {
399 | font-size: 15px;
400 |
401 | display: -webkit-box;
402 | display: -webkit-flex;
403 | display: -moz-box;
404 | display: -ms-flexbox;
405 | display: flex;
406 | align-items: center;
407 | position: absolute;
408 | border-radius: 25px;
409 | bottom: 0;
410 | left: 0;
411 | width: 100%;
412 | height: 100%;
413 | padding-left: 35px;
414 | pointer-events: none;
415 | color: #666666;
416 |
417 | -webkit-transition: all 0.4s;
418 | -o-transition: all 0.4s;
419 | -moz-transition: all 0.4s;
420 | transition: all 0.4s;
421 | }
422 |
423 | .input100:focus + .focus-input100 + .symbol-input100 {
424 | color: #57b846;
425 | padding-left: 28px;
426 | }
427 |
428 | /*------------------------------------------------------------------
429 | [ Button ]*/
430 | .container-login100-form-btn {
431 | width: 100%;
432 | display: -webkit-box;
433 | display: -webkit-flex;
434 | display: -moz-box;
435 | display: -ms-flexbox;
436 | display: flex;
437 | flex-wrap: wrap;
438 | justify-content: center;
439 | padding-top: 20px;
440 | }
441 |
442 | .login100-form-btn {
443 | font-family: Montserrat-Bold;
444 | font-size: 15px;
445 | line-height: 1.5;
446 | color: #fff;
447 | text-transform: uppercase;
448 |
449 | width: 100%;
450 | height: 50px;
451 | border-radius: 25px;
452 | background: #57b846;
453 | display: -webkit-box;
454 | display: -webkit-flex;
455 | display: -moz-box;
456 | display: -ms-flexbox;
457 | display: flex;
458 | justify-content: center;
459 | align-items: center;
460 | padding: 0 25px;
461 |
462 | -webkit-transition: all 0.4s;
463 | -o-transition: all 0.4s;
464 | -moz-transition: all 0.4s;
465 | transition: all 0.4s;
466 | }
467 |
468 | .login100-form-btn:hover {
469 | background: #333333;
470 | }
471 |
472 |
473 |
474 | /*------------------------------------------------------------------
475 | [ Responsive ]*/
476 |
477 |
478 |
479 | @media (max-width: 992px) {
480 | .wrap-login100 {
481 | padding: 177px 90px 33px 85px;
482 | }
483 |
484 | .login100-pic {
485 | width: 35%;
486 | }
487 |
488 | .login100-form {
489 | width: 50%;
490 | }
491 | }
492 |
493 | @media (max-width: 768px) {
494 | .wrap-login100 {
495 | padding: 100px 80px 33px 80px;
496 | }
497 |
498 | .login100-pic {
499 | display: none;
500 | }
501 |
502 | .login100-form {
503 | width: 100%;
504 | }
505 | }
506 |
507 | @media (max-width: 576px) {
508 | .wrap-login100 {
509 | padding: 100px 15px 33px 15px;
510 | }
511 | }
512 |
513 |
514 | /*------------------------------------------------------------------
515 | [ Alert validate ]*/
516 |
517 | .validate-input {
518 | position: relative;
519 | }
520 |
521 | .alert-validate::before {
522 | content: attr(data-validate);
523 | position: absolute;
524 | max-width: 70%;
525 | background-color: white;
526 | border: 1px solid #c80000;
527 | border-radius: 13px;
528 | padding: 4px 25px 4px 10px;
529 | top: 50%;
530 | -webkit-transform: translateY(-50%);
531 | -moz-transform: translateY(-50%);
532 | -ms-transform: translateY(-50%);
533 | -o-transform: translateY(-50%);
534 | transform: translateY(-50%);
535 | right: 8px;
536 | pointer-events: none;
537 |
538 | font-family: Poppins-Medium;
539 | color: #c80000;
540 | font-size: 13px;
541 | line-height: 1.4;
542 | text-align: left;
543 |
544 | visibility: hidden;
545 | opacity: 0;
546 |
547 | -webkit-transition: opacity 0.4s;
548 | -o-transition: opacity 0.4s;
549 | -moz-transition: opacity 0.4s;
550 | transition: opacity 0.4s;
551 | }
552 |
553 | .alert-validate::after {
554 | content: "\f06a";
555 | font-family: FontAwesome;
556 | display: block;
557 | position: absolute;
558 | color: #c80000;
559 | font-size: 15px;
560 | top: 50%;
561 | -webkit-transform: translateY(-50%);
562 | -moz-transform: translateY(-50%);
563 | -ms-transform: translateY(-50%);
564 | -o-transform: translateY(-50%);
565 | transform: translateY(-50%);
566 | right: 13px;
567 | }
568 |
569 | .alert-validate:hover:before {
570 | visibility: visible;
571 | opacity: 1;
572 | }
573 |
574 | @media (max-width: 992px) {
575 | .alert-validate::before {
576 | visibility: visible;
577 | opacity: 1;
578 | }
579 | }
580 |
581 | @media (max-width: 576px) {
582 | .wrap-login100 {
583 | padding-left: 15px;
584 | padding-right: 15px;
585 | }
586 |
587 | .btn-face,
588 | .btn-google {
589 | width: 100%;
590 | }
591 | }
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/HELP-US-OUT.txt:
--------------------------------------------------------------------------------
1 | I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,
2 | Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,
3 | comprehensive icon sets or copy and paste your own.
4 |
5 | Please. Check it out.
6 |
7 | -Dave Gandy
8 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/font-awesome-4.7.0/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/less/animated.less:
--------------------------------------------------------------------------------
1 | // Animated Icons
2 | // --------------------------
3 |
4 | .@{fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .@{fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/less/bordered-pulled.less:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em @fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .@{fa-css-prefix}-pull-left { float: left; }
11 | .@{fa-css-prefix}-pull-right { float: right; }
12 |
13 | .@{fa-css-prefix} {
14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .@{fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/less/core.less:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .@{fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/less/fixed-width.less:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .@{fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/less/font-awesome.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables.less";
7 | @import "mixins.less";
8 | @import "path.less";
9 | @import "core.less";
10 | @import "larger.less";
11 | @import "fixed-width.less";
12 | @import "list.less";
13 | @import "bordered-pulled.less";
14 | @import "animated.less";
15 | @import "rotated-flipped.less";
16 | @import "stacked.less";
17 | @import "icons.less";
18 | @import "screen-reader.less";
19 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/less/larger.less:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .@{fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .@{fa-css-prefix}-2x { font-size: 2em; }
11 | .@{fa-css-prefix}-3x { font-size: 3em; }
12 | .@{fa-css-prefix}-4x { font-size: 4em; }
13 | .@{fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/less/list.less:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: @fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .@{fa-css-prefix}-li {
11 | position: absolute;
12 | left: -@fa-li-width;
13 | width: @fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.@{fa-css-prefix}-lg {
17 | left: (-@fa-li-width + (4em / 14));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/less/mixins.less:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | .fa-icon() {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
14 | .fa-icon-rotate(@degrees, @rotation) {
15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})";
16 | -webkit-transform: rotate(@degrees);
17 | -ms-transform: rotate(@degrees);
18 | transform: rotate(@degrees);
19 | }
20 |
21 | .fa-icon-flip(@horiz, @vert, @rotation) {
22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)";
23 | -webkit-transform: scale(@horiz, @vert);
24 | -ms-transform: scale(@horiz, @vert);
25 | transform: scale(@horiz, @vert);
26 | }
27 |
28 |
29 | // Only display content to screen readers. A la Bootstrap 4.
30 | //
31 | // See: http://a11yproject.com/posts/how-to-hide-content/
32 |
33 | .sr-only() {
34 | position: absolute;
35 | width: 1px;
36 | height: 1px;
37 | padding: 0;
38 | margin: -1px;
39 | overflow: hidden;
40 | clip: rect(0,0,0,0);
41 | border: 0;
42 | }
43 |
44 | // Use in conjunction with .sr-only to only display content when it's focused.
45 | //
46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
47 | //
48 | // Credit: HTML5 Boilerplate
49 |
50 | .sr-only-focusable() {
51 | &:active,
52 | &:focus {
53 | position: static;
54 | width: auto;
55 | height: auto;
56 | margin: 0;
57 | overflow: visible;
58 | clip: auto;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/less/path.less:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/less/rotated-flipped.less:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
7 |
8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .@{fa-css-prefix}-rotate-90,
15 | :root .@{fa-css-prefix}-rotate-180,
16 | :root .@{fa-css-prefix}-rotate-270,
17 | :root .@{fa-css-prefix}-flip-horizontal,
18 | :root .@{fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/less/screen-reader.less:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { .sr-only(); }
5 | .sr-only-focusable { .sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/less/stacked.less:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; }
21 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/scss/_animated.scss:
--------------------------------------------------------------------------------
1 | // Spinning Icons
2 | // --------------------------
3 |
4 | .#{$fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .#{$fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/scss/_bordered-pulled.scss:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em $fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .#{$fa-css-prefix}-pull-left { float: left; }
11 | .#{$fa-css-prefix}-pull-right { float: right; }
12 |
13 | .#{$fa-css-prefix} {
14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .#{$fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/scss/_core.scss:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/scss/_fixed-width.scss:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .#{$fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/scss/_larger.scss:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .#{$fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .#{$fa-css-prefix}-2x { font-size: 2em; }
11 | .#{$fa-css-prefix}-3x { font-size: 3em; }
12 | .#{$fa-css-prefix}-4x { font-size: 4em; }
13 | .#{$fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/scss/_list.scss:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: $fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .#{$fa-css-prefix}-li {
11 | position: absolute;
12 | left: -$fa-li-width;
13 | width: $fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.#{$fa-css-prefix}-lg {
17 | left: -$fa-li-width + (4em / 14);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/scss/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | @mixin fa-icon() {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
14 | @mixin fa-icon-rotate($degrees, $rotation) {
15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})";
16 | -webkit-transform: rotate($degrees);
17 | -ms-transform: rotate($degrees);
18 | transform: rotate($degrees);
19 | }
20 |
21 | @mixin fa-icon-flip($horiz, $vert, $rotation) {
22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)";
23 | -webkit-transform: scale($horiz, $vert);
24 | -ms-transform: scale($horiz, $vert);
25 | transform: scale($horiz, $vert);
26 | }
27 |
28 |
29 | // Only display content to screen readers. A la Bootstrap 4.
30 | //
31 | // See: http://a11yproject.com/posts/how-to-hide-content/
32 |
33 | @mixin sr-only {
34 | position: absolute;
35 | width: 1px;
36 | height: 1px;
37 | padding: 0;
38 | margin: -1px;
39 | overflow: hidden;
40 | clip: rect(0,0,0,0);
41 | border: 0;
42 | }
43 |
44 | // Use in conjunction with .sr-only to only display content when it's focused.
45 | //
46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
47 | //
48 | // Credit: HTML5 Boilerplate
49 |
50 | @mixin sr-only-focusable {
51 | &:active,
52 | &:focus {
53 | position: static;
54 | width: auto;
55 | height: auto;
56 | margin: 0;
57 | overflow: visible;
58 | clip: auto;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/scss/_path.scss:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/scss/_rotated-flipped.scss:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
7 |
8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .#{$fa-css-prefix}-rotate-90,
15 | :root .#{$fa-css-prefix}-rotate-180,
16 | :root .#{$fa-css-prefix}-rotate-270,
17 | :root .#{$fa-css-prefix}-flip-horizontal,
18 | :root .#{$fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/scss/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { @include sr-only(); }
5 | .sr-only-focusable { @include sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/scss/_stacked.scss:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; }
21 |
--------------------------------------------------------------------------------
/static/fonts/font-awesome-4.7.0/scss/font-awesome.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables";
7 | @import "mixins";
8 | @import "path";
9 | @import "core";
10 | @import "larger";
11 | @import "fixed-width";
12 | @import "list";
13 | @import "bordered-pulled";
14 | @import "animated";
15 | @import "rotated-flipped";
16 | @import "stacked";
17 | @import "icons";
18 | @import "screen-reader";
19 |
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-Black.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-BlackItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-BlackItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-Bold.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-BoldItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-ExtraBold.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-ExtraBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-ExtraBoldItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-ExtraLight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-ExtraLight.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-ExtraLightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-ExtraLightItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-Italic.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-Light.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-LightItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-Medium.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-MediumItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-MediumItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-Regular.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-SemiBold.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-SemiBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-SemiBoldItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-Thin.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/Montserrat-ThinItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/montserrat/Montserrat-ThinItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/montserrat/OFL.txt:
--------------------------------------------------------------------------------
1 | Copyright 2011 The Montserrat Project Authors (https://github.com/JulietaUla/Montserrat)
2 |
3 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
4 | This license is copied below, and is also available with a FAQ at:
5 | http://scripts.sil.org/OFL
6 |
7 |
8 | -----------------------------------------------------------
9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10 | -----------------------------------------------------------
11 |
12 | PREAMBLE
13 | The goals of the Open Font License (OFL) are to stimulate worldwide
14 | development of collaborative font projects, to support the font creation
15 | efforts of academic and linguistic communities, and to provide a free and
16 | open framework in which fonts may be shared and improved in partnership
17 | with others.
18 |
19 | The OFL allows the licensed fonts to be used, studied, modified and
20 | redistributed freely as long as they are not sold by themselves. The
21 | fonts, including any derivative works, can be bundled, embedded,
22 | redistributed and/or sold with any software provided that any reserved
23 | names are not used by derivative works. The fonts and derivatives,
24 | however, cannot be released under any other type of license. The
25 | requirement for fonts to remain under this license does not apply
26 | to any document created using the fonts or their derivatives.
27 |
28 | DEFINITIONS
29 | "Font Software" refers to the set of files released by the Copyright
30 | Holder(s) under this license and clearly marked as such. This may
31 | include source files, build scripts and documentation.
32 |
33 | "Reserved Font Name" refers to any names specified as such after the
34 | copyright statement(s).
35 |
36 | "Original Version" refers to the collection of Font Software components as
37 | distributed by the Copyright Holder(s).
38 |
39 | "Modified Version" refers to any derivative made by adding to, deleting,
40 | or substituting -- in part or in whole -- any of the components of the
41 | Original Version, by changing formats or by porting the Font Software to a
42 | new environment.
43 |
44 | "Author" refers to any designer, engineer, programmer, technical
45 | writer or other person who contributed to the Font Software.
46 |
47 | PERMISSION & CONDITIONS
48 | Permission is hereby granted, free of charge, to any person obtaining
49 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
50 | redistribute, and sell modified and unmodified copies of the Font
51 | Software, subject to the following conditions:
52 |
53 | 1) Neither the Font Software nor any of its individual components,
54 | in Original or Modified Versions, may be sold by itself.
55 |
56 | 2) Original or Modified Versions of the Font Software may be bundled,
57 | redistributed and/or sold with any software, provided that each copy
58 | contains the above copyright notice and this license. These can be
59 | included either as stand-alone text files, human-readable headers or
60 | in the appropriate machine-readable metadata fields within text or
61 | binary files as long as those fields can be easily viewed by the user.
62 |
63 | 3) No Modified Version of the Font Software may use the Reserved Font
64 | Name(s) unless explicit written permission is granted by the corresponding
65 | Copyright Holder. This restriction only applies to the primary font name as
66 | presented to the users.
67 |
68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69 | Software shall not be used to promote, endorse or advertise any
70 | Modified Version, except to acknowledge the contribution(s) of the
71 | Copyright Holder(s) and the Author(s) or with their explicit written
72 | permission.
73 |
74 | 5) The Font Software, modified or unmodified, in part or in whole,
75 | must be distributed entirely under this license, and must not be
76 | distributed under any other license. The requirement for fonts to
77 | remain under this license does not apply to any document created
78 | using the Font Software.
79 |
80 | TERMINATION
81 | This license becomes null and void if any of the above conditions are
82 | not met.
83 |
84 | DISCLAIMER
85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93 | OTHER DEALINGS IN THE FONT SOFTWARE.
94 |
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-Black.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-BlackItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-BlackItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-Bold.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-BoldItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-ExtraBold.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-ExtraBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-ExtraBoldItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-ExtraLight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-ExtraLight.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-ExtraLightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-ExtraLightItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-Italic.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-Light.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-LightItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-Medium.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-MediumItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-MediumItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-Regular.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-SemiBold.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-SemiBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-SemiBoldItalic.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-Thin.ttf
--------------------------------------------------------------------------------
/static/fonts/poppins/Poppins-ThinItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/fonts/poppins/Poppins-ThinItalic.ttf
--------------------------------------------------------------------------------
/static/images/bahi_khata.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/images/bahi_khata.png
--------------------------------------------------------------------------------
/static/images/icons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/images/icons/favicon.ico
--------------------------------------------------------------------------------
/static/images/icons/icon-google.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/images/icons/icon-google.png
--------------------------------------------------------------------------------
/static/images/landing-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/images/landing-page.png
--------------------------------------------------------------------------------
/static/images/sample_report.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/images/sample_report.png
--------------------------------------------------------------------------------
/static/images/usage.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bahi-Khata-App/Bahi-Khata/3a51d9a3bec98ad5d8b7db041a88daf946293214/static/images/usage.gif
--------------------------------------------------------------------------------
/static/js/main.js:
--------------------------------------------------------------------------------
1 |
2 | (function ($) {
3 | "use strict";
4 |
5 |
6 | /*==================================================================
7 | [ Validate ]*/
8 | var input = $('.validate-input .input100');
9 |
10 | $('.validate-form').on('submit',function(){
11 | var check = true;
12 |
13 | for(var i=0; i=o.clientWidth&&i>=o.clientHeight}),f=0i[e]&&!t.escapeWithReference&&(n=z(p[o],i[e]-('right'===e?p.width:p.height))),pe({},o,n)}};return n.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';p=se({},p,s[t](e))}),e.offsets.popper=p,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,i=t.reference,n=e.placement.split('-')[0],r=V,p=-1!==['top','bottom'].indexOf(n),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(i[s])&&(e.offsets.popper[d]=r(i[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!F(e.instance.modifiers,'arrow','keepTogether'))return e;var o=t.element;if('string'==typeof o){if(o=e.instance.popper.querySelector(o),!o)return e;}else if(!e.instance.popper.contains(o))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var i=e.placement.split('-')[0],n=e.offsets,r=n.popper,p=n.reference,s=-1!==['left','right'].indexOf(i),d=s?'height':'width',a=s?'top':'left',f=s?'left':'top',l=s?'bottom':'right',m=O(o)[d];p[l]-mr[l]&&(e.offsets.popper[a]+=p[a]+m-r[l]);var h=p[a]+p[d]/2-m/2,g=h-c(e.offsets.popper)[a];return g=_(z(r[d]-m,g),0),e.arrowElement=o,e.offsets.arrow={},e.offsets.arrow[a]=Math.round(g),e.offsets.arrow[f]='',e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=w(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement),i=e.placement.split('-')[0],n=L(i),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case fe.FLIP:p=[i,n];break;case fe.CLOCKWISE:p=K(i);break;case fe.COUNTERCLOCKWISE:p=K(i,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(i!==s||p.length===d+1)return e;i=e.placement.split('-')[0],n=L(i);var a=e.offsets.popper,f=e.offsets.reference,l=V,m='left'===i&&l(a.right)>l(f.left)||'right'===i&&l(a.left)l(f.top)||'bottom'===i&&l(a.top)l(o.right),g=l(a.top)l(o.bottom),b='left'===i&&h||'right'===i&&c||'top'===i&&g||'bottom'===i&&u,y=-1!==['top','bottom'].indexOf(i),w=!!t.flipVariations&&(y&&'start'===r&&h||y&&'end'===r&&c||!y&&'start'===r&&g||!y&&'end'===r&&u);(m||b||w)&&(e.flipped=!0,(m||b)&&(i=p[d+1]),w&&(r=j(r)),e.placement=i+(r?'-'+r:''),e.offsets.popper=se({},e.offsets.popper,S(e.instance.popper,e.offsets.reference,e.placement)),e=N(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],i=e.offsets,n=i.popper,r=i.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return n[p?'left':'top']=r[t]-(s?n[p?'width':'height']:0),e.placement=L(t),e.offsets.popper=c(n),e}},hide:{order:800,enabled:!0,fn:function(e){if(!F(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=T(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.right',
96 | trigger: 'hover focus',
97 | offset: 0
98 | };
99 |
100 | var Tooltip = function () {
101 | /**
102 | * Create a new Tooltip.js instance
103 | * @class Tooltip
104 | * @param {HTMLElement} reference - The DOM node used as reference of the tooltip (it can be a jQuery element).
105 | * @param {Object} options
106 | * @param {String} options.placement=bottom
107 | * Placement of the popper accepted values: `top(-start, -end), right(-start, -end), bottom(-start, -end),
108 | * left(-start, -end)`
109 | * @param {HTMLElement|String|false} options.container=false - Append the tooltip to a specific element.
110 | * @param {Number|Object} options.delay=0
111 | * Delay showing and hiding the tooltip (ms) - does not apply to manual trigger type.
112 | * If a number is supplied, delay is applied to both hide/show.
113 | * Object structure is: `{ show: 500, hide: 100 }`
114 | * @param {Boolean} options.html=false - Insert HTML into the tooltip. If false, the content will inserted with `innerText`.
115 | * @param {String|PlacementFunction} options.placement='top' - One of the allowed placements, or a function returning one of them.
116 | * @param {String} [options.template='']
117 | * Base HTML to used when creating the tooltip.
118 | * The tooltip's `title` will be injected into the `.tooltip-inner` or `.tooltip__inner`.
119 | * `.tooltip-arrow` or `.tooltip__arrow` will become the tooltip's arrow.
120 | * The outermost wrapper element should have the `.tooltip` class.
121 | * @param {String|HTMLElement|TitleFunction} options.title='' - Default title value if `title` attribute isn't present.
122 | * @param {String} [options.trigger='hover focus']
123 | * How tooltip is triggered - click, hover, focus, manual.
124 | * You may pass multiple triggers; separate them with a space. `manual` cannot be combined with any other trigger.
125 | * @param {HTMLElement} options.boundariesElement
126 | * The element used as boundaries for the tooltip. For more information refer to Popper.js'
127 | * [boundariesElement docs](https://popper.js.org/popper-documentation.html)
128 | * @param {Number|String} options.offset=0 - Offset of the tooltip relative to its reference. For more information refer to Popper.js'
129 | * [offset docs](https://popper.js.org/popper-documentation.html)
130 | * @param {Object} options.popperOptions={} - Popper options, will be passed directly to popper instance. For more information refer to Popper.js'
131 | * [options docs](https://popper.js.org/popper-documentation.html)
132 | * @return {Object} instance - The generated tooltip instance
133 | */
134 | function Tooltip(reference, options) {
135 | classCallCheck(this, Tooltip);
136 |
137 | _initialiseProps.call(this);
138 |
139 | // apply user options over default ones
140 | options = _extends({}, DEFAULT_OPTIONS, options);
141 |
142 | reference.jquery && (reference = reference[0]);
143 |
144 | // cache reference and options
145 | this.reference = reference;
146 | this.options = options;
147 |
148 | // get events list
149 | var events = typeof options.trigger === 'string' ? options.trigger.split(' ').filter(function (trigger) {
150 | return ['click', 'hover', 'focus'].indexOf(trigger) !== -1;
151 | }) : [];
152 |
153 | // set initial state
154 | this._isOpen = false;
155 |
156 | // set event listeners
157 | this._setEventListeners(reference, events, options);
158 | }
159 |
160 | //
161 | // Public methods
162 | //
163 |
164 | /**
165 | * Reveals an element's tooltip. This is considered a "manual" triggering of the tooltip.
166 | * Tooltips with zero-length titles are never displayed.
167 | * @method Tooltip#show
168 | * @memberof Tooltip
169 | */
170 |
171 |
172 | /**
173 | * Hides an element’s tooltip. This is considered a “manual” triggering of the tooltip.
174 | * @method Tooltip#hide
175 | * @memberof Tooltip
176 | */
177 |
178 |
179 | /**
180 | * Hides and destroys an element’s tooltip.
181 | * @method Tooltip#dispose
182 | * @memberof Tooltip
183 | */
184 |
185 |
186 | /**
187 | * Toggles an element’s tooltip. This is considered a “manual” triggering of the tooltip.
188 | * @method Tooltip#toggle
189 | * @memberof Tooltip
190 | */
191 |
192 |
193 | //
194 | // Defaults
195 | //
196 |
197 |
198 | //
199 | // Private methods
200 | //
201 |
202 | createClass(Tooltip, [{
203 | key: '_create',
204 |
205 |
206 | /**
207 | * Creates a new tooltip node
208 | * @memberof Tooltip
209 | * @private
210 | * @param {HTMLElement} reference
211 | * @param {String} template
212 | * @param {String|HTMLElement|TitleFunction} title
213 | * @param {Boolean} allowHtml
214 | * @return {HTMLelement} tooltipNode
215 | */
216 | value: function _create(reference, template, title, allowHtml) {
217 | // create tooltip element
218 | var tooltipGenerator = window.document.createElement('div');
219 | tooltipGenerator.innerHTML = template.trim();
220 | var tooltipNode = tooltipGenerator.childNodes[0];
221 |
222 | // add unique ID to our tooltip (needed for accessibility reasons)
223 | tooltipNode.id = 'tooltip_' + Math.random().toString(36).substr(2, 10);
224 |
225 | // set initial `aria-hidden` state to `false` (it's visible!)
226 | tooltipNode.setAttribute('aria-hidden', 'false');
227 |
228 | // add title to tooltip
229 | var titleNode = tooltipGenerator.querySelector(this.innerSelector);
230 | if (title.nodeType === 1) {
231 | // if title is a node, append it only if allowHtml is true
232 | allowHtml && titleNode.appendChild(title);
233 | } else if (isFunction(title)) {
234 | // if title is a function, call it and set innerText or innerHtml depending by `allowHtml` value
235 | var titleText = title.call(reference);
236 | allowHtml ? titleNode.innerHTML = titleText : titleNode.innerText = titleText;
237 | } else {
238 | // if it's just a simple text, set innerText or innerHtml depending by `allowHtml` value
239 | allowHtml ? titleNode.innerHTML = title : titleNode.innerText = title;
240 | }
241 |
242 | // return the generated tooltip node
243 | return tooltipNode;
244 | }
245 | }, {
246 | key: '_show',
247 | value: function _show(reference, options) {
248 | // don't show if it's already visible
249 | if (this._isOpen) {
250 | return this;
251 | }
252 | this._isOpen = true;
253 |
254 | // if the tooltipNode already exists, just show it
255 | if (this._tooltipNode) {
256 | this._tooltipNode.style.display = '';
257 | this._tooltipNode.setAttribute('aria-hidden', 'false');
258 | this.popperInstance.update();
259 | return this;
260 | }
261 |
262 | // get title
263 | var title = reference.getAttribute('title') || options.title;
264 |
265 | // don't show tooltip if no title is defined
266 | if (!title) {
267 | return this;
268 | }
269 |
270 | // create tooltip node
271 | var tooltipNode = this._create(reference, options.template, title, options.html);
272 |
273 | // Add `aria-describedby` to our reference element for accessibility reasons
274 | reference.setAttribute('aria-describedby', tooltipNode.id);
275 |
276 | // append tooltip to container
277 | var container = this._findContainer(options.container, reference);
278 |
279 | this._append(tooltipNode, container);
280 |
281 | var popperOptions = _extends({}, options.popperOptions, {
282 | placement: options.placement
283 | });
284 |
285 | popperOptions.modifiers = _extends({}, popperOptions.modifiers, {
286 | arrow: {
287 | element: this.arrowSelector
288 | }
289 | });
290 |
291 | if (options.boundariesElement) {
292 | popperOptions.modifiers.preventOverflow = {
293 | boundariesElement: options.boundariesElement
294 | };
295 | }
296 |
297 | this.popperInstance = new Popper(reference, tooltipNode, popperOptions);
298 |
299 | this._tooltipNode = tooltipNode;
300 |
301 | return this;
302 | }
303 | }, {
304 | key: '_hide',
305 | value: function _hide() /*reference, options*/{
306 | // don't hide if it's already hidden
307 | if (!this._isOpen) {
308 | return this;
309 | }
310 |
311 | this._isOpen = false;
312 |
313 | // hide tooltipNode
314 | this._tooltipNode.style.display = 'none';
315 | this._tooltipNode.setAttribute('aria-hidden', 'true');
316 |
317 | return this;
318 | }
319 | }, {
320 | key: '_dispose',
321 | value: function _dispose() {
322 | var _this = this;
323 |
324 | if (this._tooltipNode) {
325 | this._hide();
326 |
327 | // destroy instance
328 | this.popperInstance.destroy();
329 |
330 | // remove event listeners
331 | this._events.forEach(function (_ref) {
332 | var func = _ref.func,
333 | event = _ref.event;
334 |
335 | _this.reference.removeEventListener(event, func);
336 | });
337 | this._events = [];
338 |
339 | // destroy tooltipNode
340 | this._tooltipNode.parentNode.removeChild(this._tooltipNode);
341 | this._tooltipNode = null;
342 | }
343 | return this;
344 | }
345 | }, {
346 | key: '_findContainer',
347 | value: function _findContainer(container, reference) {
348 | // if container is a query, get the relative element
349 | if (typeof container === 'string') {
350 | container = window.document.querySelector(container);
351 | } else if (container === false) {
352 | // if container is `false`, set it to reference parent
353 | container = reference.parentNode;
354 | }
355 | return container;
356 | }
357 |
358 | /**
359 | * Append tooltip to container
360 | * @memberof Tooltip
361 | * @private
362 | * @param {HTMLElement} tooltip
363 | * @param {HTMLElement|String|false} container
364 | */
365 |
366 | }, {
367 | key: '_append',
368 | value: function _append(tooltipNode, container) {
369 | container.appendChild(tooltipNode);
370 | }
371 | }, {
372 | key: '_setEventListeners',
373 | value: function _setEventListeners(reference, events, options) {
374 | var _this2 = this;
375 |
376 | var directEvents = [];
377 | var oppositeEvents = [];
378 |
379 | events.forEach(function (event) {
380 | switch (event) {
381 | case 'hover':
382 | directEvents.push('mouseenter');
383 | oppositeEvents.push('mouseleave');
384 | break;
385 | case 'focus':
386 | directEvents.push('focus');
387 | oppositeEvents.push('blur');
388 | break;
389 | case 'click':
390 | directEvents.push('click');
391 | oppositeEvents.push('click');
392 | break;
393 | }
394 | });
395 |
396 | // schedule show tooltip
397 | directEvents.forEach(function (event) {
398 | var func = function func(evt) {
399 | if (_this2._isOpen === true) {
400 | return;
401 | }
402 | evt.usedByTooltip = true;
403 | _this2._scheduleShow(reference, options.delay, options, evt);
404 | };
405 | _this2._events.push({ event: event, func: func });
406 | reference.addEventListener(event, func);
407 | });
408 |
409 | // schedule hide tooltip
410 | oppositeEvents.forEach(function (event) {
411 | var func = function func(evt) {
412 | if (evt.usedByTooltip === true) {
413 | return;
414 | }
415 | _this2._scheduleHide(reference, options.delay, options, evt);
416 | };
417 | _this2._events.push({ event: event, func: func });
418 | reference.addEventListener(event, func);
419 | });
420 | }
421 | }, {
422 | key: '_scheduleShow',
423 | value: function _scheduleShow(reference, delay, options /*, evt */) {
424 | var _this3 = this;
425 |
426 | // defaults to 0
427 | var computedDelay = delay && delay.show || delay || 0;
428 | window.setTimeout(function () {
429 | return _this3._show(reference, options);
430 | }, computedDelay);
431 | }
432 | }, {
433 | key: '_scheduleHide',
434 | value: function _scheduleHide(reference, delay, options, evt) {
435 | var _this4 = this;
436 |
437 | // defaults to 0
438 | var computedDelay = delay && delay.hide || delay || 0;
439 | window.setTimeout(function () {
440 | if (_this4._isOpen === false) {
441 | return;
442 | }
443 | if (!document.body.contains(_this4._tooltipNode)) {
444 | return;
445 | }
446 |
447 | // if we are hiding because of a mouseleave, we must check that the new
448 | // reference isn't the tooltip, because in this case we don't want to hide it
449 | if (evt.type === 'mouseleave') {
450 | var isSet = _this4._setTooltipNodeEvent(evt, reference, delay, options);
451 |
452 | // if we set the new event, don't hide the tooltip yet
453 | // the new event will take care to hide it if necessary
454 | if (isSet) {
455 | return;
456 | }
457 | }
458 |
459 | _this4._hide(reference, options);
460 | }, computedDelay);
461 | }
462 | }]);
463 | return Tooltip;
464 | }();
465 |
466 | /**
467 | * Placement function, its context is the Tooltip instance.
468 | * @memberof Tooltip
469 | * @callback PlacementFunction
470 | * @param {HTMLElement} tooltip - tooltip DOM node.
471 | * @param {HTMLElement} reference - reference DOM node.
472 | * @return {String} placement - One of the allowed placement options.
473 | */
474 |
475 | /**
476 | * Title function, its context is the Tooltip instance.
477 | * @memberof Tooltip
478 | * @callback TitleFunction
479 | * @return {String} placement - The desired title.
480 | */
481 |
482 |
483 | var _initialiseProps = function _initialiseProps() {
484 | var _this5 = this;
485 |
486 | this.show = function () {
487 | return _this5._show(_this5.reference, _this5.options);
488 | };
489 |
490 | this.hide = function () {
491 | return _this5._hide();
492 | };
493 |
494 | this.dispose = function () {
495 | return _this5._dispose();
496 | };
497 |
498 | this.toggle = function () {
499 | if (_this5._isOpen) {
500 | return _this5.hide();
501 | } else {
502 | return _this5.show();
503 | }
504 | };
505 |
506 | this.arrowSelector = '.tooltip-arrow, .tooltip__arrow';
507 | this.innerSelector = '.tooltip-inner, .tooltip__inner';
508 | this._events = [];
509 |
510 | this._setTooltipNodeEvent = function (evt, reference, delay, options) {
511 | var relatedreference = evt.relatedreference || evt.toElement;
512 |
513 | var callback = function callback(evt2) {
514 | var relatedreference2 = evt2.relatedreference || evt2.toElement;
515 |
516 | // Remove event listener after call
517 | _this5._tooltipNode.removeEventListener(evt.type, callback);
518 |
519 | // If the new reference is not the reference element
520 | if (!reference.contains(relatedreference2)) {
521 | // Schedule to hide tooltip
522 | _this5._scheduleHide(reference, options.delay, options, evt2);
523 | }
524 | };
525 |
526 | if (_this5._tooltipNode.contains(relatedreference)) {
527 | // listen to mouseleave on the tooltip element to be able to hide the tooltip
528 | _this5._tooltipNode.addEventListener(evt.type, callback);
529 | return true;
530 | }
531 |
532 | return false;
533 | };
534 | };
535 |
536 | return Tooltip;
537 |
538 | })));
539 | //# sourceMappingURL=tooltip.js.map
540 |
--------------------------------------------------------------------------------
/static/vendor/css-hamburgers/hamburgers.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Hamburgers
3 | * @description Tasty CSS-animated hamburgers
4 | * @author Jonathan Suh @jonsuh
5 | * @site https://jonsuh.com/hamburgers
6 | * @link https://github.com/jonsuh/hamburgers
7 | */.hamburger{font:inherit;display:inline-block;overflow:visible;margin:0;padding:15px;cursor:pointer;transition-timing-function:linear;transition-duration:.15s;transition-property:opacity,filter;text-transform:none;color:inherit;border:0;background-color:transparent}.hamburger:hover{opacity:.7}.hamburger-box{position:relative;display:inline-block;width:40px;height:24px}.hamburger-inner{top:50%;display:block;margin-top:-2px}.hamburger-inner,.hamburger-inner:after,.hamburger-inner:before{position:absolute;width:40px;height:4px;transition-timing-function:ease;transition-duration:.15s;transition-property:transform;border-radius:4px;background-color:#000}.hamburger-inner:after,.hamburger-inner:before{display:block;content:''}.hamburger-inner:before{top:-10px}.hamburger-inner:after{bottom:-10px}.hamburger--3dx .hamburger-box{perspective:80px}.hamburger--3dx .hamburger-inner{transition:transform .2s cubic-bezier(.645,.045,.355,1),background-color 0s cubic-bezier(.645,.045,.355,1) .1s}.hamburger--3dx .hamburger-inner:after,.hamburger--3dx .hamburger-inner:before{transition:transform 0s cubic-bezier(.645,.045,.355,1) .1s}.hamburger--3dx.is-active .hamburger-inner{transform:rotateY(180deg);background-color:transparent}.hamburger--3dx.is-active .hamburger-inner:before{transform:translate3d(0,10px,0) rotate(45deg)}.hamburger--3dx.is-active .hamburger-inner:after{transform:translate3d(0,-10px,0) rotate(-45deg)}.hamburger--3dx-r .hamburger-box{perspective:80px}.hamburger--3dx-r .hamburger-inner{transition:transform .2s cubic-bezier(.645,.045,.355,1),background-color 0s cubic-bezier(.645,.045,.355,1) .1s}.hamburger--3dx-r .hamburger-inner:after,.hamburger--3dx-r .hamburger-inner:before{transition:transform 0s cubic-bezier(.645,.045,.355,1) .1s}.hamburger--3dx-r.is-active .hamburger-inner{transform:rotateY(-180deg);background-color:transparent}.hamburger--3dx-r.is-active .hamburger-inner:before{transform:translate3d(0,10px,0) rotate(45deg)}.hamburger--3dx-r.is-active .hamburger-inner:after{transform:translate3d(0,-10px,0) rotate(-45deg)}.hamburger--3dy .hamburger-box{perspective:80px}.hamburger--3dy .hamburger-inner{transition:transform .2s cubic-bezier(.645,.045,.355,1),background-color 0s cubic-bezier(.645,.045,.355,1) .1s}.hamburger--3dy .hamburger-inner:after,.hamburger--3dy .hamburger-inner:before{transition:transform 0s cubic-bezier(.645,.045,.355,1) .1s}.hamburger--3dy.is-active .hamburger-inner{transform:rotateX(-180deg);background-color:transparent}.hamburger--3dy.is-active .hamburger-inner:before{transform:translate3d(0,10px,0) rotate(45deg)}.hamburger--3dy.is-active .hamburger-inner:after{transform:translate3d(0,-10px,0) rotate(-45deg)}.hamburger--3dy-r .hamburger-box{perspective:80px}.hamburger--3dy-r .hamburger-inner{transition:transform .2s cubic-bezier(.645,.045,.355,1),background-color 0s cubic-bezier(.645,.045,.355,1) .1s}.hamburger--3dy-r .hamburger-inner:after,.hamburger--3dy-r .hamburger-inner:before{transition:transform 0s cubic-bezier(.645,.045,.355,1) .1s}.hamburger--3dy-r.is-active .hamburger-inner{transform:rotateX(180deg);background-color:transparent}.hamburger--3dy-r.is-active .hamburger-inner:before{transform:translate3d(0,10px,0) rotate(45deg)}.hamburger--3dy-r.is-active .hamburger-inner:after{transform:translate3d(0,-10px,0) rotate(-45deg)}.hamburger--arrow.is-active .hamburger-inner:before{transform:translate3d(-8px,0,0) rotate(-45deg) scaleX(.7)}.hamburger--arrow.is-active .hamburger-inner:after{transform:translate3d(-8px,0,0) rotate(45deg) scaleX(.7)}.hamburger--arrow-r.is-active .hamburger-inner:before{transform:translate3d(8px,0,0) rotate(45deg) scaleX(.7)}.hamburger--arrow-r.is-active .hamburger-inner:after{transform:translate3d(8px,0,0) rotate(-45deg) scaleX(.7)}.hamburger--arrowalt .hamburger-inner:before{transition:top .1s ease .15s,transform .15s cubic-bezier(.165,.84,.44,1)}.hamburger--arrowalt .hamburger-inner:after{transition:bottom .1s ease .15s,transform .15s cubic-bezier(.165,.84,.44,1)}.hamburger--arrowalt.is-active .hamburger-inner:before{top:0;transition:top .1s ease,transform .15s cubic-bezier(.895,.03,.685,.22) .1s;transform:translate3d(-8px,-10px,0) rotate(-45deg) scaleX(.7)}.hamburger--arrowalt.is-active .hamburger-inner:after{bottom:0;transition:bottom .1s ease,transform .15s cubic-bezier(.895,.03,.685,.22) .1s;transform:translate3d(-8px,10px,0) rotate(45deg) scaleX(.7)}.hamburger--arrowalt-r .hamburger-inner:before{transition:top .1s ease .15s,transform .15s cubic-bezier(.165,.84,.44,1)}.hamburger--arrowalt-r .hamburger-inner:after{transition:bottom .1s ease .15s,transform .15s cubic-bezier(.165,.84,.44,1)}.hamburger--arrowalt-r.is-active .hamburger-inner:before{top:0;transition:top .1s ease,transform .15s cubic-bezier(.895,.03,.685,.22) .1s;transform:translate3d(8px,-10px,0) rotate(45deg) scaleX(.7)}.hamburger--arrowalt-r.is-active .hamburger-inner:after{bottom:0;transition:bottom .1s ease,transform .15s cubic-bezier(.895,.03,.685,.22) .1s;transform:translate3d(8px,10px,0) rotate(-45deg) scaleX(.7)}.hamburger--boring .hamburger-inner,.hamburger--boring .hamburger-inner:after,.hamburger--boring .hamburger-inner:before{transition-property:none}.hamburger--boring.is-active .hamburger-inner{transform:rotate(45deg)}.hamburger--boring.is-active .hamburger-inner:before{top:0;opacity:0}.hamburger--boring.is-active .hamburger-inner:after{bottom:0;transform:rotate(-90deg)}.hamburger--collapse .hamburger-inner{top:auto;bottom:0;transition-delay:.15s;transition-timing-function:cubic-bezier(.55,.055,.675,.19);transition-duration:.15s}.hamburger--collapse .hamburger-inner:after{top:-20px;transition:top .3s cubic-bezier(.33333,.66667,.66667,1) .3s,opacity .1s linear}.hamburger--collapse .hamburger-inner:before{transition:top .12s cubic-bezier(.33333,.66667,.66667,1) .3s,transform .15s cubic-bezier(.55,.055,.675,.19)}.hamburger--collapse.is-active .hamburger-inner{transition-delay:.32s;transition-timing-function:cubic-bezier(.215,.61,.355,1);transform:translate3d(0,-10px,0) rotate(-45deg)}.hamburger--collapse.is-active .hamburger-inner:after{top:0;transition:top .3s cubic-bezier(.33333,0,.66667,.33333),opacity .1s linear .27s;opacity:0}.hamburger--collapse.is-active .hamburger-inner:before{top:0;transition:top .12s cubic-bezier(.33333,0,.66667,.33333) .18s,transform .15s cubic-bezier(.215,.61,.355,1) .42s;transform:rotate(-90deg)}.hamburger--collapse-r .hamburger-inner{top:auto;bottom:0;transition-delay:.15s;transition-timing-function:cubic-bezier(.55,.055,.675,.19);transition-duration:.15s}.hamburger--collapse-r .hamburger-inner:after{top:-20px;transition:top .3s cubic-bezier(.33333,.66667,.66667,1) .3s,opacity .1s linear}.hamburger--collapse-r .hamburger-inner:before{transition:top .12s cubic-bezier(.33333,.66667,.66667,1) .3s,transform .15s cubic-bezier(.55,.055,.675,.19)}.hamburger--collapse-r.is-active .hamburger-inner{transition-delay:.32s;transition-timing-function:cubic-bezier(.215,.61,.355,1);transform:translate3d(0,-10px,0) rotate(45deg)}.hamburger--collapse-r.is-active .hamburger-inner:after{top:0;transition:top .3s cubic-bezier(.33333,0,.66667,.33333),opacity .1s linear .27s;opacity:0}.hamburger--collapse-r.is-active .hamburger-inner:before{top:0;transition:top .12s cubic-bezier(.33333,0,.66667,.33333) .18s,transform .15s cubic-bezier(.215,.61,.355,1) .42s;transform:rotate(90deg)}.hamburger--elastic .hamburger-inner{top:2px;transition-timing-function:cubic-bezier(.68,-.55,.265,1.55);transition-duration:.4s}.hamburger--elastic .hamburger-inner:before{top:10px;transition:opacity .15s ease .4s}.hamburger--elastic .hamburger-inner:after{top:20px;transition:transform .4s cubic-bezier(.68,-.55,.265,1.55)}.hamburger--elastic.is-active .hamburger-inner{transition-delay:.1s;transform:translate3d(0,10px,0) rotate(135deg)}.hamburger--elastic.is-active .hamburger-inner:before{transition-delay:0s;opacity:0}.hamburger--elastic.is-active .hamburger-inner:after{transition-delay:.1s;transform:translate3d(0,-20px,0) rotate(-270deg)}.hamburger--elastic-r .hamburger-inner{top:2px;transition-timing-function:cubic-bezier(.68,-.55,.265,1.55);transition-duration:.4s}.hamburger--elastic-r .hamburger-inner:before{top:10px;transition:opacity .15s ease .4s}.hamburger--elastic-r .hamburger-inner:after{top:20px;transition:transform .4s cubic-bezier(.68,-.55,.265,1.55)}.hamburger--elastic-r.is-active .hamburger-inner{transition-delay:.1s;transform:translate3d(0,10px,0) rotate(-135deg)}.hamburger--elastic-r.is-active .hamburger-inner:before{transition-delay:0s;opacity:0}.hamburger--elastic-r.is-active .hamburger-inner:after{transition-delay:.1s;transform:translate3d(0,-20px,0) rotate(270deg)}.hamburger--emphatic{overflow:hidden}.hamburger--emphatic .hamburger-inner{transition:background-color .2s ease-in .25s}.hamburger--emphatic .hamburger-inner:before{left:0;transition:transform .2s cubic-bezier(.6,.04,.98,.335),top .05s linear .2s,left .2s ease-in .25s}.hamburger--emphatic .hamburger-inner:after{top:10px;right:0;transition:transform .2s cubic-bezier(.6,.04,.98,.335),top .05s linear .2s,right .2s ease-in .25s}.hamburger--emphatic.is-active .hamburger-inner{transition-delay:0s;transition-timing-function:ease-out;background-color:transparent}.hamburger--emphatic.is-active .hamburger-inner:before{top:-80px;left:-80px;transition:left .2s ease-out,top .05s linear .2s,transform .2s cubic-bezier(.075,.82,.165,1) .25s;transform:translate3d(80px,80px,0) rotate(45deg)}.hamburger--emphatic.is-active .hamburger-inner:after{top:-80px;right:-80px;transition:right .2s ease-out,top .05s linear .2s,transform .2s cubic-bezier(.075,.82,.165,1) .25s;transform:translate3d(-80px,80px,0) rotate(-45deg)}.hamburger--emphatic-r{overflow:hidden}.hamburger--emphatic-r .hamburger-inner{transition:background-color .2s ease-in .25s}.hamburger--emphatic-r .hamburger-inner:before{left:0;transition:transform .2s cubic-bezier(.6,.04,.98,.335),top .05s linear .2s,left .2s ease-in .25s}.hamburger--emphatic-r .hamburger-inner:after{top:10px;right:0;transition:transform .2s cubic-bezier(.6,.04,.98,.335),top .05s linear .2s,right .2s ease-in .25s}.hamburger--emphatic-r.is-active .hamburger-inner{transition-delay:0s;transition-timing-function:ease-out;background-color:transparent}.hamburger--emphatic-r.is-active .hamburger-inner:before{top:80px;left:-80px;transition:left .2s ease-out,top .05s linear .2s,transform .2s cubic-bezier(.075,.82,.165,1) .25s;transform:translate3d(80px,-80px,0) rotate(-45deg)}.hamburger--emphatic-r.is-active .hamburger-inner:after{top:80px;right:-80px;transition:right .2s ease-out,top .05s linear .2s,transform .2s cubic-bezier(.075,.82,.165,1) .25s;transform:translate3d(-80px,-80px,0) rotate(45deg)}.hamburger--slider .hamburger-inner{top:2px}.hamburger--slider .hamburger-inner:before{top:10px;transition-timing-function:ease;transition-duration:.2s;transition-property:transform,opacity}.hamburger--slider .hamburger-inner:after{top:20px}.hamburger--slider.is-active .hamburger-inner{transform:translate3d(0,10px,0) rotate(45deg)}.hamburger--slider.is-active .hamburger-inner:before{transform:rotate(-45deg) translate3d(-5.71429px,-6px,0);opacity:0}.hamburger--slider.is-active .hamburger-inner:after{transform:translate3d(0,-20px,0) rotate(-90deg)}.hamburger--slider-r .hamburger-inner{top:2px}.hamburger--slider-r .hamburger-inner:before{top:10px;transition-timing-function:ease;transition-duration:.2s;transition-property:transform,opacity}.hamburger--slider-r .hamburger-inner:after{top:20px}.hamburger--slider-r.is-active .hamburger-inner{transform:translate3d(0,10px,0) rotate(-45deg)}.hamburger--slider-r.is-active .hamburger-inner:before{transform:rotate(45deg) translate3d(5.71429px,-6px,0);opacity:0}.hamburger--slider-r.is-active .hamburger-inner:after{transform:translate3d(0,-20px,0) rotate(90deg)}.hamburger--spring .hamburger-inner{top:2px;transition:background-color 0s linear .15s}.hamburger--spring .hamburger-inner:before{top:10px;transition:top .12s cubic-bezier(.33333,.66667,.66667,1) .3s,transform .15s cubic-bezier(.55,.055,.675,.19)}.hamburger--spring .hamburger-inner:after{top:20px;transition:top .3s cubic-bezier(.33333,.66667,.66667,1) .3s,transform .15s cubic-bezier(.55,.055,.675,.19)}.hamburger--spring.is-active .hamburger-inner{transition-delay:.32s;background-color:transparent}.hamburger--spring.is-active .hamburger-inner:before{top:0;transition:top .12s cubic-bezier(.33333,0,.66667,.33333) .18s,transform .15s cubic-bezier(.215,.61,.355,1) .32s;transform:translate3d(0,10px,0) rotate(45deg)}.hamburger--spring.is-active .hamburger-inner:after{top:0;transition:top .3s cubic-bezier(.33333,0,.66667,.33333),transform .15s cubic-bezier(.215,.61,.355,1) .32s;transform:translate3d(0,10px,0) rotate(-45deg)}.hamburger--spring-r .hamburger-inner{top:auto;bottom:0;transition-delay:0s;transition-timing-function:cubic-bezier(.55,.055,.675,.19);transition-duration:.15s}.hamburger--spring-r .hamburger-inner:after{top:-20px;transition:top .3s cubic-bezier(.33333,.66667,.66667,1) .3s,opacity 0s linear}.hamburger--spring-r .hamburger-inner:before{transition:top .12s cubic-bezier(.33333,.66667,.66667,1) .3s,transform .15s cubic-bezier(.55,.055,.675,.19)}.hamburger--spring-r.is-active .hamburger-inner{transition-delay:.32s;transition-timing-function:cubic-bezier(.215,.61,.355,1);transform:translate3d(0,-10px,0) rotate(-45deg)}.hamburger--spring-r.is-active .hamburger-inner:after{top:0;transition:top .3s cubic-bezier(.33333,0,.66667,.33333),opacity 0s linear .32s;opacity:0}.hamburger--spring-r.is-active .hamburger-inner:before{top:0;transition:top .12s cubic-bezier(.33333,0,.66667,.33333) .18s,transform .15s cubic-bezier(.215,.61,.355,1) .32s;transform:rotate(90deg)}.hamburger--stand .hamburger-inner{transition:transform .1s cubic-bezier(.55,.055,.675,.19) .22s,background-color 0s linear .1s}.hamburger--stand .hamburger-inner:before{transition:top .1s ease-in .1s,transform .1s cubic-bezier(.55,.055,.675,.19) 0s}.hamburger--stand .hamburger-inner:after{transition:bottom .1s ease-in .1s,transform .1s cubic-bezier(.55,.055,.675,.19) 0s}.hamburger--stand.is-active .hamburger-inner{transition:transform .1s cubic-bezier(.215,.61,.355,1) 0s,background-color 0s linear .22s;transform:rotate(90deg);background-color:transparent}.hamburger--stand.is-active .hamburger-inner:before{top:0;transition:top .1s ease-out .12s,transform .1s cubic-bezier(.215,.61,.355,1) .22s;transform:rotate(-45deg)}.hamburger--stand.is-active .hamburger-inner:after{bottom:0;transition:bottom .1s ease-out .12s,transform .1s cubic-bezier(.215,.61,.355,1) .22s;transform:rotate(45deg)}.hamburger--stand-r .hamburger-inner{transition:transform .1s cubic-bezier(.55,.055,.675,.19) .22s,background-color 0s linear .1s}.hamburger--stand-r .hamburger-inner:before{transition:top .1s ease-in .1s,transform .1s cubic-bezier(.55,.055,.675,.19) 0s}.hamburger--stand-r .hamburger-inner:after{transition:bottom .1s ease-in .1s,transform .1s cubic-bezier(.55,.055,.675,.19) 0s}.hamburger--stand-r.is-active .hamburger-inner{transition:transform .1s cubic-bezier(.215,.61,.355,1) 0s,background-color 0s linear .22s;transform:rotate(-90deg);background-color:transparent}.hamburger--stand-r.is-active .hamburger-inner:before{top:0;transition:top .1s ease-out .12s,transform .1s cubic-bezier(.215,.61,.355,1) .22s;transform:rotate(-45deg)}.hamburger--stand-r.is-active .hamburger-inner:after{bottom:0;transition:bottom .1s ease-out .12s,transform .1s cubic-bezier(.215,.61,.355,1) .22s;transform:rotate(45deg)}.hamburger--spin .hamburger-inner{transition-timing-function:cubic-bezier(.55,.055,.675,.19);transition-duration:.3s}.hamburger--spin .hamburger-inner:before{transition:top .1s ease-in .34s,opacity .1s ease-in}.hamburger--spin .hamburger-inner:after{transition:bottom .1s ease-in .34s,transform .3s cubic-bezier(.55,.055,.675,.19)}.hamburger--spin.is-active .hamburger-inner{transition-delay:.14s;transition-timing-function:cubic-bezier(.215,.61,.355,1);transform:rotate(225deg)}.hamburger--spin.is-active .hamburger-inner:before{top:0;transition:top .1s ease-out,opacity .1s ease-out .14s;opacity:0}.hamburger--spin.is-active .hamburger-inner:after{bottom:0;transition:bottom .1s ease-out,transform .3s cubic-bezier(.215,.61,.355,1) .14s;transform:rotate(-90deg)}.hamburger--spin-r .hamburger-inner{transition-timing-function:cubic-bezier(.55,.055,.675,.19);transition-duration:.3s}.hamburger--spin-r .hamburger-inner:before{transition:top .1s ease-in .34s,opacity .1s ease-in}.hamburger--spin-r .hamburger-inner:after{transition:bottom .1s ease-in .34s,transform .3s cubic-bezier(.55,.055,.675,.19)}.hamburger--spin-r.is-active .hamburger-inner{transition-delay:.14s;transition-timing-function:cubic-bezier(.215,.61,.355,1);transform:rotate(-225deg)}.hamburger--spin-r.is-active .hamburger-inner:before{top:0;transition:top .1s ease-out,opacity .1s ease-out .14s;opacity:0}.hamburger--spin-r.is-active .hamburger-inner:after{bottom:0;transition:bottom .1s ease-out,transform .3s cubic-bezier(.215,.61,.355,1) .14s;transform:rotate(90deg)}.hamburger--squeeze .hamburger-inner{transition-timing-function:cubic-bezier(.55,.055,.675,.19);transition-duration:.1s}.hamburger--squeeze .hamburger-inner:before{transition:top .1s ease .14s,opacity .1s ease}.hamburger--squeeze .hamburger-inner:after{transition:bottom .1s ease .14s,transform .1s cubic-bezier(.55,.055,.675,.19)}.hamburger--squeeze.is-active .hamburger-inner{transition-delay:.14s;transition-timing-function:cubic-bezier(.215,.61,.355,1);transform:rotate(45deg)}.hamburger--squeeze.is-active .hamburger-inner:before{top:0;transition:top .1s ease,opacity .1s ease .14s;opacity:0}.hamburger--squeeze.is-active .hamburger-inner:after{bottom:0;transition:bottom .1s ease,transform .1s cubic-bezier(.215,.61,.355,1) .14s;transform:rotate(-90deg)}.hamburger--vortex .hamburger-inner{transition-timing-function:cubic-bezier(.19,1,.22,1);transition-duration:.3s}.hamburger--vortex .hamburger-inner:after,.hamburger--vortex .hamburger-inner:before{transition-delay:.1s;transition-timing-function:linear;transition-duration:0s}.hamburger--vortex .hamburger-inner:before{transition-property:top,opacity}.hamburger--vortex .hamburger-inner:after{transition-property:bottom,transform}.hamburger--vortex.is-active .hamburger-inner{transition-timing-function:cubic-bezier(.19,1,.22,1);transform:rotate(765deg)}.hamburger--vortex.is-active .hamburger-inner:after,.hamburger--vortex.is-active .hamburger-inner:before{transition-delay:0s}.hamburger--vortex.is-active .hamburger-inner:before{top:0;opacity:0}.hamburger--vortex.is-active .hamburger-inner:after{bottom:0;transform:rotate(90deg)}.hamburger--vortex-r .hamburger-inner{transition-timing-function:cubic-bezier(.19,1,.22,1);transition-duration:.3s}.hamburger--vortex-r .hamburger-inner:after,.hamburger--vortex-r .hamburger-inner:before{transition-delay:.1s;transition-timing-function:linear;transition-duration:0s}.hamburger--vortex-r .hamburger-inner:before{transition-property:top,opacity}.hamburger--vortex-r .hamburger-inner:after{transition-property:bottom,transform}.hamburger--vortex-r.is-active .hamburger-inner{transition-timing-function:cubic-bezier(.19,1,.22,1);transform:rotate(-765deg)}.hamburger--vortex-r.is-active .hamburger-inner:after,.hamburger--vortex-r.is-active .hamburger-inner:before{transition-delay:0s}.hamburger--vortex-r.is-active .hamburger-inner:before{top:0;opacity:0}.hamburger--vortex-r.is-active .hamburger-inner:after{bottom:0;transform:rotate(-90deg)}
--------------------------------------------------------------------------------
/static/vendor/select2/select2.css:
--------------------------------------------------------------------------------
1 | .select2-container {
2 | box-sizing: border-box;
3 | display: inline-block;
4 | margin: 0;
5 | position: relative;
6 | vertical-align: middle; }
7 | .select2-container .select2-selection--single {
8 | box-sizing: border-box;
9 | cursor: pointer;
10 | display: block;
11 | height: 28px;
12 | user-select: none;
13 | -webkit-user-select: none; }
14 | .select2-container .select2-selection--single .select2-selection__rendered {
15 | display: block;
16 | padding-left: 8px;
17 | padding-right: 20px;
18 | overflow: hidden;
19 | text-overflow: ellipsis;
20 | white-space: nowrap; }
21 | .select2-container .select2-selection--single .select2-selection__clear {
22 | position: relative; }
23 | .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
24 | padding-right: 8px;
25 | padding-left: 20px; }
26 | .select2-container .select2-selection--multiple {
27 | box-sizing: border-box;
28 | cursor: pointer;
29 | display: block;
30 | min-height: 32px;
31 | user-select: none;
32 | -webkit-user-select: none; }
33 | .select2-container .select2-selection--multiple .select2-selection__rendered {
34 | display: inline-block;
35 | overflow: hidden;
36 | padding-left: 8px;
37 | text-overflow: ellipsis;
38 | white-space: nowrap; }
39 | .select2-container .select2-search--inline {
40 | float: left; }
41 | .select2-container .select2-search--inline .select2-search__field {
42 | box-sizing: border-box;
43 | border: none;
44 | font-size: 100%;
45 | margin-top: 5px;
46 | padding: 0; }
47 | .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
48 | -webkit-appearance: none; }
49 |
50 | .select2-dropdown {
51 | background-color: white;
52 | border: 1px solid #aaa;
53 | border-radius: 4px;
54 | box-sizing: border-box;
55 | display: block;
56 | position: absolute;
57 | left: -100000px;
58 | width: 100%;
59 | z-index: 1051; }
60 |
61 | .select2-results {
62 | display: block; }
63 |
64 | .select2-results__options {
65 | list-style: none;
66 | margin: 0;
67 | padding: 0; }
68 |
69 | .select2-results__option {
70 | padding: 6px;
71 | user-select: none;
72 | -webkit-user-select: none; }
73 | .select2-results__option[aria-selected] {
74 | cursor: pointer; }
75 |
76 | .select2-container--open .select2-dropdown {
77 | left: 0; }
78 |
79 | .select2-container--open .select2-dropdown--above {
80 | border-bottom: none;
81 | border-bottom-left-radius: 0;
82 | border-bottom-right-radius: 0; }
83 |
84 | .select2-container--open .select2-dropdown--below {
85 | border-top: none;
86 | border-top-left-radius: 0;
87 | border-top-right-radius: 0; }
88 |
89 | .select2-search--dropdown {
90 | display: block;
91 | padding: 4px; }
92 | .select2-search--dropdown .select2-search__field {
93 | padding: 4px;
94 | width: 100%;
95 | box-sizing: border-box; }
96 | .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
97 | -webkit-appearance: none; }
98 | .select2-search--dropdown.select2-search--hide {
99 | display: none; }
100 |
101 | .select2-close-mask {
102 | border: 0;
103 | margin: 0;
104 | padding: 0;
105 | display: block;
106 | position: fixed;
107 | left: 0;
108 | top: 0;
109 | min-height: 100%;
110 | min-width: 100%;
111 | height: auto;
112 | width: auto;
113 | opacity: 0;
114 | z-index: 99;
115 | background-color: #fff;
116 | filter: alpha(opacity=0); }
117 |
118 | .select2-hidden-accessible {
119 | border: 0 !important;
120 | clip: rect(0 0 0 0) !important;
121 | height: 1px !important;
122 | margin: -1px !important;
123 | overflow: hidden !important;
124 | padding: 0 !important;
125 | position: absolute !important;
126 | width: 1px !important; }
127 |
128 | .select2-container--default .select2-selection--single {
129 | background-color: #fff;
130 | border: 1px solid #aaa;
131 | border-radius: 4px; }
132 | .select2-container--default .select2-selection--single .select2-selection__rendered {
133 | color: #444;
134 | line-height: 28px; }
135 | .select2-container--default .select2-selection--single .select2-selection__clear {
136 | cursor: pointer;
137 | float: right;
138 | font-weight: bold; }
139 | .select2-container--default .select2-selection--single .select2-selection__placeholder {
140 | color: #999; }
141 | .select2-container--default .select2-selection--single .select2-selection__arrow {
142 | height: 26px;
143 | position: absolute;
144 | top: 1px;
145 | right: 1px;
146 | width: 20px; }
147 | .select2-container--default .select2-selection--single .select2-selection__arrow b {
148 | border-color: #888 transparent transparent transparent;
149 | border-style: solid;
150 | border-width: 5px 4px 0 4px;
151 | height: 0;
152 | left: 50%;
153 | margin-left: -4px;
154 | margin-top: -2px;
155 | position: absolute;
156 | top: 50%;
157 | width: 0; }
158 |
159 | .select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
160 | float: left; }
161 |
162 | .select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
163 | left: 1px;
164 | right: auto; }
165 |
166 | .select2-container--default.select2-container--disabled .select2-selection--single {
167 | background-color: #eee;
168 | cursor: default; }
169 | .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
170 | display: none; }
171 |
172 | .select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
173 | border-color: transparent transparent #888 transparent;
174 | border-width: 0 4px 5px 4px; }
175 |
176 | .select2-container--default .select2-selection--multiple {
177 | background-color: white;
178 | border: 1px solid #aaa;
179 | border-radius: 4px;
180 | cursor: text; }
181 | .select2-container--default .select2-selection--multiple .select2-selection__rendered {
182 | box-sizing: border-box;
183 | list-style: none;
184 | margin: 0;
185 | padding: 0 5px;
186 | width: 100%; }
187 | .select2-container--default .select2-selection--multiple .select2-selection__rendered li {
188 | list-style: none; }
189 | .select2-container--default .select2-selection--multiple .select2-selection__placeholder {
190 | color: #999;
191 | margin-top: 5px;
192 | float: left; }
193 | .select2-container--default .select2-selection--multiple .select2-selection__clear {
194 | cursor: pointer;
195 | float: right;
196 | font-weight: bold;
197 | margin-top: 5px;
198 | margin-right: 10px; }
199 | .select2-container--default .select2-selection--multiple .select2-selection__choice {
200 | background-color: #e4e4e4;
201 | border: 1px solid #aaa;
202 | border-radius: 4px;
203 | cursor: default;
204 | float: left;
205 | margin-right: 5px;
206 | margin-top: 5px;
207 | padding: 0 5px; }
208 | .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
209 | color: #999;
210 | cursor: pointer;
211 | display: inline-block;
212 | font-weight: bold;
213 | margin-right: 2px; }
214 | .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
215 | color: #333; }
216 |
217 | .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
218 | float: right; }
219 |
220 | .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
221 | margin-left: 5px;
222 | margin-right: auto; }
223 |
224 | .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
225 | margin-left: 2px;
226 | margin-right: auto; }
227 |
228 | .select2-container--default.select2-container--focus .select2-selection--multiple {
229 | border: solid black 1px;
230 | outline: 0; }
231 |
232 | .select2-container--default.select2-container--disabled .select2-selection--multiple {
233 | background-color: #eee;
234 | cursor: default; }
235 |
236 | .select2-container--default.select2-container--disabled .select2-selection__choice__remove {
237 | display: none; }
238 |
239 | .select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
240 | border-top-left-radius: 0;
241 | border-top-right-radius: 0; }
242 |
243 | .select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
244 | border-bottom-left-radius: 0;
245 | border-bottom-right-radius: 0; }
246 |
247 | .select2-container--default .select2-search--dropdown .select2-search__field {
248 | border: 1px solid #aaa; }
249 |
250 | .select2-container--default .select2-search--inline .select2-search__field {
251 | background: transparent;
252 | border: none;
253 | outline: 0;
254 | box-shadow: none;
255 | -webkit-appearance: textfield; }
256 |
257 | .select2-container--default .select2-results > .select2-results__options {
258 | max-height: 200px;
259 | overflow-y: auto; }
260 |
261 | .select2-container--default .select2-results__option[role=group] {
262 | padding: 0; }
263 |
264 | .select2-container--default .select2-results__option[aria-disabled=true] {
265 | color: #999; }
266 |
267 | .select2-container--default .select2-results__option[aria-selected=true] {
268 | background-color: #ddd; }
269 |
270 | .select2-container--default .select2-results__option .select2-results__option {
271 | padding-left: 1em; }
272 | .select2-container--default .select2-results__option .select2-results__option .select2-results__group {
273 | padding-left: 0; }
274 | .select2-container--default .select2-results__option .select2-results__option .select2-results__option {
275 | margin-left: -1em;
276 | padding-left: 2em; }
277 | .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
278 | margin-left: -2em;
279 | padding-left: 3em; }
280 | .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
281 | margin-left: -3em;
282 | padding-left: 4em; }
283 | .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
284 | margin-left: -4em;
285 | padding-left: 5em; }
286 | .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
287 | margin-left: -5em;
288 | padding-left: 6em; }
289 |
290 | .select2-container--default .select2-results__option--highlighted[aria-selected] {
291 | background-color: #5897fb;
292 | color: white; }
293 |
294 | .select2-container--default .select2-results__group {
295 | cursor: default;
296 | display: block;
297 | padding: 6px; }
298 |
299 | .select2-container--classic .select2-selection--single {
300 | background-color: #f7f7f7;
301 | border: 1px solid #aaa;
302 | border-radius: 4px;
303 | outline: 0;
304 | background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
305 | background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
306 | background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
307 | background-repeat: repeat-x;
308 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
309 | .select2-container--classic .select2-selection--single:focus {
310 | border: 1px solid #5897fb; }
311 | .select2-container--classic .select2-selection--single .select2-selection__rendered {
312 | color: #444;
313 | line-height: 28px; }
314 | .select2-container--classic .select2-selection--single .select2-selection__clear {
315 | cursor: pointer;
316 | float: right;
317 | font-weight: bold;
318 | margin-right: 10px; }
319 | .select2-container--classic .select2-selection--single .select2-selection__placeholder {
320 | color: #999; }
321 | .select2-container--classic .select2-selection--single .select2-selection__arrow {
322 | background-color: #ddd;
323 | border: none;
324 | border-left: 1px solid #aaa;
325 | border-top-right-radius: 4px;
326 | border-bottom-right-radius: 4px;
327 | height: 26px;
328 | position: absolute;
329 | top: 1px;
330 | right: 1px;
331 | width: 20px;
332 | background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
333 | background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
334 | background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
335 | background-repeat: repeat-x;
336 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
337 | .select2-container--classic .select2-selection--single .select2-selection__arrow b {
338 | border-color: #888 transparent transparent transparent;
339 | border-style: solid;
340 | border-width: 5px 4px 0 4px;
341 | height: 0;
342 | left: 50%;
343 | margin-left: -4px;
344 | margin-top: -2px;
345 | position: absolute;
346 | top: 50%;
347 | width: 0; }
348 |
349 | .select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear {
350 | float: left; }
351 |
352 | .select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow {
353 | border: none;
354 | border-right: 1px solid #aaa;
355 | border-radius: 0;
356 | border-top-left-radius: 4px;
357 | border-bottom-left-radius: 4px;
358 | left: 1px;
359 | right: auto; }
360 |
361 | .select2-container--classic.select2-container--open .select2-selection--single {
362 | border: 1px solid #5897fb; }
363 | .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
364 | background: transparent;
365 | border: none; }
366 | .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
367 | border-color: transparent transparent #888 transparent;
368 | border-width: 0 4px 5px 4px; }
369 |
370 | .select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
371 | border-top: none;
372 | border-top-left-radius: 0;
373 | border-top-right-radius: 0;
374 | background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
375 | background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
376 | background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
377 | background-repeat: repeat-x;
378 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
379 |
380 | .select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
381 | border-bottom: none;
382 | border-bottom-left-radius: 0;
383 | border-bottom-right-radius: 0;
384 | background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
385 | background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
386 | background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
387 | background-repeat: repeat-x;
388 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
389 |
390 | .select2-container--classic .select2-selection--multiple {
391 | background-color: white;
392 | border: 1px solid #aaa;
393 | border-radius: 4px;
394 | cursor: text;
395 | outline: 0; }
396 | .select2-container--classic .select2-selection--multiple:focus {
397 | border: 1px solid #5897fb; }
398 | .select2-container--classic .select2-selection--multiple .select2-selection__rendered {
399 | list-style: none;
400 | margin: 0;
401 | padding: 0 5px; }
402 | .select2-container--classic .select2-selection--multiple .select2-selection__clear {
403 | display: none; }
404 | .select2-container--classic .select2-selection--multiple .select2-selection__choice {
405 | background-color: #e4e4e4;
406 | border: 1px solid #aaa;
407 | border-radius: 4px;
408 | cursor: default;
409 | float: left;
410 | margin-right: 5px;
411 | margin-top: 5px;
412 | padding: 0 5px; }
413 | .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
414 | color: #888;
415 | cursor: pointer;
416 | display: inline-block;
417 | font-weight: bold;
418 | margin-right: 2px; }
419 | .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
420 | color: #555; }
421 |
422 | .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
423 | float: right; }
424 |
425 | .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
426 | margin-left: 5px;
427 | margin-right: auto; }
428 |
429 | .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
430 | margin-left: 2px;
431 | margin-right: auto; }
432 |
433 | .select2-container--classic.select2-container--open .select2-selection--multiple {
434 | border: 1px solid #5897fb; }
435 |
436 | .select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
437 | border-top: none;
438 | border-top-left-radius: 0;
439 | border-top-right-radius: 0; }
440 |
441 | .select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
442 | border-bottom: none;
443 | border-bottom-left-radius: 0;
444 | border-bottom-right-radius: 0; }
445 |
446 | .select2-container--classic .select2-search--dropdown .select2-search__field {
447 | border: 1px solid #aaa;
448 | outline: 0; }
449 |
450 | .select2-container--classic .select2-search--inline .select2-search__field {
451 | outline: 0;
452 | box-shadow: none; }
453 |
454 | .select2-container--classic .select2-dropdown {
455 | background-color: white;
456 | border: 1px solid transparent; }
457 |
458 | .select2-container--classic .select2-dropdown--above {
459 | border-bottom: none; }
460 |
461 | .select2-container--classic .select2-dropdown--below {
462 | border-top: none; }
463 |
464 | .select2-container--classic .select2-results > .select2-results__options {
465 | max-height: 200px;
466 | overflow-y: auto; }
467 |
468 | .select2-container--classic .select2-results__option[role=group] {
469 | padding: 0; }
470 |
471 | .select2-container--classic .select2-results__option[aria-disabled=true] {
472 | color: grey; }
473 |
474 | .select2-container--classic .select2-results__option--highlighted[aria-selected] {
475 | background-color: #3875d7;
476 | color: white; }
477 |
478 | .select2-container--classic .select2-results__group {
479 | cursor: default;
480 | display: block;
481 | padding: 6px; }
482 |
483 | .select2-container--classic.select2-container--open .select2-dropdown {
484 | border-color: #5897fb; }
--------------------------------------------------------------------------------
/static/vendor/select2/select2.min.css:
--------------------------------------------------------------------------------
1 | .select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}
2 |
--------------------------------------------------------------------------------
/static/vendor/tilt/tilt.jquery.min.js:
--------------------------------------------------------------------------------
1 | "use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};!function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"===("undefined"==typeof module?"undefined":_typeof(module))&&module.exports?module.exports=function(i,s){return void 0===s&&(s="undefined"!=typeof window?require("jquery"):require("jquery")(i)),t(s),s}:t(jQuery)}(function(t){return t.fn.tilt=function(i){var s=function(){this.ticking||(requestAnimationFrame(g.bind(this)),this.ticking=!0)},e=function(){var i=this;t(this).on("mousemove",o),t(this).on("mouseenter",a),this.settings.reset&&t(this).on("mouseleave",l),this.settings.glare&&t(window).on("resize",d.bind(i))},n=function(){var i=this;void 0!==this.timeout&&clearTimeout(this.timeout),t(this).css({transition:this.settings.speed+"ms "+this.settings.easing}),this.settings.glare&&this.glareElement.css({transition:"opacity "+this.settings.speed+"ms "+this.settings.easing}),this.timeout=setTimeout(function(){t(i).css({transition:""}),i.settings.glare&&i.glareElement.css({transition:""})},this.settings.speed)},a=function(i){this.ticking=!1,t(this).css({"will-change":"transform"}),n.call(this),t(this).trigger("tilt.mouseEnter")},r=function(i){return"undefined"==typeof i&&(i={pageX:t(this).offset().left+t(this).outerWidth()/2,pageY:t(this).offset().top+t(this).outerHeight()/2}),{x:i.pageX,y:i.pageY}},o=function(t){this.mousePositions=r(t),s.call(this)},l=function(){n.call(this),this.reset=!0,s.call(this),t(this).trigger("tilt.mouseLeave")},h=function(){var i=t(this).outerWidth(),s=t(this).outerHeight(),e=t(this).offset().left,n=t(this).offset().top,a=(this.mousePositions.x-e)/i,r=(this.mousePositions.y-n)/s,o=(this.settings.maxTilt/2-a*this.settings.maxTilt).toFixed(2),l=(r*this.settings.maxTilt-this.settings.maxTilt/2).toFixed(2),h=Math.atan2(this.mousePositions.x-(e+i/2),-(this.mousePositions.y-(n+s/2)))*(180/Math.PI);return{tiltX:o,tiltY:l,percentageX:100*a,percentageY:100*r,angle:h}},g=function(){return this.transforms=h.call(this),this.reset?(this.reset=!1,t(this).css("transform","perspective("+this.settings.perspective+"px) rotateX(0deg) rotateY(0deg)"),void(this.settings.glare&&(this.glareElement.css("transform","rotate(180deg) translate(-50%, -50%)"),this.glareElement.css("opacity","0")))):(t(this).css("transform","perspective("+this.settings.perspective+"px) rotateX("+("x"===this.settings.disableAxis?0:this.transforms.tiltY)+"deg) rotateY("+("y"===this.settings.disableAxis?0:this.transforms.tiltX)+"deg) scale3d("+this.settings.scale+","+this.settings.scale+","+this.settings.scale+")"),this.settings.glare&&(this.glareElement.css("transform","rotate("+this.transforms.angle+"deg) translate(-50%, -50%)"),this.glareElement.css("opacity",""+this.transforms.percentageY*this.settings.maxGlare/100)),t(this).trigger("change",[this.transforms]),void(this.ticking=!1))},c=function(){var i=this.settings.glarePrerender;if(i||t(this).append(''),this.glareElementWrapper=t(this).find(".js-tilt-glare"),this.glareElement=t(this).find(".js-tilt-glare-inner"),!i){var s={position:"absolute",top:"0",left:"0",width:"100%",height:"100%"};this.glareElementWrapper.css(s).css({overflow:"hidden","pointer-events":"none"}),this.glareElement.css({position:"absolute",top:"50%",left:"50%","background-image":"linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)",width:""+2*t(this).outerWidth(),height:""+2*t(this).outerWidth(),transform:"rotate(180deg) translate(-50%, -50%)","transform-origin":"0% 0%",opacity:"0"})}},d=function(){this.glareElement.css({width:""+2*t(this).outerWidth(),height:""+2*t(this).outerWidth()})};return t.fn.tilt.destroy=function(){t(this).each(function(){t(this).find(".js-tilt-glare").remove(),t(this).css({"will-change":"",transform:""}),t(this).off("mousemove mouseenter mouseleave")})},t.fn.tilt.getValues=function(){var i=[];return t(this).each(function(){this.mousePositions=r.call(this),i.push(h.call(this))}),i},t.fn.tilt.reset=function(){t(this).each(function(){var i=this;this.mousePositions=r.call(this),this.settings=t(this).data("settings"),l.call(this),setTimeout(function(){i.reset=!1},this.settings.transition)})},this.each(function(){var s=this;this.settings=t.extend({maxTilt:t(this).is("[data-tilt-max]")?t(this).data("tilt-max"):20,perspective:t(this).is("[data-tilt-perspective]")?t(this).data("tilt-perspective"):300,easing:t(this).is("[data-tilt-easing]")?t(this).data("tilt-easing"):"cubic-bezier(.03,.98,.52,.99)",scale:t(this).is("[data-tilt-scale]")?t(this).data("tilt-scale"):"1",speed:t(this).is("[data-tilt-speed]")?t(this).data("tilt-speed"):"400",transition:!t(this).is("[data-tilt-transition]")||t(this).data("tilt-transition"),disableAxis:t(this).is("[data-tilt-disable-axis]")?t(this).data("tilt-disable-axis"):null,axis:t(this).is("[data-tilt-axis]")?t(this).data("tilt-axis"):null,reset:!t(this).is("[data-tilt-reset]")||t(this).data("tilt-reset"),glare:!!t(this).is("[data-tilt-glare]")&&t(this).data("tilt-glare"),maxGlare:t(this).is("[data-tilt-maxglare]")?t(this).data("tilt-maxglare"):1},i),null!==this.settings.axis&&(console.warn("Tilt.js: the axis setting has been renamed to disableAxis. See https://github.com/gijsroge/tilt.js/pull/26 for more information"),this.settings.disableAxis=this.settings.axis),this.init=function(){t(s).data("settings",s.settings),s.settings.glare&&c.call(s),e.call(s)},this.init()})},t("[data-tilt]").tilt(),!0});
--------------------------------------------------------------------------------
/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
14 |
15 | Bahi Khata
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
70 |
71 | {% block content %}
72 | {% endblock %}
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
92 |
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/templates/index.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block content %}
4 |
5 |
6 |

7 |
8 |
9 |
24 |
25 | {% endblock %}
--------------------------------------------------------------------------------
/templates/login.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block content %}
4 |
5 |
6 |

7 |
8 |
36 |
37 | {% endblock %}
--------------------------------------------------------------------------------
/templates/profile.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block content %}
4 |
5 |
6 |

7 |
8 |
16 |
17 | {% endblock %}
--------------------------------------------------------------------------------
/templates/report.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
84 |
85 |
86 |
87 |
88 |
89 |
91 | Lorem ipsum dolor que ist
92 |
93 |
94 |
95 |
96 |
99 |
104 |
105 |
106 |
107 |
108 | |
109 |
110 |
111 |
113 | Your annual online spendings report
114 |
115 | You have spent ₹{{ amount }} in the last year
116 |
117 | |
118 |
119 |
120 |
125 | |
126 |
127 |
128 |
130 |
135 |
136 |
137 |
139 |
140 |
141 |
142 |
145 | |
146 |
147 |
148 |
150 |
151 |
152 |
153 |
154 |
155 | |
156 |
157 |
158 | |
159 |
160 |
161 |
166 | |
167 |
168 |
169 |
171 |
176 |
177 |
178 |
179 |
181 | |
182 |
183 |
184 |
186 |
187 | 69 Amphitheatre Parkway
188 | Mountain View, CA 420
189 |
190 |
191 |
192 | View Online
193 | •
194 | Unsubscribe
195 |
196 | |
197 |
198 |
199 |
204 | |
205 |
206 |
207 |
208 |
209 |
--------------------------------------------------------------------------------
/templates/signup.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block content %}
4 |
5 |
6 |

7 |
8 |
40 |
41 | {% endblock %}
--------------------------------------------------------------------------------
/templates/thankyou.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block content %}
4 |
14 | {% endblock %}
15 |
--------------------------------------------------------------------------------
/wsgi.py:
--------------------------------------------------------------------------------
1 | from gmail_flask import app
2 |
3 | if __name__ == "__main__":
4 | app.run()
5 |
--------------------------------------------------------------------------------