Repository: tomdyson/wagalytics
Branch: master
Commit: e38d6e748051
Files: 19
Total size: 152.3 KB
Directory structure:
gitextract_vh81vh8u/
├── .gitignore
├── LICENSE
├── MANIFEST.in
├── README.md
├── client/
│ ├── src/
│ │ └── wagalytics.js
│ └── webpack.config.js
├── package.json
├── pytest.ini
├── setup.cfg
├── setup.py
└── wagalytics/
├── __init__.py
├── static/
│ └── wagalytics/
│ ├── .gitkeep
│ ├── vendors.bundle.js
│ └── wagalytics.bundle.js
├── templates/
│ └── wagalytics/
│ └── dashboard.html
├── tests/
│ └── tests.py
├── urls.py
├── views.py
└── wagtail_hooks.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
dist/
build/
*.pyc
.DS_Store
*.egg-info
npm-debug.log
node_modules
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2017 Tom Dyson
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.
================================================
FILE: MANIFEST.in
================================================
graft wagalytics
global-exclude __pycache__
global-exclude *.py[co]
================================================
FILE: README.md
================================================
# Wagtail Analytics
(Last Updated 12/17/19 for Wagtail v2.x)
This module provides a simple dashboard of Google Analytics data, integrated into the Wagtail admin UI. Tested on Wagtail 2.0+.


