diff --git a/assets/js/jquery.mask.js b/assets/js/jquery.mask.js
new file mode 100644
index 0000000..6f2417d
--- /dev/null
+++ b/assets/js/jquery.mask.js
@@ -0,0 +1,604 @@
+/**
+ * jquery.mask.js
+ * @version: v1.14.16
+ * @author: Igor Escobar
+ *
+ * Created by Igor Escobar on 2012-03-10. Please report any bug at github.com/igorescobar/jQuery-Mask-Plugin
+ *
+ * Copyright (c) 2012 Igor Escobar http://igorescobar.com
+ *
+ * The MIT License (http://www.opensource.org/licenses/mit-license.php)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* jshint laxbreak: true */
+/* jshint maxcomplexity:17 */
+/* global define */
+
+// UMD (Universal Module Definition) patterns for JavaScript modules that work everywhere.
+// https://github.com/umdjs/umd/blob/master/templates/jqueryPlugin.js
+(function (factory, jQuery, Zepto) {
+
+	if (typeof define === 'function' && define.amd) {
+		define(['jquery'], factory);
+	} else if (typeof exports === 'object' && typeof Meteor === 'undefined') {
+		module.exports = factory(require('jquery'));
+	} else {
+		factory(jQuery || Zepto);
+	}
+
+}(function ($) {
+	'use strict';
+
+	var Mask = function (el, mask, options) {
+
+		var p = {
+			invalid: [],
+			getCaret: function () {
+				try {
+					var sel,
+						pos = 0,
+						ctrl = el.get(0),
+						dSel = document.selection,
+						cSelStart = ctrl.selectionStart;
+
+					// IE Support
+					if (dSel && navigator.appVersion.indexOf('MSIE 10') === -1) {
+						sel = dSel.createRange();
+						sel.moveStart('character', -p.val().length);
+						pos = sel.text.length;
+					}
+					// Firefox support
+					else if (cSelStart || cSelStart === '0') {
+						pos = cSelStart;
+					}
+
+					return pos;
+				} catch (e) {}
+			},
+			setCaret: function(pos) {
+				try {
+					if (el.is(':focus')) {
+						var range, ctrl = el.get(0);
+
+						// Firefox, WebKit, etc..
+						if (ctrl.setSelectionRange) {
+							ctrl.setSelectionRange(pos, pos);
+						} else { // IE
+							range = ctrl.createTextRange();
+							range.collapse(true);
+							range.moveEnd('character', pos);
+							range.moveStart('character', pos);
+							range.select();
+						}
+					}
+				} catch (e) {}
+			},
+			events: function() {
+				el
+					.on('keydown.mask', function(e) {
+						el.data('mask-keycode', e.keyCode || e.which);
+						el.data('mask-previus-value', el.val());
+						el.data('mask-previus-caret-pos', p.getCaret());
+						p.maskDigitPosMapOld = p.maskDigitPosMap;
+					})
+					.on($.jMaskGlobals.useInput ? 'input.mask' : 'keyup.mask', p.behaviour)
+					.on('paste.mask drop.mask', function() {
+						setTimeout(function() {
+							el.keydown().keyup();
+						}, 100);
+					})
+					.on('change.mask', function(){
+						el.data('changed', true);
+					})
+					.on('blur.mask', function(){
+						if (oldValue !== p.val() && !el.data('changed')) {
+							el.trigger('change');
+						}
+						el.data('changed', false);
+					})
+					// it's very important that this callback remains in this position
+					// otherwhise oldValue it's going to work buggy
+					.on('blur.mask', function() {
+						oldValue = p.val();
+					})
+					// select all text on focus
+					.on('focus.mask', function (e) {
+						if (options.selectOnFocus === true) {
+							$(e.target).select();
+						}
+					})
+					// clear the value if it not complete the mask
+					.on('focusout.mask', function() {
+						if (options.clearIfNotMatch && !regexMask.test(p.val())) {
+							p.val('');
+						}
+					});
+			},
+			getRegexMask: function() {
+				var maskChunks = [], translation, pattern, optional, recursive, oRecursive, r;
+
+				for (var i = 0; i < mask.length; i++) {
+					translation = jMask.translation[mask.charAt(i)];
+
+					if (translation) {
+
+						pattern = translation.pattern.toString().replace(/.{1}$|^.{1}/g, '');
+						optional = translation.optional;
+						recursive = translation.recursive;
+
+						if (recursive) {
+							maskChunks.push(mask.charAt(i));
+							oRecursive = {digit: mask.charAt(i), pattern: pattern};
+						} else {
+							maskChunks.push(!optional && !recursive ? pattern : (pattern + '?'));
+						}
+
+					} else {
+						maskChunks.push(mask.charAt(i).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));
+					}
+				}
+
+				r = maskChunks.join('');
+
+				if (oRecursive) {
+					r = r.replace(new RegExp('(' + oRecursive.digit + '(.*' + oRecursive.digit + ')?)'), '($1)?')
+						.replace(new RegExp(oRecursive.digit, 'g'), oRecursive.pattern);
+				}
+
+				return new RegExp(r);
+			},
+			destroyEvents: function() {
+				el.off(['input', 'keydown', 'keyup', 'paste', 'drop', 'blur', 'focusout', ''].join('.mask '));
+			},
+			val: function(v) {
+				var isInput = el.is('input'),
+					method = isInput ? 'val' : 'text',
+					r;
+
+				if (arguments.length > 0) {
+					if (el[method]() !== v) {
+						el[method](v);
+					}
+					r = el;
+				} else {
+					r = el[method]();
+				}
+
+				return r;
+			},
+			calculateCaretPosition: function(oldVal) {
+				var newVal = p.getMasked(),
+					caretPosNew = p.getCaret();
+				if (oldVal !== newVal) {
+					var caretPosOld = el.data('mask-previus-caret-pos') || 0,
+						newValL = newVal.length,
+						oldValL = oldVal.length,
+						maskDigitsBeforeCaret = 0,
+						maskDigitsAfterCaret = 0,
+						maskDigitsBeforeCaretAll = 0,
+						maskDigitsBeforeCaretAllOld = 0,
+						i = 0;
+
+					for (i = caretPosNew; i < newValL; i++) {
+						if (!p.maskDigitPosMap[i]) {
+							break;
+						}
+						maskDigitsAfterCaret++;
+					}
+
+					for (i = caretPosNew - 1; i >= 0; i--) {
+						if (!p.maskDigitPosMap[i]) {
+							break;
+						}
+						maskDigitsBeforeCaret++;
+					}
+
+					for (i = caretPosNew - 1; i >= 0; i--) {
+						if (p.maskDigitPosMap[i]) {
+							maskDigitsBeforeCaretAll++;
+						}
+					}
+
+					for (i = caretPosOld - 1; i >= 0; i--) {
+						if (p.maskDigitPosMapOld[i]) {
+							maskDigitsBeforeCaretAllOld++;
+						}
+					}
+
+					// if the cursor is at the end keep it there
+					if (caretPosNew > oldValL) {
+						caretPosNew = newValL * 10;
+					} else if (caretPosOld >= caretPosNew && caretPosOld !== oldValL) {
+						if (!p.maskDigitPosMapOld[caretPosNew])  {
+							var caretPos = caretPosNew;
+							caretPosNew -= maskDigitsBeforeCaretAllOld - maskDigitsBeforeCaretAll;
+							caretPosNew -= maskDigitsBeforeCaret;
+							if (p.maskDigitPosMap[caretPosNew])  {
+								caretPosNew = caretPos;
+							}
+						}
+					}
+					else if (caretPosNew > caretPosOld) {
+						caretPosNew += maskDigitsBeforeCaretAll - maskDigitsBeforeCaretAllOld;
+						caretPosNew += maskDigitsAfterCaret;
+					}
+				}
+				return caretPosNew;
+			},
+			behaviour: function(e) {
+				e = e || window.event;
+				p.invalid = [];
+
+				var keyCode = el.data('mask-keycode');
+
+				if ($.inArray(keyCode, jMask.byPassKeys) === -1) {
+					var newVal = p.getMasked(),
+						caretPos = p.getCaret(),
+						oldVal = el.data('mask-previus-value') || '';
+
+					// this is a compensation to devices/browsers that don't compensate
+					// caret positioning the right way
+					setTimeout(function() {
+						p.setCaret(p.calculateCaretPosition(oldVal));
+					}, $.jMaskGlobals.keyStrokeCompensation);
+
+					p.val(newVal);
+					p.setCaret(caretPos);
+					return p.callbacks(e);
+				}
+			},
+			getMasked: function(skipMaskChars, val) {
+				var buf = [],
+					value = val === undefined ? p.val() : val + '',
+					m = 0, maskLen = mask.length,
+					v = 0, valLen = value.length,
+					offset = 1, addMethod = 'push',
+					resetPos = -1,
+					maskDigitCount = 0,
+					maskDigitPosArr = [],
+					lastMaskChar,
+					check;
+
+				if (options.reverse) {
+					addMethod = 'unshift';
+					offset = -1;
+					lastMaskChar = 0;
+					m = maskLen - 1;
+					v = valLen - 1;
+					check = function () {
+						return m > -1 && v > -1;
+					};
+				} else {
+					lastMaskChar = maskLen - 1;
+					check = function () {
+						return m < maskLen && v < valLen;
+					};
+				}
+
+				var lastUntranslatedMaskChar;
+				while (check()) {
+					var maskDigit = mask.charAt(m),
+						valDigit = value.charAt(v),
+						translation = jMask.translation[maskDigit];
+
+					if (translation) {
+						if (valDigit.match(translation.pattern)) {
+							buf[addMethod](valDigit);
+							if (translation.recursive) {
+								if (resetPos === -1) {
+									resetPos = m;
+								} else if (m === lastMaskChar && m !== resetPos) {
+									m = resetPos - offset;
+								}
+
+								if (lastMaskChar === resetPos) {
+									m -= offset;
+								}
+							}
+							m += offset;
+						} else if (valDigit === lastUntranslatedMaskChar) {
+							// matched the last untranslated (raw) mask character that we encountered
+							// likely an insert offset the mask character from the last entry; fall
+							// through and only increment v
+							maskDigitCount--;
+							lastUntranslatedMaskChar = undefined;
+						} else if (translation.optional) {
+							m += offset;
+							v -= offset;
+						} else if (translation.fallback) {
+							buf[addMethod](translation.fallback);
+							m += offset;
+							v -= offset;
+						} else {
+							p.invalid.push({p: v, v: valDigit, e: translation.pattern});
+						}
+						v += offset;
+					} else {
+						if (!skipMaskChars) {
+							buf[addMethod](maskDigit);
+						}
+
+						if (valDigit === maskDigit) {
+							maskDigitPosArr.push(v);
+							v += offset;
+						} else {
+							lastUntranslatedMaskChar = maskDigit;
+							maskDigitPosArr.push(v + maskDigitCount);
+							maskDigitCount++;
+						}
+
+						m += offset;
+					}
+				}
+
+				var lastMaskCharDigit = mask.charAt(lastMaskChar);
+				if (maskLen === valLen + 1 && !jMask.translation[lastMaskCharDigit]) {
+					buf.push(lastMaskCharDigit);
+				}
+
+				var newVal = buf.join('');
+				p.mapMaskdigitPositions(newVal, maskDigitPosArr, valLen);
+				return newVal;
+			},
+			mapMaskdigitPositions: function(newVal, maskDigitPosArr, valLen) {
+				var maskDiff = options.reverse ? newVal.length - valLen : 0;
+				p.maskDigitPosMap = {};
+				for (var i = 0; i < maskDigitPosArr.length; i++) {
+					p.maskDigitPosMap[maskDigitPosArr[i] + maskDiff] = 1;
+				}
+			},
+			callbacks: function (e) {
+				var val = p.val(),
+					changed = val !== oldValue,
+					defaultArgs = [val, e, el, options],
+					callback = function(name, criteria, args) {
+						if (typeof options[name] === 'function' && criteria) {
+							options[name].apply(this, args);
+						}
+					};
+
+				callback('onChange', changed === true, defaultArgs);
+				callback('onKeyPress', changed === true, defaultArgs);
+				callback('onComplete', val.length === mask.length, defaultArgs);
+				callback('onInvalid', p.invalid.length > 0, [val, e, el, p.invalid, options]);
+			}
+		};
+
+		el = $(el);
+		var jMask = this, oldValue = p.val(), regexMask;
+
+		mask = typeof mask === 'function' ? mask(p.val(), undefined, el,  options) : mask;
+
+		// public methods
+		jMask.mask = mask;
+		jMask.options = options;
+		jMask.remove = function() {
+			var caret = p.getCaret();
+			if (jMask.options.placeholder) {
+				el.removeAttr('placeholder');
+			}
+			if (el.data('mask-maxlength')) {
+				el.removeAttr('maxlength');
+			}
+			p.destroyEvents();
+			p.val(jMask.getCleanVal());
+			p.setCaret(caret);
+			return el;
+		};
+
+		// get value without mask
+		jMask.getCleanVal = function() {
+			return p.getMasked(true);
+		};
+
+		// get masked value without the value being in the input or element
+		jMask.getMaskedVal = function(val) {
+			return p.getMasked(false, val);
+		};
+
+		jMask.init = function(onlyMask) {
+			onlyMask = onlyMask || false;
+			options = options || {};
+
+			jMask.clearIfNotMatch  = $.jMaskGlobals.clearIfNotMatch;
+			jMask.byPassKeys       = $.jMaskGlobals.byPassKeys;
+			jMask.translation      = $.extend({}, $.jMaskGlobals.translation, options.translation);
+
+			jMask = $.extend(true, {}, jMask, options);
+
+			regexMask = p.getRegexMask();
+
+			if (onlyMask) {
+				p.events();
+				p.val(p.getMasked());
+			} else {
+				if (options.placeholder) {
+					el.attr('placeholder' , options.placeholder);
+				}
+
+				// this is necessary, otherwise if the user submit the form
+				// and then press the "back" button, the autocomplete will erase
+				// the data. Works fine on IE9+, FF, Opera, Safari.
+				if (el.data('mask')) {
+					el.attr('autocomplete', 'off');
+				}
+
+				// detect if is necessary let the user type freely.
+				// for is a lot faster than forEach.
+				for (var i = 0, maxlength = true; i < mask.length; i++) {
+					var translation = jMask.translation[mask.charAt(i)];
+					if (translation && translation.recursive) {
+						maxlength = false;
+						break;
+					}
+				}
+
+				if (maxlength) {
+					el.attr('maxlength', mask.length).data('mask-maxlength', true);
+				}
+
+				p.destroyEvents();
+				p.events();
+
+				var caret = p.getCaret();
+				p.val(p.getMasked());
+				p.setCaret(caret);
+			}
+		};
+
+		jMask.init(!el.is('input'));
+	};
+
+	$.maskWatchers = {};
+	var HTMLAttributes = function () {
+			var input = $(this),
+				options = {},
+				prefix = 'data-mask-',
+				mask = input.attr('data-mask');
+
+			if (input.attr(prefix + 'reverse')) {
+				options.reverse = true;
+			}
+
+			if (input.attr(prefix + 'clearifnotmatch')) {
+				options.clearIfNotMatch = true;
+			}
+
+			if (input.attr(prefix + 'selectonfocus') === 'true') {
+				options.selectOnFocus = true;
+			}
+
+			if (notSameMaskObject(input, mask, options)) {
+				return input.data('mask', new Mask(this, mask, options));
+			}
+		},
+		notSameMaskObject = function(field, mask, options) {
+			options = options || {};
+			var maskObject = $(field).data('mask'),
+				stringify = JSON.stringify,
+				value = $(field).val() || $(field).text();
+			try {
+				if (typeof mask === 'function') {
+					mask = mask(value);
+				}
+				return typeof maskObject !== 'object' || stringify(maskObject.options) !== stringify(options) || maskObject.mask !== mask;
+			} catch (e) {}
+		},
+		eventSupported = function(eventName) {
+			var el = document.createElement('div'), isSupported;
+
+			eventName = 'on' + eventName;
+			isSupported = (eventName in el);
+
+			if ( !isSupported ) {
+				el.setAttribute(eventName, 'return;');
+				isSupported = typeof el[eventName] === 'function';
+			}
+			el = null;
+
+			return isSupported;
+		};
+
+	$.fn.mask = function(mask, options) {
+		options = options || {};
+		var selector = this.selector,
+			globals = $.jMaskGlobals,
+			interval = globals.watchInterval,
+			watchInputs = options.watchInputs || globals.watchInputs,
+			maskFunction = function() {
+				if (notSameMaskObject(this, mask, options)) {
+					return $(this).data('mask', new Mask(this, mask, options));
+				}
+			};
+
+		$(this).each(maskFunction);
+
+		if (selector && selector !== '' && watchInputs) {
+			clearInterval($.maskWatchers[selector]);
+			$.maskWatchers[selector] = setInterval(function(){
+				$(document).find(selector).each(maskFunction);
+			}, interval);
+		}
+		return this;
+	};
+
+	$.fn.masked = function(val) {
+		return this.data('mask').getMaskedVal(val);
+	};
+
+	$.fn.unmask = function() {
+		clearInterval($.maskWatchers[this.selector]);
+		delete $.maskWatchers[this.selector];
+		return this.each(function() {
+			var dataMask = $(this).data('mask');
+			if (dataMask) {
+				dataMask.remove().removeData('mask');
+			}
+		});
+	};
+
+	$.fn.cleanVal = function() {
+		return this.data('mask').getCleanVal();
+	};
+
+	$.applyDataMask = function(selector) {
+		selector = selector || $.jMaskGlobals.maskElements;
+		var $selector = (selector instanceof $) ? selector : $(selector);
+		$selector.filter($.jMaskGlobals.dataMaskAttr).each(HTMLAttributes);
+	};
+
+	var globals = {
+		maskElements: 'input,td,span,div',
+		dataMaskAttr: '*[data-mask]',
+		dataMask: true,
+		watchInterval: 300,
+		watchInputs: true,
+		keyStrokeCompensation: 10,
+		// old versions of chrome dont work great with input event
+		useInput: !/Chrome\/[2-4][0-9]|SamsungBrowser/.test(window.navigator.userAgent) && eventSupported('input'),
+		watchDataMask: false,
+		byPassKeys: [9, 16, 17, 18, 36, 37, 38, 39, 40, 91],
+		translation: {
+			'0': {pattern: /\d/},
+			'9': {pattern: /\d/, optional: true},
+			'#': {pattern: /\d/, recursive: true},
+			'A': {pattern: /[a-zA-Z0-9]/},
+			'S': {pattern: /[a-zA-Z]/}
+		}
+	};
+
+	$.jMaskGlobals = $.jMaskGlobals || {};
+	globals = $.jMaskGlobals = $.extend(true, {}, globals, $.jMaskGlobals);
+
+	// looking for inputs with data-mask attribute
+	if (globals.dataMask) {
+		$.applyDataMask();
+	}
+
+	setInterval(function() {
+		if ($.jMaskGlobals.watchDataMask) {
+			$.applyDataMask();
+		}
+	}, globals.watchInterval);
+}, window.jQuery, window.Zepto));
