Commit 9214318d authored by David Haynes's avatar David Haynes 🙆
Browse files

Merge branch '185-go-forward' into 'go-three'

Resolve "Outline the project structure for "Go Forward""

See merge request !124
parents 267806e3 238ac8b5
Pipeline #2881 passed with stage
in 1 minute and 12 seconds
"""
settings/urls.py
The URLs of the project and their associated view that requests are routed to.
"""
# Django Imports
from django.urls import path, re_path, include
from django.contrib import admin
from django.views.decorators.cache import cache_page
from django.views.generic import TemplateView
# App Imports
from . import views
from cas import views as cas_views
# Third Party
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'golinks', views.URLViewSet, base_name="golinks")
# This function attempts to import an admin module in each installed
# application. Such modules are expected to register models with the admin.
admin.autodiscover()
urlpatterns = [
# Root API URL
path("api/", include(router.urls)),
# Authentication URLs
path('auth/login/', cas_views.login, name='cas_login'),
path('auth/logout/', cas_views.logout, {'next_page': '/'}, name='cas_logout'),
# /admin - Administrator interface.
path('admin/', admin.site.urls, name='go_admin'),
path('auth/', include('rest_framework.urls'))
# # /view/<short> - View URL data. Cached for 15 minutes
# re_path(r'^view/(?P<short>([\U00010000-\U0010ffff][\U0000200D]?)+)$',
# cache_page(60 * 15)(go.views.view), name='view'),
# re_path(r'^view/(?P<short>[-\w]+)$',
# cache_page(60 * 15)(go.views.view), name='view'),
# # Redirection regex.
# re_path(r'^(?P<short>([\U00010000-\U0010ffff][\U0000200D]?)+)$',
# go.views.redirection, name='redirection'),
# re_path(r'^(?P<short>[-\w]+)$',
# go.views.redirection, name='redirection'),
]
......@@ -26,6 +26,8 @@ else:
}
# STANDALONE VARS
# /go/go
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# You can generate a secret key from the following link:
......@@ -62,6 +64,7 @@ STATIC_URL = '/static/'
STATIC_ROOT = ''
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static/'),
'./go/static/'
)
STATICFILES_FINDERS = (
......@@ -74,7 +77,8 @@ TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates')
os.path.join(BASE_DIR, 'templates'),
'./go/go_ahead/templates/'
],
'APP_DIRS': True,
'OPTIONS': {
......@@ -123,7 +127,8 @@ INSTALLED_APPS = (
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'go',
'go_back',
'go_ahead',
# Third party
'crispy_forms',
'cas',
......@@ -183,7 +188,7 @@ CAS_LOGOUT_COMPLETELY = True
CAS_PROVIDE_URL_TO_LOGOUT = True
CAS_RESPONSE_CALLBACKS = (
'go.cas_callbacks.create_user',
'go_back.cas_callbacks.create_user',
)
CAS_SERVER_URL = "https://login.gmu.edu"
......
"""
settings/urls.py
The URLs of the project and their associated view that requests are routed to.
"""
# Django Imports
import django.contrib.auth.views
from django.urls import path, re_path, include
from django.contrib import admin
from django.views.decorators.cache import cache_page
from django.views.generic import TemplateView
# App Imports
from go import views
from cas import views as cas_views
# Third Party
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'golinks', views.URLViewSet, base_name="golinks")
# This function attempts to import an admin module in each installed
# application. Such modules are expected to register models with the admin.
admin.autodiscover()
from django.urls import path, include
urlpatterns = [
# Root API URL
path("", include(router.urls)),
# Authentication URLs
path('auth/login/', cas_views.login, name='cas_login'),
path('auth/logout/', cas_views.logout, {'next_page': '/'}, name='cas_logout'),
# /admin - Administrator interface.
path('admin/', admin.site.urls, name='go_admin'),
path('auth/', include('rest_framework.urls'))
# # /view/<short> - View URL data. Cached for 15 minutes
# re_path(r'^view/(?P<short>([\U00010000-\U0010ffff][\U0000200D]?)+)$',
# cache_page(60 * 15)(go.views.view), name='view'),
# re_path(r'^view/(?P<short>[-\w]+)$',
# cache_page(60 * 15)(go.views.view), name='view'),
# # Redirection regex.
# re_path(r'^(?P<short>([\U00010000-\U0010ffff][\U0000200D]?)+)$',
# go.views.redirection, name='redirection'),
# re_path(r'^(?P<short>[-\w]+)$',
# go.views.redirection, name='redirection'),
path('', include('go_back.urls')),
path('', include('go_ahead.urls')),
]
.begin {
margin-top: 6rem;
}
.landing-card {
box-shadow: 0 0 4px 2px rgba(0, 0, 0, .2);
}
.pointer:hover,
.shadow-hover {
cursor: pointer
}
.shadow-hover {
position: relative;
transition: all .5s cubic-bezier(.165, .84, .44, 1)
}
.shadow-hover:after {
content: "";
box-shadow: 0 0 16px 2px rgba(0, 0, 0, .2);
border-radius: inherit;
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
transition: opacity .5s cubic-bezier(.165, .84, .44, 1)
}
.shadow-hover:focus:after,
.shadow-hover:hover:after {
opacity: 1
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 2100 2100" enable-background="new 0 0 2100 2100" xml:space="preserve">
<g>
<polygon fill="none" points="1299,908.2 1299,1221.6 1295.3,1223.7 1023,1380.4 1023,1446.7 1299,1606.1 1351.5,1636.4
1680,1446.7 1680,1126.7 1680,1067.5 1352.2,878.2 1352.2,878.2 1351.6,877.9 1351.6,877.9 1350.2,878.7 1300.4,907.5
1299.2,908.2 1299.1,908.2 "/>
<polygon fill="none" points="988.4,1046.6 1019.7,1064.7 1023.8,1067.1 1019.7,1064.7 "/>
<polygon fill="#FBB03B" points="1352.1,560.5 1352,560.4 1024.3,749.6 1077.1,780.1 1214.7,859.5 1299,908.1 1299.2,908.2
1300.4,907.5 1350.2,878.7 1351.6,877.9 1351.6,877.9 1351.6,877.9 1352.2,878.2 1352.2,878.2 1680,1067.5 1680,1126.7
1680,1446.7 1351.5,1636.4 1299,1606.1 1023,1446.7 1023,1380.4 1023,1221.6 1023,1067.5 1023.8,1067.1 1019.7,1064.7
988.4,1046.6 749.1,908.4 749.1,908.4 749,908.6 749,1220.9 749,1379.7 749,1538.6 749,1605.6 1352,1954.1 1955,1605.6 1955,908.6
"/>
<polygon fill="#FBB03B" points="749.1,908.4 749.1,908.4 749.1,908.4 "/>
<polygon fill="#FBB03B" points="1680,1067.5 1352.2,878.2 1352.2,878.2 1352.2,878.2 "/>
<polygon fill="#FBB03B" points="1351.6,877.9 1350.2,878.7 1351.6,877.9 "/>
<polygon fill="#006837" points="749.2,908.4 749.1,908.4 988.4,1046.6 855.9,969.9 "/>
<polygon fill="#006837" points="855.9,969.9 749.3,908.3 749.2,908.4 "/>
<polygon fill="#006837" points="1024,749.4 1023.9,749.4 1023.9,749.4 1024.3,749.6 1024.3,749.6 "/>
<polygon fill="#006837" points="749.2,908.4 749.2,908.3 749.1,908.4 749.1,908.4 "/>
<polygon fill="#006837" points="749.3,908.3 749.2,908.2 749.2,908.3 749.2,908.4 "/>
<polygon fill="#006837" points="1214.6,859.5 1299,908.2 1299,908.1 1214.7,859.5 1077.1,780.1 1024.3,749.6 1024.3,749.6
1077.1,780.1 "/>
<polygon fill="#006837" points="1299.1,908.2 1299.2,908.2 1299,908.1 1299,908.2 "/>
<polygon fill="#006837" points="988.4,1046.6 1019.7,1064.7 1023.8,1067.1 1023,1067.5 1023,1221.6 1023,1380.4 1295.3,1223.7
1299,1221.6 1299,908.2 1214.6,859.5 1077.1,780.1 1024.3,749.6 749.3,908.3 855.9,969.9 "/>
<polygon fill="#006837" points="749,1220.9 420,1031.6 420,657.1 420,652.4 748.5,462.8 752.7,465.1 1066.2,646.1 1203.8,566.7
1341.4,487.2 1027.9,306.2 748.6,145 145,493.5 145,1190.5 749,1538.6 749,1379.7 "/>
</g>
</svg>
/*!
* clipboard.js v1.5.12
* https://zenorocha.github.io/clipboard.js
*
* Licensed MIT © Zeno Rocha
*/
!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,o){function i(a,c){if(!n[a]){if(!e[a]){var s="function"==typeof require&&require;if(!c&&s)return s(a,!0);if(r)return r(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var u=n[a]={exports:{}};e[a][0].call(u.exports,function(t){var n=e[a][1][t];return i(n?n:t)},u,u.exports,t,e,n,o)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;a<o.length;a++)i(o[a]);return i}({1:[function(t,e,n){var o=t("matches-selector");e.exports=function(t,e,n){for(var i=n?t:t.parentNode;i&&i!==document;){if(o(i,e))return i;i=i.parentNode}}},{"matches-selector":5}],2:[function(t,e,n){function o(t,e,n,o,r){var a=i.apply(this,arguments);return t.addEventListener(n,a,r),{destroy:function(){t.removeEventListener(n,a,r)}}}function i(t,e,n,o){return function(n){n.delegateTarget=r(n.target,e,!0),n.delegateTarget&&o.call(t,n)}}var r=t("closest");e.exports=o},{closest:1}],3:[function(t,e,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){var e=Object.prototype.toString.call(t);return"[object Function]"===e}},{}],4:[function(t,e,n){function o(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!c.string(e))throw new TypeError("Second argument must be a String");if(!c.fn(n))throw new TypeError("Third argument must be a Function");if(c.node(t))return i(t,e,n);if(c.nodeList(t))return r(t,e,n);if(c.string(t))return a(t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function i(t,e,n){return t.addEventListener(e,n),{destroy:function(){t.removeEventListener(e,n)}}}function r(t,e,n){return Array.prototype.forEach.call(t,function(t){t.addEventListener(e,n)}),{destroy:function(){Array.prototype.forEach.call(t,function(t){t.removeEventListener(e,n)})}}}function a(t,e,n){return s(document.body,t,e,n)}var c=t("./is"),s=t("delegate");e.exports=o},{"./is":3,delegate:2}],5:[function(t,e,n){function o(t,e){if(r)return r.call(t,e);for(var n=t.parentNode.querySelectorAll(e),o=0;o<n.length;++o)if(n[o]==t)return!0;return!1}var i=Element.prototype,r=i.matchesSelector||i.webkitMatchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector;e.exports=o},{}],6:[function(t,e,n){function o(t){var e;if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName)t.focus(),t.setSelectionRange(0,t.value.length),e=t.value;else{t.hasAttribute("contenteditable")&&t.focus();var n=window.getSelection(),o=document.createRange();o.selectNodeContents(t),n.removeAllRanges(),n.addRange(o),e=n.toString()}return e}e.exports=o},{}],7:[function(t,e,n){function o(){}o.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){function o(){i.off(t,o),e.apply(n,arguments)}var i=this;return o._=e,this.on(t,o,n)},emit:function(t){var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,i=n.length;for(o;i>o;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],i=[];if(o&&e)for(var r=0,a=o.length;a>r;r++)o[r].fn!==e&&o[r].fn._!==e&&i.push(o[r]);return i.length?n[t]=i:delete n[t],this}},e.exports=o},{}],8:[function(e,n,o){!function(i,r){if("function"==typeof t&&t.amd)t(["module","select"],r);else if("undefined"!=typeof o)r(n,e("select"));else{var a={exports:{}};r(a,i.select),i.clipboardAction=a.exports}}(this,function(t,e){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var i=n(e),r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},a=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),c=function(){function t(e){o(this,t),this.resolveOptions(e),this.initSelection()}return t.prototype.resolveOptions=function t(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];this.action=e.action,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""},t.prototype.initSelection=function t(){this.text?this.selectFake():this.target&&this.selectTarget()},t.prototype.selectFake=function t(){var e=this,n="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=document.body.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[n?"right":"left"]="-9999px",this.fakeElem.style.top=(window.pageYOffset||document.documentElement.scrollTop)+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,document.body.appendChild(this.fakeElem),this.selectedText=(0,i.default)(this.fakeElem),this.copyText()},t.prototype.removeFake=function t(){this.fakeHandler&&(document.body.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(document.body.removeChild(this.fakeElem),this.fakeElem=null)},t.prototype.selectTarget=function t(){this.selectedText=(0,i.default)(this.target),this.copyText()},t.prototype.copyText=function t(){var e=void 0;try{e=document.execCommand(this.action)}catch(n){e=!1}this.handleResult(e)},t.prototype.handleResult=function t(e){e?this.emitter.emit("success",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)}):this.emitter.emit("error",{action:this.action,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})},t.prototype.clearSelection=function t(){this.target&&this.target.blur(),window.getSelection().removeAllRanges()},t.prototype.destroy=function t(){this.removeFake()},a(t,[{key:"action",set:function t(){var e=arguments.length<=0||void 0===arguments[0]?"copy":arguments[0];if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function t(){return this._action}},{key:"target",set:function t(e){if(void 0!==e){if(!e||"object"!==("undefined"==typeof e?"undefined":r(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function t(){return this._target}}]),t}();t.exports=c})},{select:6}],9:[function(e,n,o){!function(i,r){if("function"==typeof t&&t.amd)t(["module","./clipboard-action","tiny-emitter","good-listener"],r);else if("undefined"!=typeof o)r(n,e("./clipboard-action"),e("tiny-emitter"),e("good-listener"));else{var a={exports:{}};r(a,i.clipboardAction,i.tinyEmitter,i.goodListener),i.clipboard=a.exports}}(this,function(t,e,n,o){"use strict";function i(t){return t&&t.__esModule?t:{"default":t}}function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function a(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function c(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function s(t,e){var n="data-clipboard-"+t;if(e.hasAttribute(n))return e.getAttribute(n)}var l=i(e),u=i(n),f=i(o),d=function(t){function e(n,o){r(this,e);var i=a(this,t.call(this));return i.resolveOptions(o),i.listenClick(n),i}return c(e,t),e.prototype.resolveOptions=function t(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText},e.prototype.listenClick=function t(e){var n=this;this.listener=(0,f.default)(e,"click",function(t){return n.onClick(t)})},e.prototype.onClick=function t(e){var n=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new l.default({action:this.action(n),target:this.target(n),text:this.text(n),trigger:n,emitter:this})},e.prototype.defaultAction=function t(e){return s("action",e)},e.prototype.defaultTarget=function t(e){var n=s("target",e);return n?document.querySelector(n):void 0},e.prototype.defaultText=function t(e){return s("text",e)},e.prototype.destroy=function t(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)},e}(u.default);t.exports=d})},{"./clipboard-action":8,"good-listener":4,"tiny-emitter":7}]},{},[9])(9)});
\ No newline at end of file
/*
* Script for copying text and displaying a tooltip.
*/
var clipboard = new Clipboard('#copy-button');
$('#copy-button').tooltip({
trigger: 'hover',
placement: 'bottom'
});
$('#copy-button').on('hidden.bs.tooltip', function () {
$('#copy-button').attr('data-original-title', 'Copy to Clipboard');
});
clipboard.on('success', function (e) {
e.clearSelection();
$('#copy-button').attr('data-original-title', 'Copied!').tooltip('show');
});
// hide by default
$("div_id_expires_custom").hide();
// if the expires_custom checkbox is checked..
if ($("#id_expires_5").is(":checked")) {
// display the field
$("#div_id_expires_custom").slideDown();
} else {
// keep it up
$("#div_id_expires_custom").slideUp();
}
// if the expires_custom checkbox is clicked..
$("#div_id_expires").click(function () {
// if the expires_custom checkbox is checked..
if ($("#id_expires_5").is(":checked")) {
// display the field
$("#div_id_expires_custom").slideDown();
} else {
// keep it hidden
$("#div_id_expires_custom").slideUp();
}
})
/* ========================================================================
* Bootstrap: tab.js v3.3.6
* http://getbootstrap.com/javascript/#tabs
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
+function ($) {
'use strict';
// TAB CLASS DEFINITION
// ====================
var Tab = function (element) {
// jscs:disable requireDollarBeforejQueryAssignment
this.element = $(element)
// jscs:enable requireDollarBeforejQueryAssignment
}
Tab.VERSION = '3.3.6'
Tab.TRANSITION_DURATION = 150
Tab.prototype.show = function () {
var $this = this.element
var $ul = $this.closest('ul:not(.dropdown-menu)')
var selector = $this.data('target')
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
}
if ($this.parent('li').hasClass('active')) return
var $previous = $ul.find('.active:last a')
var hideEvent = $.Event('hide.bs.tab', {
relatedTarget: $this[0]
})
var showEvent = $.Event('show.bs.tab', {
relatedTarget: $previous[0]
})
$previous.trigger(hideEvent)
$this.trigger(showEvent)
if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
var $target = $(selector)
this.activate($this.closest('li'), $ul)
this.activate($target, $target.parent(), function () {
$previous.trigger({
type: 'hidden.bs.tab',
relatedTarget: $this[0]
})
$this.trigger({
type: 'shown.bs.tab',
relatedTarget: $previous[0]
})
})
}
Tab.prototype.activate = function (element, container, callback) {
var $active = container.find('> .active')
var transition = callback
&& $.support.transition
&& ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
function next() {
$active
.removeClass('active')
.find('> .dropdown-menu > .active')
.removeClass('active')
.end()
.find('[data-toggle="tab"]')
.attr('aria-expanded', false)
element
.addClass('active')
.find('[data-toggle="tab"]')
.attr('aria-expanded', true)
if (transition) {
element[0].offsetWidth // reflow for transition
element.addClass('in')
} else {
element.removeClass('fade')
}
if (element.parent('.dropdown-menu').length) {
element
.closest('li.dropdown')
.addClass('active')
.end()
.find('[data-toggle="tab"]')
.attr('aria-expanded', true)
}
callback && callback()
}
$active.length && transition ?
$active
.one('bsTransitionEnd', next)
.emulateTransitionEnd(Tab.TRANSITION_DURATION) :
next()
$active.removeClass('in')
}
// TAB PLUGIN DEFINITION
// =====================
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.tab')
if (!data) $this.data('bs.tab', (data = new Tab(this)))
if (typeof option == 'string') data[option]()
})
}
var old = $.fn.tab
$.fn.tab = Plugin
$.fn.tab.Constructor = Tab
// TAB NO CONFLICT
// ===============
$.fn.tab.noConflict = function () {
$.fn.tab = old
return this
}
// TAB DATA-API
// ============
var clickHandler = function (e) {
e.preventDefault()
Plugin.call($(this), 'show')
}
$(document)
.on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
.on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
}(jQuery);
/* ========================================================================
* Bootstrap: tooltip.js v3.3.7
* http://getbootstrap.com/javascript/#tooltip
* Inspired by the original jQuery.tipsy by Jason Frame
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
+function ($) {
'use strict';
// TOOLTIP PUBLIC CLASS DEFINITION
// ===============================
var Tooltip = function (element, options) {
this.type = null
this.options = null
this.enabled = null
this.timeout = null
this.hoverState = null
this.$element = null
this.inState = null
this.init('tooltip', element, options)
}
Tooltip.VERSION = '3.3.7'
Tooltip.TRANSITION_DURATION = 150
Tooltip.DEFAULTS = {
animation: true,
placement: 'top',
selector: false,
template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
trigger: 'hover focus',
title: '',
delay: 0,
html: false,
container: false,
viewport: {
selector: 'body',
padding: 0
}
}
Tooltip.prototype.init = function (type, element, options) {
this.enabled = true
this.type = type
this.$element = $(element)
this.options = this.getOptions(options)
this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
this.inState = { click: false, hover: false, focus: false }
if (this.$element[0] instanceof document.constructor && !this.options.selector) {
throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
}
var triggers = this.options.trigger.split(' ')
for (var i = triggers.length; i--;) {
var trigger = triggers[i]
if (trigger == 'click') {
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
} else if (trigger != 'manual') {
var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
}
}
this.options.selector ?
(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
this.fixTitle()
}
Tooltip.prototype.getDefaults = function () {
return Tooltip.DEFAULTS
}
Tooltip.prototype.getOptions = function (options) {
options = $.extend({}, this.getDefaults(), this.$element.data(), options)
if (options.delay && typeof options.delay == 'number') {
options.delay = {
show: options.delay,
hide: options.delay
}
}
return options
}
Tooltip.prototype.getDelegateOptions = function () {
var options = {}
var defaults = this.getDefaults()
this._options && $.each(this._options, function (key, value) {
if (defaults[key] != value) options[key] = value
})
return options
}
Tooltip.prototype.enter = function (obj) {
var self = obj instanceof this.constructor ?
obj : $(obj.currentTarget).data('bs.' + this.type)
if (!self) {
self = new this.constructor(obj.currentTarget, this.getDelegateOptions())