## Instructions
1. [Create a service account](https://ga-dev-tools.appspot.com/embed-api/server-side-authorization) and download the JSON key (Credentials > Create Credentials > API key)
1. Make sure the [Analytics API is enabled for your project](https://console.developers.google.com/apis/api/analytics.googleapis.com) (See [issue 2](https://github.com/tomdyson/wagalytics/issues/2))
1. Add the [service account email address](https://console.developers.google.com/permissions/serviceaccounts) as a read-only user in Google Analytics (Admin > User Management)
1. Find the ID for your Google Analytics property (Admin > Property > View Settings, note: this is NOT the key that begins with "UA-")
1. Store your JSON key somewhere safe, and do not check it into your repo
1. `pip install wagalytics`
1. Add 'wagalytics' to your INSTALLED_APPS
1. Add 'wagtailfontawesome' to INSTALLED_APPS if it's not there already
1. Update your settings:
- `GA_KEY_FILEPATH = '/path/to/secure/directory/your-key.json'`
or when using environment variables (e.g. Heroku):
- `GA_KEY_CONTENT = 'content_of_your_key.json'`
- `GA_VIEW_ID = 'ga:xxxxxxxx'`
If you get CryptoUnavailableError errors, you probably need to `pip install PyOpenSSL` and/or `pip install pycrypto`. See [StackOverflow](http://stackoverflow.com/questions/27305867/google-api-access-using-service-account-oauth2client-client-cryptounavailableerr).
Ensure that your code snippet is included on each page you want to be tracked (likely by putting it in your base.html template.) (Admin > Property > Tracking Code)
## Multisite Support
To enable multisite support you'll need to update your Wagalytics settings _and_ have `wagtail.contrib.settings` installed. Sites can use a `GA_KEY_FILEPATH` or a `GA_KEY_CONTENT` key, but it's best not to use both.
In the snippet below, you'll see `site_id`. This is the ID (Primary Key) of your Wagtail Site.
```python
# Use either the GA_KEY_FILEPATH or the GA_KEY_CONTENT setting on your sites,
# but don't use both
WAGALYTICS_SETTINGS = {
site_id: {
'GA_VIEW_ID': 'ga:xxxxxxxx',
'GA_KEY_FILEPATH': '/path/to/secure/directory/your-key.json',
},
site_id: {
'GA_VIEW_ID': 'ga:xxxxxxxx',
'GA_KEY_CONTENT': 'content_of_your_key.json',
}
}
```
For every Wagalytics site you add in your multisite `WAGALYTICS_SETTINGS` you'll need to make sure you have the proper GA View ID and API Key. One View ID and API Key won't work for all your sites automatically.
Here's a working example of multisite WAGALYTICS_SETTINGS:
```python
WAGALYTICS_SETTINGS = {
# My default site. 2 is the site ID. This one uses GA_KEY_FILEPATH.
2: {
'GA_VIEW_ID': 'ga:xxxxxxxx',
'GA_KEY_FILEPATH': '/path/to/secure/directory/your-key.json',
},
# The secondary site. 3 is the Site ID. This one uses GA_KEY_CONTENT.
3: {
'GA_KEY_CONTENT': 'content_of_your_key.json',
'GA_VIEW_ID': 'ga:xxxxxxxx',
}
}
```
## Wagalytics Developers
Developers will need to carry out the following steps after cloning wagalytics:
- Ensure NodeJS & NPM are installed
- Run `npm install` then `npm run build` in the top level wagalytics directory
You will need to run `npm run build` anytime the javascript source is updated.
### TODO
- [ ] allow configuration of results
- [x] better styling, e.g. using [chart.js](https://ga-dev-tools.appspot.com/embed-api/third-party-visualizations/)
- [ ] Throw an error if the relevant settings aren't available
- [x] add [per-page results](https://github.com/tomdyson/wagalytics/issues/12)
### Notes
This module doesn't help with recording user activity. See [the Wagtail docs](http://docs.wagtail.io/en/latest/topics/writing_templates.html?highlight=analytics#varying-output-between-preview-and-live) and [StackOverflow](http://stackoverflow.com/a/1272312/181793) for pointers on how to avoid gathering data during preview and testing.
### Contributors
- Thijs Kramer
- Stefan Schärmeli
- Alex Gleason
- James Ramm
- Jake Kent
- Kalob Taulien
- Julius Parishy
================================================
FILE: client/src/wagalytics.js
================================================
import moment from 'moment';
$(document).ready(() => {
const el = document.getElementById('wagalytics-data');
setup(el.dataset.token, el.dataset.viewId);
});
/**
* Initialises google analytics and creates the dashboard charts
* @param {*} token_url
* @param {*} view_id
*/
function setup(token_url, view_id) {
if (!window.google || !window.google.load) {
var tag = document.createElement('script');
tag.type = 'text/javascript';
tag.src = 'https://www.google.com/jsapi';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(tag, s);
}
gapi.analytics.ready(function () {
$.get(token_url, function (data) {
gapi.analytics.auth.authorize({
'serverAuth': {
'access_token': data
}
});
});
// Create the dashboard controller
const dashboard = new Dashboard(view_id);
dashboard.refresh();
});
}
/**
* Wagtails' colour palette
*/
const colors = {
BLUE: '#71b2d4',
GREEN: '#189370',
ORANGE: '#e9b04d',
RED: '#cd3238',
SALMON: '#f37e77',
SALMON_LIGHT: '#fcf2f2',
TEAL: '#43b1b0',
TEAL_DARKER: '#358c8b',
TEAL_DARK: '#246060'
};
/**
* Sets up the various charts and controls their UI functionality
*/
class Dashboard {
constructor(view_id) {
this.view_id = view_id;
this.start_date_input = document.getElementById("id_date_from");
this.end_date_input = document.getElementById("id_date_to");
this.export_btn = document.getElementById("export-button");
this.start_date_input.addEventListener('change', () => this.refresh());
this.end_date_input.addEventListener('change', () => this.refresh());
$(document.getElementById("export")).submit(() => {
$(document.getElementById('export-data')).val(JSON.stringify(this.data));
});
this.data = {};
this.tooltips = {
enabled: true,
mode: 'label',
callbacks: {
title: function (tooltipItems, data) {
var idx = tooltipItems[0].index;
return 'Title:' + data.labels[idx];//do something with title
},
label: function (tooltipItems, data) {
return tooltipItems.xLabel;
}
}
}
}
setLoading(id) {
document.getElementById(id).innerHTML = ' ';
}
/**
* Setup the charts within the specified date range (last 7 or last 30 days)
* @param {int} range - use the `ranges` enum to select. (Can be 1 or 2)
*/
refresh() {
this.sessionsLineChart();
this.popularPagesTable();
this.topReferrersTable();
}
/**
* Query the google API for data within
* the set range.
* @param {Object} options Options specifying metrics, dimensions and any
* other keys accepted by gapi.
*/
getQuery(options) {
$(this.export_btn).prop('disabled', true);
return query(Object.assign({
ids: this.view_id,
'start-date': $(this.start_date_input).val(),
'end-date': $(this.end_date_input).val()
}, options));
}
/**
* Create a line chart showing number of sessions per day
*/
sessionsLineChart() {
const id = 'sessions-line-chart-container';
this.setLoading(id);
this.getQuery(
{
dimensions: 'ga:date,ga:nthDay',
metrics: 'ga:sessions'
}).then(results => {
this.data['sessions'] = results.rows;
$(this.export_btn).prop('disabled', false);
$(this.export_btn).removeClass('button-longrunning-active');
var data1 = results.rows.map(row => row[2]);
var labels = results.rows.map(row => row[0]);
labels = labels.map(function (label) {
return moment(label, 'YYYYMMDD').format('ll');
});
var data = {
labels: labels,
datasets: [
{
label: 'Sessions',
backgroundColor: colors.SALMON_LIGHT,
borderColor: colors.SALMON,
pointBackgroundColor: colors.SALMON,
pointBorderColor: '#fff',
data: data1
}
]
};
new Chart(makeCanvas(id), {
type: 'line',
data: data,
options: {
legend: {
display: false
},
scales: {
xAxes: [{
ticks: {
autoSkip: true,
maxTicksLimit: 4,
maxRotation: 0
}
}]
}
}
});
//generateLegend('legend-1-container', data.datasets);
});
}
/**
* Create table showing 25 most popular pages
*/
popularPagesTable() {
const id = 'popular-pages-table-container';
this.setLoading(id);
const queryData = {
'metrics': 'ga:pageviews',
'dimensions': 'ga:hostname,ga:pagePath',
'sort': '-ga:pageviews',
'max-results': 25
};
this.getQuery(queryData).then(results => {
// The results contain duplicates for variations in hostname
// e.g. if someone visit http://mywebsite.com vs http://www.mywebsite.com
// Here we aggregate these results into single values per page, regardless
// of hostname
var i = 0;
const rows = results.rows;
const l = rows.length;
const bars = {};
for (i; i < l; ++i) {
const key = rows[i][1]
if (bars.hasOwnProperty(key)) {
bars[key][1] += parseInt(rows[i][2], 10);
}
else {
bars[key] = [key, parseInt(rows[i][2], 10)];
}
}
this.data['pages'] = Object.values(bars);
$(this.export_btn).prop('disabled', false);
$(this.export_btn).removeClass('button-longrunning-active');
const table = createTable(['Page URL', 'Views'], Object.values(bars));
const pager = paginateTable(table);
const container = document.getElementById(id);
container.innerHTML = '';
container.appendChild(table);
$(container).append(pager);
});
}
/**
* Create table showing 25 top referrers
*/
topReferrersTable() {
const id = 'top-referrers-table-container';
this.setLoading(id);
const queryData = {
'metrics': 'ga:pageviews',
'dimensions': 'ga:fullReferrer',
'sort': '-ga:pageviews',
'max-results': 25
};
this.getQuery(queryData).then(results => {
this.data['referrers'] = results.rows;
$(this.export_btn).prop('disabled', false);
$(this.export_btn).removeClass('button-longrunning-active');
const table = createTable(['Source', 'Views'], results.rows);
const pager = paginateTable(table);
const container = document.getElementById(id);
container.innerHTML = '';
container.appendChild(table);
$(container).append(pager);
});
}
}
/**
* Create a table
* @param {*} headings
* @param {*} rows
*/
function createTable(headings, rows){
const table = document.createElement('table');
table.className = 'listing';
const head = table.createTHead();
const headerRow = head.insertRow(0);
let i = 0;
for (i; i < headings.length; ++i) {
const heading = headerRow.insertCell(i);
heading.innerHTML = headings[i];
heading.className = 'title';
}
const body = table.createTBody();
for (i = 0; i < rows.length; ++i) {
const rowData = rows[i];
const row = body.insertRow(i);
for (let j = 0; j < rowData.length; ++j) {
row.insertCell(j).innerHTML = rowData[j];
}
}
return table;
}
/**
* Client side pagination of a table.
* Table rows are hidden/shown according to the page number
* @param {*} table
*/
function paginateTable(table) {
let currentPage = 0;
const numPerPage = 5;
const $table = $(table);
// This is the function which controls display of content
$table.bind('repaginate', function() {
$table.find('tbody tr').hide().slice(currentPage * numPerPage, (currentPage + 1) * numPerPage).show();
let $pager = $table.next();
if (currentPage <= 0) {
$pager.find('.prev').addClass('disabled');
} else {
$pager.find('.prev').removeClass('disabled');
}
if (currentPage >= numPages - 1) {
$pager.find('.next').addClass('disabled');
} else {
$pager.find('.next').removeClass('disabled');
}
});
$table.trigger('repaginate');
const numRows = $table.find('tbody tr').length;
const numPages = Math.ceil(numRows / numPerPage);
// Create the page selector element and add callbacks to handle setting the page
const $pager = $(`
`);
// Previous page click handler
$pager.find('.prev a').bind('click', event => {
event.preventDefault();
currentPage -= 1;
if (currentPage < 0) {
currentPage = 0;
}
$pager.find('.page-num').text(`${currentPage + 1}`);
$table.trigger('repaginate');
});
// Next page click handler
$pager.find('.next a').bind('click', event => {
event.preventDefault();
currentPage += 1;
if (currentPage >= numPages) {
currentPage = numPages - 1;
}
$pager.find('.page-num').text(`${currentPage + 1}`);
$table.trigger('repaginate');
});
return $pager;
}
/**
* Extend the Embed APIs `gapi.analytics.report.Data` component to
* return a promise the is fulfilled with the value returned by the API.
* @param {Object} params The request parameters.
* @return {Promise} A promise.
*/
function query(params) {
return new Promise(function (resolve, reject) {
var data = new gapi.analytics.report.Data({ query: params });
data.once('success', function (response) { resolve(response); })
.once('error', function (response) { reject(response); })
.execute();
});
}
/**
* Create a new canvas inside the specified element. Set it to be the width
* and height of its container.
* @param {string} id The id attribute of the element to host the canvas.
* @return {RenderingContext} The 2D canvas context.
*/
function makeCanvas(id) {
var container = document.getElementById(id);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
container.innerHTML = '';
canvas.width = container.offsetWidth;
canvas.height = container.offsetHeight;
container.appendChild(canvas);
return ctx;
}
/**
* Create a visual legend inside the specified element based off of a
* Chart.js dataset.
* @param {string} id The id attribute of the element to host the legend.
* @param {Array.} items A list of labels and colors for the legend.
*/
function generateLegend(id, items) {
var legend = document.getElementById(id);
legend.innerHTML = items.map(function (item) {
var color = item.color || item.fillColor;
var label = item.label;
return ' ' +
escapeHtml(label) + ' ';
}).join('');
}
/**
* Escapes a potentially unsafe HTML string.
* @param {string} str An string that may contain HTML entities.
* @return {string} The HTML-escaped string.
*/
function escapeHtml(str) {
var div = document.createElement('div');
div.appendChild(document.createTextNode(str));
return div.innerHTML;
}
// Set some global Chart.js defaults.
Chart.defaults.global.animationSteps = 60;
Chart.defaults.global.animationEasing = 'easeInOutQuart';
Chart.defaults.global.responsive = true;
Chart.defaults.global.maintainAspectRatio = false;
================================================
FILE: client/webpack.config.js
================================================
var path = require('path');
var webpack = require('webpack');
module.exports = {
context: __dirname,
entry: {
wagalytics: './src/wagalytics.js',
vendors: [
'moment',
]
},
output: {
path: path.resolve('./wagalytics/static/wagalytics/'),
filename: "[name].bundle.js"
},
module: {
rules: [{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: {
presets: [],
},
},
]
}]
},
mode: 'production',
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production')
}
}),
new webpack.SourceMapDevToolPlugin({
filename: '[name].js.map',
append: '\n//# sourceMappingURL=http://127.0.0.1:3001/dist/js/[url]'
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]
}
================================================
FILE: package.json
================================================
{
"name": "wagalytics",
"version": "1.0.0",
"description": "",
"repository": {
"type": "git",
"url": "https://github.com/tomdyson/wagalytics.git"
},
"author": "Tom Dyson",
"license": "MIT",
"scripts": {
"build": "npx webpack --config ./client/webpack.config.js",
"watch": "npx webpack --config ./client/webpack.config.js --watch",
"dist": "npm install && npx webpack --config ./client/webpack.config.js"
},
"babel": {
"presets": [
"@babel/preset-env"
]
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-do-expressions": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-bind": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.0.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/polyfill": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"babel-loader": "^8.0.0",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
},
"dependencies": {
"moment": "^2.17.1"
}
}
================================================
FILE: pytest.ini
================================================
[pytest]
DJANGO_SETTINGS_MODULE = wagalytics.tests.settings
python_files = tests.py test_*.py *_tests.py
================================================
FILE: setup.cfg
================================================
[metadata]
description-file = README.md
[bdist_wheel]
universal=1
================================================
FILE: setup.py
================================================
from os import path
from setuptools import setup, find_packages
try:
from wagtail.utils.setup import sdist
cmdclass = {
'sdist': sdist
}
except ModuleNotFoundError:
cmdclass = {}
from wagalytics import __version__
testing_extras = [
'pytest==5.3.1',
'pytest-django==3.7.0',
'wagtail-factories==2.0.0',
'factory-boy==2.11.0',
]
setup(
name='wagalytics',
version=__version__,
description='Show Google Analytics data in Wagtail.',
long_description='See https://github.com/tomdyson/wagalytics for details',
url='https://github.com/tomdyson/wagalytics',
author='Tom Dyson',
author_email='tom+wagalytics@torchbox.com',
license='MIT',
classifiers=[
"Environment :: Web Environment",
"Framework :: Django",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Programming Language :: Python",
'Topic :: Internet :: WWW/HTTP',
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
],
keywords='development',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
install_requires=[
"wagtail>=2.0",
"Django>=2.0.13",
"oauth2client",
"wagtailfontawesome>=1.1.2",
"pyexcel-ods==0.5.3"
],
cmdclass=cmdclass,
extras_require={
'testing': testing_extras,
},
)
================================================
FILE: wagalytics/__init__.py
================================================
__version__ = '1.3'
================================================
FILE: wagalytics/static/wagalytics/.gitkeep
================================================
================================================
FILE: wagalytics/static/wagalytics/vendors.bundle.js
================================================
!function(e){var t={};function n(s){if(t[s])return t[s].exports;var i=t[s]={i:s,l:!1,exports:{}};return e[s].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,s){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(n.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(s,i,function(t){return e[t]}.bind(null,i));return s},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=3)}([function(e,t,n){(function(e){e.exports=function(){"use strict";var t,n;function s(){return t.apply(null,arguments)}function i(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function r(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function a(e){return void 0===e}function o(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function u(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function l(e,t){var n,s=[];for(n=0;n>>0,s=0;s0)for(n=0;n=0?n?"+":"":"-")+Math.pow(10,Math.max(0,i)).toString().substr(1)+s}var G=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,V=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,E={},j={};function I(e,t,n,s){var i=s;"string"==typeof s&&(i=function(){return this[s]()}),e&&(j[e]=i),t&&(j[t[0]]=function(){return N(i.apply(this,arguments),t[1],t[2])}),n&&(j[n]=function(){return this.localeData().ordinal(i.apply(this,arguments),e)})}function A(e,t){return e.isValid()?(t=Z(t,e.localeData()),E[t]=E[t]||function(e){var t,n,s,i=e.match(G);for(t=0,n=i.length;t=0&&V.test(e);)e=e.replace(V,s),V.lastIndex=0,n-=1;return e}var z=/\d/,$=/\d\d/,J=/\d{3}/,q=/\d{4}/,B=/[+-]?\d{6}/,Q=/\d\d?/,X=/\d\d\d\d?/,K=/\d\d\d\d\d\d?/,ee=/\d{1,3}/,te=/\d{1,4}/,ne=/[+-]?\d{1,6}/,se=/\d+/,ie=/[+-]?\d+/,re=/Z|[+-]\d\d:?\d\d/gi,ae=/Z|[+-]\d\d(?::?\d\d)?/gi,oe=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,ue={};function le(e,t,n){ue[e]=x(t)?t:function(e,s){return e&&n?n:t}}function de(e,t){return d(ue,e)?ue[e](t._strict,t._locale):new RegExp(he(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,(function(e,t,n,s,i){return t||n||s||i}))))}function he(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var ce={};function fe(e,t){var n,s=t;for("string"==typeof e&&(e=[e]),o(t)&&(s=function(e,n){n[t]=S(e)}),n=0;n68?1900:2e3)};var pe,ve=we("FullYear",!0);function we(e,t){return function(n){return null!=n?(Se(this,e,n),s.updateOffset(this,t),this):Me(this,e)}}function Me(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function Se(e,t,n){e.isValid()&&!isNaN(n)&&("FullYear"===t&&ge(e.year())&&1===e.month()&&29===e.date()?e._d["set"+(e._isUTC?"UTC":"")+t](n,e.month(),De(n,e.month())):e._d["set"+(e._isUTC?"UTC":"")+t](n))}function De(e,t){if(isNaN(e)||isNaN(t))return NaN;var n,s=(t%(n=12)+n)%n;return e+=(t-s)/12,1===s?ge(e)?29:28:31-s%7%2}pe=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var t;for(t=0;t=0&&isFinite(o.getFullYear())&&o.setFullYear(e),o}function Re(e){var t=new Date(Date.UTC.apply(null,arguments));return e<100&&e>=0&&isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e),t}function Fe(e,t,n){var s=7+t-n;return-(7+Re(e,0,s).getUTCDay()-t)%7+s-1}function Le(e,t,n,s,i){var r,a,o=1+7*(t-1)+(7+n-s)%7+Fe(e,s,i);return o<=0?a=ye(r=e-1)+o:o>ye(e)?(r=e+1,a=o-ye(e)):(r=e,a=o),{year:r,dayOfYear:a}}function Ue(e,t,n){var s,i,r=Fe(e.year(),t,n),a=Math.floor((e.dayOfYear()-r-1)/7)+1;return a<1?s=a+Ne(i=e.year()-1,t,n):a>Ne(e.year(),t,n)?(s=a-Ne(e.year(),t,n),i=e.year()+1):(i=e.year(),s=a),{week:s,year:i}}function Ne(e,t,n){var s=Fe(e,t,n),i=Fe(e+1,t,n);return(ye(e)-s+i)/7}I("w",["ww",2],"wo","week"),I("W",["WW",2],"Wo","isoWeek"),H("week","w"),H("isoWeek","W"),U("week",5),U("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),me(["w","ww","W","WW"],(function(e,t,n,s){t[s.substr(0,1)]=S(e)})),I("d",0,"do","day"),I("dd",0,0,(function(e){return this.localeData().weekdaysMin(this,e)})),I("ddd",0,0,(function(e){return this.localeData().weekdaysShort(this,e)})),I("dddd",0,0,(function(e){return this.localeData().weekdays(this,e)})),I("e",0,0,"weekday"),I("E",0,0,"isoWeekday"),H("day","d"),H("weekday","e"),H("isoWeekday","E"),U("day",11),U("weekday",11),U("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",(function(e,t){return t.weekdaysMinRegex(e)})),le("ddd",(function(e,t){return t.weekdaysShortRegex(e)})),le("dddd",(function(e,t){return t.weekdaysRegex(e)})),me(["dd","ddd","dddd"],(function(e,t,n,s){var i=n._locale.weekdaysParse(e,s,n._strict);null!=i?t.d=i:f(n).invalidWeekday=e})),me(["d","e","E"],(function(e,t,n,s){t[s]=S(e)}));var Ge="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Ve="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Ee="Su_Mo_Tu_We_Th_Fr_Sa".split("_");function je(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],s=0;s<7;++s)r=c([2e3,1]).day(s),this._minWeekdaysParse[s]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[s]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[s]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===t?-1!==(i=pe.call(this._weekdaysParse,a))?i:null:"ddd"===t?-1!==(i=pe.call(this._shortWeekdaysParse,a))?i:null:-1!==(i=pe.call(this._minWeekdaysParse,a))?i:null:"dddd"===t?-1!==(i=pe.call(this._weekdaysParse,a))||-1!==(i=pe.call(this._shortWeekdaysParse,a))||-1!==(i=pe.call(this._minWeekdaysParse,a))?i:null:"ddd"===t?-1!==(i=pe.call(this._shortWeekdaysParse,a))||-1!==(i=pe.call(this._weekdaysParse,a))||-1!==(i=pe.call(this._minWeekdaysParse,a))?i:null:-1!==(i=pe.call(this._minWeekdaysParse,a))||-1!==(i=pe.call(this._weekdaysParse,a))||-1!==(i=pe.call(this._shortWeekdaysParse,a))?i:null}var Ie=oe,Ae=oe,Ze=oe;function ze(){function e(e,t){return t.length-e.length}var t,n,s,i,r,a=[],o=[],u=[],l=[];for(t=0;t<7;t++)n=c([2e3,1]).day(t),s=this.weekdaysMin(n,""),i=this.weekdaysShort(n,""),r=this.weekdays(n,""),a.push(s),o.push(i),u.push(r),l.push(s),l.push(i),l.push(r);for(a.sort(e),o.sort(e),u.sort(e),l.sort(e),t=0;t<7;t++)o[t]=he(o[t]),u[t]=he(u[t]),l[t]=he(l[t]);this._weekdaysRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+a.join("|")+")","i")}function $e(){return this.hours()%12||12}function Je(e,t){I(e,0,0,(function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)}))}function qe(e,t){return t._meridiemParse}I("H",["HH",2],0,"hour"),I("h",["hh",2],0,$e),I("k",["kk",2],0,(function(){return this.hours()||24})),I("hmm",0,0,(function(){return""+$e.apply(this)+N(this.minutes(),2)})),I("hmmss",0,0,(function(){return""+$e.apply(this)+N(this.minutes(),2)+N(this.seconds(),2)})),I("Hmm",0,0,(function(){return""+this.hours()+N(this.minutes(),2)})),I("Hmmss",0,0,(function(){return""+this.hours()+N(this.minutes(),2)+N(this.seconds(),2)})),Je("a",!0),Je("A",!1),H("hour","h"),U("hour",13),le("a",qe),le("A",qe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",X),le("hmmss",K),le("Hmm",X),le("Hmmss",K),fe(["H","HH"],3),fe(["k","kk"],(function(e,t,n){var s=S(e);t[3]=24===s?0:s})),fe(["a","A"],(function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e})),fe(["h","hh"],(function(e,t,n){t[3]=S(e),f(n).bigHour=!0})),fe("hmm",(function(e,t,n){var s=e.length-2;t[3]=S(e.substr(0,s)),t[4]=S(e.substr(s)),f(n).bigHour=!0})),fe("hmmss",(function(e,t,n){var s=e.length-4,i=e.length-2;t[3]=S(e.substr(0,s)),t[4]=S(e.substr(s,2)),t[5]=S(e.substr(i)),f(n).bigHour=!0})),fe("Hmm",(function(e,t,n){var s=e.length-2;t[3]=S(e.substr(0,s)),t[4]=S(e.substr(s))})),fe("Hmmss",(function(e,t,n){var s=e.length-4,i=e.length-2;t[3]=S(e.substr(0,s)),t[4]=S(e.substr(s,2)),t[5]=S(e.substr(i))}));var Be,Qe=we("Hours",!0),Xe={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Ye,monthsShort:Oe,week:{dow:0,doy:6},weekdays:Ge,weekdaysMin:Ee,weekdaysShort:Ve,meridiemParse:/[ap]\.?m?\.?/i},Ke={},et={};function tt(e){return e?e.toLowerCase().replace("_","-"):e}function nt(t){var n=null;if(!Ke[t]&&void 0!==e&&e&&e.exports)try{n=Be._abbr,!function(){var e=new Error("Cannot find module 'undefined'");throw e.code="MODULE_NOT_FOUND",e}(),st(n)}catch(e){}return Ke[t]}function st(e,t){var n;return e&&((n=a(t)?rt(e):it(e,t))?Be=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),Be._abbr}function it(e,t){if(null!==t){var n,s=Xe;if(t.abbr=e,null!=Ke[e])b("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=Ke[e]._config;else if(null!=t.parentLocale)if(null!=Ke[t.parentLocale])s=Ke[t.parentLocale]._config;else{if(null==(n=nt(t.parentLocale)))return et[t.parentLocale]||(et[t.parentLocale]=[]),et[t.parentLocale].push({name:e,config:t}),null;s=n._config}return Ke[e]=new W(P(s,t)),et[e]&&et[e].forEach((function(e){it(e.name,e.config)})),st(e),Ke[e]}return delete Ke[e],null}function rt(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return Be;if(!i(e)){if(t=nt(e))return t;e=[e]}return function(e){for(var t,n,s,i,r=0;r0;){if(s=nt(i.slice(0,t).join("-")))return s;if(n&&n.length>=t&&D(i,n,!0)>=t-1)break;t--}r++}return Be}(e)}function at(e){var t,n=e._a;return n&&-2===f(e).overflow&&(t=n[1]<0||n[1]>11?1:n[2]<1||n[2]>De(n[0],n[1])?2:n[3]<0||n[3]>24||24===n[3]&&(0!==n[4]||0!==n[5]||0!==n[6])?3:n[4]<0||n[4]>59?4:n[5]<0||n[5]>59?5:n[6]<0||n[6]>999?6:-1,f(e)._overflowDayOfYear&&(t<0||t>2)&&(t=2),f(e)._overflowWeeks&&-1===t&&(t=7),f(e)._overflowWeekday&&-1===t&&(t=8),f(e).overflow=t),e}function ot(e,t,n){return null!=e?e:null!=t?t:n}function ut(e){var t,n,i,r,a,o=[];if(!e._d){for(i=function(e){var t=new Date(s.now());return e._useUTC?[t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate()]:[t.getFullYear(),t.getMonth(),t.getDate()]}(e),e._w&&null==e._a[2]&&null==e._a[1]&&function(e){var t,n,s,i,r,a,o,u;if(null!=(t=e._w).GG||null!=t.W||null!=t.E)r=1,a=4,n=ot(t.GG,e._a[0],Ue(Dt(),1,4).year),s=ot(t.W,1),((i=ot(t.E,1))<1||i>7)&&(u=!0);else{r=e._locale._week.dow,a=e._locale._week.doy;var l=Ue(Dt(),r,a);n=ot(t.gg,e._a[0],l.year),s=ot(t.w,l.week),null!=t.d?((i=t.d)<0||i>6)&&(u=!0):null!=t.e?(i=t.e+r,(t.e<0||t.e>6)&&(u=!0)):i=r}s<1||s>Ne(n,r,a)?f(e)._overflowWeeks=!0:null!=u?f(e)._overflowWeekday=!0:(o=Le(n,s,i,r,a),e._a[0]=o.year,e._dayOfYear=o.dayOfYear)}(e),null!=e._dayOfYear&&(a=ot(e._a[0],i[0]),(e._dayOfYear>ye(a)||0===e._dayOfYear)&&(f(e)._overflowDayOfYear=!0),n=Re(a,0,e._dayOfYear),e._a[1]=n.getUTCMonth(),e._a[2]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[3]&&0===e._a[4]&&0===e._a[5]&&0===e._a[6]&&(e._nextDay=!0,e._a[3]=0),e._d=(e._useUTC?Re:He).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[3]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(f(e).weekdayMismatch=!0)}}var lt=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,dt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ht=/Z|[+-]\d\d(?::?\d\d)?/,ct=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],ft=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],mt=/^\/?Date\((\-?\d+)/i;function _t(e){var t,n,s,i,r,a,o=e._i,u=lt.exec(o)||dt.exec(o);if(u){for(f(e).iso=!0,t=0,n=ct.length;t0&&f(e).unusedInput.push(a),o=o.slice(o.indexOf(n)+n.length),l+=n.length),j[r]?(n?f(e).empty=!1:f(e).unusedTokens.push(r),_e(r,n,e)):e._strict&&!n&&f(e).unusedTokens.push(r);f(e).charsLeftOver=u-l,o.length>0&&f(e).unusedInput.push(o),e._a[3]<=12&&!0===f(e).bigHour&&e._a[3]>0&&(f(e).bigHour=void 0),f(e).parsedDateParts=e._a.slice(0),f(e).meridiem=e._meridiem,e._a[3]=function(e,t,n){var s;return null==n?t:null!=e.meridiemHour?e.meridiemHour(t,n):null!=e.isPM?((s=e.isPM(n))&&t<12&&(t+=12),s||12!==t||(t=0),t):t}(e._locale,e._a[3],e._meridiem),ut(e),at(e)}else vt(e);else _t(e)}function Mt(e){var t=e._i,n=e._f;return e._locale=e._locale||rt(e._l),null===t||void 0===n&&""===t?_({nullInput:!0}):("string"==typeof t&&(e._i=t=e._locale.preparse(t)),w(t)?new v(at(t)):(u(t)?e._d=t:i(n)?function(e){var t,n,s,i,r;if(0===e._f.length)return f(e).invalidFormat=!0,void(e._d=new Date(NaN));for(i=0;ithis?this:e:_()}));function Ot(e,t){var n,s;if(1===t.length&&i(t[0])&&(t=t[0]),!t.length)return Dt();for(n=t[0],s=1;s(r=Ne(e,s,i))&&(t=r),Xt.call(this,e,t,n,s,i))}function Xt(e,t,n,s,i){var r=Le(e,t,n,s,i),a=Re(r.year,0,r.dayOfYear);return this.year(a.getUTCFullYear()),this.month(a.getUTCMonth()),this.date(a.getUTCDate()),this}I(0,["gg",2],0,(function(){return this.weekYear()%100})),I(0,["GG",2],0,(function(){return this.isoWeekYear()%100})),Bt("gggg","weekYear"),Bt("ggggg","weekYear"),Bt("GGGG","isoWeekYear"),Bt("GGGGG","isoWeekYear"),H("weekYear","gg"),H("isoWeekYear","GG"),U("weekYear",1),U("isoWeekYear",1),le("G",ie),le("g",ie),le("GG",Q,$),le("gg",Q,$),le("GGGG",te,q),le("gggg",te,q),le("GGGGG",ne,B),le("ggggg",ne,B),me(["gggg","ggggg","GGGG","GGGGG"],(function(e,t,n,s){t[s.substr(0,2)]=S(e)})),me(["gg","GG"],(function(e,t,n,i){t[i]=s.parseTwoDigitYear(e)})),I("Q",0,"Qo","quarter"),H("quarter","Q"),U("quarter",7),le("Q",z),fe("Q",(function(e,t){t[1]=3*(S(e)-1)})),I("D",["DD",2],"Do","date"),H("date","D"),U("date",9),le("D",Q),le("DD",Q,$),le("Do",(function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient})),fe(["D","DD"],2),fe("Do",(function(e,t){t[2]=S(e.match(Q)[0])}));var Kt=we("Date",!0);I("DDD",["DDDD",3],"DDDo","dayOfYear"),H("dayOfYear","DDD"),U("dayOfYear",4),le("DDD",ee),le("DDDD",J),fe(["DDD","DDDD"],(function(e,t,n){n._dayOfYear=S(e)})),I("m",["mm",2],0,"minute"),H("minute","m"),U("minute",14),le("m",Q),le("mm",Q,$),fe(["m","mm"],4);var en=we("Minutes",!1);I("s",["ss",2],0,"second"),H("second","s"),U("second",15),le("s",Q),le("ss",Q,$),fe(["s","ss"],5);var tn,nn=we("Seconds",!1);for(I("S",0,0,(function(){return~~(this.millisecond()/100)})),I(0,["SS",2],0,(function(){return~~(this.millisecond()/10)})),I(0,["SSS",3],0,"millisecond"),I(0,["SSSS",4],0,(function(){return 10*this.millisecond()})),I(0,["SSSSS",5],0,(function(){return 100*this.millisecond()})),I(0,["SSSSSS",6],0,(function(){return 1e3*this.millisecond()})),I(0,["SSSSSSS",7],0,(function(){return 1e4*this.millisecond()})),I(0,["SSSSSSSS",8],0,(function(){return 1e5*this.millisecond()})),I(0,["SSSSSSSSS",9],0,(function(){return 1e6*this.millisecond()})),H("millisecond","ms"),U("millisecond",16),le("S",ee,z),le("SS",ee,$),le("SSS",ee,J),tn="SSSS";tn.length<=9;tn+="S")le(tn,se);function sn(e,t){t[6]=S(1e3*("0."+e))}for(tn="S";tn.length<=9;tn+="S")fe(tn,sn);var rn=we("Milliseconds",!1);I("z",0,0,"zoneAbbr"),I("zz",0,0,"zoneName");var an=v.prototype;function on(e){return e}an.add=At,an.calendar=function(e,t){var n=e||Dt(),i=Rt(n,this).startOf("day"),r=s.calendarFormat(this,i)||"sameElse",a=t&&(x(t[r])?t[r].call(this,n):t[r]);return this.format(a||this.localeData().calendar(r,this,Dt(n)))},an.clone=function(){return new v(this)},an.diff=function(e,t,n){var s,i,r;if(!this.isValid())return NaN;if(!(s=Rt(e,this)).isValid())return NaN;switch(i=6e4*(s.utcOffset()-this.utcOffset()),t=R(t)){case"year":r=zt(this,s)/12;break;case"month":r=zt(this,s);break;case"quarter":r=zt(this,s)/3;break;case"second":r=(this-s)/1e3;break;case"minute":r=(this-s)/6e4;break;case"hour":r=(this-s)/36e5;break;case"day":r=(this-s-i)/864e5;break;case"week":r=(this-s-i)/6048e5;break;default:r=this-s}return n?r:M(r)},an.endOf=function(e){return void 0===(e=R(e))||"millisecond"===e?this:("date"===e&&(e="day"),this.startOf(e).add(1,"isoWeek"===e?"week":e).subtract(1,"ms"))},an.format=function(e){e||(e=this.isUtc()?s.defaultFormatUtc:s.defaultFormat);var t=A(this,e);return this.localeData().postformat(t)},an.from=function(e,t){return this.isValid()&&(w(e)&&e.isValid()||Dt(e).isValid())?Gt({to:this,from:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},an.fromNow=function(e){return this.from(Dt(),e)},an.to=function(e,t){return this.isValid()&&(w(e)&&e.isValid()||Dt(e).isValid())?Gt({from:this,to:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},an.toNow=function(e){return this.to(Dt(),e)},an.get=function(e){return x(this[e=R(e)])?this[e]():this},an.invalidAt=function(){return f(this).overflow},an.isAfter=function(e,t){var n=w(e)?e:Dt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=R(a(t)?"millisecond":t))?this.valueOf()>n.valueOf():n.valueOf()9999?A(n,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):x(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",A(n,"Z")):A(n,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},an.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e="moment",t="";this.isLocal()||(e=0===this.utcOffset()?"moment.utc":"moment.parseZone",t="Z");var n="["+e+'("]',s=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",i=t+'[")]';return this.format(n+s+"-MM-DD[T]HH:mm:ss.SSS"+i)},an.toJSON=function(){return this.isValid()?this.toISOString():null},an.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},an.unix=function(){return Math.floor(this.valueOf()/1e3)},an.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},an.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},an.year=ve,an.isLeapYear=function(){return ge(this.year())},an.weekYear=function(e){return Qt.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},an.isoWeekYear=function(e){return Qt.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},an.quarter=an.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},an.month=xe,an.daysInMonth=function(){return De(this.year(),this.month())},an.week=an.weeks=function(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")},an.isoWeek=an.isoWeeks=function(e){var t=Ue(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")},an.weeksInYear=function(){var e=this.localeData()._week;return Ne(this.year(),e.dow,e.doy)},an.isoWeeksInYear=function(){return Ne(this.year(),1,4)},an.date=Kt,an.day=an.days=function(e){if(!this.isValid())return null!=e?this:NaN;var t=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(e=function(e,t){return"string"!=typeof e?e:isNaN(e)?"number"==typeof(e=t.weekdaysParse(e))?e:null:parseInt(e,10)}(e,this.localeData()),this.add(e-t,"d")):t},an.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")},an.isoWeekday=function(e){if(!this.isValid())return null!=e?this:NaN;if(null!=e){var t=function(e,t){return"string"==typeof e?t.weekdaysParse(e)%7||7:isNaN(e)?null:e}(e,this.localeData());return this.day(this.day()%7?t:t-7)}return this.day()||7},an.dayOfYear=function(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")},an.hour=an.hours=Qe,an.minute=an.minutes=en,an.second=an.seconds=nn,an.millisecond=an.milliseconds=rn,an.utcOffset=function(e,t,n){var i,r=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null!=e){if("string"==typeof e){if(null===(e=Ht(ae,e)))return this}else Math.abs(e)<16&&!n&&(e*=60);return!this._isUTC&&t&&(i=Ft(this)),this._offset=e,this._isUTC=!0,null!=i&&this.add(i,"m"),r!==e&&(!t||this._changeInProgress?It(this,Gt(e-r,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,s.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?r:Ft(this)},an.utc=function(e){return this.utcOffset(0,e)},an.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Ft(this),"m")),this},an.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var e=Ht(re,this._i);null!=e?this.utcOffset(e):this.utcOffset(0,!0)}return this},an.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?Dt(e).utcOffset():0,(this.utcOffset()-e)%60==0)},an.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},an.isLocal=function(){return!!this.isValid()&&!this._isUTC},an.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},an.isUtc=Lt,an.isUTC=Lt,an.zoneAbbr=function(){return this._isUTC?"UTC":""},an.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},an.dates=Y("dates accessor is deprecated. Use date instead.",Kt),an.months=Y("months accessor is deprecated. Use month instead",xe),an.years=Y("years accessor is deprecated. Use year instead",ve),an.zone=Y("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",(function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()})),an.isDSTShifted=Y("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",(function(){if(!a(this._isDSTShifted))return this._isDSTShifted;var e={};if(g(e,this),(e=Mt(e))._a){var t=e._isUTC?c(e._a):Dt(e._a);this._isDSTShifted=this.isValid()&&D(e._a,t.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}));var un=W.prototype;function ln(e,t,n,s){var i=rt(),r=c().set(s,t);return i[n](r,e)}function dn(e,t,n){if(o(e)&&(t=e,e=void 0),e=e||"",null!=t)return ln(e,t,n,"month");var s,i=[];for(s=0;s<12;s++)i[s]=ln(e,s,n,"month");return i}function hn(e,t,n,s){"boolean"==typeof e?(o(t)&&(n=t,t=void 0),t=t||""):(n=t=e,e=!1,o(t)&&(n=t,t=void 0),t=t||"");var i,r=rt(),a=e?r._week.dow:0;if(null!=n)return ln(t,(n+a)%7,s,"day");var u=[];for(i=0;i<7;i++)u[i]=ln(t,(i+a)%7,s,"day");return u}un.calendar=function(e,t,n){var s=this._calendar[e]||this._calendar.sameElse;return x(s)?s.call(t,n):s},un.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.replace(/MMMM|MM|DD|dddd/g,(function(e){return e.slice(1)})),this._longDateFormat[e])},un.invalidDate=function(){return this._invalidDate},un.ordinal=function(e){return this._ordinal.replace("%d",e)},un.preparse=on,un.postformat=on,un.relativeTime=function(e,t,n,s){var i=this._relativeTime[n];return x(i)?i(e,t,n,s):i.replace(/%d/i,e)},un.pastFuture=function(e,t){var n=this._relativeTime[e>0?"future":"past"];return x(n)?n(t):n.replace(/%s/i,t)},un.set=function(e){var t,n;for(n in e)x(t=e[n])?this[n]=t:this["_"+n]=t;this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},un.months=function(e,t){return e?i(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||ke).test(t)?"format":"standalone"][e.month()]:i(this._months)?this._months:this._months.standalone},un.monthsShort=function(e,t){return e?i(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[ke.test(t)?"format":"standalone"][e.month()]:i(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},un.monthsParse=function(e,t,n){var s,i,r;if(this._monthsParseExact)return Te.call(this,e,t,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),s=0;s<12;s++){if(i=c([2e3,s]),n&&!this._longMonthsParse[s]&&(this._longMonthsParse[s]=new RegExp("^"+this.months(i,"").replace(".","")+"$","i"),this._shortMonthsParse[s]=new RegExp("^"+this.monthsShort(i,"").replace(".","")+"$","i")),n||this._monthsParse[s]||(r="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[s]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===t&&this._longMonthsParse[s].test(e))return s;if(n&&"MMM"===t&&this._shortMonthsParse[s].test(e))return s;if(!n&&this._monthsParse[s].test(e))return s}},un.monthsRegex=function(e){return this._monthsParseExact?(d(this,"_monthsRegex")||Ce.call(this),e?this._monthsStrictRegex:this._monthsRegex):(d(this,"_monthsRegex")||(this._monthsRegex=We),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},un.monthsShortRegex=function(e){return this._monthsParseExact?(d(this,"_monthsRegex")||Ce.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(d(this,"_monthsShortRegex")||(this._monthsShortRegex=Pe),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},un.week=function(e){return Ue(e,this._week.dow,this._week.doy).week},un.firstDayOfYear=function(){return this._week.doy},un.firstDayOfWeek=function(){return this._week.dow},un.weekdays=function(e,t){return e?i(this._weekdays)?this._weekdays[e.day()]:this._weekdays[this._weekdays.isFormat.test(t)?"format":"standalone"][e.day()]:i(this._weekdays)?this._weekdays:this._weekdays.standalone},un.weekdaysMin=function(e){return e?this._weekdaysMin[e.day()]:this._weekdaysMin},un.weekdaysShort=function(e){return e?this._weekdaysShort[e.day()]:this._weekdaysShort},un.weekdaysParse=function(e,t,n){var s,i,r;if(this._weekdaysParseExact)return je.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),s=0;s<7;s++){if(i=c([2e3,1]).day(s),n&&!this._fullWeekdaysParse[s]&&(this._fullWeekdaysParse[s]=new RegExp("^"+this.weekdays(i,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[s]=new RegExp("^"+this.weekdaysShort(i,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[s]=new RegExp("^"+this.weekdaysMin(i,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[s]||(r="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[s]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[s].test(e))return s;if(n&&"ddd"===t&&this._shortWeekdaysParse[s].test(e))return s;if(n&&"dd"===t&&this._minWeekdaysParse[s].test(e))return s;if(!n&&this._weekdaysParse[s].test(e))return s}},un.weekdaysRegex=function(e){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||ze.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(d(this,"_weekdaysRegex")||(this._weekdaysRegex=Ie),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},un.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||ze.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(d(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Ae),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},un.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||ze.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(d(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Ze),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},un.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},un.meridiem=function(e,t,n){return e>11?n?"pm":"PM":n?"am":"AM"},st("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===S(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}}),s.lang=Y("moment.lang is deprecated. Use moment.locale instead.",st),s.langData=Y("moment.langData is deprecated. Use moment.localeData instead.",rt);var cn=Math.abs;function fn(e,t,n,s){var i=Gt(t,n);return e._milliseconds+=s*i._milliseconds,e._days+=s*i._days,e._months+=s*i._months,e._bubble()}function mn(e){return e<0?Math.floor(e):Math.ceil(e)}function _n(e){return 4800*e/146097}function yn(e){return 146097*e/4800}function gn(e){return function(){return this.as(e)}}var pn=gn("ms"),vn=gn("s"),wn=gn("m"),Mn=gn("h"),Sn=gn("d"),Dn=gn("w"),kn=gn("M"),Yn=gn("y");function On(e){return function(){return this.isValid()?this._data[e]:NaN}}var Tn=On("milliseconds"),bn=On("seconds"),xn=On("minutes"),Pn=On("hours"),Wn=On("days"),Cn=On("months"),Hn=On("years"),Rn=Math.round,Fn={ss:44,s:45,m:45,h:22,d:26,M:11};function Ln(e,t,n,s,i){return i.relativeTime(t||1,!!n,e,s)}var Un=Math.abs;function Nn(e){return(e>0)-(e<0)||+e}function Gn(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n=Un(this._milliseconds)/1e3,s=Un(this._days),i=Un(this._months);e=M(n/60),t=M(e/60),n%=60,e%=60;var r=M(i/12),a=i%=12,o=s,u=t,l=e,d=n?n.toFixed(3).replace(/\.?0+$/,""):"",h=this.asSeconds();if(!h)return"P0D";var c=h<0?"-":"",f=Nn(this._months)!==Nn(h)?"-":"",m=Nn(this._days)!==Nn(h)?"-":"",_=Nn(this._milliseconds)!==Nn(h)?"-":"";return c+"P"+(r?f+r+"Y":"")+(a?f+a+"M":"")+(o?m+o+"D":"")+(u||l||d?"T":"")+(u?_+u+"H":"")+(l?_+l+"M":"")+(d?_+d+"S":"")}var Vn=bt.prototype;return Vn.isValid=function(){return this._isValid},Vn.abs=function(){var e=this._data;return this._milliseconds=cn(this._milliseconds),this._days=cn(this._days),this._months=cn(this._months),e.milliseconds=cn(e.milliseconds),e.seconds=cn(e.seconds),e.minutes=cn(e.minutes),e.hours=cn(e.hours),e.months=cn(e.months),e.years=cn(e.years),this},Vn.add=function(e,t){return fn(this,e,t,1)},Vn.subtract=function(e,t){return fn(this,e,t,-1)},Vn.as=function(e){if(!this.isValid())return NaN;var t,n,s=this._milliseconds;if("month"===(e=R(e))||"year"===e)return t=this._days+s/864e5,n=this._months+_n(t),"month"===e?n:n/12;switch(t=this._days+Math.round(yn(this._months)),e){case"week":return t/7+s/6048e5;case"day":return t+s/864e5;case"hour":return 24*t+s/36e5;case"minute":return 1440*t+s/6e4;case"second":return 86400*t+s/1e3;case"millisecond":return Math.floor(864e5*t)+s;default:throw new Error("Unknown unit "+e)}},Vn.asMilliseconds=pn,Vn.asSeconds=vn,Vn.asMinutes=wn,Vn.asHours=Mn,Vn.asDays=Sn,Vn.asWeeks=Dn,Vn.asMonths=kn,Vn.asYears=Yn,Vn.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*S(this._months/12):NaN},Vn._bubble=function(){var e,t,n,s,i,r=this._milliseconds,a=this._days,o=this._months,u=this._data;return r>=0&&a>=0&&o>=0||r<=0&&a<=0&&o<=0||(r+=864e5*mn(yn(o)+a),a=0,o=0),u.milliseconds=r%1e3,e=M(r/1e3),u.seconds=e%60,t=M(e/60),u.minutes=t%60,n=M(t/60),u.hours=n%24,a+=M(n/24),i=M(_n(a)),o+=i,a-=mn(yn(i)),s=M(o/12),o%=12,u.days=a,u.months=o,u.years=s,this},Vn.clone=function(){return Gt(this)},Vn.get=function(e){return e=R(e),this.isValid()?this[e+"s"]():NaN},Vn.milliseconds=Tn,Vn.seconds=bn,Vn.minutes=xn,Vn.hours=Pn,Vn.days=Wn,Vn.weeks=function(){return M(this.days()/7)},Vn.months=Cn,Vn.years=Hn,Vn.humanize=function(e){if(!this.isValid())return this.localeData().invalidDate();var t=this.localeData(),n=function(e,t,n){var s=Gt(e).abs(),i=Rn(s.as("s")),r=Rn(s.as("m")),a=Rn(s.as("h")),o=Rn(s.as("d")),u=Rn(s.as("M")),l=Rn(s.as("y")),d=i<=Fn.ss&&["s",i]||i0,d[4]=n,Ln.apply(null,d)}(this,!e,t);return e&&(n=t.pastFuture(+this,n)),t.postformat(n)},Vn.toISOString=Gn,Vn.toString=Gn,Vn.toJSON=Gn,Vn.locale=$t,Vn.localeData=qt,Vn.toIsoString=Y("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Gn),Vn.lang=Jt,I("X",0,0,"unix"),I("x",0,0,"valueOf"),le("x",ie),le("X",/[+-]?\d+(\.\d{1,3})?/),fe("X",(function(e,t,n){n._d=new Date(1e3*parseFloat(e,10))})),fe("x",(function(e,t,n){n._d=new Date(S(e))})),s.version="2.22.2",t=Dt,s.fn=an,s.min=function(){var e=[].slice.call(arguments,0);return Ot("isBefore",e)},s.max=function(){var e=[].slice.call(arguments,0);return Ot("isAfter",e)},s.now=function(){return Date.now?Date.now():+new Date},s.utc=c,s.unix=function(e){return Dt(1e3*e)},s.months=function(e,t){return dn(e,t,"months")},s.isDate=u,s.locale=st,s.invalid=_,s.duration=Gt,s.isMoment=w,s.weekdays=function(e,t,n){return hn(e,t,n,"weekdays")},s.parseZone=function(){return Dt.apply(null,arguments).parseZone()},s.localeData=rt,s.isDuration=xt,s.monthsShort=function(e,t){return dn(e,t,"monthsShort")},s.weekdaysMin=function(e,t,n){return hn(e,t,n,"weekdaysMin")},s.defineLocale=it,s.updateLocale=function(e,t){if(null!=t){var n,s,i=Xe;null!=(s=nt(e))&&(i=s._config),t=P(i,t),(n=new W(t)).parentLocale=Ke[e],Ke[e]=n,st(e)}else null!=Ke[e]&&(null!=Ke[e].parentLocale?Ke[e]=Ke[e].parentLocale:null!=Ke[e]&&delete Ke[e]);return Ke[e]},s.locales=function(){return O(Ke)},s.weekdaysShort=function(e,t,n){return hn(e,t,n,"weekdaysShort")},s.normalizeUnits=R,s.relativeTimeRounding=function(e){return void 0===e?Rn:"function"==typeof e&&(Rn=e,!0)},s.relativeTimeThreshold=function(e,t){return void 0!==Fn[e]&&(void 0===t?Fn[e]:(Fn[e]=t,"s"===e&&(Fn.ss=t-1),!0))},s.calendarFormat=function(e,t){var n=e.diff(t,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},s.prototype=an,s.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"YYYY-[W]WW",MONTH:"YYYY-MM"},s}()}).call(this,n(1)(e))},function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}},,function(e,t,n){e.exports=n(0)}]);
//# sourceMappingURL=http://127.0.0.1:3001/dist/js/vendors.js.map
================================================
FILE: wagalytics/static/wagalytics/wagalytics.bundle.js
================================================
!function(e){var t={};function n(i){if(t[i])return t[i].exports;var s=t[i]={i:i,l:!1,exports:{}};return e[i].call(s.exports,s,s.exports,n),s.l=!0,s.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)n.d(i,s,function(t){return e[t]}.bind(null,s));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=2)}([function(e,t,n){(function(e){e.exports=function(){"use strict";var t,n;function i(){return t.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function r(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function a(e){return void 0===e}function o(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function u(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function l(e,t){var n,i=[];for(n=0;n>>0,i=0;i0)for(n=0;n=0?n?"+":"":"-")+Math.pow(10,Math.max(0,s)).toString().substr(1)+i}var U=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,I=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,V={},G={};function j(e,t,n,i){var s=i;"string"==typeof i&&(s=function(){return this[i]()}),e&&(G[e]=s),t&&(G[t[0]]=function(){return N(s.apply(this,arguments),t[1],t[2])}),n&&(G[n]=function(){return this.localeData().ordinal(s.apply(this,arguments),e)})}function A(e,t){return e.isValid()?(t=z(t,e.localeData()),V[t]=V[t]||function(e){var t,n,i,s=e.match(U);for(t=0,n=s.length;t=0&&I.test(e);)e=e.replace(I,i),I.lastIndex=0,n-=1;return e}var Z=/\d/,$=/\d\d/,B=/\d{3}/,J=/\d{4}/,q=/[+-]?\d{6}/,Q=/\d\d?/,X=/\d\d\d\d?/,K=/\d\d\d\d\d\d?/,ee=/\d{1,3}/,te=/\d{1,4}/,ne=/[+-]?\d{1,6}/,ie=/\d+/,se=/[+-]?\d+/,re=/Z|[+-]\d\d:?\d\d/gi,ae=/Z|[+-]\d\d(?::?\d\d)?/gi,oe=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,ue={};function le(e,t,n){ue[e]=x(t)?t:function(e,i){return e&&n?n:t}}function de(e,t){return d(ue,e)?ue[e](t._strict,t._locale):new RegExp(he(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,(function(e,t,n,i,s){return t||n||i||s}))))}function he(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var ce={};function fe(e,t){var n,i=t;for("string"==typeof e&&(e=[e]),o(t)&&(i=function(e,n){n[t]=S(e)}),n=0;n68?1900:2e3)};var pe,ve=we("FullYear",!0);function we(e,t){return function(n){return null!=n?(Se(this,e,n),i.updateOffset(this,t),this):Me(this,e)}}function Me(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function Se(e,t,n){e.isValid()&&!isNaN(n)&&("FullYear"===t&&ge(e.year())&&1===e.month()&&29===e.date()?e._d["set"+(e._isUTC?"UTC":"")+t](n,e.month(),ke(n,e.month())):e._d["set"+(e._isUTC?"UTC":"")+t](n))}function ke(e,t){if(isNaN(e)||isNaN(t))return NaN;var n,i=(t%(n=12)+n)%n;return e+=(t-i)/12,1===i?ge(e)?29:28:31-i%7%2}pe=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var t;for(t=0;t=0&&isFinite(o.getFullYear())&&o.setFullYear(e),o}function He(e){var t=new Date(Date.UTC.apply(null,arguments));return e<100&&e>=0&&isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e),t}function Re(e,t,n){var i=7+t-n;return-(7+He(e,0,i).getUTCDay()-t)%7+i-1}function Fe(e,t,n,i,s){var r,a,o=1+7*(t-1)+(7+n-i)%7+Re(e,i,s);return o<=0?a=ye(r=e-1)+o:o>ye(e)?(r=e+1,a=o-ye(e)):(r=e,a=o),{year:r,dayOfYear:a}}function Ee(e,t,n){var i,s,r=Re(e.year(),t,n),a=Math.floor((e.dayOfYear()-r-1)/7)+1;return a<1?i=a+Ne(s=e.year()-1,t,n):a>Ne(e.year(),t,n)?(i=a-Ne(e.year(),t,n),s=e.year()+1):(s=e.year(),i=a),{week:i,year:s}}function Ne(e,t,n){var i=Re(e,t,n),s=Re(e+1,t,n);return(ye(e)-i+s)/7}j("w",["ww",2],"wo","week"),j("W",["WW",2],"Wo","isoWeek"),L("week","w"),L("isoWeek","W"),E("week",5),E("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),me(["w","ww","W","WW"],(function(e,t,n,i){t[i.substr(0,1)]=S(e)})),j("d",0,"do","day"),j("dd",0,0,(function(e){return this.localeData().weekdaysMin(this,e)})),j("ddd",0,0,(function(e){return this.localeData().weekdaysShort(this,e)})),j("dddd",0,0,(function(e){return this.localeData().weekdays(this,e)})),j("e",0,0,"weekday"),j("E",0,0,"isoWeekday"),L("day","d"),L("weekday","e"),L("isoWeekday","E"),E("day",11),E("weekday",11),E("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",(function(e,t){return t.weekdaysMinRegex(e)})),le("ddd",(function(e,t){return t.weekdaysShortRegex(e)})),le("dddd",(function(e,t){return t.weekdaysRegex(e)})),me(["dd","ddd","dddd"],(function(e,t,n,i){var s=n._locale.weekdaysParse(e,i,n._strict);null!=s?t.d=s:f(n).invalidWeekday=e})),me(["d","e","E"],(function(e,t,n,i){t[i]=S(e)}));var Ue="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Ie="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Ve="Su_Mo_Tu_We_Th_Fr_Sa".split("_");function Ge(e,t,n){var i,s,r,a=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],i=0;i<7;++i)r=c([2e3,1]).day(i),this._minWeekdaysParse[i]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===t?-1!==(s=pe.call(this._weekdaysParse,a))?s:null:"ddd"===t?-1!==(s=pe.call(this._shortWeekdaysParse,a))?s:null:-1!==(s=pe.call(this._minWeekdaysParse,a))?s:null:"dddd"===t?-1!==(s=pe.call(this._weekdaysParse,a))||-1!==(s=pe.call(this._shortWeekdaysParse,a))||-1!==(s=pe.call(this._minWeekdaysParse,a))?s:null:"ddd"===t?-1!==(s=pe.call(this._shortWeekdaysParse,a))||-1!==(s=pe.call(this._weekdaysParse,a))||-1!==(s=pe.call(this._minWeekdaysParse,a))?s:null:-1!==(s=pe.call(this._minWeekdaysParse,a))||-1!==(s=pe.call(this._weekdaysParse,a))||-1!==(s=pe.call(this._shortWeekdaysParse,a))?s:null}var je=oe,Ae=oe,ze=oe;function Ze(){function e(e,t){return t.length-e.length}var t,n,i,s,r,a=[],o=[],u=[],l=[];for(t=0;t<7;t++)n=c([2e3,1]).day(t),i=this.weekdaysMin(n,""),s=this.weekdaysShort(n,""),r=this.weekdays(n,""),a.push(i),o.push(s),u.push(r),l.push(i),l.push(s),l.push(r);for(a.sort(e),o.sort(e),u.sort(e),l.sort(e),t=0;t<7;t++)o[t]=he(o[t]),u[t]=he(u[t]),l[t]=he(l[t]);this._weekdaysRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+a.join("|")+")","i")}function $e(){return this.hours()%12||12}function Be(e,t){j(e,0,0,(function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)}))}function Je(e,t){return t._meridiemParse}j("H",["HH",2],0,"hour"),j("h",["hh",2],0,$e),j("k",["kk",2],0,(function(){return this.hours()||24})),j("hmm",0,0,(function(){return""+$e.apply(this)+N(this.minutes(),2)})),j("hmmss",0,0,(function(){return""+$e.apply(this)+N(this.minutes(),2)+N(this.seconds(),2)})),j("Hmm",0,0,(function(){return""+this.hours()+N(this.minutes(),2)})),j("Hmmss",0,0,(function(){return""+this.hours()+N(this.minutes(),2)+N(this.seconds(),2)})),Be("a",!0),Be("A",!1),L("hour","h"),E("hour",13),le("a",Je),le("A",Je),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",X),le("hmmss",K),le("Hmm",X),le("Hmmss",K),fe(["H","HH"],3),fe(["k","kk"],(function(e,t,n){var i=S(e);t[3]=24===i?0:i})),fe(["a","A"],(function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e})),fe(["h","hh"],(function(e,t,n){t[3]=S(e),f(n).bigHour=!0})),fe("hmm",(function(e,t,n){var i=e.length-2;t[3]=S(e.substr(0,i)),t[4]=S(e.substr(i)),f(n).bigHour=!0})),fe("hmmss",(function(e,t,n){var i=e.length-4,s=e.length-2;t[3]=S(e.substr(0,i)),t[4]=S(e.substr(i,2)),t[5]=S(e.substr(s)),f(n).bigHour=!0})),fe("Hmm",(function(e,t,n){var i=e.length-2;t[3]=S(e.substr(0,i)),t[4]=S(e.substr(i))})),fe("Hmmss",(function(e,t,n){var i=e.length-4,s=e.length-2;t[3]=S(e.substr(0,i)),t[4]=S(e.substr(i,2)),t[5]=S(e.substr(s))}));var qe,Qe=we("Hours",!0),Xe={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Ye,monthsShort:be,week:{dow:0,doy:6},weekdays:Ue,weekdaysMin:Ve,weekdaysShort:Ie,meridiemParse:/[ap]\.?m?\.?/i},Ke={},et={};function tt(e){return e?e.toLowerCase().replace("_","-"):e}function nt(t){var n=null;if(!Ke[t]&&void 0!==e&&e&&e.exports)try{n=qe._abbr,!function(){var e=new Error("Cannot find module 'undefined'");throw e.code="MODULE_NOT_FOUND",e}(),it(n)}catch(e){}return Ke[t]}function it(e,t){var n;return e&&((n=a(t)?rt(e):st(e,t))?qe=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),qe._abbr}function st(e,t){if(null!==t){var n,i=Xe;if(t.abbr=e,null!=Ke[e])T("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=Ke[e]._config;else if(null!=t.parentLocale)if(null!=Ke[t.parentLocale])i=Ke[t.parentLocale]._config;else{if(null==(n=nt(t.parentLocale)))return et[t.parentLocale]||(et[t.parentLocale]=[]),et[t.parentLocale].push({name:e,config:t}),null;i=n._config}return Ke[e]=new C(P(i,t)),et[e]&&et[e].forEach((function(e){st(e.name,e.config)})),it(e),Ke[e]}return delete Ke[e],null}function rt(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return qe;if(!s(e)){if(t=nt(e))return t;e=[e]}return function(e){for(var t,n,i,s,r=0;r0;){if(i=nt(s.slice(0,t).join("-")))return i;if(n&&n.length>=t&&k(s,n,!0)>=t-1)break;t--}r++}return qe}(e)}function at(e){var t,n=e._a;return n&&-2===f(e).overflow&&(t=n[1]<0||n[1]>11?1:n[2]<1||n[2]>ke(n[0],n[1])?2:n[3]<0||n[3]>24||24===n[3]&&(0!==n[4]||0!==n[5]||0!==n[6])?3:n[4]<0||n[4]>59?4:n[5]<0||n[5]>59?5:n[6]<0||n[6]>999?6:-1,f(e)._overflowDayOfYear&&(t<0||t>2)&&(t=2),f(e)._overflowWeeks&&-1===t&&(t=7),f(e)._overflowWeekday&&-1===t&&(t=8),f(e).overflow=t),e}function ot(e,t,n){return null!=e?e:null!=t?t:n}function ut(e){var t,n,s,r,a,o=[];if(!e._d){for(s=function(e){var t=new Date(i.now());return e._useUTC?[t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate()]:[t.getFullYear(),t.getMonth(),t.getDate()]}(e),e._w&&null==e._a[2]&&null==e._a[1]&&function(e){var t,n,i,s,r,a,o,u;if(null!=(t=e._w).GG||null!=t.W||null!=t.E)r=1,a=4,n=ot(t.GG,e._a[0],Ee(kt(),1,4).year),i=ot(t.W,1),((s=ot(t.E,1))<1||s>7)&&(u=!0);else{r=e._locale._week.dow,a=e._locale._week.doy;var l=Ee(kt(),r,a);n=ot(t.gg,e._a[0],l.year),i=ot(t.w,l.week),null!=t.d?((s=t.d)<0||s>6)&&(u=!0):null!=t.e?(s=t.e+r,(t.e<0||t.e>6)&&(u=!0)):s=r}i<1||i>Ne(n,r,a)?f(e)._overflowWeeks=!0:null!=u?f(e)._overflowWeekday=!0:(o=Fe(n,i,s,r,a),e._a[0]=o.year,e._dayOfYear=o.dayOfYear)}(e),null!=e._dayOfYear&&(a=ot(e._a[0],s[0]),(e._dayOfYear>ye(a)||0===e._dayOfYear)&&(f(e)._overflowDayOfYear=!0),n=He(a,0,e._dayOfYear),e._a[1]=n.getUTCMonth(),e._a[2]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=s[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[3]&&0===e._a[4]&&0===e._a[5]&&0===e._a[6]&&(e._nextDay=!0,e._a[3]=0),e._d=(e._useUTC?He:Le).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[3]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(f(e).weekdayMismatch=!0)}}var lt=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,dt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ht=/Z|[+-]\d\d(?::?\d\d)?/,ct=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],ft=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],mt=/^\/?Date\((\-?\d+)/i;function _t(e){var t,n,i,s,r,a,o=e._i,u=lt.exec(o)||dt.exec(o);if(u){for(f(e).iso=!0,t=0,n=ct.length;t0&&f(e).unusedInput.push(a),o=o.slice(o.indexOf(n)+n.length),l+=n.length),G[r]?(n?f(e).empty=!1:f(e).unusedTokens.push(r),_e(r,n,e)):e._strict&&!n&&f(e).unusedTokens.push(r);f(e).charsLeftOver=u-l,o.length>0&&f(e).unusedInput.push(o),e._a[3]<=12&&!0===f(e).bigHour&&e._a[3]>0&&(f(e).bigHour=void 0),f(e).parsedDateParts=e._a.slice(0),f(e).meridiem=e._meridiem,e._a[3]=function(e,t,n){var i;return null==n?t:null!=e.meridiemHour?e.meridiemHour(t,n):null!=e.isPM?((i=e.isPM(n))&&t<12&&(t+=12),i||12!==t||(t=0),t):t}(e._locale,e._a[3],e._meridiem),ut(e),at(e)}else vt(e);else _t(e)}function Mt(e){var t=e._i,n=e._f;return e._locale=e._locale||rt(e._l),null===t||void 0===n&&""===t?_({nullInput:!0}):("string"==typeof t&&(e._i=t=e._locale.preparse(t)),w(t)?new v(at(t)):(u(t)?e._d=t:s(n)?function(e){var t,n,i,s,r;if(0===e._f.length)return f(e).invalidFormat=!0,void(e._d=new Date(NaN));for(s=0;sthis?this:e:_()}));function bt(e,t){var n,i;if(1===t.length&&s(t[0])&&(t=t[0]),!t.length)return kt();for(n=t[0],i=1;i(r=Ne(e,i,s))&&(t=r),Xt.call(this,e,t,n,i,s))}function Xt(e,t,n,i,s){var r=Fe(e,t,n,i,s),a=He(r.year,0,r.dayOfYear);return this.year(a.getUTCFullYear()),this.month(a.getUTCMonth()),this.date(a.getUTCDate()),this}j(0,["gg",2],0,(function(){return this.weekYear()%100})),j(0,["GG",2],0,(function(){return this.isoWeekYear()%100})),qt("gggg","weekYear"),qt("ggggg","weekYear"),qt("GGGG","isoWeekYear"),qt("GGGGG","isoWeekYear"),L("weekYear","gg"),L("isoWeekYear","GG"),E("weekYear",1),E("isoWeekYear",1),le("G",se),le("g",se),le("GG",Q,$),le("gg",Q,$),le("GGGG",te,J),le("gggg",te,J),le("GGGGG",ne,q),le("ggggg",ne,q),me(["gggg","ggggg","GGGG","GGGGG"],(function(e,t,n,i){t[i.substr(0,2)]=S(e)})),me(["gg","GG"],(function(e,t,n,s){t[s]=i.parseTwoDigitYear(e)})),j("Q",0,"Qo","quarter"),L("quarter","Q"),E("quarter",7),le("Q",Z),fe("Q",(function(e,t){t[1]=3*(S(e)-1)})),j("D",["DD",2],"Do","date"),L("date","D"),E("date",9),le("D",Q),le("DD",Q,$),le("Do",(function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient})),fe(["D","DD"],2),fe("Do",(function(e,t){t[2]=S(e.match(Q)[0])}));var Kt=we("Date",!0);j("DDD",["DDDD",3],"DDDo","dayOfYear"),L("dayOfYear","DDD"),E("dayOfYear",4),le("DDD",ee),le("DDDD",B),fe(["DDD","DDDD"],(function(e,t,n){n._dayOfYear=S(e)})),j("m",["mm",2],0,"minute"),L("minute","m"),E("minute",14),le("m",Q),le("mm",Q,$),fe(["m","mm"],4);var en=we("Minutes",!1);j("s",["ss",2],0,"second"),L("second","s"),E("second",15),le("s",Q),le("ss",Q,$),fe(["s","ss"],5);var tn,nn=we("Seconds",!1);for(j("S",0,0,(function(){return~~(this.millisecond()/100)})),j(0,["SS",2],0,(function(){return~~(this.millisecond()/10)})),j(0,["SSS",3],0,"millisecond"),j(0,["SSSS",4],0,(function(){return 10*this.millisecond()})),j(0,["SSSSS",5],0,(function(){return 100*this.millisecond()})),j(0,["SSSSSS",6],0,(function(){return 1e3*this.millisecond()})),j(0,["SSSSSSS",7],0,(function(){return 1e4*this.millisecond()})),j(0,["SSSSSSSS",8],0,(function(){return 1e5*this.millisecond()})),j(0,["SSSSSSSSS",9],0,(function(){return 1e6*this.millisecond()})),L("millisecond","ms"),E("millisecond",16),le("S",ee,Z),le("SS",ee,$),le("SSS",ee,B),tn="SSSS";tn.length<=9;tn+="S")le(tn,ie);function sn(e,t){t[6]=S(1e3*("0."+e))}for(tn="S";tn.length<=9;tn+="S")fe(tn,sn);var rn=we("Milliseconds",!1);j("z",0,0,"zoneAbbr"),j("zz",0,0,"zoneName");var an=v.prototype;function on(e){return e}an.add=At,an.calendar=function(e,t){var n=e||kt(),s=Ht(n,this).startOf("day"),r=i.calendarFormat(this,s)||"sameElse",a=t&&(x(t[r])?t[r].call(this,n):t[r]);return this.format(a||this.localeData().calendar(r,this,kt(n)))},an.clone=function(){return new v(this)},an.diff=function(e,t,n){var i,s,r;if(!this.isValid())return NaN;if(!(i=Ht(e,this)).isValid())return NaN;switch(s=6e4*(i.utcOffset()-this.utcOffset()),t=H(t)){case"year":r=Zt(this,i)/12;break;case"month":r=Zt(this,i);break;case"quarter":r=Zt(this,i)/3;break;case"second":r=(this-i)/1e3;break;case"minute":r=(this-i)/6e4;break;case"hour":r=(this-i)/36e5;break;case"day":r=(this-i-s)/864e5;break;case"week":r=(this-i-s)/6048e5;break;default:r=this-i}return n?r:M(r)},an.endOf=function(e){return void 0===(e=H(e))||"millisecond"===e?this:("date"===e&&(e="day"),this.startOf(e).add(1,"isoWeek"===e?"week":e).subtract(1,"ms"))},an.format=function(e){e||(e=this.isUtc()?i.defaultFormatUtc:i.defaultFormat);var t=A(this,e);return this.localeData().postformat(t)},an.from=function(e,t){return this.isValid()&&(w(e)&&e.isValid()||kt(e).isValid())?Ut({to:this,from:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},an.fromNow=function(e){return this.from(kt(),e)},an.to=function(e,t){return this.isValid()&&(w(e)&&e.isValid()||kt(e).isValid())?Ut({from:this,to:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},an.toNow=function(e){return this.to(kt(),e)},an.get=function(e){return x(this[e=H(e)])?this[e]():this},an.invalidAt=function(){return f(this).overflow},an.isAfter=function(e,t){var n=w(e)?e:kt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=H(a(t)?"millisecond":t))?this.valueOf()>n.valueOf():n.valueOf()9999?A(n,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):x(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",A(n,"Z")):A(n,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},an.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e="moment",t="";this.isLocal()||(e=0===this.utcOffset()?"moment.utc":"moment.parseZone",t="Z");var n="["+e+'("]',i=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",s=t+'[")]';return this.format(n+i+"-MM-DD[T]HH:mm:ss.SSS"+s)},an.toJSON=function(){return this.isValid()?this.toISOString():null},an.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},an.unix=function(){return Math.floor(this.valueOf()/1e3)},an.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},an.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},an.year=ve,an.isLeapYear=function(){return ge(this.year())},an.weekYear=function(e){return Qt.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},an.isoWeekYear=function(e){return Qt.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},an.quarter=an.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},an.month=xe,an.daysInMonth=function(){return ke(this.year(),this.month())},an.week=an.weeks=function(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")},an.isoWeek=an.isoWeeks=function(e){var t=Ee(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")},an.weeksInYear=function(){var e=this.localeData()._week;return Ne(this.year(),e.dow,e.doy)},an.isoWeeksInYear=function(){return Ne(this.year(),1,4)},an.date=Kt,an.day=an.days=function(e){if(!this.isValid())return null!=e?this:NaN;var t=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(e=function(e,t){return"string"!=typeof e?e:isNaN(e)?"number"==typeof(e=t.weekdaysParse(e))?e:null:parseInt(e,10)}(e,this.localeData()),this.add(e-t,"d")):t},an.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")},an.isoWeekday=function(e){if(!this.isValid())return null!=e?this:NaN;if(null!=e){var t=function(e,t){return"string"==typeof e?t.weekdaysParse(e)%7||7:isNaN(e)?null:e}(e,this.localeData());return this.day(this.day()%7?t:t-7)}return this.day()||7},an.dayOfYear=function(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")},an.hour=an.hours=Qe,an.minute=an.minutes=en,an.second=an.seconds=nn,an.millisecond=an.milliseconds=rn,an.utcOffset=function(e,t,n){var s,r=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null!=e){if("string"==typeof e){if(null===(e=Lt(ae,e)))return this}else Math.abs(e)<16&&!n&&(e*=60);return!this._isUTC&&t&&(s=Rt(this)),this._offset=e,this._isUTC=!0,null!=s&&this.add(s,"m"),r!==e&&(!t||this._changeInProgress?jt(this,Ut(e-r,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,i.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?r:Rt(this)},an.utc=function(e){return this.utcOffset(0,e)},an.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Rt(this),"m")),this},an.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var e=Lt(re,this._i);null!=e?this.utcOffset(e):this.utcOffset(0,!0)}return this},an.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?kt(e).utcOffset():0,(this.utcOffset()-e)%60==0)},an.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},an.isLocal=function(){return!!this.isValid()&&!this._isUTC},an.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},an.isUtc=Ft,an.isUTC=Ft,an.zoneAbbr=function(){return this._isUTC?"UTC":""},an.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},an.dates=Y("dates accessor is deprecated. Use date instead.",Kt),an.months=Y("months accessor is deprecated. Use month instead",xe),an.years=Y("years accessor is deprecated. Use year instead",ve),an.zone=Y("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",(function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()})),an.isDSTShifted=Y("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",(function(){if(!a(this._isDSTShifted))return this._isDSTShifted;var e={};if(g(e,this),(e=Mt(e))._a){var t=e._isUTC?c(e._a):kt(e._a);this._isDSTShifted=this.isValid()&&k(e._a,t.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}));var un=C.prototype;function ln(e,t,n,i){var s=rt(),r=c().set(i,t);return s[n](r,e)}function dn(e,t,n){if(o(e)&&(t=e,e=void 0),e=e||"",null!=t)return ln(e,t,n,"month");var i,s=[];for(i=0;i<12;i++)s[i]=ln(e,i,n,"month");return s}function hn(e,t,n,i){"boolean"==typeof e?(o(t)&&(n=t,t=void 0),t=t||""):(n=t=e,e=!1,o(t)&&(n=t,t=void 0),t=t||"");var s,r=rt(),a=e?r._week.dow:0;if(null!=n)return ln(t,(n+a)%7,i,"day");var u=[];for(s=0;s<7;s++)u[s]=ln(t,(s+a)%7,i,"day");return u}un.calendar=function(e,t,n){var i=this._calendar[e]||this._calendar.sameElse;return x(i)?i.call(t,n):i},un.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.replace(/MMMM|MM|DD|dddd/g,(function(e){return e.slice(1)})),this._longDateFormat[e])},un.invalidDate=function(){return this._invalidDate},un.ordinal=function(e){return this._ordinal.replace("%d",e)},un.preparse=on,un.postformat=on,un.relativeTime=function(e,t,n,i){var s=this._relativeTime[n];return x(s)?s(e,t,n,i):s.replace(/%d/i,e)},un.pastFuture=function(e,t){var n=this._relativeTime[e>0?"future":"past"];return x(n)?n(t):n.replace(/%s/i,t)},un.set=function(e){var t,n;for(n in e)x(t=e[n])?this[n]=t:this["_"+n]=t;this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},un.months=function(e,t){return e?s(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||De).test(t)?"format":"standalone"][e.month()]:s(this._months)?this._months:this._months.standalone},un.monthsShort=function(e,t){return e?s(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[De.test(t)?"format":"standalone"][e.month()]:s(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},un.monthsParse=function(e,t,n){var i,s,r;if(this._monthsParseExact)return Oe.call(this,e,t,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),i=0;i<12;i++){if(s=c([2e3,i]),n&&!this._longMonthsParse[i]&&(this._longMonthsParse[i]=new RegExp("^"+this.months(s,"").replace(".","")+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(s,"").replace(".","")+"$","i")),n||this._monthsParse[i]||(r="^"+this.months(s,"")+"|^"+this.monthsShort(s,""),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===t&&this._longMonthsParse[i].test(e))return i;if(n&&"MMM"===t&&this._shortMonthsParse[i].test(e))return i;if(!n&&this._monthsParse[i].test(e))return i}},un.monthsRegex=function(e){return this._monthsParseExact?(d(this,"_monthsRegex")||We.call(this),e?this._monthsStrictRegex:this._monthsRegex):(d(this,"_monthsRegex")||(this._monthsRegex=Ce),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},un.monthsShortRegex=function(e){return this._monthsParseExact?(d(this,"_monthsRegex")||We.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(d(this,"_monthsShortRegex")||(this._monthsShortRegex=Pe),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},un.week=function(e){return Ee(e,this._week.dow,this._week.doy).week},un.firstDayOfYear=function(){return this._week.doy},un.firstDayOfWeek=function(){return this._week.dow},un.weekdays=function(e,t){return e?s(this._weekdays)?this._weekdays[e.day()]:this._weekdays[this._weekdays.isFormat.test(t)?"format":"standalone"][e.day()]:s(this._weekdays)?this._weekdays:this._weekdays.standalone},un.weekdaysMin=function(e){return e?this._weekdaysMin[e.day()]:this._weekdaysMin},un.weekdaysShort=function(e){return e?this._weekdaysShort[e.day()]:this._weekdaysShort},un.weekdaysParse=function(e,t,n){var i,s,r;if(this._weekdaysParseExact)return Ge.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),i=0;i<7;i++){if(s=c([2e3,1]).day(i),n&&!this._fullWeekdaysParse[i]&&(this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(s,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(s,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(s,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[i]||(r="^"+this.weekdays(s,"")+"|^"+this.weekdaysShort(s,"")+"|^"+this.weekdaysMin(s,""),this._weekdaysParse[i]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[i].test(e))return i;if(n&&"ddd"===t&&this._shortWeekdaysParse[i].test(e))return i;if(n&&"dd"===t&&this._minWeekdaysParse[i].test(e))return i;if(!n&&this._weekdaysParse[i].test(e))return i}},un.weekdaysRegex=function(e){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||Ze.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(d(this,"_weekdaysRegex")||(this._weekdaysRegex=je),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},un.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||Ze.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(d(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Ae),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},un.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||Ze.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(d(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=ze),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},un.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},un.meridiem=function(e,t,n){return e>11?n?"pm":"PM":n?"am":"AM"},it("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===S(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}}),i.lang=Y("moment.lang is deprecated. Use moment.locale instead.",it),i.langData=Y("moment.langData is deprecated. Use moment.localeData instead.",rt);var cn=Math.abs;function fn(e,t,n,i){var s=Ut(t,n);return e._milliseconds+=i*s._milliseconds,e._days+=i*s._days,e._months+=i*s._months,e._bubble()}function mn(e){return e<0?Math.floor(e):Math.ceil(e)}function _n(e){return 4800*e/146097}function yn(e){return 146097*e/4800}function gn(e){return function(){return this.as(e)}}var pn=gn("ms"),vn=gn("s"),wn=gn("m"),Mn=gn("h"),Sn=gn("d"),kn=gn("w"),Dn=gn("M"),Yn=gn("y");function bn(e){return function(){return this.isValid()?this._data[e]:NaN}}var On=bn("milliseconds"),Tn=bn("seconds"),xn=bn("minutes"),Pn=bn("hours"),Cn=bn("days"),Wn=bn("months"),Ln=bn("years"),Hn=Math.round,Rn={ss:44,s:45,m:45,h:22,d:26,M:11};function Fn(e,t,n,i,s){return s.relativeTime(t||1,!!n,e,i)}var En=Math.abs;function Nn(e){return(e>0)-(e<0)||+e}function Un(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n=En(this._milliseconds)/1e3,i=En(this._days),s=En(this._months);e=M(n/60),t=M(e/60),n%=60,e%=60;var r=M(s/12),a=s%=12,o=i,u=t,l=e,d=n?n.toFixed(3).replace(/\.?0+$/,""):"",h=this.asSeconds();if(!h)return"P0D";var c=h<0?"-":"",f=Nn(this._months)!==Nn(h)?"-":"",m=Nn(this._days)!==Nn(h)?"-":"",_=Nn(this._milliseconds)!==Nn(h)?"-":"";return c+"P"+(r?f+r+"Y":"")+(a?f+a+"M":"")+(o?m+o+"D":"")+(u||l||d?"T":"")+(u?_+u+"H":"")+(l?_+l+"M":"")+(d?_+d+"S":"")}var In=Tt.prototype;return In.isValid=function(){return this._isValid},In.abs=function(){var e=this._data;return this._milliseconds=cn(this._milliseconds),this._days=cn(this._days),this._months=cn(this._months),e.milliseconds=cn(e.milliseconds),e.seconds=cn(e.seconds),e.minutes=cn(e.minutes),e.hours=cn(e.hours),e.months=cn(e.months),e.years=cn(e.years),this},In.add=function(e,t){return fn(this,e,t,1)},In.subtract=function(e,t){return fn(this,e,t,-1)},In.as=function(e){if(!this.isValid())return NaN;var t,n,i=this._milliseconds;if("month"===(e=H(e))||"year"===e)return t=this._days+i/864e5,n=this._months+_n(t),"month"===e?n:n/12;switch(t=this._days+Math.round(yn(this._months)),e){case"week":return t/7+i/6048e5;case"day":return t+i/864e5;case"hour":return 24*t+i/36e5;case"minute":return 1440*t+i/6e4;case"second":return 86400*t+i/1e3;case"millisecond":return Math.floor(864e5*t)+i;default:throw new Error("Unknown unit "+e)}},In.asMilliseconds=pn,In.asSeconds=vn,In.asMinutes=wn,In.asHours=Mn,In.asDays=Sn,In.asWeeks=kn,In.asMonths=Dn,In.asYears=Yn,In.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*S(this._months/12):NaN},In._bubble=function(){var e,t,n,i,s,r=this._milliseconds,a=this._days,o=this._months,u=this._data;return r>=0&&a>=0&&o>=0||r<=0&&a<=0&&o<=0||(r+=864e5*mn(yn(o)+a),a=0,o=0),u.milliseconds=r%1e3,e=M(r/1e3),u.seconds=e%60,t=M(e/60),u.minutes=t%60,n=M(t/60),u.hours=n%24,a+=M(n/24),s=M(_n(a)),o+=s,a-=mn(yn(s)),i=M(o/12),o%=12,u.days=a,u.months=o,u.years=i,this},In.clone=function(){return Ut(this)},In.get=function(e){return e=H(e),this.isValid()?this[e+"s"]():NaN},In.milliseconds=On,In.seconds=Tn,In.minutes=xn,In.hours=Pn,In.days=Cn,In.weeks=function(){return M(this.days()/7)},In.months=Wn,In.years=Ln,In.humanize=function(e){if(!this.isValid())return this.localeData().invalidDate();var t=this.localeData(),n=function(e,t,n){var i=Ut(e).abs(),s=Hn(i.as("s")),r=Hn(i.as("m")),a=Hn(i.as("h")),o=Hn(i.as("d")),u=Hn(i.as("M")),l=Hn(i.as("y")),d=s<=Rn.ss&&["s",s]||s0,d[4]=n,Fn.apply(null,d)}(this,!e,t);return e&&(n=t.pastFuture(+this,n)),t.postformat(n)},In.toISOString=Un,In.toString=Un,In.toJSON=Un,In.locale=$t,In.localeData=Jt,In.toIsoString=Y("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Un),In.lang=Bt,j("X",0,0,"unix"),j("x",0,0,"valueOf"),le("x",se),le("X",/[+-]?\d+(\.\d{1,3})?/),fe("X",(function(e,t,n){n._d=new Date(1e3*parseFloat(e,10))})),fe("x",(function(e,t,n){n._d=new Date(S(e))})),i.version="2.22.2",t=kt,i.fn=an,i.min=function(){var e=[].slice.call(arguments,0);return bt("isBefore",e)},i.max=function(){var e=[].slice.call(arguments,0);return bt("isAfter",e)},i.now=function(){return Date.now?Date.now():+new Date},i.utc=c,i.unix=function(e){return kt(1e3*e)},i.months=function(e,t){return dn(e,t,"months")},i.isDate=u,i.locale=it,i.invalid=_,i.duration=Ut,i.isMoment=w,i.weekdays=function(e,t,n){return hn(e,t,n,"weekdays")},i.parseZone=function(){return kt.apply(null,arguments).parseZone()},i.localeData=rt,i.isDuration=xt,i.monthsShort=function(e,t){return dn(e,t,"monthsShort")},i.weekdaysMin=function(e,t,n){return hn(e,t,n,"weekdaysMin")},i.defineLocale=st,i.updateLocale=function(e,t){if(null!=t){var n,i,s=Xe;null!=(i=nt(e))&&(s=i._config),t=P(s,t),(n=new C(t)).parentLocale=Ke[e],Ke[e]=n,it(e)}else null!=Ke[e]&&(null!=Ke[e].parentLocale?Ke[e]=Ke[e].parentLocale:null!=Ke[e]&&delete Ke[e]);return Ke[e]},i.locales=function(){return b(Ke)},i.weekdaysShort=function(e,t,n){return hn(e,t,n,"weekdaysShort")},i.normalizeUnits=H,i.relativeTimeRounding=function(e){return void 0===e?Hn:"function"==typeof e&&(Hn=e,!0)},i.relativeTimeThreshold=function(e,t){return void 0!==Rn[e]&&(void 0===t?Rn[e]:(Rn[e]=t,"s"===e&&(Rn.ss=t-1),!0))},i.calendarFormat=function(e,t){var n=e.diff(t,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},i.prototype=an,i.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"YYYY-[W]WW",MONTH:"YYYY-MM"},i}()}).call(this,n(1)(e))},function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}},function(e,t,n){"use strict";n.r(t);var i=n(0),s=n.n(i);function r(e,t){for(var n=0;n'}},{key:"refresh",value:function(){this.sessionsLineChart(),this.popularPagesTable(),this.topReferrersTable()}},{key:"getQuery",value:function(e){return $(this.export_btn).prop("disabled",!0),t=Object.assign({ids:this.view_id,"start-date":$(this.start_date_input).val(),"end-date":$(this.end_date_input).val()},e),new Promise((function(e,n){new gapi.analytics.report.Data({query:t}).once("success",(function(t){e(t)})).once("error",(function(e){n(e)})).execute()}));var t}},{key:"sessionsLineChart",value:function(){var e=this,t="sessions-line-chart-container";this.setLoading(t),this.getQuery({dimensions:"ga:date,ga:nthDay",metrics:"ga:sessions"}).then((function(n){e.data.sessions=n.rows,$(e.export_btn).prop("disabled",!1),$(e.export_btn).removeClass("button-longrunning-active");var i=n.rows.map((function(e){return e[2]})),r=n.rows.map((function(e){return e[0]})),u={labels:r=r.map((function(e){return s()(e,"YYYYMMDD").format("ll")})),datasets:[{label:"Sessions",backgroundColor:o,borderColor:a,pointBackgroundColor:a,pointBorderColor:"#fff",data:i}]};new Chart(function(e){var t=document.getElementById(e),n=document.createElement("canvas"),i=n.getContext("2d");return t.innerHTML="",n.width=t.offsetWidth,n.height=t.offsetHeight,t.appendChild(n),i}(t),{type:"line",data:u,options:{legend:{display:!1},scales:{xAxes:[{ticks:{autoSkip:!0,maxTicksLimit:4,maxRotation:0}}]}}})}))}},{key:"popularPagesTable",value:function(){var e=this,t="popular-pages-table-container";this.setLoading(t),this.getQuery({metrics:"ga:pageviews",dimensions:"ga:hostname,ga:pagePath",sort:"-ga:pageviews","max-results":25}).then((function(n){for(var i=0,s=n.rows,r=s.length,a={};i=s-1?e.find(".next").addClass("disabled"):e.find(".next").removeClass("disabled")})),n.trigger("repaginate");var i=n.find("tbody tr").length,s=Math.ceil(i/5),r=$('\n '));return r.find(".prev a").bind("click",(function(e){e.preventDefault(),(t-=1)<0&&(t=0),r.find(".page-num").text("".concat(t+1)),n.trigger("repaginate")})),r.find(".next a").bind("click",(function(e){e.preventDefault(),(t+=1)>=s&&(t=s-1),r.find(".page-num").text("".concat(t+1)),n.trigger("repaginate")})),r}Chart.defaults.global.animationSteps=60,Chart.defaults.global.animationEasing="easeInOutQuart",Chart.defaults.global.responsive=!0,Chart.defaults.global.maintainAspectRatio=!1}]);
//# sourceMappingURL=http://127.0.0.1:3001/dist/js/wagalytics.js.map
================================================
FILE: wagalytics/templates/wagalytics/dashboard.html
================================================
{% extends "wagtailadmin/base.html" %}
{% load wagtailadmin_tags i18n static %}
{% block extra_css %}
{% include "wagtailadmin/pages/_editor_css.html" %}
{{ block.super }}
{% endblock %}
{% block titletag %}{% trans 'Analytics' %}{% endblock %}
{% block content %}
{% endblock %}
{% block extra_js %}
{{ block.super }}
{{ site_switcher.media.js }}
{% endblock %}
================================================
FILE: wagalytics/tests/tests.py
================================================
import pytest
from django.conf import settings
from django.test import TestCase
from django.urls import reverse
from wagtail.tests.utils import WagtailTestUtils
from wagtail.core.models import Site
import wagtail_factories
pytestmark = pytest.mark.django_db
@pytest.mark.django_db
class TestWagalyticsDashboard(TestCase, WagtailTestUtils):
def setUp(self):
self.dashboard_url = reverse('wagalytics_dashboard')
# Clear KEY settings in case tests are being run inside of a project.
self._clean_wagalytics_keys()
# Login
self.login()
def _clean_wagalytics_keys(self):
"""Remove Wagalytics settings."""
if hasattr(settings, 'WAGALYTICS_SETTINGS'):
del settings.WAGALYTICS_SETTINGS
if hasattr(settings, 'GA_VIEW_ID'):
del settings.GA_VIEW_ID
if hasattr(settings, 'GA_KEY_FILEPATH'):
del settings.GA_KEY_FILEPATH
if hasattr(settings, 'GA_KEY_CONTENT'):
del settings.GA_KEY_CONTENT
def _use_single_site_settings(self):
if hasattr(settings, 'WAGALYTICS_SETTINGS'):
del settings.WAGALYTICS_SETTINGS
settings.GA_VIEW_ID = 'ga:xxxxxxxx'
settings.GA_KEY_FILEPATH = '/path/to/your/analytics-key.json'
def _use_multi_site_settings(self):
settings.WAGALYTICS_SETTINGS = {
# My default site.
2: {
'GA_VIEW_ID': 'ga:xxxxxxxx',
'GA_KEY_FILEPATH': '/path/to/your/analytics-key.json',
},
# The secondary site.
3: {
'GA_KEY_CONTENT': 'content_of_your_key.json',
'GA_VIEW_ID': 'ga:xxxxxxxx',
}
}
def test_dashboard_view(self):
self._use_single_site_settings()
response_200 = self.client.get(self.dashboard_url)
# Default URL should not redirect to ^analytics/dashboard/{num}/$
self.assertEqual(response_200.status_code, 200)
def test_dashboard_404_view(self):
response_404 = self.client.get(reverse('wagalytics_site_dashboard', args=(999,)))
self.assertEqual(response_404.status_code, 404)
def test_single_site_missing_keys(self):
self._clean_wagalytics_keys()
response = self.client.get(self.dashboard_url)
messages = list(response.context['messages'])
self.assertEqual(len(messages), 2)
self.assertEqual(messages[0].message, "You are missing your GA_VIEW_ID setting. Your analytics dashboard won't load without this setting.")
self.assertEqual(messages[1].message, "You are missing your GA_KEY_FILEPATH or your GA_KEY_CONTENT setting.")
def test_single_site_no_siteswitcher(self):
"""Make sure the site switcher does not show up in the dashboard context."""
self._clean_wagalytics_keys()
response = self.client.get(self.dashboard_url)
self.assertEqual(response.context['site_switcher'], None)
def test_single_site_dashboard(self):
self._use_single_site_settings()
response = self.client.get(self.dashboard_url)
messages = list(response.context['messages'])
self.assertEqual(len(messages), 0)
def test_single_site_dashboard_on_multisite_url(self):
self._use_single_site_settings()
response = self.client.get(reverse('wagalytics_site_dashboard', args=(2,)))
self.assertEqual(response.status_code, 200) # Will still 200.
messages = list(response.context['messages'])
# Should have 1 message
self.assertEqual(len(messages), 1)
# The one message should be "You are missing Wagalytics Multisite settings."
self.assertEqual(messages[0].message, "You are missing Wagalytics Multisite settings.")
def test_multi_site_dashboard(self):
self._use_multi_site_settings()
wagtail_factories.SiteFactory(hostname="example.com")
sites = Site.objects.all()
# There should be 2 Wagtail Sites.
self.assertEqual(len(sites), 2)
# Go to ^analytics/dashboard/{num}/$. Should redirect.
response = self.client.get(self.dashboard_url)
self.assertEqual(response.status_code, 302) # Redirect
# Went to /dashboard/2/ by default
self.assertEqual(response.url, reverse('wagalytics_site_dashboard', args=(2,)))
def test_multi_site_siteswitcher(self):
self._use_multi_site_settings()
wagtail_factories.SiteFactory(hostname="example.com")
response = self.client.get(reverse('wagalytics_site_dashboard', args=(2,)))
self.assertNotEqual(response.context['site_switcher'], None)
def test_multi_site_dashboard_change_site(self):
self._use_multi_site_settings()
wagtail_factories.SiteFactory(hostname="example.com")
site = Site.objects.last()
response = self.client.get(reverse('wagalytics_site_dashboard', args=(site.id,)))
self.assertEqual(response.status_code, 200)
def test_multi_site_token_no_api_keys(self):
"""Test the ^analytics/token/2/$ url. There will always be an id of 2 available."""
self._clean_wagalytics_keys()
url = reverse('wagalytics_site_token', args=(2,))
response = self.client.get(url)
self.assertEqual(response.status_code, 403)
def test_single_site_token_no_api_keys(self):
"""Test the ^analytics/token/$ url. """
self._clean_wagalytics_keys()
url = reverse('wagalytics_token')
response = self.client.get(url)
self.assertEqual(response.status_code, 403)
def test_multi_site_token_using_single_site_api_keys(self):
self._use_single_site_settings()
url = reverse('wagalytics_site_token', args=(2,))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
def test_multi_site_token_using_multi_site_api_keys(self):
self._use_multi_site_settings()
url = reverse('wagalytics_site_token', args=(2,))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
================================================
FILE: wagalytics/urls.py
================================================
from __future__ import absolute_import, unicode_literals
from django.urls import path
from django.views.decorators.cache import cache_page
from .views import dashboard, token, export
urlpatterns = [
path('dashboard/', dashboard, name='wagalytics_dashboard'),
path('dashboard//', dashboard, name='wagalytics_site_dashboard'),
path('token/', token, name='wagalytics_token'),
path('token//', cache_page(3600)(token), name='wagalytics_site_token'),
path('export/', export, name='wagalytics_export'),
]
================================================
FILE: wagalytics/views.py
================================================
import json
import datetime
from io import BytesIO
from oauth2client.service_account import ServiceAccountCredentials
from django.shortcuts import redirect, render, get_object_or_404
from django.conf import settings
from django.contrib import messages
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden
from django.utils import timezone
from django.urls import reverse
from collections import OrderedDict
from pyexcel_ods import save_data
from wagtail.contrib.settings.forms import SiteSwitchForm as SettingsSiteSwitchForm
from wagtail.core.models import Site
class SiteSwitchForm(SettingsSiteSwitchForm):
"""Overwrite the get_change_url() method from SiteSwitchForm."""
@classmethod
def get_change_url(cls, site, model):
"""Change the url based on the Site."""
return reverse('wagalytics_site_dashboard', args=[site.pk])
def get_access_token(ga_key_filepath):
"""Get the access token for Google Analytics.
from https://ga-dev-tools.appspot.com/embed-api/server-side-authorization/
Defines a method to get an access token from the credentials object.
The access token is automatically refreshed if it has expired.
"""
# The scope for the OAuth2 request.
SCOPE = 'https://www.googleapis.com/auth/analytics.readonly'
# Construct a credentials objects from the key data and OAuth2 scope.
_credentials = ServiceAccountCredentials.from_json_keyfile_name(
ga_key_filepath, SCOPE)
return _credentials.get_access_token().access_token
def get_access_token_from_str(ga_key_content):
"""Get the access token from a string.
from https://ga-dev-tools.appspot.com/embed-api/server-side-authorization/
Defines a method to get an access token from the credentials object.
The access token is automatically refreshed if it has expired.
"""
# The scope for the OAuth2 request.
SCOPE = 'https://www.googleapis.com/auth/analytics.readonly'
# Construct a credentials objects from the key data and OAuth2 scope.
keyDict = json.loads(ga_key_content.replace('\n', '').replace('\r', ''))
_credentials = ServiceAccountCredentials.from_json_keyfile_dict(
keyDict, SCOPE)
return _credentials.get_access_token().access_token
def token(request, site_id=None):
"""Generate the token.
Will detect Wagalyics Multisite settings.
Defaults to single-site settings.
"""
if hasattr(settings, 'WAGALYTICS_SETTINGS'):
if site_id is None:
site_id = Site.find_for_request(request).id
wagalytics_settings = settings.WAGALYTICS_SETTINGS[site_id]
if wagalytics_settings.get('GA_KEY_CONTENT', None):
access_token = get_access_token_from_str(wagalytics_settings['GA_KEY_CONTENT'])
elif wagalytics_settings.get('GA_KEY_FILEPATH', None):
access_token = get_access_token(wagalytics_settings['GA_KEY_FILEPATH'])
else:
return HttpResponseForbidden()
else:
if (hasattr(settings, 'GA_KEY_CONTENT') and settings.GA_KEY_CONTENT != ''):
access_token = get_access_token_from_str(settings.GA_KEY_CONTENT)
elif (hasattr(settings, 'GA_KEY_FILEPATH') and settings.GA_KEY_FILEPATH != ''):
access_token = get_access_token(settings.GA_KEY_FILEPATH)
else:
return HttpResponseForbidden()
return HttpResponse(access_token)
def dashboard(request, site_id=None):
"""Display the Wagalytics Dashboard.
If a site_id is provided, the dashboard will display an instance of a multi site.
"""
# If there is no site_id provided in the URL but WAGALYTICS_SETTINGS have been set,
# Redirect the viewer to the site main site.
# Default redirect will be to the current site they are. ie. ^analytics/dashboard/2/$
if not site_id and (hasattr(settings, 'WAGALYTICS_SETTINGS') and len(settings.WAGALYTICS_SETTINGS) > 0):
# This site has multi-site wagalytics enabled.
# Redirect user to ^analytics/dashboard/{site_id}/$
return redirect('wagalytics_site_dashboard', site_id=Site.find_for_request(request).id)
initial_start_date = (timezone.now() - datetime.timedelta(days=30)).strftime("%Y-%m-%d")
ga_view_id = None
if site_id:
# Multisite analytics URL is being used.
# The URL being used looks something like this: ^/analytics/dashboard/2/$
# Look for the site object, or 404.
site = get_object_or_404(Site, id=site_id)
# Check for wagtail.contrib.settings app. Without it, the SiteSwitcher is not available.
if 'wagtail.contrib.settings' not in settings.INSTALLED_APPS:
display_message = "You must enable the Wagtail Site Settings app for " \
"Multisite Wagalytics to work properly."
messages.error(request, display_message)
# Check for WAGALYTICS_SETTINGS
if not hasattr(settings, 'WAGALYTICS_SETTINGS'):
# Has no WAGALYTICS_SETTINGS at all
messages.error(request, "You are missing Wagalytics Multisite settings.")
elif not settings.WAGALYTICS_SETTINGS[site.id]:
# Has WAGALYTICS_SETTINGS but doesn't have settings for this specific site.
display_message = "You have Wagalytics Multisite settings, but not " \
"for this site. Please add your settings for this site."
messages.error(request, display_message)
else:
# Has WAGALYTICS_SETTINGS for this specific site.
# Assign WAGALYTICS_SETTINGS[site_id]['GA_VIEW_ID] to ga_view_id for local use
ga_view_id = settings.WAGALYTICS_SETTINGS[site.id]['GA_VIEW_ID']
else:
# The regular ^analytics/dashboard/$ url is being viewed.
site = Site.objects.get(hostname=Site.find_for_request(request).hostname)
try:
ga_view_id = settings.GA_VIEW_ID
except AttributeError:
display_message = "You are missing your GA_VIEW_ID setting. Your " \
"analytics dashboard won't load without this setting."
messages.error(request, display_message)
if not hasattr(settings, 'GA_KEY_FILEPATH') and not hasattr(settings, 'GA_KEY_CONTENT'):
display_message = "You are missing your GA_KEY_FILEPATH or your "\
"GA_KEY_CONTENT setting."
messages.error(request, display_message)
# Check if a SiteSwitcher is required and add it. Otherwise return None.
# SiteSwitcher is disabled by default.
site_switcher = None
if Site.objects.count() > 1 and hasattr(settings, 'WAGALYTICS_SETTINGS'):
site_switcher = SiteSwitchForm(site, Site)
return render(request, 'wagalytics/dashboard.html', {
'ga_view_id': ga_view_id,
'initial_start_date': initial_start_date,
'site_switcher': site_switcher,
'site_id': site.id,
})
def export(request):
"""Export the data in the current view."""
# Get JSON string posted to `data`
raw_data = request.POST.get('data')
# Reject a request without data
if not raw_data:
return HttpResponseBadRequest()
# Convert JSON to a Python dict
data = json.loads(raw_data)
# Clean up session data
for n in data["sessions"]:
# Convert dates into datetime.date objects
n[0] = datetime.datetime.strptime(n[0], '%Y%m%d').strftime("%Y-%m-%d")
# Convert session counts into integers
n[2] = int(n[2])
# Second key is just the index, which isn't needed
del n[1]
# Clean up referrers data
for n in data["referrers"]:
# Convert counts into integers
n[1] = int(n[1])
# Format spreadsheet file
ods = OrderedDict()
ods["Sessions"] = [["Date", "Sessions"]] + data["sessions"]
ods["Popular Content"] = [["Page URL", "Views"]] + data["pages"]
ods["Top Referrers"] = [["Source", "Views"]] + data["referrers"]
# Save the spreadsheet into memory
io = BytesIO()
save_data(io, ods)
# Set response metadata
response = HttpResponse(content_type='application/vnd.oasis.opendocument.spreadsheet')
response['Content-Disposition'] = 'attachment; filename="wagalytics.ods"'
# Write spreadsheet into response
response.write(io.getvalue())
return response
================================================
FILE: wagalytics/wagtail_hooks.py
================================================
from django.utils.translation import ugettext_lazy as _
try:
from wagtail.core import hooks
from wagtail.admin.menu import MenuItem
except ImportError: # fallback for Wagtail <2.0
from wagtail.wagtailcore import hooks
from wagtail.wagtailadmin.menu import MenuItem
try:
from django.urls import re_path, include
except ImportError: # fallback for Django <2.0
from django.conf.urls import url as re_path
from django.conf.urls import include
try:
from django.urls import reverse
except ImportError: # fallback for Django <1.9
from django.core.urlresolvers import reverse
from . import urls
from . import views
@hooks.register('register_admin_urls')
def register_admin_urls():
return [
re_path(r'^analytics/', include(urls)),
]
@hooks.register('register_admin_menu_item')
def register_styleguide_menu_item():
return MenuItem(
_('Analytics'),
reverse('wagalytics_dashboard'),
classnames='icon icon-fa-bar-chart',
order=1000
)