aboutsummaryrefslogtreecommitdiff
path: root/public/javascripts
diff options
context:
space:
mode:
Diffstat (limited to 'public/javascripts')
-rw-r--r--public/javascripts/autocomplete.js46
-rw-r--r--public/javascripts/bundle.js1753
-rw-r--r--public/javascripts/favorite.js2
-rw-r--r--public/javascripts/main.bak.js244
-rw-r--r--public/javascripts/main.js54
-rw-r--r--public/javascripts/schedule.js31
-rw-r--r--public/javascripts/scrollSnap.js14
-rw-r--r--public/javascripts/search.js27
-rw-r--r--public/javascripts/url.js67
-rw-r--r--public/javascripts/zoom.js30
10 files changed, 459 insertions, 1809 deletions
diff --git a/public/javascripts/autocomplete.js b/public/javascripts/autocomplete.js
index 71fb17d..61f400a 100644
--- a/public/javascripts/autocomplete.js
+++ b/public/javascripts/autocomplete.js
@@ -2,8 +2,8 @@ const EventEmitter = require('events')
const self = new EventEmitter()
-self._items = []
-self._selectedItemIndex = -1
+self._users = []
+self._selectedUserIndex = -1
self._nodes = {
search: document.querySelector('#search'),
@@ -11,63 +11,63 @@ self._nodes = {
autocomplete: document.querySelector('.autocomplete')
}
-self.getSelectedItem = function () {
+self.getSelectedUser = function () {
if (self.getItems() === []) return
- if (self.getSelectedItemIndex() === -1) {
+ if (self.getSelectedUserIndex() === -1) {
return self.getItems()[0]
} else {
- return self.getItems()[self.getSelectedItemIndex()]
+ return self.getItems()[self.getSelectedUserIndex()]
}
}
-self.getSelectedItemIndex = function () {
- return self._selectedItemIndex
+self.getSelectedUserIndex = function () {
+ return self._selectedUserIndex
}
self.getItems = function () {
- return self._items
+ return self._users
}
self.removeAllItems = function () {
while (self._nodes.autocomplete.firstChild) {
self._nodes.autocomplete.removeChild(self._nodes.autocomplete.firstChild)
}
- self._items = []
- self._selectedItemIndex = -1
+ self._users = []
+ self._selectedUserIndex = -1
}
-self.addItem = function (item) {
+self.addItem = function (user) {
const listItem = document.createElement('li')
- listItem.textContent = item.value
+ listItem.textContent = user.value
self._nodes.autocomplete.appendChild(listItem)
- self._items.push(item)
+ self._users.push(user)
}
self._moveSelected = function (shift) {
- if (self._selectedItemIndex + shift >= self.getItems().length) {
- self._selectedItemIndex = -1
- } else if (self._selectedItemIndex + shift < -1) {
- self._selectedItemIndex = self.getItems().length - 1
+ if (self._selectedUserIndex + shift >= self.getItems().length) {
+ self._selectedUserIndex = -1
+ } else if (self._selectedUserIndex + shift < -1) {
+ self._selectedUserIndex = self.getItems().length - 1
} else {
- self._selectedItemIndex += shift
+ self._selectedUserIndex += shift
}
for (let i = 0; i < self.getItems().length; i++) {
self._nodes.autocomplete.children[i].classList.remove('selected')
}
- if (self._selectedItemIndex >= 0) {
+ if (self._selectedUserIndex >= 0) {
self._nodes.autocomplete
- .children[self._selectedItemIndex].classList.add('selected')
+ .children[self._selectedUserIndex].classList.add('selected')
}
}
self._handleItemClick = function (event) {
if (!self._nodes.autocomplete.contains(event.target)) return
- const itemIndex = Array.prototype.indexOf
+ const userIndex = Array.prototype.indexOf
.call(self._nodes.autocomplete.children, event.target)
- self._selectedItemIndex = itemIndex
- self.emit('select', self.getSelectedItem())
+ self._selectedUserIndex = userIndex
+ self.emit('select', self.getSelectedUser())
}
self._handleKeydown = function (event) {
diff --git a/public/javascripts/bundle.js b/public/javascripts/bundle.js
index 427fb9b..25695a4 100644
--- a/public/javascripts/bundle.js
+++ b/public/javascripts/bundle.js
@@ -1,1497 +1,256 @@
-(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// 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.
-
-function EventEmitter() {
- this._events = this._events || {};
- this._maxListeners = this._maxListeners || undefined;
-}
-module.exports = EventEmitter;
-
-// Backwards-compat with node 0.10.x
-EventEmitter.EventEmitter = EventEmitter;
-
-EventEmitter.prototype._events = undefined;
-EventEmitter.prototype._maxListeners = undefined;
-
-// By default EventEmitters will print a warning if more than 10 listeners are
-// added to it. This is a useful default which helps finding memory leaks.
-EventEmitter.defaultMaxListeners = 10;
-
-// Obviously not all Emitters should be limited to 10. This function allows
-// that to be increased. Set to zero for unlimited.
-EventEmitter.prototype.setMaxListeners = function(n) {
- if (!isNumber(n) || n < 0 || isNaN(n))
- throw TypeError('n must be a positive number');
- this._maxListeners = n;
- return this;
-};
-
-EventEmitter.prototype.emit = function(type) {
- var er, handler, len, args, i, listeners;
-
- if (!this._events)
- this._events = {};
-
- // If there is no 'error' event listener then throw.
- if (type === 'error') {
- if (!this._events.error ||
- (isObject(this._events.error) && !this._events.error.length)) {
- er = arguments[1];
- if (er instanceof Error) {
- throw er; // Unhandled 'error' event
- } else {
- // At least give some kind of context to the user
- var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
- err.context = er;
- throw err;
- }
- }
- }
-
- handler = this._events[type];
-
- if (isUndefined(handler))
- return false;
-
- if (isFunction(handler)) {
- switch (arguments.length) {
- // fast cases
- case 1:
- handler.call(this);
- break;
- case 2:
- handler.call(this, arguments[1]);
- break;
- case 3:
- handler.call(this, arguments[1], arguments[2]);
- break;
- // slower
- default:
- args = Array.prototype.slice.call(arguments, 1);
- handler.apply(this, args);
- }
- } else if (isObject(handler)) {
- args = Array.prototype.slice.call(arguments, 1);
- listeners = handler.slice();
- len = listeners.length;
- for (i = 0; i < len; i++)
- listeners[i].apply(this, args);
- }
-
- return true;
-};
-
-EventEmitter.prototype.addListener = function(type, listener) {
- var m;
-
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- if (!this._events)
- this._events = {};
-
- // To avoid recursion in the case that type === "newListener"! Before
- // adding it to the listeners, first emit "newListener".
- if (this._events.newListener)
- this.emit('newListener', type,
- isFunction(listener.listener) ?
- listener.listener : listener);
-
- if (!this._events[type])
- // Optimize the case of one listener. Don't need the extra array object.
- this._events[type] = listener;
- else if (isObject(this._events[type]))
- // If we've already got an array, just append.
- this._events[type].push(listener);
- else
- // Adding the second element, need to change to array.
- this._events[type] = [this._events[type], listener];
-
- // Check for listener leak
- if (isObject(this._events[type]) && !this._events[type].warned) {
- if (!isUndefined(this._maxListeners)) {
- m = this._maxListeners;
- } else {
- m = EventEmitter.defaultMaxListeners;
- }
-
- if (m && m > 0 && this._events[type].length > m) {
- this._events[type].warned = true;
- console.error('(node) warning: possible EventEmitter memory ' +
- 'leak detected. %d listeners added. ' +
- 'Use emitter.setMaxListeners() to increase limit.',
- this._events[type].length);
- if (typeof console.trace === 'function') {
- // not supported in IE 10
- console.trace();
- }
- }
- }
-
- return this;
-};
-
-EventEmitter.prototype.on = EventEmitter.prototype.addListener;
-
-EventEmitter.prototype.once = function(type, listener) {
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- var fired = false;
-
- function g() {
- this.removeListener(type, g);
-
- if (!fired) {
- fired = true;
- listener.apply(this, arguments);
- }
- }
-
- g.listener = listener;
- this.on(type, g);
-
- return this;
-};
-
-// emits a 'removeListener' event iff the listener was removed
-EventEmitter.prototype.removeListener = function(type, listener) {
- var list, position, length, i;
-
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- if (!this._events || !this._events[type])
- return this;
-
- list = this._events[type];
- length = list.length;
- position = -1;
-
- if (list === listener ||
- (isFunction(list.listener) && list.listener === listener)) {
- delete this._events[type];
- if (this._events.removeListener)
- this.emit('removeListener', type, listener);
-
- } else if (isObject(list)) {
- for (i = length; i-- > 0;) {
- if (list[i] === listener ||
- (list[i].listener && list[i].listener === listener)) {
- position = i;
- break;
- }
- }
-
- if (position < 0)
- return this;
-
- if (list.length === 1) {
- list.length = 0;
- delete this._events[type];
- } else {
- list.splice(position, 1);
- }
-
- if (this._events.removeListener)
- this.emit('removeListener', type, listener);
- }
-
- return this;
-};
-
-EventEmitter.prototype.removeAllListeners = function(type) {
- var key, listeners;
-
- if (!this._events)
- return this;
-
- // not listening for removeListener, no need to emit
- if (!this._events.removeListener) {
- if (arguments.length === 0)
- this._events = {};
- else if (this._events[type])
- delete this._events[type];
- return this;
- }
-
- // emit removeListener for all listeners on all events
- if (arguments.length === 0) {
- for (key in this._events) {
- if (key === 'removeListener') continue;
- this.removeAllListeners(key);
- }
- this.removeAllListeners('removeListener');
- this._events = {};
- return this;
- }
-
- listeners = this._events[type];
-
- if (isFunction(listeners)) {
- this.removeListener(type, listeners);
- } else if (listeners) {
- // LIFO order
- while (listeners.length)
- this.removeListener(type, listeners[listeners.length - 1]);
- }
- delete this._events[type];
-
- return this;
-};
-
-EventEmitter.prototype.listeners = function(type) {
- var ret;
- if (!this._events || !this._events[type])
- ret = [];
- else if (isFunction(this._events[type]))
- ret = [this._events[type]];
- else
- ret = this._events[type].slice();
- return ret;
-};
-
-EventEmitter.prototype.listenerCount = function(type) {
- if (this._events) {
- var evlistener = this._events[type];
-
- if (isFunction(evlistener))
- return 1;
- else if (evlistener)
- return evlistener.length;
- }
- return 0;
-};
-
-EventEmitter.listenerCount = function(emitter, type) {
- return emitter.listenerCount(type);
-};
-
-function isFunction(arg) {
- return typeof arg === 'function';
-}
-
-function isNumber(arg) {
- return typeof arg === 'number';
-}
-
-function isObject(arg) {
- return typeof arg === 'object' && arg !== null;
-}
-
-function isUndefined(arg) {
- return arg === void 0;
-}
-
-},{}],2:[function(require,module,exports){
-/*
- * Fuzzy
- * https://github.com/myork/fuzzy
- *
- * Copyright (c) 2012 Matt York
- * Licensed under the MIT license.
- */
-
-(function() {
-
-var root = this;
-
-var fuzzy = {};
-
-// Use in node or in browser
-if (typeof exports !== 'undefined') {
- module.exports = fuzzy;
-} else {
- root.fuzzy = fuzzy;
-}
-
-// Return all elements of `array` that have a fuzzy
-// match against `pattern`.
-fuzzy.simpleFilter = function(pattern, array) {
- return array.filter(function(str) {
- return fuzzy.test(pattern, str);
- });
-};
-
-// Does `pattern` fuzzy match `str`?
-fuzzy.test = function(pattern, str) {
- return fuzzy.match(pattern, str) !== null;
-};
-
-// If `pattern` matches `str`, wrap each matching character
-// in `opts.pre` and `opts.post`. If no match, return null
-fuzzy.match = function(pattern, str, opts) {
- opts = opts || {};
- var patternIdx = 0
- , result = []
- , len = str.length
- , totalScore = 0
- , currScore = 0
- // prefix
- , pre = opts.pre || ''
- // suffix
- , post = opts.post || ''
- // String to compare against. This might be a lowercase version of the
- // raw string
- , compareString = opts.caseSensitive && str || str.toLowerCase()
- , ch;
-
- pattern = opts.caseSensitive && pattern || pattern.toLowerCase();
-
- // For each character in the string, either add it to the result
- // or wrap in template if it's the next string in the pattern
- for(var idx = 0; idx < len; idx++) {
- ch = str[idx];
- if(compareString[idx] === pattern[patternIdx]) {
- ch = pre + ch + post;
- patternIdx += 1;
-
- // consecutive characters should increase the score more than linearly
- currScore += 1 + currScore;
- } else {
- currScore = 0;
- }
- totalScore += currScore;
- result[result.length] = ch;
- }
-
- // return rendered string if we have a match for every char
- if(patternIdx === pattern.length) {
- // if the string is an exact match with pattern, totalScore should be maxed
- totalScore = (compareString === pattern) ? Infinity : totalScore;
- return {rendered: result.join(''), score: totalScore};
- }
-
- return null;
-};
-
-// The normal entry point. Filters `arr` for matches against `pattern`.
-// It returns an array with matching values of the type:
-//
-// [{
-// string: '<b>lah' // The rendered string
-// , index: 2 // The index of the element in `arr`
-// , original: 'blah' // The original element in `arr`
-// }]
-//
-// `opts` is an optional argument bag. Details:
-//
-// opts = {
-// // string to put before a matching character
-// pre: '<b>'
-//
-// // string to put after matching character
-// , post: '</b>'
-//
-// // Optional function. Input is an entry in the given arr`,
-// // output should be the string to test `pattern` against.
-// // In this example, if `arr = [{crying: 'koala'}]` we would return
-// // 'koala'.
-// , extract: function(arg) { return arg.crying; }
-// }
-fuzzy.filter = function(pattern, arr, opts) {
- if(!arr || arr.length === 0) {
- return [];
- }
- if (typeof pattern !== 'string') {
- return arr;
- }
- opts = opts || {};
- return arr
- .reduce(function(prev, element, idx, arr) {
- var str = element;
- if(opts.extract) {
- str = opts.extract(element);
- }
- var rendered = fuzzy.match(pattern, str, opts);
- if(rendered != null) {
- prev[prev.length] = {
- string: rendered.rendered
- , score: rendered.score
- , index: idx
- , original: element
- };
- }
- return prev;
- }, [])
-
- // Sort by score. Browsers are inconsistent wrt stable/unstable
- // sorting, so force stable by using the index in the case of tie.
- // See http://ofb.net/~sethml/is-sort-stable.html
- .sort(function(a,b) {
- var compare = b.score - a.score;
- if(compare) return compare;
- return a.index - b.index;
- });
-};
-
-
-}());
-
-
-},{}],3:[function(require,module,exports){
-/* This program is free software. It comes without any warranty, to
- * the extent permitted by applicable law. You can redistribute it
- * and/or modify it under the terms of the Do What The Fuck You Want
- * To Public License, Version 2, as published by Sam Hocevar. See
- * http://www.wtfpl.net/ for more details. */
-'use strict';
-module.exports = leftPad;
-
-var cache = [
- '',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' '
-];
-
-function leftPad (str, len, ch) {
- // convert `str` to `string`
- str = str + '';
- // `len` is the `pad`'s length now
- len = len - str.length;
- // doesn't need to pad
- if (len <= 0) return str;
- // `ch` defaults to `' '`
- if (!ch && ch !== 0) ch = ' ';
- // convert `ch` to `string`
- ch = ch + '';
- // cache common use cases
- if (ch === ' ' && len < 10) return cache[len] + str;
- // `pad` starts with an empty string
- var pad = '';
- // loop
- while (true) {
- // add `ch` to `pad` if `len` is odd
- if (len & 1) pad += ch;
- // divide `len` by 2, ditch the remainder
- len >>= 1;
- // "double" the `ch` so this operation count grows logarithmically on `len`
- // each time `ch` is "doubled", the `len` would need to be "doubled" too
- // similar to finding a value in binary search tree, hence O(log(n))
- if (len) ch += ch;
- // `len` is 0, exit the loop
- else break;
- }
- // pad `str`!
- return pad + str;
-}
-
-},{}],4:[function(require,module,exports){
-/*
- * smoothscroll polyfill - v0.3.5
- * https://iamdustan.github.io/smoothscroll
- * 2016 (c) Dustan Kasten, Jeremias Menichelli - MIT License
- */
-
-(function(w, d, undefined) {
- 'use strict';
-
- /*
- * aliases
- * w: window global object
- * d: document
- * undefined: undefined
- */
-
- // polyfill
- function polyfill() {
- // return when scrollBehavior interface is supported
- if ('scrollBehavior' in d.documentElement.style) {
- return;
- }
-
- /*
- * globals
- */
- var Element = w.HTMLElement || w.Element;
- var SCROLL_TIME = 468;
-
- /*
- * object gathering original scroll methods
- */
- var original = {
- scroll: w.scroll || w.scrollTo,
- scrollBy: w.scrollBy,
- elScroll: Element.prototype.scroll || scrollElement,
- scrollIntoView: Element.prototype.scrollIntoView
- };
-
- /*
- * define timing method
- */
- var now = w.performance && w.performance.now
- ? w.performance.now.bind(w.performance) : Date.now;
-
- /**
- * changes scroll position inside an element
- * @method scrollElement
- * @param {Number} x
- * @param {Number} y
- */
- function scrollElement(x, y) {
- this.scrollLeft = x;
- this.scrollTop = y;
- }
-
- /**
- * returns result of applying ease math function to a number
- * @method ease
- * @param {Number} k
- * @returns {Number}
- */
- function ease(k) {
- return 0.5 * (1 - Math.cos(Math.PI * k));
- }
-
- /**
- * indicates if a smooth behavior should be applied
- * @method shouldBailOut
- * @param {Number|Object} x
- * @returns {Boolean}
- */
- function shouldBailOut(x) {
- if (typeof x !== 'object'
- || x === null
- || x.behavior === undefined
- || x.behavior === 'auto'
- || x.behavior === 'instant') {
- // first arg not an object/null
- // or behavior is auto, instant or undefined
- return true;
- }
-
- if (typeof x === 'object'
- && x.behavior === 'smooth') {
- // first argument is an object and behavior is smooth
- return false;
- }
-
- // throw error when behavior is not supported
- throw new TypeError('behavior not valid');
- }
-
- /**
- * finds scrollable parent of an element
- * @method findScrollableParent
- * @param {Node} el
- * @returns {Node} el
- */
- function findScrollableParent(el) {
- var isBody;
- var hasScrollableSpace;
- var hasVisibleOverflow;
-
- do {
- el = el.parentNode;
-
- // set condition variables
- isBody = el === d.body;
- hasScrollableSpace =
- el.clientHeight < el.scrollHeight ||
- el.clientWidth < el.scrollWidth;
- hasVisibleOverflow =
- w.getComputedStyle(el, null).overflow === 'visible';
- } while (!isBody && !(hasScrollableSpace && !hasVisibleOverflow));
-
- isBody = hasScrollableSpace = hasVisibleOverflow = null;
-
- return el;
- }
-
- /**
- * self invoked function that, given a context, steps through scrolling
- * @method step
- * @param {Object} context
- */
- function step(context) {
- var time = now();
- var value;
- var currentX;
- var currentY;
- var elapsed = (time - context.startTime) / SCROLL_TIME;
-
- // avoid elapsed times higher than one
- elapsed = elapsed > 1 ? 1 : elapsed;
-
- // apply easing to elapsed time
- value = ease(elapsed);
-
- currentX = context.startX + (context.x - context.startX) * value;
- currentY = context.startY + (context.y - context.startY) * value;
-
- context.method.call(context.scrollable, currentX, currentY);
-
- // scroll more if we have not reached our destination
- if (currentX !== context.x || currentY !== context.y) {
- w.requestAnimationFrame(step.bind(w, context));
- }
- }
-
- /**
- * scrolls window with a smooth behavior
- * @method smoothScroll
- * @param {Object|Node} el
- * @param {Number} x
- * @param {Number} y
- */
- function smoothScroll(el, x, y) {
- var scrollable;
- var startX;
- var startY;
- var method;
- var startTime = now();
-
- // define scroll context
- if (el === d.body) {
- scrollable = w;
- startX = w.scrollX || w.pageXOffset;
- startY = w.scrollY || w.pageYOffset;
- method = original.scroll;
- } else {
- scrollable = el;
- startX = el.scrollLeft;
- startY = el.scrollTop;
- method = scrollElement;
- }
-
- // scroll looping over a frame
- step({
- scrollable: scrollable,
- method: method,
- startTime: startTime,
- startX: startX,
- startY: startY,
- x: x,
- y: y
- });
- }
-
- /*
- * ORIGINAL METHODS OVERRIDES
- */
-
- // w.scroll and w.scrollTo
- w.scroll = w.scrollTo = function() {
- // avoid smooth behavior if not required
- if (shouldBailOut(arguments[0])) {
- original.scroll.call(
- w,
- arguments[0].left || arguments[0],
- arguments[0].top || arguments[1]
- );
- return;
- }
-
- // LET THE SMOOTHNESS BEGIN!
- smoothScroll.call(
- w,
- d.body,
- ~~arguments[0].left,
- ~~arguments[0].top
- );
- };
-
- // w.scrollBy
- w.scrollBy = function() {
- // avoid smooth behavior if not required
- if (shouldBailOut(arguments[0])) {
- original.scrollBy.call(
- w,
- arguments[0].left || arguments[0],
- arguments[0].top || arguments[1]
- );
- return;
- }
-
- // LET THE SMOOTHNESS BEGIN!
- smoothScroll.call(
- w,
- d.body,
- ~~arguments[0].left + (w.scrollX || w.pageXOffset),
- ~~arguments[0].top + (w.scrollY || w.pageYOffset)
- );
- };
-
- // Element.prototype.scroll and Element.prototype.scrollTo
- Element.prototype.scroll = Element.prototype.scrollTo = function() {
- // avoid smooth behavior if not required
- if (shouldBailOut(arguments[0])) {
- original.elScroll.call(
- this,
- arguments[0].left || arguments[0],
- arguments[0].top || arguments[1]
- );
- return;
- }
-
- var left = arguments[0].left;
- var top = arguments[0].top;
-
- // LET THE SMOOTHNESS BEGIN!
- smoothScroll.call(
- this,
- this,
- typeof left === 'number' ? left : this.scrollLeft,
- typeof top === 'number' ? top : this.scrollTop
- );
- };
-
- // Element.prototype.scrollBy
- Element.prototype.scrollBy = function() {
- var arg0 = arguments[0];
-
- if (typeof arg0 === 'object') {
- this.scroll({
- left: arg0.left + this.scrollLeft,
- top: arg0.top + this.scrollTop,
- behavior: arg0.behavior
- });
- } else {
- this.scroll(
- this.scrollLeft + arg0,
- this.scrollTop + arguments[1]
- );
- }
- };
-
- // Element.prototype.scrollIntoView
- Element.prototype.scrollIntoView = function() {
- // avoid smooth behavior if not required
- if (shouldBailOut(arguments[0])) {
- original.scrollIntoView.call(
- this,
- arguments[0] === undefined ? true : arguments[0]
- );
- return;
- }
-
- // LET THE SMOOTHNESS BEGIN!
- var scrollableParent = findScrollableParent(this);
- var parentRects = scrollableParent.getBoundingClientRect();
- var clientRects = this.getBoundingClientRect();
-
- if (scrollableParent !== d.body) {
- // reveal element inside parent
- smoothScroll.call(
- this,
- scrollableParent,
- scrollableParent.scrollLeft + clientRects.left - parentRects.left,
- scrollableParent.scrollTop + clientRects.top - parentRects.top
- );
- // reveal parent in viewport
- w.scrollBy({
- left: parentRects.left,
- top: parentRects.top,
- behavior: 'smooth'
- });
- } else {
- // reveal element in viewport
- w.scrollBy({
- left: clientRects.left,
- top: clientRects.top,
- behavior: 'smooth'
- });
- }
- };
- }
-
- if (typeof exports === 'object') {
- // commonjs
- module.exports = { polyfill: polyfill };
- } else {
- // global
- polyfill();
- }
-})(window, document);
-
-},{}],5:[function(require,module,exports){
-'use strict';
-
-/* global ga */
-
-var self = {};
-
-self.send = {};
-
-self.send.search = function (selectedUser, favorite) {
- var hitType = 'event';
-
- var eventCategory = favorite ? 'search fav' : 'search';
-
- var eventAction = void 0;
- switch (selectedUser.type) {
- case 'c':
- eventAction = 'Class';
- break;
- case 't':
- eventAction = 'Teacher';
- break;
- case 'r':
- eventAction = 'Room';
- break;
- case 's':
- eventAction = 'Student';
- break;
- }
-
- var eventLabel = selectedUser.value;
-
- ga(function () {
- ga('send', { hitType: hitType, eventCategory: eventCategory, eventAction: eventAction, eventLabel: eventLabel });
- });
-};
-
-module.exports = self;
-
-},{}],6:[function(require,module,exports){
-'use strict';
-
-var EventEmitter = require('events');
-
-var self = new EventEmitter();
-
-self._items = [];
-self._selectedItemIndex = -1;
-
-self._nodes = {
- search: document.querySelector('#search'),
- input: document.querySelector('input[type="search"]'),
- autocomplete: document.querySelector('.autocomplete')
-};
-
-self.getSelectedItem = function () {
- if (self.getItems() === []) return;
-
- if (self.getSelectedItemIndex() === -1) {
- return self.getItems()[0];
- } else {
- return self.getItems()[self.getSelectedItemIndex()];
- }
-};
-
-self.getSelectedItemIndex = function () {
- return self._selectedItemIndex;
-};
-
-self.getItems = function () {
- return self._items;
-};
-
-self.removeAllItems = function () {
- while (self._nodes.autocomplete.firstChild) {
- self._nodes.autocomplete.removeChild(self._nodes.autocomplete.firstChild);
- }
- self._items = [];
- self._selectedItemIndex = -1;
-};
-
-self.addItem = function (item) {
- var listItem = document.createElement('li');
- listItem.textContent = item.value;
- self._nodes.autocomplete.appendChild(listItem);
- self._items.push(item);
-};
-
-self._moveSelected = function (shift) {
- if (self._selectedItemIndex + shift >= self.getItems().length) {
- self._selectedItemIndex = -1;
- } else if (self._selectedItemIndex + shift < -1) {
- self._selectedItemIndex = self.getItems().length - 1;
- } else {
- self._selectedItemIndex += shift;
- }
-
- for (var i = 0; i < self.getItems().length; i++) {
- self._nodes.autocomplete.children[i].classList.remove('selected');
- }
- if (self._selectedItemIndex >= 0) {
- self._nodes.autocomplete.children[self._selectedItemIndex].classList.add('selected');
- }
-};
-
-self._handleItemClick = function (event) {
- if (!self._nodes.autocomplete.contains(event.target)) return;
- var itemIndex = Array.prototype.indexOf.call(self._nodes.autocomplete.children, event.target);
- self._selectedItemIndex = itemIndex;
- self.emit('select', self.getSelectedItem());
-};
-
-self._handleKeydown = function (event) {
- if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
- event.preventDefault();
- if (event.key === 'ArrowDown') {
- self._moveSelected(1);
- } else if (event.key === 'ArrowUp') {
- self._moveSelected(-1);
- }
- }
-};
-
-self._nodes.autocomplete.addEventListener('click', self._handleItemClick);
-self._nodes.input.addEventListener('keydown', self._handleKeydown);
-
-module.exports = self;
-
-},{"events":1}],7:[function(require,module,exports){
-'use strict';
-
-var self = {};
-
-self.isIE = navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0;
-
-if (self.isIE) {
- self.inputEvent = 'textinput';
-} else {
- self.inputEvent = 'input';
-}
-
-module.exports = self;
-
-},{}],8:[function(require,module,exports){
-'use strict';
-
-/* global USERS */
-
-var EventEmitter = require('events');
-
-var self = new EventEmitter();
-
-self._nodes = {
- toggle: document.querySelector('.fav')
-};
-
-self.get = function () {
- try {
- var localStorageUser = JSON.parse(window.localStorage.getItem('fav'));
- if (localStorageUser == null) return;
-
- var correctedUser = USERS.filter(function (user) {
- return user.type === localStorageUser.type && user.value === localStorageUser.value;
- })[0];
- return correctedUser;
- } catch (e) {
- self.delete();
- return;
- }
-};
-
-self.set = function (user) {
- window.localStorage.setItem('fav', JSON.stringify(user));
- self._nodes.innerHTML = '&#xE838;';
-};
-
-self.delete = function () {
- window.localStorage.removeItem('fav');
-};
-
-self.updateDom = function (isFavorite) {
- if (isFavorite) {
- self._nodes.toggle.innerHTML = '&#xE838;';
- } else {
- self._nodes.toggle.innerHTML = '&#xE83A';
- }
-};
-
-self.update = function (selectedUser) {
- var currentUser = self.get();
-
- if (currentUser == null) {
- self.updateDom(false);
- return;
- }
-
- var isEqual = currentUser.type === selectedUser.type && currentUser.index === selectedUser.index;
-
- self.updateDom(isEqual);
-};
-
-self.toggle = function (selectedUser) {
- var currentUser = self.get();
- var isEqual = currentUser != null && currentUser.type === selectedUser.type && currentUser.index === selectedUser.index;
-
- if (isEqual) {
- self.delete();
- self.updateDom(false);
- } else {
- self.set(selectedUser);
- self.updateDom(true);
- }
-};
-
-self._handleClick = function () {
- self.emit('click');
-};
-
-self._nodes.toggle.addEventListener('click', self._handleClick);
-
-module.exports = self;
-
-},{"events":1}],9:[function(require,module,exports){
-'use strict';
-
-/* global FLAGS */
-
-var self = {};
-
-self._nodes = {
- input: document.querySelector('input[type="search"]'),
- overflowButton: document.querySelector('#overflow-button')
-};
-
-self._shouldCheck = function () {
- return FLAGS.indexOf('NO_FEATURE_DETECT') === -1;
-};
-
-self._redirect = function () {
- window.location.href = 'http://www.meetingpointmco.nl/Roosters-AL/doc/';
-};
-
-self.check = function () {
- if (!self._shouldCheck()) return;
-
- window.onerror = self._redirect;
-
- if (self._nodes.input.getClientRects()[0].top !== self._nodes.overflowButton.getClientRects()[0].top) {
- self._redirect();
- }
-};
-
-module.exports = self;
-
-},{}],10:[function(require,module,exports){
-'use strict';
-
-var browserFixToolkit = require('./browserFixToolkit');
-
-var self = {};
-
-self._nodes = {
- input: document.querySelector('input[type="search"]')
-};
-
-self.isShown = false;
-
-self.show = function () {
- document.body.classList.add('no-input');
- self.isShown = true;
-};
-
-self.hide = function () {
- document.body.classList.remove('no-input');
- self.isShown = false;
-};
-
-self._nodes.input.addEventListener(browserFixToolkit.inputEvent, self.hide);
-
-module.exports = self;
-
-},{"./browserFixToolkit":7}],11:[function(require,module,exports){
-'use strict';
-
-require('./featureDetect').check();
-
-var frontpage = require('./frontpage');
-var search = require('./search');
-var schedule = require('./schedule');
-var weekSelector = require('./weekSelector');
-var favorite = require('./favorite');
-var scrollSnap = require('./scrollSnap');
-var analytics = require('./analytics');
-
-var state = {};
-
-window.state = state;
-window.require = require;
-
-frontpage.show();
-weekSelector.updateCurrentWeek();
-scrollSnap.startListening();
-
-if (favorite.get() != null) {
- state.selectedItem = favorite.get();
- favorite.update(state.selectedItem);
- analytics.send.search(state.selectedItem, true);
- schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedItem);
-} else {
- search.focus();
-}
-
-search.on('search', function (selectedItem) {
- state.selectedItem = selectedItem;
- favorite.update(state.selectedItem);
- analytics.send.search(state.selectedItem);
- schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedItem);
-});
-
-weekSelector.on('weekChanged', function (newWeek) {
- analytics.send.search(state.selectedItem);
- schedule.viewItem(newWeek, state.selectedItem);
-});
-
-favorite.on('click', function () {
- favorite.toggle(state.selectedItem);
-});
-
-document.body.style.opacity = 1;
-
-},{"./analytics":5,"./favorite":8,"./featureDetect":9,"./frontpage":10,"./schedule":12,"./scrollSnap":13,"./search":14,"./weekSelector":15}],12:[function(require,module,exports){
-'use strict';
-
-/* global VALID_WEEK_NUMBERS */
-
-var EventEmitter = require('events');
-var leftPad = require('left-pad');
-var search = require('./search');
-
-var self = new EventEmitter();
-
-self._nodes = {
- schedule: document.querySelector('#schedule')
-};
-
-self._parseMeetingpointHTML = function (htmlStr) {
- var html = document.createElement('html');
- html.innerHTML = htmlStr;
- var centerNode = html.querySelector('center');
- return centerNode;
-};
-
-self._handleLoad = function (event) {
- var request = event.target;
- if (request.status < 200 || request.status >= 400) {
- self._handleError(event);
- return;
- }
- var document = self._parseMeetingpointHTML(request.response);
- self._removeChilds();
- self._nodes.schedule.appendChild(document);
- self._nodes.schedule.classList.remove('error');
- self.emit('load');
-};
-
-self._handleError = function (event) {
- var request = event.target;
- var error = void 0;
- if (request.status === 404) {
- error = 'Sorry, er is (nog) geen rooster voor deze week.';
- } else {
- error = 'Sorry, er is iets mis gegaan tijdens het laden van deze week.';
- }
- self._removeChilds();
- self._nodes.schedule.textContent = error;
- self._nodes.schedule.classList.add('error');
- self.emit('load');
-};
-
-self._getURLOfUsers = function (week, type, index) {
- var id = index + 1;
- return '//' + window.location.host + '/meetingpointProxy/Roosters-AL%2Fdoc%2Fdagroosters%2F' + leftPad(week, 2, '0') + '%2F' + type + '%2F' + type + leftPad(id, 5, '0') + '.htm';
-};
-
-self._removeChilds = function () {
- while (self._nodes.schedule.firstChild) {
- self._nodes.schedule.removeChild(self._nodes.schedule.firstChild);
- }
-};
-
-self.viewItem = function (week, selectedUser) {
- if (VALID_WEEK_NUMBERS.indexOf(week) === -1) {
- self._handleError({ target: { status: 404 } });
- return;
- }
- var url = self._getURLOfUsers(week, selectedUser.type, selectedUser.index);
-
- self._removeChilds();
-
- var request = new window.XMLHttpRequest();
- request.addEventListener('load', self._handleLoad);
- request.addEventListener('error', self._handleError);
- request.open('GET', url, true);
- request.send();
-
- search.updateDom(selectedUser);
-};
-
-module.exports = self;
-
-},{"./search":14,"events":1,"left-pad":3}],13:[function(require,module,exports){
-'use strict';
-
-require('smoothscroll-polyfill').polyfill();
-
-var self = {};
-var schedule = require('./schedule');
-
-self._nodes = {
- search: document.querySelector('#search'),
- weekSelector: document.querySelector('#week-selector')
-};
-
-self._timeoutID = null;
-
-self._getScrollPosition = function () {
- return document.documentElement && document.documentElement.scrollTop || document.body.scrollTop;
-};
-
-self._handleDoneScrolling = function () {
- var scrollPosition = self._getScrollPosition();
- var weekSelectorHeight = self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight;
- if (scrollPosition < weekSelectorHeight && scrollPosition > 0) {
- window.scroll({ top: weekSelectorHeight, left: 0, behavior: 'smooth' });
- }
-};
-
-self._handleScroll = function () {
- if (self._timeoutID != null) window.clearTimeout(self._timeoutID);
- self._timeoutID = window.setTimeout(self._handleDoneScrolling, 500);
-
- var scrollPosition = self._getScrollPosition();
- var weekSelectorHeight = self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight;
- if (scrollPosition >= weekSelectorHeight) {
- document.body.classList.add('week-selector-not-visible');
- } else {
- document.body.classList.remove('week-selector-not-visible');
- }
-};
-
-self._handleWindowResize = function () {
- var weekSelectorHeight = self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight;
- var extraPixelsNeeded = weekSelectorHeight - (document.body.clientHeight - window.innerHeight);
- if (extraPixelsNeeded > 0) {
- document.body.style.marginBottom = extraPixelsNeeded + 'px';
- } else {
- document.body.style.marginBottom = null;
- }
-};
-
-self.startListening = function () {
- window.addEventListener('scroll', self._handleScroll);
-};
-
-schedule.on('load', self._handleWindowResize);
-window.addEventListener('resize', self._handleWindowResize);
-module.exports = self;
-
-},{"./schedule":12,"smoothscroll-polyfill":4}],14:[function(require,module,exports){
-'use strict';
-
-/* global USERS */
-
-var EventEmitter = require('events');
-var fuzzy = require('fuzzy');
-var autocomplete = require('./autocomplete');
-var browserFixToolkit = require('./browserFixToolkit');
-
-var self = new EventEmitter();
-
-self._nodes = {
- search: document.querySelector('#search'),
- input: document.querySelector('input[type="search"]')
-};
-
-self.submit = function () {
- var selectedItem = autocomplete.getSelectedItem();
- if (selectedItem == null) return;
-
- console.log(selectedItem);
-
- self._nodes.input.blur();
- document.body.classList.remove('week-selector-not-visible'); // Safari bug
-
- self.emit('search', selectedItem);
-};
-
-self.updateDom = function (selectedItem) {
- self._nodes.input.value = selectedItem.value;
- autocomplete.removeAllItems();
- document.body.classList.remove('no-input');
- document.body.classList.add('searched');
-};
-
-self.focus = function () {
- self._nodes.input.focus();
-};
-
-self._handleSubmit = function (event) {
- event.preventDefault();
- self.submit();
-};
-
-self._calculate = function (searchTerm) {
- var allResults = fuzzy.filter(searchTerm, USERS, {
- extract: function extract(item) {
- return item.value;
- }
- });
- var firstResults = allResults.slice(0, 7);
-
- var originalResults = firstResults.map(function (result) {
- return result.original;
- });
-
- return originalResults;
-};
-
-self._handleTextUpdate = function () {
- var results = self._calculate(self._nodes.input.value);
-
- autocomplete.removeAllItems();
- for (var i = 0; i < results.length; i++) {
- autocomplete.addItem(results[i]);
- }
-};
-
-self._handleFocus = function () {
- self._nodes.input.select();
-};
-
-self._handleBlur = function () {
- // this will removed the selection without drawing focus on it (safari)
- // this will removed selection even when focusing an iframe (chrome)
- var oldValue = self._nodes.value;
- self._nodes.value = '';
- self._nodes.value = oldValue;
-
- // this will hide the keyboard (iOS safari)
- document.activeElement.blur();
-};
-
-autocomplete.on('select', self.submit);
-
-self._nodes.search.addEventListener('submit', self._handleSubmit);
-self._nodes.input.addEventListener('focus', self._handleFocus);
-self._nodes.input.addEventListener('blur', self._handleBlur);
-self._nodes.input.addEventListener(browserFixToolkit.inputEvent, self._handleTextUpdate);
-
-module.exports = self;
-
-},{"./autocomplete":6,"./browserFixToolkit":7,"events":1,"fuzzy":2}],15:[function(require,module,exports){
-'use strict';
-
-var EventEmitter = require('events');
-
-var self = new EventEmitter();
-
-self._nodes = {
- prevButton: document.querySelectorAll('#week-selector button')[0],
- nextButton: document.querySelectorAll('#week-selector button')[1],
- currentWeekNode: document.querySelector('#week-selector .current'),
- currentWeekNormalText: document.querySelector('#week-selector .current .no-print'),
- currentWeekPrintText: document.querySelector('#week-selector .current .print')
-};
-
-self._weekOffset = 0;
-
-// copied from http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/untisscripts.js,
-// were using the same code as they do to be sure that we always get the same
-// week number.
-self.getCurrentWeek = function (target) {
- var dayNr = (target.getDay() + 6) % 7;
- target.setDate(target.getDate() - dayNr + 3);
- var firstThursday = target.valueOf();
- target.setMonth(0, 1);
- if (target.getDay() !== 4) {
- target.setMonth(0, 1 + (4 - target.getDay() + 7) % 7);
- }
-
- return 1 + Math.ceil((firstThursday - target) / 604800000);
-};
-
-self.getSelectedWeek = function () {
- var now = new Date();
- var targetDate = new Date(now.getTime() + self._weekOffset * 604800 * 1000 + 86400 * 1000);
- return self.getCurrentWeek(targetDate);
-};
-
-self.updateCurrentWeek = function () {
- var selectedWeekNumber = self.getSelectedWeek();
- if (self.getCurrentWeek(new Date()) !== selectedWeekNumber) {
- self._nodes.currentWeekNode.classList.add('changed');
- } else {
- self._nodes.currentWeekNode.classList.remove('changed');
- }
- self.updateDom();
- self.emit('weekChanged', selectedWeekNumber);
-};
-
-self.updateDom = function () {
- var selectedWeekNumber = self.getSelectedWeek();
- var isSunday = new Date().getDay() === 0;
- var humanReadableWeek = null;
- if (isSunday) {
- switch (self._weekOffset) {
- case 0:
- humanReadableWeek = 'Aanstaande week';
- break;
- case 1:
- humanReadableWeek = 'Volgende week';
- break;
- case -1:
- humanReadableWeek = 'Afgelopen week';
- break;
- }
- } else {
- switch (self._weekOffset) {
- case 0:
- humanReadableWeek = 'Huidige week';
- break;
- case 1:
- humanReadableWeek = 'Volgende week';
- break;
- case -1:
- humanReadableWeek = 'Vorige week';
- break;
- }
- }
- if (humanReadableWeek != null) {
- self._nodes.currentWeekNormalText.textContent = humanReadableWeek + ' • ' + selectedWeekNumber;
- self._nodes.currentWeekPrintText.textContent = 'Week ' + selectedWeekNumber;
- } else {
- self._nodes.currentWeekNormalText.textContent = 'Week ' + selectedWeekNumber;
- self._nodes.currentWeekPrintText.textContent = 'Week ' + selectedWeekNumber;
- }
-};
-
-self._handlePrevButtonClick = function () {
- self._weekOffset -= 1;
- self.updateCurrentWeek();
-};
-
-self._handleNextButtonClick = function () {
- self._weekOffset += 1;
- self.updateCurrentWeek();
-};
-
-self._nodes.prevButton.addEventListener('click', self._handlePrevButtonClick);
-self._nodes.nextButton.addEventListener('click', self._handleNextButtonClick);
-
-module.exports = self;
-
-},{"events":1}]},{},[11])
-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9mdXp6eS9saWIvZnV6enkuanMiLCJub2RlX21vZHVsZXMvbGVmdC1wYWQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc21vb3Roc2Nyb2xsLXBvbHlmaWxsL2Rpc3Qvc21vb3Roc2Nyb2xsLmpzIiwicHVibGljL2phdmFzY3JpcHRzL2FuYWx5dGljcy5qcyIsInB1YmxpYy9qYXZhc2NyaXB0cy9hdXRvY29tcGxldGUuanMiLCJwdWJsaWMvamF2YXNjcmlwdHMvYnJvd3NlckZpeFRvb2xraXQuanMiLCJwdWJsaWMvamF2YXNjcmlwdHMvZmF2b3JpdGUuanMiLCJwdWJsaWMvamF2YXNjcmlwdHMvZmVhdHVyZURldGVjdC5qcyIsInB1YmxpYy9qYXZhc2NyaXB0cy9mcm9udHBhZ2UuanMiLCJwdWJsaWMvamF2YXNjcmlwdHMvbWFpbi5qcyIsInB1YmxpYy9qYXZhc2NyaXB0cy9zY2hlZHVsZS5qcyIsInB1YmxpYy9qYXZhc2NyaXB0cy9zY3JvbGxTbmFwLmpzIiwicHVibGljL2phdmFzY3JpcHRzL3NlYXJjaC5qcyIsInB1YmxpYy9qYXZhc2NyaXB0cy93ZWVrU2VsZWN0b3IuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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cEI7QUFDQSxPQUFLLGlCQUFMO0FBQ0QsQ0FIRDs7QUFLQSxLQUFLLE1BQUwsQ0FBWSxVQUFaLENBQXVCLGdCQUF2QixDQUF3QyxPQUF4QyxFQUFpRCxLQUFLLHNCQUF0RDtBQUNBLEtBQUssTUFBTCxDQUFZLFVBQVosQ0FBdUIsZ0JBQXZCLENBQXdDLE9BQXhDLEVBQWlELEtBQUssc0JBQXREOztBQUVBLE9BQU8sT0FBUCxHQUFpQixJQUFqQiIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICB0aGlzLl9ldmVudHMgPSB0aGlzLl9ldmVudHMgfHwge307XG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbkV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbi8vIE9idmlvdXNseSBub3QgYWxsIEVtaXR0ZXJzIHNob3VsZCBiZSBsaW1pdGVkIHRvIDEwLiBUaGlzIGZ1bmN0aW9uIGFsbG93c1xuLy8gdGhhdCB0byBiZSBpbmNyZWFzZWQuIFNldCB0byB6ZXJvIGZvciB1bmxpbWl0ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnNldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uKG4pIHtcbiAgaWYgKCFpc051bWJlcihuKSB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ24gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSBuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGVyLCBoYW5kbGVyLCBsZW4sIGFyZ3MsIGksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmICh0eXBlID09PSAnZXJyb3InKSB7XG4gICAgaWYgKCF0aGlzLl9ldmVudHMuZXJyb3IgfHxcbiAgICAgICAgKGlzT2JqZWN0KHRoaXMuX2V2ZW50cy5lcnJvcikgJiYgIXRoaXMuX2V2ZW50cy5lcnJvci5sZW5ndGgpKSB7XG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdVbmNhdWdodCwgdW5zcGVjaWZpZWQgXCJlcnJvclwiIGV2ZW50LiAoJyArIGVyICsgJyknKTtcbiAgICAgICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGhhbmRsZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKGlzVW5kZWZpbmVkKGhhbmRsZXIpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xuICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgLy8gZmFzdCBjYXNlc1xuICAgICAgY2FzZSAxOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgaGFuZGxlci5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QoaGFuZGxlcikpIHtcbiAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICBsaXN0ZW5lcnMgPSBoYW5kbGVyLnNsaWNlKCk7XG4gICAgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbTtcblxuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lclwiLlxuICBpZiAodGhpcy5fZXZlbnRzLm5ld0xpc3RlbmVyKVxuICAgIHRoaXMuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICBpc0Z1bmN0aW9uKGxpc3RlbmVyLmxpc3RlbmVyKSA/XG4gICAgICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICBlbHNlIGlmIChpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pKVxuICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG4gIGVsc2VcbiAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBbdGhpcy5fZXZlbnRzW3R5cGVdLCBsaXN0ZW5lcl07XG5cbiAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkgJiYgIXRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQpIHtcbiAgICBpZiAoIWlzVW5kZWZpbmVkKHRoaXMuX21heExpc3RlbmVycykpIHtcbiAgICAgIG0gPSB0aGlzLl9tYXhMaXN0ZW5lcnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgICB9XG5cbiAgICBpZiAobSAmJiBtID4gMCAmJiB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoID4gbSkge1xuICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCA9IHRydWU7XG4gICAgICBjb25zb2xlLmVycm9yKCcobm9kZSkgd2FybmluZzogcG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSAnICtcbiAgICAgICAgICAgICAgICAgICAgJ2xlYWsgZGV0ZWN0ZWQuICVkIGxpc3RlbmVycyBhZGRlZC4gJyArXG4gICAgICAgICAgICAgICAgICAgICdVc2UgZW1pdHRlci5zZXRNYXhMaXN0ZW5lcnMoKSB0byBpbmNyZWFzZSBsaW1pdC4nLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoKTtcbiAgICAgIGlmICh0eXBlb2YgY29uc29sZS50cmFjZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBub3Qgc3VwcG9ydGVkIGluIElFIDEwXG4gICAgICAgIGNvbnNvbGUudHJhY2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgdmFyIGZpcmVkID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gZygpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGcpO1xuXG4gICAgaWYgKCFmaXJlZCkge1xuICAgICAgZmlyZWQgPSB0cnVlO1xuICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cblxuICBnLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHRoaXMub24odHlwZSwgZyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBlbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWZmIHRoZSBsaXN0ZW5lciB3YXMgcmVtb3ZlZFxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBsaXN0LCBwb3NpdGlvbiwgbGVuZ3RoLCBpO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIGxpc3QgPSB0aGlzLl9ldmVudHNbdHlwZV07XG4gIGxlbmd0aCA9IGxpc3QubGVuZ3RoO1xuICBwb3NpdGlvbiA9IC0xO1xuXG4gIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fFxuICAgICAgKGlzRnVuY3Rpb24obGlzdC5saXN0ZW5lcikgJiYgbGlzdC5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcblxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGxpc3QpKSB7XG4gICAgZm9yIChpID0gbGVuZ3RoOyBpLS0gPiAwOykge1xuICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8XG4gICAgICAgICAgKGxpc3RbaV0ubGlzdGVuZXIgJiYgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgICBsaXN0Lmxlbmd0aCA9IDA7XG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBsaXN0LnNwbGljZShwb3NpdGlvbiwgMSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIga2V5LCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICBpZiAoIXRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxuICAgICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgZWxzZSBpZiAodGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIGZvciAoa2V5IGluIHRoaXMuX2V2ZW50cykge1xuICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgIH1cbiAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICBpZiAoaXNGdW5jdGlvbihsaXN0ZW5lcnMpKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgIC8vIExJRk8gb3JkZXJcbiAgICB3aGlsZSAobGlzdGVuZXJzLmxlbmd0aClcbiAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGggLSAxXSk7XG4gIH1cbiAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgcmV0O1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldCA9IFtdO1xuICBlbHNlIGlmIChpc0Z1bmN0aW9uKHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgcmV0ID0gW3RoaXMuX2V2ZW50c1t0eXBlXV07XG4gIGVsc2VcbiAgICByZXQgPSB0aGlzLl9ldmVudHNbdHlwZV0uc2xpY2UoKTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgaWYgKHRoaXMuX2V2ZW50cykge1xuICAgIHZhciBldmxpc3RlbmVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKGlzRnVuY3Rpb24oZXZsaXN0ZW5lcikpXG4gICAgICByZXR1cm4gMTtcbiAgICBlbHNlIGlmIChldmxpc3RlbmVyKVxuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICB9XG4gIHJldHVybiAwO1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG59O1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG4iLCIvKlxuICogRnV6enlcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9teW9yay9mdXp6eVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMiBNYXR0IFlvcmtcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cbiAqL1xuXG4oZnVuY3Rpb24oKSB7XG5cbnZhciByb290ID0gdGhpcztcblxudmFyIGZ1enp5ID0ge307XG5cbi8vIFVzZSBpbiBub2RlIG9yIGluIGJyb3dzZXJcbmlmICh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdXp6eTtcbn0gZWxzZSB7XG4gIHJvb3QuZnV6enkgPSBmdXp6eTtcbn1cblxuLy8gUmV0dXJuIGFsbCBlbGVtZW50cyBvZiBgYXJyYXlgIHRoYXQgaGF2ZSBhIGZ1enp5XG4vLyBtYXRjaCBhZ2FpbnN0IGBwYXR0ZXJuYC5cbmZ1enp5LnNpbXBsZUZpbHRlciA9IGZ1bmN0aW9uKHBhdHRlcm4sIGFycmF5KSB7XG4gIHJldHVybiBhcnJheS5maWx0ZXIoZnVuY3Rpb24oc3RyKSB7XG4gICAgcmV0dXJuIGZ1enp5LnRlc3QocGF0dGVybiwgc3RyKTtcbiAgfSk7XG59O1xuXG4vLyBEb2VzIGBwYXR0ZXJuYCBmdXp6eSBtYXRjaCBgc3RyYD9cbmZ1enp5LnRlc3QgPSBmdW5jdGlvbihwYXR0ZXJuLCBzdHIpIHtcbiAgcmV0dXJuIGZ1enp5Lm1hdGNoKHBhdHRlcm4sIHN0cikgIT09IG51bGw7XG59O1xuXG4vLyBJZiBgcGF0dGVybmAgbWF0Y2hlcyBgc3RyYCwgd3JhcCBlYWNoIG1hdGNoaW5nIGNoYXJhY3RlclxuLy8gaW4gYG9wdHMucHJlYCBhbmQgYG9wdHMucG9zdGAuIElmIG5vIG1hdGNoLCByZXR1cm4gbnVsbFxuZnV6enkubWF0Y2ggPSBmdW5jdGlvbihwYXR0ZXJuLCBzdHIsIG9wdHMpIHtcbiAgb3B0cyA9IG9wdHMgfHwge307XG4gIHZhciBwYXR0ZXJuSWR4ID0gMFxuICAgICwgcmVzdWx0ID0gW11cbiAgICAsIGxlbiA9IHN0ci5sZW5ndGhcbiAgICAsIHRvdGFsU2NvcmUgPSAwXG4gICAgLCBjdXJyU2NvcmUgPSAwXG4gICAgLy8gcHJlZml4XG4gICAgLCBwcmUgPSBvcHRzLnByZSB8fCAnJ1xuICAgIC8vIHN1ZmZpeFxuICAgICwgcG9zdCA9IG9wdHMucG9zdCB8fCAnJ1xuICAgIC8vIFN0cmluZyB0byBjb21wYXJlIGFnYWluc3QuIFRoaXMgbWlnaHQgYmUgYSBsb3dlcmNhc2UgdmVyc2lvbiBvZiB0aGVcbiAgICAvLyByYXcgc3RyaW5nXG4gICAgLCBjb21wYXJlU3RyaW5nID0gIG9wdHMuY2FzZVNlbnNpdGl2ZSAmJiBzdHIgfHwgc3RyLnRvTG93ZXJDYXNlKClcbiAgICAsIGNoO1xuXG4gIHBhdHRlcm4gPSBvcHRzLmNhc2VTZW5zaXRpdmUgJiYgcGF0dGVybiB8fCBwYXR0ZXJuLnRvTG93ZXJDYXNlKCk7XG5cbiAgLy8gRm9yIGVhY2ggY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcsIGVpdGhlciBhZGQgaXQgdG8gdGhlIHJlc3VsdFxuICAvLyBvciB3cmFwIGluIHRlbXBsYXRlIGlmIGl0J3MgdGhlIG5leHQgc3RyaW5nIGluIHRoZSBwYXR0ZXJuXG4gIGZvcih2YXIgaWR4ID0gMDsgaWR4IDwgbGVuOyBpZHgrKykge1xuICAgIGNoID0gc3RyW2lkeF07XG4gICAgaWYoY29tcGFyZVN0cmluZ1tpZHhdID09PSBwYXR0ZXJuW3BhdHRlcm5JZHhdKSB7XG4gICAgICBjaCA9IHByZSArIGNoICsgcG9zdDtcbiAgICAgIHBhdHRlcm5JZHggKz0gMTtcblxuICAgICAgLy8gY29uc2VjdXRpdmUgY2hhcmFjdGVycyBzaG91bGQgaW5jcmVhc2UgdGhlIHNjb3JlIG1vcmUgdGhhbiBsaW5lYXJseVxuICAgICAgY3VyclNjb3JlICs9IDEgKyBjdXJyU2NvcmU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJTY29yZSA9IDA7XG4gICAgfVxuICAgIHRvdGFsU2NvcmUgKz0gY3VyclNjb3JlO1xuICAgIHJlc3VsdFtyZXN1bHQubGVuZ3RoXSA9IGNoO1xuICB9XG5cbiAgLy8gcmV0dXJuIHJlbmRlcmVkIHN0cmluZyBpZiB3ZSBoYXZlIGEgbWF0Y2ggZm9yIGV2ZXJ5IGNoYXJcbiAgaWYocGF0dGVybklkeCA9PT0gcGF0dGVybi5sZW5ndGgpIHtcbiAgICAvLyBpZiB0aGUgc3RyaW5nIGlzIGFuIGV4YWN0IG1hdGNoIHdpdGggcGF0dGVybiwgdG90YWxTY29yZSBzaG91bGQgYmUgbWF4ZWRcbiAgICB0b3RhbFNjb3JlID0gKGNvbXBhcmVTdHJpbmcgPT09IHBhdHRlcm4pID8gSW5maW5pdHkgOiB0b3RhbFNjb3JlO1xuICAgIHJldHVybiB7cmVuZGVyZWQ6IHJlc3VsdC5qb2luKCcnKSwgc2NvcmU6IHRvdGFsU2NvcmV9O1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vLyBUaGUgbm9ybWFsIGVudHJ5IHBvaW50LiBGaWx0ZXJzIGBhcnJgIGZvciBtYXRjaGVzIGFnYWluc3QgYHBhdHRlcm5gLlxuLy8gSXQgcmV0dXJucyBhbiBhcnJheSB3aXRoIG1hdGNoaW5nIHZhbHVlcyBvZiB0aGUgdHlwZTpcbi8vXG4vLyAgICAgW3tcbi8vICAgICAgICAgc3RyaW5nOiAgICc8Yj5sYWgnIC8vIFRoZSByZW5kZXJlZCBzdHJpbmdcbi8vICAgICAgICwgaW5kZXg6ICAgIDIgICAgICAgIC8vIFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCBpbiBgYXJyYFxuLy8gICAgICAgLCBvcmlnaW5hbDogJ2JsYWgnICAgLy8gVGhlIG9yaWdpbmFsIGVsZW1lbnQgaW4gYGFycmBcbi8vICAgICB9XVxuLy9cbi8vIGBvcHRzYCBpcyBhbiBvcHRpb25hbCBhcmd1bWVudCBiYWcuIERldGFpbHM6XG4vL1xuLy8gICAgb3B0cyA9IHtcbi8vICAgICAgICAvLyBzdHJpbmcgdG8gcHV0IGJlZm9yZSBhIG1hdGNoaW5nIGNoYXJhY3RlclxuLy8gICAgICAgIHByZTogICAgICc8Yj4nXG4vL1xuLy8gICAgICAgIC8vIHN0cmluZyB0byBwdXQgYWZ0ZXIgbWF0Y2hpbmcgY2hhcmFjdGVyXG4vLyAgICAgICwgcG9zdDogICAgJzwvYj4nXG4vL1xuLy8gICAgICAgIC8vIE9wdGlvbmFsIGZ1bmN0aW9uLiBJbnB1dCBpcyBhbiBlbnRyeSBpbiB0aGUgZ2l2ZW4gYXJyYCxcbi8vICAgICAgICAvLyBvdXRwdXQgc2hvdWxkIGJlIHRoZSBzdHJpbmcgdG8gdGVzdCBgcGF0dGVybmAgYWdhaW5zdC5cbi8vICAgICAgICAvLyBJbiB0aGlzIGV4YW1wbGUsIGlmIGBhcnIgPSBbe2NyeWluZzogJ2tvYWxhJ31dYCB3ZSB3b3VsZCByZXR1cm5cbi8vICAgICAgICAvLyAna29hbGEnLlxuLy8gICAgICAsIGV4dHJhY3Q6IGZ1bmN0aW9uKGFyZykgeyByZXR1cm4gYXJnLmNyeWluZzsgfVxuLy8gICAgfVxuZnV6enkuZmlsdGVyID0gZnVuY3Rpb24ocGF0dGVybiwgYXJyLCBvcHRzKSB7XG4gIGlmKCFhcnIgfHwgYXJyLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBpZiAodHlwZW9mIHBhdHRlcm4gIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGFycjtcbiAgfVxuICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgcmV0dXJuIGFyclxuICAgIC5yZWR1Y2UoZnVuY3Rpb24ocHJldiwgZWxlbWVudCwgaWR4LCBhcnIpIHtcbiAgICAgIHZhciBzdHIgPSBlbGVtZW50O1xuICAgICAgaWYob3B0cy5leHRyYWN0KSB7XG4gICAgICAgIHN0ciA9IG9wdHMuZXh0cmFjdChlbGVtZW50KTtcbiAgICAgIH1cbiAgICAgIHZhciByZW5kZXJlZCA9IGZ1enp5Lm1hdGNoKHBhdHRlcm4sIHN0ciwgb3B0cyk7XG4gICAgICBpZihyZW5kZXJlZCAhPSBudWxsKSB7XG4gICAgICAgIHByZXZbcHJldi5sZW5ndGhdID0ge1xuICAgICAgICAgICAgc3RyaW5nOiByZW5kZXJlZC5yZW5kZXJlZFxuICAgICAgICAgICwgc2NvcmU6IHJlbmRlcmVkLnNjb3JlXG4gICAgICAgICAgLCBpbmRleDogaWR4XG4gICAgICAgICAgLCBvcmlnaW5hbDogZWxlbWVudFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHByZXY7XG4gICAgfSwgW10pXG5cbiAgICAvLyBTb3J0IGJ5IHNjb3JlLiBCcm93c2VycyBhcmUgaW5jb25zaXN0ZW50IHdydCBzdGFibGUvdW5zdGFibGVcbiAgICAvLyBzb3J0aW5nLCBzbyBmb3JjZSBzdGFibGUgYnkgdXNpbmcgdGhlIGluZGV4IGluIHRoZSBjYXNlIG9mIHRpZS5cbiAgICAvLyBTZWUgaHR0cDovL29mYi5uZXQvfnNldGhtbC9pcy1zb3J0LXN0YWJsZS5odG1sXG4gICAgLnNvcnQoZnVuY3Rpb24oYSxiKSB7XG4gICAgICB2YXIgY29tcGFyZSA9IGIuc2NvcmUgLSBhLnNjb3JlO1xuICAgICAgaWYoY29tcGFyZSkgcmV0dXJuIGNvbXBhcmU7XG4gICAgICByZXR1cm4gYS5pbmRleCAtIGIuaW5kZXg7XG4gICAgfSk7XG59O1xuXG5cbn0oKSk7XG5cbiIsIi8qIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlLiBJdCBjb21lcyB3aXRob3V0IGFueSB3YXJyYW50eSwgdG9cbiAgICAgKiB0aGUgZXh0ZW50IHBlcm1pdHRlZCBieSBhcHBsaWNhYmxlIGxhdy4gWW91IGNhbiByZWRpc3RyaWJ1dGUgaXRcbiAgICAgKiBhbmQvb3IgbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRG8gV2hhdCBUaGUgRnVjayBZb3UgV2FudFxuICAgICAqIFRvIFB1YmxpYyBMaWNlbnNlLCBWZXJzaW9uIDIsIGFzIHB1Ymxpc2hlZCBieSBTYW0gSG9jZXZhci4gU2VlXG4gICAgICogaHR0cDovL3d3dy53dGZwbC5uZXQvIGZvciBtb3JlIGRldGFpbHMuICovXG4ndXNlIHN0cmljdCc7XG5tb2R1bGUuZXhwb3J0cyA9IGxlZnRQYWQ7XG5cbnZhciBjYWNoZSA9IFtcbiAgJycsXG4gICcgJyxcbiAgJyAgJyxcbiAgJyAgICcsXG4gICcgICAgJyxcbiAgJyAgICAgJyxcbiAgJyAgICAgICcsXG4gICcgICAgICAgJyxcbiAgJyAgICAgICAgJyxcbiAgJyAgICAgICAgICdcbl07XG5cbmZ1bmN0aW9uIGxlZnRQYWQgKHN0ciwgbGVuLCBjaCkge1xuICAvLyBjb252ZXJ0IGBzdHJgIHRvIGBzdHJpbmdgXG4gIHN0ciA9IHN0ciArICcnO1xuICAvLyBgbGVuYCBpcyB0aGUgYHBhZGAncyBsZW5ndGggbm93XG4gIGxlbiA9IGxlbiAtIHN0ci5sZW5ndGg7XG4gIC8vIGRvZXNuJ3QgbmVlZCB0byBwYWRcbiAgaWYgKGxlbiA8PSAwKSByZXR1cm4gc3RyO1xuICAvLyBgY2hgIGRlZmF1bHRzIHRvIGAnICdgXG4gIGlmICghY2ggJiYgY2ggIT09IDApIGNoID0gJyAnO1xuICAvLyBjb252ZXJ0IGBjaGAgdG8gYHN0cmluZ2BcbiAgY2ggPSBjaCArICcnO1xuICAvLyBjYWNoZSBjb21tb24gdXNlIGNhc2VzXG4gIGlmIChjaCA9PT0gJyAnICYmIGxlbiA8IDEwKSByZXR1cm4gY2FjaGVbbGVuXSArIHN0cjtcbiAgLy8gYHBhZGAgc3RhcnRzIHdpdGggYW4gZW1wdHkgc3RyaW5nXG4gIHZhciBwYWQgPSAnJztcbiAgLy8gbG9vcFxuICB3aGlsZSAodHJ1ZSkge1xuICAgIC8vIGFkZCBgY2hgIHRvIGBwYWRgIGlmIGBsZW5gIGlzIG9kZFxuICAgIGlmIChsZW4gJiAxKSBwYWQgKz0gY2g7XG4gICAgLy8gZGl2aWRlIGBsZW5gIGJ5IDIsIGRpdGNoIHRoZSByZW1haW5kZXJcbiAgICBsZW4gPj49IDE7XG4gICAgLy8gXCJkb3VibGVcIiB0aGUgYGNoYCBzbyB0aGlzIG9wZXJhdGlvbiBjb3VudCBncm93cyBsb2dhcml0aG1pY2FsbHkgb24gYGxlbmBcbiAgICAvLyBlYWNoIHRpbWUgYGNoYCBpcyBcImRvdWJsZWRcIiwgdGhlIGBsZW5gIHdvdWxkIG5lZWQgdG8gYmUgXCJkb3VibGVkXCIgdG9vXG4gICAgLy8gc2ltaWxhciB0byBmaW5kaW5nIGEgdmFsdWUgaW4gYmluYXJ5IHNlYXJjaCB0cmVlLCBoZW5jZSBPKGxvZyhuKSlcbiAgICBpZiAobGVuKSBjaCArPSBjaDtcbiAgICAvLyBgbGVuYCBpcyAwLCBleGl0IHRoZSBsb29wXG4gICAgZWxzZSBicmVhaztcbiAgfVxuICAvLyBwYWQgYHN0cmAhXG4gIHJldHVybiBwYWQgKyBzdHI7XG59XG4iLCIvKlxuICogc21vb3Roc2Nyb2xsIHBvbHlmaWxsIC0gdjAuMy41XG4gKiBodHRwczovL2lhbWR1c3Rhbi5naXRodWIuaW8vc21vb3Roc2Nyb2xsXG4gKiAyMDE2IChjKSBEdXN0YW4gS2FzdGVuLCBKZXJlbWlhcyBNZW5pY2hlbGxpIC0gTUlUIExpY2Vuc2VcbiAqL1xuXG4oZnVuY3Rpb24odywgZCwgdW5kZWZpbmVkKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKlxuICAgKiBhbGlhc2VzXG4gICAqIHc6IHdpbmRvdyBnbG9iYWwgb2JqZWN0XG4gICAqIGQ6IGRvY3VtZW50XG4gICAqIHVuZGVmaW5lZDogdW5kZWZpbmVkXG4gICAqL1xuXG4gIC8vIHBvbHlmaWxsXG4gIGZ1bmN0aW9uIHBvbHlmaWxsKCkge1xuICAgIC8vIHJldHVybiB3aGVuIHNjcm9sbEJlaGF2aW9yIGludGVyZmFjZSBpcyBzdXBwb3J0ZWRcbiAgICBpZiAoJ3Njcm9sbEJlaGF2aW9yJyBpbiBkLmRvY3VtZW50RWxlbWVudC5zdHlsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogZ2xvYmFsc1xuICAgICAqL1xuICAgIHZhciBFbGVtZW50ID0gdy5IVE1MRWxlbWVudCB8fCB3LkVsZW1lbnQ7XG4gICAgdmFyIFNDUk9MTF9USU1FID0gNDY4O1xuXG4gICAgLypcbiAgICAgKiBvYmplY3QgZ2F0aGVyaW5nIG9yaWdpbmFsIHNjcm9sbCBtZXRob2RzXG4gICAgICovXG4gICAgdmFyIG9yaWdpbmFsID0ge1xuICAgICAgc2Nyb2xsOiB3LnNjcm9sbCB8fCB3LnNjcm9sbFRvLFxuICAgICAgc2Nyb2xsQnk6IHcuc2Nyb2xsQnksXG4gICAgICBlbFNjcm9sbDogRWxlbWVudC5wcm90b3R5cGUuc2Nyb2xsIHx8IHNjcm9sbEVsZW1lbnQsXG4gICAgICBzY3JvbGxJbnRvVmlldzogRWxlbWVudC5wcm90b3R5cGUuc2Nyb2xsSW50b1ZpZXdcbiAgICB9O1xuXG4gICAgLypcbiAgICAgKiBkZWZpbmUgdGltaW5nIG1ldGhvZFxuICAgICAqL1xuICAgIHZhciBub3cgPSB3LnBlcmZvcm1hbmNlICYmIHcucGVyZm9ybWFuY2Uubm93XG4gICAgICA/IHcucGVyZm9ybWFuY2Uubm93LmJpbmQody5wZXJmb3JtYW5jZSkgOiBEYXRlLm5vdztcblxuICAgIC8qKlxuICAgICAqIGNoYW5nZXMgc2Nyb2xsIHBvc2l0aW9uIGluc2lkZSBhbiBlbGVtZW50XG4gICAgICogQG1ldGhvZCBzY3JvbGxFbGVtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHhcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNjcm9sbEVsZW1lbnQoeCwgeSkge1xuICAgICAgdGhpcy5zY3JvbGxMZWZ0ID0geDtcbiAgICAgIHRoaXMuc2Nyb2xsVG9wID0geTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiByZXR1cm5zIHJlc3VsdCBvZiBhcHBseWluZyBlYXNlIG1hdGggZnVuY3Rpb24gdG8gYSBudW1iZXJcbiAgICAgKiBAbWV0aG9kIGVhc2VcbiAgICAgKiBAcGFyYW0ge051bWJlcn0ga1xuICAgICAqIEByZXR1cm5zIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZnVuY3Rpb24gZWFzZShrKSB7XG4gICAgICByZXR1cm4gMC41ICogKDEgLSBNYXRoLmNvcyhNYXRoLlBJICogaykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGluZGljYXRlcyBpZiBhIHNtb290aCBiZWhhdmlvciBzaG91bGQgYmUgYXBwbGllZFxuICAgICAqIEBtZXRob2Qgc2hvdWxkQmFpbE91dFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfE9iamVjdH0geFxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNob3VsZEJhaWxPdXQoeCkge1xuICAgICAgaWYgKHR5cGVvZiB4ICE9PSAnb2JqZWN0J1xuICAgICAgICAgICAgfHwgeCA9PT0gbnVsbFxuICAgICAgICAgICAgfHwgeC5iZWhhdmlvciA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICB8fCB4LmJlaGF2aW9yID09PSAnYXV0bydcbiAgICAgICAgICAgIHx8IHguYmVoYXZpb3IgPT09ICdpbnN0YW50Jykge1xuICAgICAgICAvLyBmaXJzdCBhcmcgbm90IGFuIG9iamVjdC9udWxsXG4gICAgICAgIC8vIG9yIGJlaGF2aW9yIGlzIGF1dG8sIGluc3RhbnQgb3IgdW5kZWZpbmVkXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHggPT09ICdvYmplY3QnXG4gICAgICAgICAgICAmJiB4LmJlaGF2aW9yID09PSAnc21vb3RoJykge1xuICAgICAgICAvLyBmaXJzdCBhcmd1bWVudCBpcyBhbiBvYmplY3QgYW5kIGJlaGF2aW9yIGlzIHNtb290aFxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIC8vIHRocm93IGVycm9yIHdoZW4gYmVoYXZpb3IgaXMgbm90IHN1cHBvcnRlZFxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYmVoYXZpb3Igbm90IHZhbGlkJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZmluZHMgc2Nyb2xsYWJsZSBwYXJlbnQgb2YgYW4gZWxlbWVudFxuICAgICAqIEBtZXRob2QgZmluZFNjcm9sbGFibGVQYXJlbnRcbiAgICAgKiBAcGFyYW0ge05vZGV9IGVsXG4gICAgICogQHJldHVybnMge05vZGV9IGVsXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmluZFNjcm9sbGFibGVQYXJlbnQoZWwpIHtcbiAgICAgIHZhciBpc0JvZHk7XG4gICAgICB2YXIgaGFzU2Nyb2xsYWJsZVNwYWNlO1xuICAgICAgdmFyIGhhc1Zpc2libGVPdmVyZmxvdztcblxuICAgICAgZG8ge1xuICAgICAgICBlbCA9IGVsLnBhcmVudE5vZGU7XG5cbiAgICAgICAgLy8gc2V0IGNvbmRpdGlvbiB2YXJpYWJsZXNcbiAgICAgICAgaXNCb2R5ID0gZWwgPT09IGQuYm9keTtcbiAgICAgICAgaGFzU2Nyb2xsYWJsZVNwYWNlID1cbiAgICAgICAgICBlbC5jbGllbnRIZWlnaHQgPCBlbC5zY3JvbGxIZWlnaHQgfHxcbiAgICAgICAgICBlbC5jbGllbnRXaWR0aCA8IGVsLnNjcm9sbFdpZHRoO1xuICAgICAgICBoYXNWaXNpYmxlT3ZlcmZsb3cgPVxuICAgICAgICAgIHcuZ2V0Q29tcHV0ZWRTdHlsZShlbCwgbnVsbCkub3ZlcmZsb3cgPT09ICd2aXNpYmxlJztcbiAgICAgIH0gd2hpbGUgKCFpc0JvZHkgJiYgIShoYXNTY3JvbGxhYmxlU3BhY2UgJiYgIWhhc1Zpc2libGVPdmVyZmxvdykpO1xuXG4gICAgICBpc0JvZHkgPSBoYXNTY3JvbGxhYmxlU3BhY2UgPSBoYXNWaXNpYmxlT3ZlcmZsb3cgPSBudWxsO1xuXG4gICAgICByZXR1cm4gZWw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogc2VsZiBpbnZva2VkIGZ1bmN0aW9uIHRoYXQsIGdpdmVuIGEgY29udGV4dCwgc3RlcHMgdGhyb3VnaCBzY3JvbGxpbmdcbiAgICAgKiBAbWV0aG9kIHN0ZXBcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0ZXAoY29udGV4dCkge1xuICAgICAgdmFyIHRpbWUgPSBub3coKTtcbiAgICAgIHZhciB2YWx1ZTtcbiAgICAgIHZhciBjdXJyZW50WDtcbiAgICAgIHZhciBjdXJyZW50WTtcbiAgICAgIHZhciBlbGFwc2VkID0gKHRpbWUgLSBjb250ZXh0LnN0YXJ0VGltZSkgLyBTQ1JPTExfVElNRTtcblxuICAgICAgLy8gYXZvaWQgZWxhcHNlZCB0aW1lcyBoaWdoZXIgdGhhbiBvbmVcbiAgICAgIGVsYXBzZWQgPSBlbGFwc2VkID4gMSA/IDEgOiBlbGFwc2VkO1xuXG4gICAgICAvLyBhcHBseSBlYXNpbmcgdG8gZWxhcHNlZCB0aW1lXG4gICAgICB2YWx1ZSA9IGVhc2UoZWxhcHNlZCk7XG5cbiAgICAgIGN1cnJlbnRYID0gY29udGV4dC5zdGFydFggKyAoY29udGV4dC54IC0gY29udGV4dC5zdGFydFgpICogdmFsdWU7XG4gICAgICBjdXJyZW50WSA9IGNvbnRleHQuc3RhcnRZICsgKGNvbnRleHQueSAtIGNvbnRleHQuc3RhcnRZKSAqIHZhbHVlO1xuXG4gICAgICBjb250ZXh0Lm1ldGhvZC5jYWxsKGNvbnRleHQuc2Nyb2xsYWJsZSwgY3VycmVudFgsIGN1cnJlbnRZKTtcblxuICAgICAgLy8gc2Nyb2xsIG1vcmUgaWYgd2UgaGF2ZSBub3QgcmVhY2hlZCBvdXIgZGVzdGluYXRpb25cbiAgICAgIGlmIChjdXJyZW50WCAhPT0gY29udGV4dC54IHx8IGN1cnJlbnRZICE9PSBjb250ZXh0LnkpIHtcbiAgICAgICAgdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoc3RlcC5iaW5kKHcsIGNvbnRleHQpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBzY3JvbGxzIHdpbmRvdyB3aXRoIGEgc21vb3RoIGJlaGF2aW9yXG4gICAgICogQG1ldGhvZCBzbW9vdGhTY3JvbGxcbiAgICAgKiBAcGFyYW0ge09iamVjdHxOb2RlfSBlbFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHlcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzbW9vdGhTY3JvbGwoZWwsIHgsIHkpIHtcbiAgICAgIHZhciBzY3JvbGxhYmxlO1xuICAgICAgdmFyIHN0YXJ0WDtcbiAgICAgIHZhciBzdGFydFk7XG4gICAgICB2YXIgbWV0aG9kO1xuICAgICAgdmFyIHN0YXJ0VGltZSA9IG5vdygpO1xuXG4gICAgICAvLyBkZWZpbmUgc2Nyb2xsIGNvbnRleHRcbiAgICAgIGlmIChlbCA9PT0gZC5ib2R5KSB7XG4gICAgICAgIHNjcm9sbGFibGUgPSB3O1xuICAgICAgICBzdGFydFggPSB3LnNjcm9sbFggfHwgdy5wYWdlWE9mZnNldDtcbiAgICAgICAgc3RhcnRZID0gdy5zY3JvbGxZIHx8IHcucGFnZVlPZmZzZXQ7XG4gICAgICAgIG1ldGhvZCA9IG9yaWdpbmFsLnNjcm9sbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNjcm9sbGFibGUgPSBlbDtcbiAgICAgICAgc3RhcnRYID0gZWwuc2Nyb2xsTGVmdDtcbiAgICAgICAgc3RhcnRZID0gZWwuc2Nyb2xsVG9wO1xuICAgICAgICBtZXRob2QgPSBzY3JvbGxFbGVtZW50O1xuICAgICAgfVxuXG4gICAgICAvLyBzY3JvbGwgbG9vcGluZyBvdmVyIGEgZnJhbWVcbiAgICAgIHN0ZXAoe1xuICAgICAgICBzY3JvbGxhYmxlOiBzY3JvbGxhYmxlLFxuICAgICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgICAgc3RhcnRUaW1lOiBzdGFydFRpbWUsXG4gICAgICAgIHN0YXJ0WDogc3RhcnRYLFxuICAgICAgICBzdGFydFk6IHN0YXJ0WSxcbiAgICAgICAgeDogeCxcbiAgICAgICAgeTogeVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBPUklHSU5BTCBNRVRIT0RTIE9WRVJSSURFU1xuICAgICAqL1xuXG4gICAgLy8gdy5zY3JvbGwgYW5kIHcuc2Nyb2xsVG9cbiAgICB3LnNjcm9sbCA9IHcuc2Nyb2xsVG8gPSBmdW5jdGlvbigpIHtcbiAgICAgIC8vIGF2b2lkIHNtb290aCBiZWhhdmlvciBpZiBub3QgcmVxdWlyZWRcbiAgICAgIGlmIChzaG91bGRCYWlsT3V0KGFyZ3VtZW50c1swXSkpIHtcbiAgICAgICAgb3JpZ2luYWwuc2Nyb2xsLmNhbGwoXG4gICAgICAgICAgdyxcbiAgICAgICAgICBhcmd1bWVudHNbMF0ubGVmdCB8fCBhcmd1bWVudHNbMF0sXG4gICAgICAgICAgYXJndW1lbnRzWzBdLnRvcCB8fCBhcmd1bWVudHNbMV1cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBMRVQgVEhFIFNNT09USE5FU1MgQkVHSU4hXG4gICAgICBzbW9vdGhTY3JvbGwuY2FsbChcbiAgICAgICAgdyxcbiAgICAgICAgZC5ib2R5LFxuICAgICAgICB+fmFyZ3VtZW50c1swXS5sZWZ0LFxuICAgICAgICB+fmFyZ3VtZW50c1swXS50b3BcbiAgICAgICk7XG4gICAgfTtcblxuICAgIC8vIHcuc2Nyb2xsQnlcbiAgICB3LnNjcm9sbEJ5ID0gZnVuY3Rpb24oKSB7XG4gICAgICAvLyBhdm9pZCBzbW9vdGggYmVoYXZpb3IgaWYgbm90IHJlcXVpcmVkXG4gICAgICBpZiAoc2hvdWxkQmFpbE91dChhcmd1bWVudHNbMF0pKSB7XG4gICAgICAgIG9yaWdpbmFsLnNjcm9sbEJ5LmNhbGwoXG4gICAgICAgICAgdyxcbiAgICAgICAgICBhcmd1bWVudHNbMF0ubGVmdCB8fCBhcmd1bWVudHNbMF0sXG4gICAgICAgICAgYXJndW1lbnRzWzBdLnRvcCB8fCBhcmd1bWVudHNbMV1cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBMRVQgVEhFIFNNT09USE5FU1MgQkVHSU4hXG4gICAgICBzbW9vdGhTY3JvbGwuY2FsbChcbiAgICAgICAgdyxcbiAgICAgICAgZC5ib2R5LFxuICAgICAgICB+fmFyZ3VtZW50c1swXS5sZWZ0ICsgKHcuc2Nyb2xsWCB8fCB3LnBhZ2VYT2Zmc2V0KSxcbiAgICAgICAgfn5hcmd1bWVudHNbMF0udG9wICsgKHcuc2Nyb2xsWSB8fCB3LnBhZ2VZT2Zmc2V0KVxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgLy8gRWxlbWVudC5wcm90b3R5cGUuc2Nyb2xsIGFuZCBFbGVtZW50LnByb3RvdHlwZS5zY3JvbGxUb1xuICAgIEVsZW1lbnQucHJvdG90eXBlLnNjcm9sbCA9IEVsZW1lbnQucHJvdG90eXBlLnNjcm9sbFRvID0gZnVuY3Rpb24oKSB7XG4gICAgICAvLyBhdm9pZCBzbW9vdGggYmVoYXZpb3IgaWYgbm90IHJlcXVpcmVkXG4gICAgICBpZiAoc2hvdWxkQmFpbE91dChhcmd1bWVudHNbMF0pKSB7XG4gICAgICAgIG9yaWdpbmFsLmVsU2Nyb2xsLmNhbGwoXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgYXJndW1lbnRzWzBdLmxlZnQgfHwgYXJndW1lbnRzWzBdLFxuICAgICAgICAgICAgYXJndW1lbnRzWzBdLnRvcCB8fCBhcmd1bWVudHNbMV1cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgbGVmdCA9IGFyZ3VtZW50c1swXS5sZWZ0O1xuICAgICAgdmFyIHRvcCA9IGFyZ3VtZW50c1swXS50b3A7XG5cbiAgICAgIC8vIExFVCBUSEUgU01PT1RITkVTUyBCRUdJTiFcbiAgICAgIHNtb290aFNjcm9sbC5jYWxsKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICB0eXBlb2YgbGVmdCA9PT0gJ251bWJlcicgPyBsZWZ0IDogdGhpcy5zY3JvbGxMZWZ0LFxuICAgICAgICAgIHR5cGVvZiB0b3AgPT09ICdudW1iZXInID8gdG9wIDogdGhpcy5zY3JvbGxUb3BcbiAgICAgICk7XG4gICAgfTtcblxuICAgIC8vIEVsZW1lbnQucHJvdG90eXBlLnNjcm9sbEJ5XG4gICAgRWxlbWVudC5wcm90b3R5cGUuc2Nyb2xsQnkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhcmcwID0gYXJndW1lbnRzWzBdO1xuXG4gICAgICBpZiAodHlwZW9mIGFyZzAgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIHRoaXMuc2Nyb2xsKHtcbiAgICAgICAgICBsZWZ0OiBhcmcwLmxlZnQgKyB0aGlzLnNjcm9sbExlZnQsXG4gICAgICAgICAgdG9wOiBhcmcwLnRvcCArIHRoaXMuc2Nyb2xsVG9wLFxuICAgICAgICAgIGJlaGF2aW9yOiBhcmcwLmJlaGF2aW9yXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zY3JvbGwoXG4gICAgICAgICAgdGhpcy5zY3JvbGxMZWZ0ICsgYXJnMCxcbiAgICAgICAgICB0aGlzLnNjcm9sbFRvcCArIGFyZ3VtZW50c1sxXVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBFbGVtZW50LnByb3RvdHlwZS5zY3JvbGxJbnRvVmlld1xuICAgIEVsZW1lbnQucHJvdG90eXBlLnNjcm9sbEludG9WaWV3ID0gZnVuY3Rpb24oKSB7XG4gICAgICAvLyBhdm9pZCBzbW9vdGggYmVoYXZpb3IgaWYgbm90IHJlcXVpcmVkXG4gICAgICBpZiAoc2hvdWxkQmFpbE91dChhcmd1bWVudHNbMF0pKSB7XG4gICAgICAgIG9yaWdpbmFsLnNjcm9sbEludG9WaWV3LmNhbGwoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCA/IHRydWUgOiBhcmd1bWVudHNbMF1cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBMRVQgVEhFIFNNT09USE5FU1MgQkVHSU4hXG4gICAgICB2YXIgc2Nyb2xsYWJsZVBhcmVudCA9IGZpbmRTY3JvbGxhYmxlUGFyZW50KHRoaXMpO1xuICAgICAgdmFyIHBhcmVudFJlY3RzID0gc2Nyb2xsYWJsZVBhcmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHZhciBjbGllbnRSZWN0cyA9IHRoaXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgIGlmIChzY3JvbGxhYmxlUGFyZW50ICE9PSBkLmJvZHkpIHtcbiAgICAgICAgLy8gcmV2ZWFsIGVsZW1lbnQgaW5zaWRlIHBhcmVudFxuICAgICAgICBzbW9vdGhTY3JvbGwuY2FsbChcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIHNjcm9sbGFibGVQYXJlbnQsXG4gICAgICAgICAgc2Nyb2xsYWJsZVBhcmVudC5zY3JvbGxMZWZ0ICsgY2xpZW50UmVjdHMubGVmdCAtIHBhcmVudFJlY3RzLmxlZnQsXG4gICAgICAgICAgc2Nyb2xsYWJsZVBhcmVudC5zY3JvbGxUb3AgKyBjbGllbnRSZWN0cy50b3AgLSBwYXJlbnRSZWN0cy50b3BcbiAgICAgICAgKTtcbiAgICAgICAgLy8gcmV2ZWFsIHBhcmVudCBpbiB2aWV3cG9ydFxuICAgICAgICB3LnNjcm9sbEJ5KHtcbiAgICAgICAgICBsZWZ0OiBwYXJlbnRSZWN0cy5sZWZ0LFxuICAgICAgICAgIHRvcDogcGFyZW50UmVjdHMudG9wLFxuICAgICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJ1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHJldmVhbCBlbGVtZW50IGluIHZpZXdwb3J0XG4gICAgICAgIHcuc2Nyb2xsQnkoe1xuICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3RzLmxlZnQsXG4gICAgICAgICAgdG9wOiBjbGllbnRSZWN0cy50b3AsXG4gICAgICAgICAgYmVoYXZpb3I6ICdzbW9vdGgnXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBpZiAodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKSB7XG4gICAgLy8gY29tbW9uanNcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHsgcG9seWZpbGw6IHBvbHlmaWxsIH07XG4gIH0gZWxzZSB7XG4gICAgLy8gZ2xvYmFsXG4gICAgcG9seWZpbGwoKTtcbiAgfVxufSkod2luZG93LCBkb2N1bWVudCk7XG4iLCIvKiBnbG9iYWwgZ2EgKi9cblxuY29uc3Qgc2VsZiA9IHt9XG5cbnNlbGYuc2VuZCA9IHt9XG5cbnNlbGYuc2VuZC5zZWFyY2ggPSBmdW5jdGlvbiAoc2VsZWN0ZWRVc2VyLCBmYXZvcml0ZSkge1xuICBjb25zdCBoaXRUeXBlID0gJ2V2ZW50J1xuXG4gIGNvbnN0IGV2ZW50Q2F0ZWdvcnkgPSBmYXZvcml0ZSA/ICdzZWFyY2ggZmF2JyA6ICdzZWFyY2gnXG5cbiAgbGV0IGV2ZW50QWN0aW9uXG4gIHN3aXRjaCAoc2VsZWN0ZWRVc2VyLnR5cGUpIHtcbiAgICBjYXNlICdjJzpcbiAgICAgIGV2ZW50QWN0aW9uID0gJ0NsYXNzJ1xuICAgICAgYnJlYWtcbiAgICBjYXNlICd0JzpcbiAgICAgIGV2ZW50QWN0aW9uID0gJ1RlYWNoZXInXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3InOlxuICAgICAgZXZlbnRBY3Rpb24gPSAnUm9vbSdcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAncyc6XG4gICAgICBldmVudEFjdGlvbiA9ICdTdHVkZW50J1xuICAgICAgYnJlYWtcbiAgfVxuXG4gIGNvbnN0IGV2ZW50TGFiZWwgPSBzZWxlY3RlZFVzZXIudmFsdWVcblxuICBnYShmdW5jdGlvbiAoKSB7XG4gICAgZ2EoJ3NlbmQnLCB7IGhpdFR5cGUsIGV2ZW50Q2F0ZWdvcnksIGV2ZW50QWN0aW9uLCBldmVudExhYmVsIH0pXG4gIH0pXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2VsZlxuIiwiY29uc3QgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJylcblxuY29uc3Qgc2VsZiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG5zZWxmLl9pdGVtcyA9IFtdXG5zZWxmLl9zZWxlY3RlZEl0ZW1JbmRleCA9IC0xXG5cbnNlbGYuX25vZGVzID0ge1xuICBzZWFyY2g6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNzZWFyY2gnKSxcbiAgaW5wdXQ6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W3R5cGU9XCJzZWFyY2hcIl0nKSxcbiAgYXV0b2NvbXBsZXRlOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYXV0b2NvbXBsZXRlJylcbn1cblxuc2VsZi5nZXRTZWxlY3RlZEl0ZW0gPSBmdW5jdGlvbiAoKSB7XG4gIGlmIChzZWxmLmdldEl0ZW1zKCkgPT09IFtdKSByZXR1cm5cblxuICBpZiAoc2VsZi5nZXRTZWxlY3RlZEl0ZW1JbmRleCgpID09PSAtMSkge1xuICAgIHJldHVybiBzZWxmLmdldEl0ZW1zKClbMF1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc2VsZi5nZXRJdGVtcygpW3NlbGYuZ2V0U2VsZWN0ZWRJdGVtSW5kZXgoKV1cbiAgfVxufVxuXG5zZWxmLmdldFNlbGVjdGVkSXRlbUluZGV4ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gc2VsZi5fc2VsZWN0ZWRJdGVtSW5kZXhcbn1cblxuc2VsZi5nZXRJdGVtcyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHNlbGYuX2l0ZW1zXG59XG5cbnNlbGYucmVtb3ZlQWxsSXRlbXMgPSBmdW5jdGlvbiAoKSB7XG4gIHdoaWxlIChzZWxmLl9ub2Rlcy5hdXRvY29tcGxldGUuZmlyc3RDaGlsZCkge1xuICAgIHNlbGYuX25vZGVzLmF1dG9jb21wbGV0ZS5yZW1vdmVDaGlsZChzZWxmLl9ub2Rlcy5hdXRvY29tcGxldGUuZmlyc3RDaGlsZClcbiAgfVxuICBzZWxmLl9pdGVtcyA9IFtdXG4gIHNlbGYuX3NlbGVjdGVkSXRlbUluZGV4ID0gLTFcbn1cblxuc2VsZi5hZGRJdGVtID0gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgY29uc3QgbGlzdEl0ZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaScpXG4gIGxpc3RJdGVtLnRleHRDb250ZW50ID0gaXRlbS52YWx1ZVxuICBzZWxmLl9ub2Rlcy5hdXRvY29tcGxldGUuYXBwZW5kQ2hpbGQobGlzdEl0ZW0pXG4gIHNlbGYuX2l0ZW1zLnB1c2goaXRlbSlcbn1cblxuc2VsZi5fbW92ZVNlbGVjdGVkID0gZnVuY3Rpb24gKHNoaWZ0KSB7XG4gIGlmIChzZWxmLl9zZWxlY3RlZEl0ZW1JbmRleCArIHNoaWZ0ID49IHNlbGYuZ2V0SXRlbXMoKS5sZW5ndGgpIHtcbiAgICBzZWxmLl9zZWxlY3RlZEl0ZW1JbmRleCA9IC0xXG4gIH0gZWxzZSBpZiAoc2VsZi5fc2VsZWN0ZWRJdGVtSW5kZXggKyBzaGlmdCA8IC0xKSB7XG4gICAgc2VsZi5fc2VsZWN0ZWRJdGVtSW5kZXggPSBzZWxmLmdldEl0ZW1zKCkubGVuZ3RoIC0gMVxuICB9IGVsc2Uge1xuICAgIHNlbGYuX3NlbGVjdGVkSXRlbUluZGV4ICs9IHNoaWZ0XG4gIH1cblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHNlbGYuZ2V0SXRlbXMoKS5sZW5ndGg7IGkrKykge1xuICAgIHNlbGYuX25vZGVzLmF1dG9jb21wbGV0ZS5jaGlsZHJlbltpXS5jbGFzc0xpc3QucmVtb3ZlKCdzZWxlY3RlZCcpXG4gIH1cbiAgaWYgKHNlbGYuX3NlbGVjdGVkSXRlbUluZGV4ID49IDApIHtcbiAgICBzZWxmLl9ub2Rlcy5hdXRvY29tcGxldGVcbiAgICAgICAgLmNoaWxkcmVuW3NlbGYuX3NlbGVjdGVkSXRlbUluZGV4XS5jbGFzc0xpc3QuYWRkKCdzZWxlY3RlZCcpXG4gIH1cbn1cblxuc2VsZi5faGFuZGxlSXRlbUNsaWNrID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gIGlmICghc2VsZi5fbm9kZXMuYXV0b2NvbXBsZXRlLmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpIHJldHVyblxuICBjb25zdCBpdGVtSW5kZXggPSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZlxuICAgICAgLmNhbGwoc2VsZi5fbm9kZXMuYXV0b2NvbXBsZXRlLmNoaWxkcmVuLCBldmVudC50YXJnZXQpXG4gIHNlbGYuX3NlbGVjdGVkSXRlbUluZGV4ID0gaXRlbUluZGV4XG4gIHNlbGYuZW1pdCgnc2VsZWN0Jywgc2VsZi5nZXRTZWxlY3RlZEl0ZW0oKSlcbn1cblxuc2VsZi5faGFuZGxlS2V5ZG93biA9IGZ1bmN0aW9uIChldmVudCkge1xuICBpZiAoZXZlbnQua2V5ID09PSAnQXJyb3dEb3duJyB8fCBldmVudC5rZXkgPT09ICdBcnJvd1VwJykge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnQXJyb3dEb3duJykge1xuICAgICAgc2VsZi5fbW92ZVNlbGVjdGVkKDEpXG4gICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09ICdBcnJvd1VwJykge1xuICAgICAgc2VsZi5fbW92ZVNlbGVjdGVkKC0xKVxuICAgIH1cbiAgfVxufVxuXG5zZWxmLl9ub2Rlcy5hdXRvY29tcGxldGUuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBzZWxmLl9oYW5kbGVJdGVtQ2xpY2spXG5zZWxmLl9ub2Rlcy5pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgc2VsZi5faGFuZGxlS2V5ZG93bilcblxubW9kdWxlLmV4cG9ydHMgPSBzZWxmXG4iLCJjb25zdCBzZWxmID0ge31cblxuc2VsZi5pc0lFID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdNU0lFJykgIT09IC0xIHx8XG4gICAgICAgICAgICBuYXZpZ2F0b3IuYXBwVmVyc2lvbi5pbmRleE9mKCdUcmlkZW50LycpID4gMFxuXG5pZiAoc2VsZi5pc0lFKSB7XG4gIHNlbGYuaW5wdXRFdmVudCA9ICd0ZXh0aW5wdXQnXG59IGVsc2Uge1xuICBzZWxmLmlucHV0RXZlbnQgPSAnaW5wdXQnXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2VsZlxuIiwiLyogZ2xvYmFsIFVTRVJTICovXG5cbmNvbnN0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ2V2ZW50cycpXG5cbmNvbnN0IHNlbGYgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuc2VsZi5fbm9kZXMgPSB7XG4gIHRvZ2dsZTogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmZhdicpXG59XG5cbnNlbGYuZ2V0ID0gZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIGNvbnN0IGxvY2FsU3RvcmFnZVVzZXIgPSBKU09OLnBhcnNlKHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnZmF2JykpXG4gICAgaWYgKGxvY2FsU3RvcmFnZVVzZXIgPT0gbnVsbCkgcmV0dXJuXG5cbiAgICBjb25zdCBjb3JyZWN0ZWRVc2VyID0gVVNFUlMuZmlsdGVyKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICByZXR1cm4gdXNlci50eXBlID09PSBsb2NhbFN0b3JhZ2VVc2VyLnR5cGUgJiZcbiAgICAgICAgICAgICB1c2VyLnZhbHVlID09PSBsb2NhbFN0b3JhZ2VVc2VyLnZhbHVlXG4gICAgfSlbMF1cbiAgICByZXR1cm4gY29ycmVjdGVkVXNlclxuICB9IGNhdGNoIChlKSB7XG4gICAgc2VsZi5kZWxldGUoKVxuICAgIHJldHVyblxuICB9XG59XG5cbnNlbGYuc2V0ID0gZnVuY3Rpb24gKHVzZXIpIHtcbiAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKCdmYXYnLCBKU09OLnN0cmluZ2lmeSh1c2VyKSlcbiAgc2VsZi5fbm9kZXMuaW5uZXJIVE1MID0gJyYjeEU4Mzg7J1xufVxuXG5zZWxmLmRlbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgd2luZG93LmxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKCdmYXYnKVxufVxuXG5zZWxmLnVwZGF0ZURvbSA9IGZ1bmN0aW9uIChpc0Zhdm9yaXRlKSB7XG4gIGlmIChpc0Zhdm9yaXRlKSB7XG4gICAgc2VsZi5fbm9kZXMudG9nZ2xlLmlubmVySFRNTCA9ICcmI3hFODM4OydcbiAgfSBlbHNlIHtcbiAgICBzZWxmLl9ub2Rlcy50b2dnbGUuaW5uZXJIVE1MID0gJyYjeEU4M0EnXG4gIH1cbn1cblxuc2VsZi51cGRhdGUgPSBmdW5jdGlvbiAoc2VsZWN0ZWRVc2VyKSB7XG4gIGNvbnN0IGN1cnJlbnRVc2VyID0gc2VsZi5nZXQoKVxuXG4gIGlmIChjdXJyZW50VXNlciA9PSBudWxsKSB7XG4gICAgc2VsZi51cGRhdGVEb20oZmFsc2UpXG4gICAgcmV0dXJuXG4gIH1cblxuICBjb25zdCBpc0VxdWFsID0gY3VycmVudFVzZXIudHlwZSA9PT0gc2VsZWN0ZWRVc2VyLnR5cGUgJiZcbiAgICAgICAgICAgICAgICAgIGN1cnJlbnRVc2VyLmluZGV4ID09PSBzZWxlY3RlZFVzZXIuaW5kZXhcblxuICBzZWxmLnVwZGF0ZURvbShpc0VxdWFsKVxufVxuXG5zZWxmLnRvZ2dsZSA9IGZ1bmN0aW9uIChzZWxlY3RlZFVzZXIpIHtcbiAgY29uc3QgY3VycmVudFVzZXIgPSBzZWxmLmdldCgpXG4gIGNvbnN0IGlzRXF1YWwgPSBjdXJyZW50VXNlciAhPSBudWxsICYmXG4gICAgICAgICAgICAgICAgICBjdXJyZW50VXNlci50eXBlID09PSBzZWxlY3RlZFVzZXIudHlwZSAmJlxuICAgICAgICAgICAgICAgICAgY3VycmVudFVzZXIuaW5kZXggPT09IHNlbGVjdGVkVXNlci5pbmRleFxuXG4gIGlmIChpc0VxdWFsKSB7XG4gICAgc2VsZi5kZWxldGUoKVxuICAgIHNlbGYudXBkYXRlRG9tKGZhbHNlKVxuICB9IGVsc2Uge1xuICAgIHNlbGYuc2V0KHNlbGVjdGVkVXNlcilcbiAgICBzZWxmLnVwZGF0ZURvbSh0cnVlKVxuICB9XG59XG5cbnNlbGYuX2hhbmRsZUNsaWNrID0gZnVuY3Rpb24gKCkge1xuICBzZWxmLmVtaXQoJ2NsaWNrJylcbn1cblxuc2VsZi5fbm9kZXMudG9nZ2xlLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgc2VsZi5faGFuZGxlQ2xpY2spXG5cbm1vZHVsZS5leHBvcnRzID0gc2VsZlxuIiwiLyogZ2xvYmFsIEZMQUdTICovXG5cbmNvbnN0IHNlbGYgPSB7fVxuXG5zZWxmLl9ub2RlcyA9IHtcbiAgaW5wdXQ6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W3R5cGU9XCJzZWFyY2hcIl0nKSxcbiAgb3ZlcmZsb3dCdXR0b246IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNvdmVyZmxvdy1idXR0b24nKVxufVxuXG5zZWxmLl9zaG91bGRDaGVjayA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIEZMQUdTLmluZGV4T2YoJ05PX0ZFQVRVUkVfREVURUNUJykgPT09IC0xXG59XG5cbnNlbGYuX3JlZGlyZWN0ID0gZnVuY3Rpb24gKCkge1xuICB3aW5kb3cubG9jYXRpb24uaHJlZiA9ICdodHRwOi8vd3d3Lm1lZXRpbmdwb2ludG1jby5ubC9Sb29zdGVycy1BTC9kb2MvJ1xufVxuXG5zZWxmLmNoZWNrID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXNlbGYuX3Nob3VsZENoZWNrKCkpIHJldHVyblxuXG4gIHdpbmRvdy5vbmVycm9yID0gc2VsZi5fcmVkaXJlY3RcblxuICBpZiAoc2VsZi5fbm9kZXMuaW5wdXQuZ2V0Q2xpZW50UmVjdHMoKVswXS50b3AgIT09XG4gICAgICBzZWxmLl9ub2Rlcy5vdmVyZmxvd0J1dHRvbi5nZXRDbGllbnRSZWN0cygpWzBdLnRvcCkge1xuICAgIHNlbGYuX3JlZGlyZWN0KClcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNlbGZcbiIsImNvbnN0IGJyb3dzZXJGaXhUb29sa2l0ID0gcmVxdWlyZSgnLi9icm93c2VyRml4VG9vbGtpdCcpXG5cbmNvbnN0IHNlbGYgPSB7fVxuXG5zZWxmLl9ub2RlcyA9IHtcbiAgaW5wdXQ6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W3R5cGU9XCJzZWFyY2hcIl0nKVxufVxuXG5zZWxmLmlzU2hvd24gPSBmYWxzZVxuXG5zZWxmLnNob3cgPSBmdW5jdGlvbiAoKSB7XG4gIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnbm8taW5wdXQnKVxuICBzZWxmLmlzU2hvd24gPSB0cnVlXG59XG5cbnNlbGYuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCduby1pbnB1dCcpXG4gIHNlbGYuaXNTaG93biA9IGZhbHNlXG59XG5cbnNlbGYuX25vZGVzLmlucHV0LmFkZEV2ZW50TGlzdGVuZXIoYnJvd3NlckZpeFRvb2xraXQuaW5wdXRFdmVudCwgc2VsZi5oaWRlKVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNlbGZcbiIsInJlcXVpcmUoJy4vZmVhdHVyZURldGVjdCcpLmNoZWNrKClcblxuY29uc3QgZnJvbnRwYWdlID0gcmVxdWlyZSgnLi9mcm9udHBhZ2UnKVxuY29uc3Qgc2VhcmNoID0gcmVxdWlyZSgnLi9zZWFyY2gnKVxuY29uc3Qgc2NoZWR1bGUgPSByZXF1aXJlKCcuL3NjaGVkdWxlJylcbmNvbnN0IHdlZWtTZWxlY3RvciA9IHJlcXVpcmUoJy4vd2Vla1NlbGVjdG9yJylcbmNvbnN0IGZhdm9yaXRlID0gcmVxdWlyZSgnLi9mYXZvcml0ZScpXG5jb25zdCBzY3JvbGxTbmFwID0gcmVxdWlyZSgnLi9zY3JvbGxTbmFwJylcbmNvbnN0IGFuYWx5dGljcyA9IHJlcXVpcmUoJy4vYW5hbHl0aWNzJylcblxuY29uc3Qgc3RhdGUgPSB7fVxuXG53aW5kb3cuc3RhdGUgPSBzdGF0ZVxud2luZG93LnJlcXVpcmUgPSByZXF1aXJlXG5cbmZyb250cGFnZS5zaG93KClcbndlZWtTZWxlY3Rvci51cGRhdGVDdXJyZW50V2VlaygpXG5zY3JvbGxTbmFwLnN0YXJ0TGlzdGVuaW5nKClcblxuaWYgKGZhdm9yaXRlLmdldCgpICE9IG51bGwpIHtcbiAgc3RhdGUuc2VsZWN0ZWRJdGVtID0gZmF2b3JpdGUuZ2V0KClcbiAgZmF2b3JpdGUudXBkYXRlKHN0YXRlLnNlbGVjdGVkSXRlbSlcbiAgYW5hbHl0aWNzLnNlbmQuc2VhcmNoKHN0YXRlLnNlbGVjdGVkSXRlbSwgdHJ1ZSlcbiAgc2NoZWR1bGUudmlld0l0ZW0od2Vla1NlbGVjdG9yLmdldFNlbGVjdGVkV2VlaygpLCBzdGF0ZS5zZWxlY3RlZEl0ZW0pXG59IGVsc2Uge1xuICBzZWFyY2guZm9jdXMoKVxufVxuXG5zZWFyY2gub24oJ3NlYXJjaCcsIGZ1bmN0aW9uIChzZWxlY3RlZEl0ZW0pIHtcbiAgc3RhdGUuc2VsZWN0ZWRJdGVtID0gc2VsZWN0ZWRJdGVtXG4gIGZhdm9yaXRlLnVwZGF0ZShzdGF0ZS5zZWxlY3RlZEl0ZW0pXG4gIGFuYWx5dGljcy5zZW5kLnNlYXJjaChzdGF0ZS5zZWxlY3RlZEl0ZW0pXG4gIHNjaGVkdWxlLnZpZXdJdGVtKHdlZWtTZWxlY3Rvci5nZXRTZWxlY3RlZFdlZWsoKSwgc3RhdGUuc2VsZWN0ZWRJdGVtKVxufSlcblxud2Vla1NlbGVjdG9yLm9uKCd3ZWVrQ2hhbmdlZCcsIGZ1bmN0aW9uIChuZXdXZWVrKSB7XG4gIGFuYWx5dGljcy5zZW5kLnNlYXJjaChzdGF0ZS5zZWxlY3RlZEl0ZW0pXG4gIHNjaGVkdWxlLnZpZXdJdGVtKG5ld1dlZWssIHN0YXRlLnNlbGVjdGVkSXRlbSlcbn0pXG5cbmZhdm9yaXRlLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgZmF2b3JpdGUudG9nZ2xlKHN0YXRlLnNlbGVjdGVkSXRlbSlcbn0pXG5cbmRvY3VtZW50LmJvZHkuc3R5bGUub3BhY2l0eSA9IDFcbiIsIi8qIGdsb2JhbCBWQUxJRF9XRUVLX05VTUJFUlMgKi9cblxuY29uc3QgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJylcbmNvbnN0IGxlZnRQYWQgPSByZXF1aXJlKCdsZWZ0LXBhZCcpXG5jb25zdCBzZWFyY2ggPSByZXF1aXJlKCcuL3NlYXJjaCcpXG5cbmNvbnN0IHNlbGYgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuc2VsZi5fbm9kZXMgPSB7XG4gIHNjaGVkdWxlOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2NoZWR1bGUnKVxufVxuXG5zZWxmLl9wYXJzZU1lZXRpbmdwb2ludEhUTUwgPSBmdW5jdGlvbiAoaHRtbFN0cikge1xuICBjb25zdCBodG1sID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaHRtbCcpXG4gIGh0bWwuaW5uZXJIVE1MID0gaHRtbFN0clxuICBjb25zdCBjZW50ZXJOb2RlID0gaHRtbC5xdWVyeVNlbGVjdG9yKCdjZW50ZXInKVxuICByZXR1cm4gY2VudGVyTm9kZVxufVxuXG5zZWxmLl9oYW5kbGVMb2FkID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gIGNvbnN0IHJlcXVlc3QgPSBldmVudC50YXJnZXRcbiAgaWYgKHJlcXVlc3Quc3RhdHVzIDwgMjAwIHx8IHJlcXVlc3Quc3RhdHVzID49IDQwMCkge1xuICAgIHNlbGYuX2hhbmRsZUVycm9yKGV2ZW50KVxuICAgIHJldHVyblxuICB9XG4gIGNvbnN0IGRvY3VtZW50ID0gc2VsZi5fcGFyc2VNZWV0aW5ncG9pbnRIVE1MKHJlcXVlc3QucmVzcG9uc2UpXG4gIHNlbGYuX3JlbW92ZUNoaWxkcygpXG4gIHNlbGYuX25vZGVzLnNjaGVkdWxlLmFwcGVuZENoaWxkKGRvY3VtZW50KVxuICBzZWxmLl9ub2Rlcy5zY2hlZHVsZS5jbGFzc0xpc3QucmVtb3ZlKCdlcnJvcicpXG4gIHNlbGYuZW1pdCgnbG9hZCcpXG59XG5cbnNlbGYuX2hhbmRsZUVycm9yID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gIGNvbnN0IHJlcXVlc3QgPSBldmVudC50YXJnZXRcbiAgbGV0IGVycm9yXG4gIGlmIChyZXF1ZXN0LnN0YXR1cyA9PT0gNDA0KSB7XG4gICAgZXJyb3IgPSAnU29ycnksIGVyIGlzIChub2cpIGdlZW4gcm9vc3RlciB2b29yIGRlemUgd2Vlay4nXG4gIH0gZWxzZSB7XG4gICAgZXJyb3IgPSAnU29ycnksIGVyIGlzIGlldHMgbWlzIGdlZ2FhbiB0aWpkZW5zIGhldCBsYWRlbiB2YW4gZGV6ZSB3ZWVrLidcbiAgfVxuICBzZWxmLl9yZW1vdmVDaGlsZHMoKVxuICBzZWxmLl9ub2Rlcy5zY2hlZHVsZS50ZXh0Q29udGVudCA9IGVycm9yXG4gIHNlbGYuX25vZGVzLnNjaGVkdWxlLmNsYXNzTGlzdC5hZGQoJ2Vycm9yJylcbiAgc2VsZi5lbWl0KCdsb2FkJylcbn1cblxuc2VsZi5fZ2V0VVJMT2ZVc2VycyA9IGZ1bmN0aW9uICh3ZWVrLCB0eXBlLCBpbmRleCkge1xuICBjb25zdCBpZCA9IGluZGV4ICsgMVxuICByZXR1cm4gJy8vJyArIHdpbmRvdy5sb2NhdGlvbi5ob3N0ICsgJy9tZWV0aW5ncG9pbnRQcm94eS9Sb29zdGVycy1BTCUyRmRvYyUyRmRhZ3Jvb3N0ZXJzJTJGJyArXG4gICAgICBsZWZ0UGFkKHdlZWssIDIsICcwJykgKyAnJTJGJyArIHR5cGUgKyAnJTJGJyArIHR5cGUgKyBsZWZ0UGFkKGlkLCA1LCAnMCcpICsgJy5odG0nXG59XG5cbnNlbGYuX3JlbW92ZUNoaWxkcyA9IGZ1bmN0aW9uICgpIHtcbiAgd2hpbGUgKHNlbGYuX25vZGVzLnNjaGVkdWxlLmZpcnN0Q2hpbGQpIHtcbiAgICBzZWxmLl9ub2Rlcy5zY2hlZHVsZS5yZW1vdmVDaGlsZChzZWxmLl9ub2Rlcy5zY2hlZHVsZS5maXJzdENoaWxkKVxuICB9XG59XG5cbnNlbGYudmlld0l0ZW0gPSBmdW5jdGlvbiAod2Vlaywgc2VsZWN0ZWRVc2VyKSB7XG4gIGlmIChWQUxJRF9XRUVLX05VTUJFUlMuaW5kZXhPZih3ZWVrKSA9PT0gLTEpIHtcbiAgICBzZWxmLl9oYW5kbGVFcnJvcih7IHRhcmdldDogeyBzdGF0dXM6IDQwNCB9IH0pO1xuICAgIHJldHVyblxuICB9XG4gIGNvbnN0IHVybCA9IHNlbGYuX2dldFVSTE9mVXNlcnMod2Vlaywgc2VsZWN0ZWRVc2VyLnR5cGUsIHNlbGVjdGVkVXNlci5pbmRleClcblxuICBzZWxmLl9yZW1vdmVDaGlsZHMoKVxuXG4gIGNvbnN0IHJlcXVlc3QgPSBuZXcgd2luZG93LlhNTEh0dHBSZXF1ZXN0KClcbiAgcmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgc2VsZi5faGFuZGxlTG9hZClcbiAgcmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIHNlbGYuX2hhbmRsZUVycm9yKVxuICByZXF1ZXN0Lm9wZW4oJ0dFVCcsIHVybCwgdHJ1ZSlcbiAgcmVxdWVzdC5zZW5kKClcblxuICBzZWFyY2gudXBkYXRlRG9tKHNlbGVjdGVkVXNlcilcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZWxmXG4iLCJyZXF1aXJlKCdzbW9vdGhzY3JvbGwtcG9seWZpbGwnKS5wb2x5ZmlsbCgpXG5cbmNvbnN0IHNlbGYgPSB7fVxuY29uc3Qgc2NoZWR1bGUgPSByZXF1aXJlKCcuL3NjaGVkdWxlJylcblxuc2VsZi5fbm9kZXMgPSB7XG4gIHNlYXJjaDogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3NlYXJjaCcpLFxuICB3ZWVrU2VsZWN0b3I6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyN3ZWVrLXNlbGVjdG9yJylcbn1cblxuc2VsZi5fdGltZW91dElEID0gbnVsbFxuXG5zZWxmLl9nZXRTY3JvbGxQb3NpdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCkgfHxcbiAgICAgICAgICBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcFxufVxuXG5zZWxmLl9oYW5kbGVEb25lU2Nyb2xsaW5nID0gZnVuY3Rpb24gKCkge1xuICBjb25zdCBzY3JvbGxQb3NpdGlvbiA9IHNlbGYuX2dldFNjcm9sbFBvc2l0aW9uKClcbiAgY29uc3Qgd2Vla1NlbGVjdG9ySGVpZ2h0ID0gc2VsZi5fbm9kZXMud2Vla1NlbGVjdG9yLmNsaWVudEhlaWdodCAtIHNlbGYuX25vZGVzLnNlYXJjaC5jbGllbnRIZWlnaHRcbiAgaWYgKHNjcm9sbFBvc2l0aW9uIDwgd2Vla1NlbGVjdG9ySGVpZ2h0ICYmIHNjcm9sbFBvc2l0aW9uID4gMCkge1xuICAgIHdpbmRvdy5zY3JvbGwoeyB0b3A6IHdlZWtTZWxlY3RvckhlaWdodCwgbGVmdDogMCwgYmVoYXZpb3I6ICdzbW9vdGgnIH0pXG4gIH1cbn1cblxuc2VsZi5faGFuZGxlU2Nyb2xsID0gZnVuY3Rpb24gKCkge1xuICBpZiAoc2VsZi5fdGltZW91dElEICE9IG51bGwpIHdpbmRvdy5jbGVhclRpbWVvdXQoc2VsZi5fdGltZW91dElEKVxuICBzZWxmLl90aW1lb3V0SUQgPSB3aW5kb3cuc2V0VGltZW91dChzZWxmLl9oYW5kbGVEb25lU2Nyb2xsaW5nLCA1MDApXG5cbiAgY29uc3Qgc2Nyb2xsUG9zaXRpb24gPSBzZWxmLl9nZXRTY3JvbGxQb3NpdGlvbigpXG4gIGNvbnN0IHdlZWtTZWxlY3RvckhlaWdodCA9IHNlbGYuX25vZGVzLndlZWtTZWxlY3Rvci5jbGllbnRIZWlnaHQgLSBzZWxmLl9ub2Rlcy5zZWFyY2guY2xpZW50SGVpZ2h0XG4gIGlmIChzY3JvbGxQb3NpdGlvbiA+PSB3ZWVrU2VsZWN0b3JIZWlnaHQpIHtcbiAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ3dlZWstc2VsZWN0b3Itbm90LXZpc2libGUnKVxuICB9IGVsc2Uge1xuICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnd2Vlay1zZWxlY3Rvci1ub3QtdmlzaWJsZScpXG4gIH1cbn1cblxuc2VsZi5faGFuZGxlV2luZG93UmVzaXplID0gZnVuY3Rpb24gKCkge1xuICBjb25zdCB3ZWVrU2VsZWN0b3JIZWlnaHQgPSBzZWxmLl9ub2Rlcy53ZWVrU2VsZWN0b3IuY2xpZW50SGVpZ2h0IC0gc2VsZi5fbm9kZXMuc2VhcmNoLmNsaWVudEhlaWdodFxuICBjb25zdCBleHRyYVBpeGVsc05lZWRlZCA9IHdlZWtTZWxlY3RvckhlaWdodCAtIChkb2N1bWVudC5ib2R5LmNsaWVudEhlaWdodCAtIHdpbmRvdy5pbm5lckhlaWdodClcbiAgaWYgKGV4dHJhUGl4ZWxzTmVlZGVkID4gMCkge1xuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUubWFyZ2luQm90dG9tID0gZXh0cmFQaXhlbHNOZWVkZWQgKyAncHgnXG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuYm9keS5zdHlsZS5tYXJnaW5Cb3R0b20gPSBudWxsXG4gIH1cbn1cblxuc2VsZi5zdGFydExpc3RlbmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHNlbGYuX2hhbmRsZVNjcm9sbClcbn1cblxuc2NoZWR1bGUub24oJ2xvYWQnLCBzZWxmLl9oYW5kbGVXaW5kb3dSZXNpemUpXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgc2VsZi5faGFuZGxlV2luZG93UmVzaXplKVxubW9kdWxlLmV4cG9ydHMgPSBzZWxmXG4iLCIvKiBnbG9iYWwgVVNFUlMgKi9cblxuY29uc3QgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJylcbmNvbnN0IGZ1enp5ID0gcmVxdWlyZSgnZnV6enknKVxuY29uc3QgYXV0b2NvbXBsZXRlID0gcmVxdWlyZSgnLi9hdXRvY29tcGxldGUnKVxuY29uc3QgYnJvd3NlckZpeFRvb2xraXQgPSByZXF1aXJlKCcuL2Jyb3dzZXJGaXhUb29sa2l0JylcblxuY29uc3Qgc2VsZiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG5zZWxmLl9ub2RlcyA9IHtcbiAgc2VhcmNoOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2VhcmNoJyksXG4gIGlucHV0OiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPVwic2VhcmNoXCJdJylcbn1cblxuc2VsZi5zdWJtaXQgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IHNlbGVjdGVkSXRlbSA9IGF1dG9jb21wbGV0ZS5nZXRTZWxlY3RlZEl0ZW0oKVxuICBpZiAoc2VsZWN0ZWRJdGVtID09IG51bGwpIHJldHVyblxuXG4gIGNvbnNvbGUubG9nKHNlbGVjdGVkSXRlbSlcblxuICBzZWxmLl9ub2Rlcy5pbnB1dC5ibHVyKClcbiAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCd3ZWVrLXNlbGVjdG9yLW5vdC12aXNpYmxlJykgLy8gU2FmYXJpIGJ1Z1xuXG4gIHNlbGYuZW1pdCgnc2VhcmNoJywgc2VsZWN0ZWRJdGVtKVxufVxuXG5zZWxmLnVwZGF0ZURvbSA9IGZ1bmN0aW9uIChzZWxlY3RlZEl0ZW0pIHtcbiAgc2VsZi5fbm9kZXMuaW5wdXQudmFsdWUgPSBzZWxlY3RlZEl0ZW0udmFsdWVcbiAgYXV0b2NvbXBsZXRlLnJlbW92ZUFsbEl0ZW1zKClcbiAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCduby1pbnB1dCcpXG4gIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnc2VhcmNoZWQnKVxufVxuXG5zZWxmLmZvY3VzID0gZnVuY3Rpb24gKCkge1xuICBzZWxmLl9ub2Rlcy5pbnB1dC5mb2N1cygpXG59XG5cbnNlbGYuX2hhbmRsZVN1Ym1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpXG4gIHNlbGYuc3VibWl0KClcbn1cblxuc2VsZi5fY2FsY3VsYXRlID0gZnVuY3Rpb24gKHNlYXJjaFRlcm0pIHtcbiAgY29uc3QgYWxsUmVzdWx0cyA9IGZ1enp5LmZpbHRlcihzZWFyY2hUZXJtLCBVU0VSUywge1xuICAgIGV4dHJhY3Q6IGZ1bmN0aW9uIChpdGVtKSB7IHJldHVybiBpdGVtLnZhbHVlIH1cbiAgfSlcbiAgY29uc3QgZmlyc3RSZXN1bHRzID0gYWxsUmVzdWx0cy5zbGljZSgwLCA3KVxuXG4gIGNvbnN0IG9yaWdpbmFsUmVzdWx0cyA9IGZpcnN0UmVzdWx0cy5tYXAoZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgIHJldHVybiByZXN1bHQub3JpZ2luYWxcbiAgfSlcblxuICByZXR1cm4gb3JpZ2luYWxSZXN1bHRzXG59XG5cbnNlbGYuX2hhbmRsZVRleHRVcGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IHJlc3VsdHMgPSBzZWxmLl9jYWxjdWxhdGUoc2VsZi5fbm9kZXMuaW5wdXQudmFsdWUpXG5cbiAgYXV0b2NvbXBsZXRlLnJlbW92ZUFsbEl0ZW1zKClcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRzLmxlbmd0aDsgaSsrKSB7XG4gICAgYXV0b2NvbXBsZXRlLmFkZEl0ZW0ocmVzdWx0c1tpXSlcbiAgfVxufVxuXG5zZWxmLl9oYW5kbGVGb2N1cyA9IGZ1bmN0aW9uICgpIHtcbiAgc2VsZi5fbm9kZXMuaW5wdXQuc2VsZWN0KClcbn1cblxuc2VsZi5faGFuZGxlQmx1ciA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gdGhpcyB3aWxsIHJlbW92ZWQgdGhlIHNlbGVjdGlvbiB3aXRob3V0IGRyYXdpbmcgZm9jdXMgb24gaXQgKHNhZmFyaSlcbiAgLy8gdGhpcyB3aWxsIHJlbW92ZWQgc2VsZWN0aW9uIGV2ZW4gd2hlbiBmb2N1c2luZyBhbiBpZnJhbWUgKGNocm9tZSlcbiAgY29uc3Qgb2xkVmFsdWUgPSBzZWxmLl9ub2Rlcy52YWx1ZVxuICBzZWxmLl9ub2Rlcy52YWx1ZSA9ICcnXG4gIHNlbGYuX25vZGVzLnZhbHVlID0gb2xkVmFsdWVcblxuICAvLyB0aGlzIHdpbGwgaGlkZSB0aGUga2V5Ym9hcmQgKGlPUyBzYWZhcmkpXG4gIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQuYmx1cigpXG59XG5cbmF1dG9jb21wbGV0ZS5vbignc2VsZWN0Jywgc2VsZi5zdWJtaXQpXG5cbnNlbGYuX25vZGVzLnNlYXJjaC5hZGRFdmVudExpc3RlbmVyKCdzdWJtaXQnLCBzZWxmLl9oYW5kbGVTdWJtaXQpXG5zZWxmLl9ub2Rlcy5pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdmb2N1cycsIHNlbGYuX2hhbmRsZUZvY3VzKVxuc2VsZi5fbm9kZXMuaW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsIHNlbGYuX2hhbmRsZUJsdXIpXG5zZWxmLl9ub2Rlcy5pbnB1dC5hZGRFdmVudExpc3RlbmVyKGJyb3dzZXJGaXhUb29sa2l0LmlucHV0RXZlbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2hhbmRsZVRleHRVcGRhdGUpXG5cbm1vZHVsZS5leHBvcnRzID0gc2VsZlxuIiwiY29uc3QgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJylcblxuY29uc3Qgc2VsZiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG5zZWxmLl9ub2RlcyA9IHtcbiAgcHJldkJ1dHRvbjogZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnI3dlZWstc2VsZWN0b3IgYnV0dG9uJylbMF0sXG4gIG5leHRCdXR0b246IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyN3ZWVrLXNlbGVjdG9yIGJ1dHRvbicpWzFdLFxuICBjdXJyZW50V2Vla05vZGU6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyN3ZWVrLXNlbGVjdG9yIC5jdXJyZW50JyksXG4gIGN1cnJlbnRXZWVrTm9ybWFsVGV4dDogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3dlZWstc2VsZWN0b3IgLmN1cnJlbnQgLm5vLXByaW50JyksXG4gIGN1cnJlbnRXZWVrUHJpbnRUZXh0OiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjd2Vlay1zZWxlY3RvciAuY3VycmVudCAucHJpbnQnKVxufVxuXG5zZWxmLl93ZWVrT2Zmc2V0ID0gMFxuXG4vLyBjb3BpZWQgZnJvbSBodHRwOi8vd3d3Lm1lZXRpbmdwb2ludG1jby5ubC9Sb29zdGVycy1BTC9kb2MvZGFncm9vc3RlcnMvdW50aXNzY3JpcHRzLmpzLFxuLy8gd2VyZSB1c2luZyB0aGUgc2FtZSBjb2RlIGFzIHRoZXkgZG8gdG8gYmUgc3VyZSB0aGF0IHdlIGFsd2F5cyBnZXQgdGhlIHNhbWVcbi8vIHdlZWsgbnVtYmVyLlxuc2VsZi5nZXRDdXJyZW50V2VlayA9IGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgY29uc3QgZGF5TnIgPSAodGFyZ2V0LmdldERheSgpICsgNikgJSA3XG4gIHRhcmdldC5zZXREYXRlKHRhcmdldC5nZXREYXRlKCkgLSBkYXlOciArIDMpXG4gIGNvbnN0IGZpcnN0VGh1cnNkYXkgPSB0YXJnZXQudmFsdWVPZigpXG4gIHRhcmdldC5zZXRNb250aCgwLCAxKVxuICBpZiAodGFyZ2V0LmdldERheSgpICE9PSA0KSB7XG4gICAgdGFyZ2V0LnNldE1vbnRoKDAsIDEgKyAoKDQgLSB0YXJnZXQuZ2V0RGF5KCkpICsgNykgJSA3KVxuICB9XG5cbiAgcmV0dXJuIDEgKyBNYXRoLmNlaWwoKGZpcnN0VGh1cnNkYXkgLSB0YXJnZXQpIC8gNjA0ODAwMDAwKVxufVxuXG5zZWxmLmdldFNlbGVjdGVkV2VlayA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3Qgbm93ID0gbmV3IERhdGUoKVxuICBjb25zdCB0YXJnZXREYXRlID0gbmV3IERhdGUobm93LmdldFRpbWUoKSArXG4gICAgICBzZWxmLl93ZWVrT2Zmc2V0ICogNjA0ODAwICogMTAwMCArIDg2NDAwICogMTAwMClcbiAgcmV0dXJuIHNlbGYuZ2V0Q3VycmVudFdlZWsodGFyZ2V0RGF0ZSlcbn1cblxuc2VsZi51cGRhdGVDdXJyZW50V2VlayA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3Qgc2VsZWN0ZWRXZWVrTnVtYmVyID0gc2VsZi5nZXRTZWxlY3RlZFdlZWsoKVxuICBpZiAoc2VsZi5nZXRDdXJyZW50V2VlayhuZXcgRGF0ZSgpKSAhPT0gc2VsZWN0ZWRXZWVrTnVtYmVyKSB7XG4gICAgc2VsZi5fbm9kZXMuY3VycmVudFdlZWtOb2RlLmNsYXNzTGlzdC5hZGQoJ2NoYW5nZWQnKVxuICB9IGVsc2Uge1xuICAgIHNlbGYuX25vZGVzLmN1cnJlbnRXZWVrTm9kZS5jbGFzc0xpc3QucmVtb3ZlKCdjaGFuZ2VkJylcbiAgfVxuICBzZWxmLnVwZGF0ZURvbSgpXG4gIHNlbGYuZW1pdCgnd2Vla0NoYW5nZWQnLCBzZWxlY3RlZFdlZWtOdW1iZXIpXG59XG5cbnNlbGYudXBkYXRlRG9tID0gZnVuY3Rpb24gKCkge1xuICBjb25zdCBzZWxlY3RlZFdlZWtOdW1iZXIgPSBzZWxmLmdldFNlbGVjdGVkV2VlaygpXG4gIGNvbnN0IGlzU3VuZGF5ID0gbmV3IERhdGUoKS5nZXREYXkoKSA9PT0gMFxuICBsZXQgaHVtYW5SZWFkYWJsZVdlZWsgPSBudWxsXG4gIGlmIChpc1N1bmRheSkge1xuICAgIHN3aXRjaCAoc2VsZi5fd2Vla09mZnNldCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICBodW1hblJlYWRhYmxlV2VlayA9ICdBYW5zdGFhbmRlIHdlZWsnXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlIDE6XG4gICAgICAgIGh1bWFuUmVhZGFibGVXZWVrID0gJ1ZvbGdlbmRlIHdlZWsnXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlIC0xOlxuICAgICAgICBodW1hblJlYWRhYmxlV2VlayA9ICdBZmdlbG9wZW4gd2VlaydcbiAgICAgICAgYnJlYWtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc3dpdGNoIChzZWxmLl93ZWVrT2Zmc2V0KSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIGh1bWFuUmVhZGFibGVXZWVrID0gJ0h1aWRpZ2Ugd2VlaydcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgaHVtYW5SZWFkYWJsZVdlZWsgPSAnVm9sZ2VuZGUgd2VlaydcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgLTE6XG4gICAgICAgIGh1bWFuUmVhZGFibGVXZWVrID0gJ1ZvcmlnZSB3ZWVrJ1xuICAgICAgICBicmVha1xuICAgIH1cbiAgfVxuICBpZiAoaHVtYW5SZWFkYWJsZVdlZWsgIT0gbnVsbCkge1xuICAgIHNlbGYuX25vZGVzLmN1cnJlbnRXZWVrTm9ybWFsVGV4dC50ZXh0Q29udGVudCA9IGh1bWFuUmVhZGFibGVXZWVrICsgJyDigKIgJyArIHNlbGVjdGVkV2Vla051bWJlclxuICAgIHNlbGYuX25vZGVzLmN1cnJlbnRXZWVrUHJpbnRUZXh0LnRleHRDb250ZW50ID0gJ1dlZWsgJyArIHNlbGVjdGVkV2Vla051bWJlclxuICB9IGVsc2Uge1xuICAgIHNlbGYuX25vZGVzLmN1cnJlbnRXZWVrTm9ybWFsVGV4dC50ZXh0Q29udGVudCA9ICdXZWVrICcgKyBzZWxlY3RlZFdlZWtOdW1iZXJcbiAgICBzZWxmLl9ub2Rlcy5jdXJyZW50V2Vla1ByaW50VGV4dC50ZXh0Q29udGVudCA9ICdXZWVrICcgKyBzZWxlY3RlZFdlZWtOdW1iZXJcbiAgfVxufVxuXG5zZWxmLl9oYW5kbGVQcmV2QnV0dG9uQ2xpY2sgPSBmdW5jdGlvbiAoKSB7XG4gIHNlbGYuX3dlZWtPZmZzZXQgLT0gMVxuICBzZWxmLnVwZGF0ZUN1cnJlbnRXZWVrKClcbn1cblxuc2VsZi5faGFuZGxlTmV4dEJ1dHRvbkNsaWNrID0gZnVuY3Rpb24gKCkge1xuICBzZWxmLl93ZWVrT2Zmc2V0ICs9IDFcbiAgc2VsZi51cGRhdGVDdXJyZW50V2VlaygpXG59XG5cbnNlbGYuX25vZGVzLnByZXZCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBzZWxmLl9oYW5kbGVQcmV2QnV0dG9uQ2xpY2spXG5zZWxmLl9ub2Rlcy5uZXh0QnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgc2VsZi5faGFuZGxlTmV4dEJ1dHRvbkNsaWNrKVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNlbGZcbiJdfQ==
+/******/ (function(modules) { // webpackBootstrap
+/******/ // The module cache
+/******/ var installedModules = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/
+/******/ // Check if module is in cache
+/******/ if(installedModules[moduleId]) {
+/******/ return installedModules[moduleId].exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = installedModules[moduleId] = {
+/******/ i: moduleId,
+/******/ l: false,
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ // Flag the module as loaded
+/******/ module.l = true;
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/******/
+/******/ // expose the modules object (__webpack_modules__)
+/******/ __webpack_require__.m = modules;
+/******/
+/******/ // expose the module cache
+/******/ __webpack_require__.c = installedModules;
+/******/
+/******/ // define getter function for harmony exports
+/******/ __webpack_require__.d = function(exports, name, getter) {
+/******/ if(!__webpack_require__.o(exports, name)) {
+/******/ Object.defineProperty(exports, name, {
+/******/ configurable: false,
+/******/ enumerable: true,
+/******/ get: getter
+/******/ });
+/******/ }
+/******/ };
+/******/
+/******/ // getDefaultExport function for compatibility with non-harmony modules
+/******/ __webpack_require__.n = function(module) {
+/******/ var getter = module && module.__esModule ?
+/******/ function getDefault() { return module['default']; } :
+/******/ function getModuleExports() { return module; };
+/******/ __webpack_require__.d(getter, 'a', getter);
+/******/ return getter;
+/******/ };
+/******/
+/******/ // Object.prototype.hasOwnProperty.call
+/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ // __webpack_public_path__
+/******/ __webpack_require__.p = "";
+/******/
+/******/ // Load entry module and return exports
+/******/ return __webpack_require__(__webpack_require__.s = 4);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/*!***************************************!*\
+ !*** ./node_modules/events/events.js ***!
+ \***************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports) {
+
+eval("// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n this._events = this._events || {};\n this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n if (!isNumber(n) || n < 0 || isNaN(n))\n throw TypeError('n must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n var er, handler, len, args, i, listeners;\n\n if (!this._events)\n this._events = {};\n\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events.error ||\n (isObject(this._events.error) && !this._events.error.length)) {\n er = arguments[1];\n if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n } else {\n // At least give some kind of context to the user\n var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n err.context = er;\n throw err;\n }\n }\n }\n\n handler = this._events[type];\n\n if (isUndefined(handler))\n return false;\n\n if (isFunction(handler)) {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n args = Array.prototype.slice.call(arguments, 1);\n handler.apply(this, args);\n }\n } else if (isObject(handler)) {\n args = Array.prototype.slice.call(arguments, 1);\n listeners = handler.slice();\n len = listeners.length;\n for (i = 0; i < len; i++)\n listeners[i].apply(this, args);\n }\n\n return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n var m;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events)\n this._events = {};\n\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (this._events.newListener)\n this.emit('newListener', type,\n isFunction(listener.listener) ?\n listener.listener : listener);\n\n if (!this._events[type])\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n else if (isObject(this._events[type]))\n // If we've already got an array, just append.\n this._events[type].push(listener);\n else\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n // Check for listener leak\n if (isObject(this._events[type]) && !this._events[type].warned) {\n if (!isUndefined(this._maxListeners)) {\n m = this._maxListeners;\n } else {\n m = EventEmitter.defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9ldmVudHMvZXZlbnRzLmpzP2JmMzAiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSB0aGlzLl9tYXhMaXN0ZW5lcnMgfHwgdW5kZWZpbmVkO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG5FdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbihuKSB7XG4gIGlmICghaXNOdW1iZXIobikgfHwgbiA8IDAgfHwgaXNOYU4obikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCduIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAodHlwZSA9PT0gJ2Vycm9yJykge1xuICAgIGlmICghdGhpcy5fZXZlbnRzLmVycm9yIHx8XG4gICAgICAgIChpc09iamVjdCh0aGlzLl9ldmVudHMuZXJyb3IpICYmICF0aGlzLl9ldmVudHMuZXJyb3IubGVuZ3RoKSkge1xuICAgICAgZXIgPSBhcmd1bWVudHNbMV07XG4gICAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5jYXVnaHQsIHVuc3BlY2lmaWVkIFwiZXJyb3JcIiBldmVudC4gKCcgKyBlciArICcpJyk7XG4gICAgICAgIGVyci5jb250ZXh0ID0gZXI7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBoYW5kbGVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc1VuZGVmaW5lZChoYW5kbGVyKSlcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKGlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIC8vIHNsb3dlclxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgIGhhbmRsZXIuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGhhbmRsZXIpKSB7XG4gICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgbGlzdGVuZXJzID0gaGFuZGxlci5zbGljZSgpO1xuICAgIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIG07XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIFRvIGF2b2lkIHJlY3Vyc2lvbiBpbiB0aGUgY2FzZSB0aGF0IHR5cGUgPT09IFwibmV3TGlzdGVuZXJcIiEgQmVmb3JlXG4gIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgaWYgKHRoaXMuX2V2ZW50cy5uZXdMaXN0ZW5lcilcbiAgICB0aGlzLmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICAgICAgaXNGdW5jdGlvbihsaXN0ZW5lci5saXN0ZW5lcikgP1xuICAgICAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgZWxzZSBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdLnB1c2gobGlzdGVuZXIpO1xuICBlbHNlXG4gICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gW3RoaXMuX2V2ZW50c1t0eXBlXSwgbGlzdGVuZXJdO1xuXG4gIC8vIENoZWNrIGZvciBsaXN0ZW5lciBsZWFrXG4gIGlmIChpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pICYmICF0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkKSB7XG4gICAgaWYgKCFpc1VuZGVmaW5lZCh0aGlzLl9tYXhMaXN0ZW5lcnMpKSB7XG4gICAgICBtID0gdGhpcy5fbWF4TGlzdGVuZXJzO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfVxuXG4gICAgaWYgKG0gJiYgbSA+IDAgJiYgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCA+IG0pIHtcbiAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQgPSB0cnVlO1xuICAgICAgY29uc29sZS5lcnJvcignKG5vZGUpIHdhcm5pbmc6IHBvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgJyArXG4gICAgICAgICAgICAgICAgICAgICdsZWFrIGRldGVjdGVkLiAlZCBsaXN0ZW5lcnMgYWRkZWQuICcgK1xuICAgICAgICAgICAgICAgICAgICAnVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gaW5jcmVhc2UgbGltaXQuJyxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCk7XG4gICAgICBpZiAodHlwZW9mIGNvbnNvbGUudHJhY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gbm90IHN1cHBvcnRlZCBpbiBJRSAxMFxuICAgICAgICBjb25zb2xlLnRyYWNlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIHZhciBmaXJlZCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGcoKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBnKTtcblxuICAgIGlmICghZmlyZWQpIHtcbiAgICAgIGZpcmVkID0gdHJ1ZTtcbiAgICAgIGxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuICB9XG5cbiAgZy5saXN0ZW5lciA9IGxpc3RlbmVyO1xuICB0aGlzLm9uKHR5cGUsIGcpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gZW1pdHMgYSAncmVtb3ZlTGlzdGVuZXInIGV2ZW50IGlmZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWRcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbGlzdCwgcG9zaXRpb24sIGxlbmd0aCwgaTtcblxuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXR1cm4gdGhpcztcblxuICBsaXN0ID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuICBsZW5ndGggPSBsaXN0Lmxlbmd0aDtcbiAgcG9zaXRpb24gPSAtMTtcblxuICBpZiAobGlzdCA9PT0gbGlzdGVuZXIgfHxcbiAgICAgIChpc0Z1bmN0aW9uKGxpc3QubGlzdGVuZXIpICYmIGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgaWYgKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG5cbiAgfSBlbHNlIGlmIChpc09iamVjdChsaXN0KSkge1xuICAgIGZvciAoaSA9IGxlbmd0aDsgaS0tID4gMDspIHtcbiAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fFxuICAgICAgICAgIChsaXN0W2ldLmxpc3RlbmVyICYmIGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICByZXR1cm4gdGhpcztcblxuICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgbGlzdC5sZW5ndGggPSAwO1xuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGlzdC5zcGxpY2UocG9zaXRpb24sIDEpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGtleSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgaWYgKCF0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIGVsc2UgaWYgKHRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBlbWl0IHJlbW92ZUxpc3RlbmVyIGZvciBhbGwgbGlzdGVuZXJzIG9uIGFsbCBldmVudHNcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICBmb3IgKGtleSBpbiB0aGlzLl9ldmVudHMpIHtcbiAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICB9XG4gICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKGlzRnVuY3Rpb24obGlzdGVuZXJzKSkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzKTtcbiAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAvLyBMSUZPIG9yZGVyXG4gICAgd2hpbGUgKGxpc3RlbmVycy5sZW5ndGgpXG4gICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tsaXN0ZW5lcnMubGVuZ3RoIC0gMV0pO1xuICB9XG4gIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIHJldDtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXQgPSBbXTtcbiAgZWxzZSBpZiAoaXNGdW5jdGlvbih0aGlzLl9ldmVudHNbdHlwZV0pKVxuICAgIHJldCA9IFt0aGlzLl9ldmVudHNbdHlwZV1dO1xuICBlbHNlXG4gICAgcmV0ID0gdGhpcy5fZXZlbnRzW3R5cGVdLnNsaWNlKCk7XG4gIHJldHVybiByZXQ7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIGlmICh0aGlzLl9ldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICAgIGlmIChpc0Z1bmN0aW9uKGV2bGlzdGVuZXIpKVxuICAgICAgcmV0dXJuIDE7XG4gICAgZWxzZSBpZiAoZXZsaXN0ZW5lcilcbiAgICAgIHJldHVybiBldmxpc3RlbmVyLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gMDtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xufTtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qc1xuLy8gbW9kdWxlIGlkID0gMFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0\n");
+
+/***/ }),
+/* 1 */
+/*!****************************************!*\
+ !*** ./public/javascripts/schedule.js ***!
+ \****************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\n/* global VALID_WEEK_NUMBERS */\n\nvar EventEmitter = __webpack_require__(/*! events */ 0);\nvar search = __webpack_require__(/*! ./search */ 2);\n\nvar self = new EventEmitter();\n\nself._nodes = {\n schedule: document.querySelector('#schedule')\n};\n\nself._parseMeetingpointHTML = function (htmlStr) {\n var html = document.createElement('html');\n html.innerHTML = htmlStr;\n var centerNode = html.querySelector('center');\n return centerNode;\n};\n\nself._handleLoad = function (event) {\n var request = event.target;\n if (request.status < 200 || request.status >= 400) {\n self._handleError(event);\n return;\n }\n var document = self._parseMeetingpointHTML(request.response);\n self._removeChilds();\n self._nodes.schedule.appendChild(document);\n self._nodes.schedule.classList.remove('error');\n self.emit('load');\n};\n\nself._handleError = function (event) {\n var request = event.target;\n var error = void 0;\n if (request.status === 404) {\n error = 'Sorry, er is (nog) geen rooster voor deze week.';\n } else {\n error = 'Sorry, er is iets mis gegaan tijdens het laden van deze week.';\n }\n self._removeChilds();\n self._nodes.schedule.textContent = error;\n self._nodes.schedule.classList.add('error');\n self.emit('load');\n};\n\nself._getURLOfUser = function (week, user) {\n return '/get/' + user.type + '/' + user.value + '?week=' + week;\n};\n\nself._removeChilds = function () {\n while (self._nodes.schedule.firstChild) {\n self._nodes.schedule.removeChild(self._nodes.schedule.firstChild);\n }\n};\n\nself.viewItem = function (week, selectedUser) {\n if (selectedUser == null) {\n self._removeChilds();\n search.updateDom(selectedUser);\n } else if (VALID_WEEK_NUMBERS.indexOf(week) === -1) {\n self._handleError({ target: { status: 404 } });\n return;\n } else {\n var url = self._getURLOfUser(week, selectedUser);\n\n self._removeChilds();\n\n var request = new window.XMLHttpRequest();\n request.addEventListener('load', self._handleLoad);\n request.addEventListener('error', self._handleError);\n request.open('GET', url, true);\n request.send();\n\n search.updateDom(selectedUser);\n }\n};\n\nmodule.exports = self;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9wdWJsaWMvamF2YXNjcmlwdHMvc2NoZWR1bGUuanM/ZGZjNSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBnbG9iYWwgVkFMSURfV0VFS19OVU1CRVJTICovXG5cbmNvbnN0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ2V2ZW50cycpXG5jb25zdCBzZWFyY2ggPSByZXF1aXJlKCcuL3NlYXJjaCcpXG5cbmNvbnN0IHNlbGYgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuc2VsZi5fbm9kZXMgPSB7XG4gIHNjaGVkdWxlOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2NoZWR1bGUnKVxufVxuXG5zZWxmLl9wYXJzZU1lZXRpbmdwb2ludEhUTUwgPSBmdW5jdGlvbiAoaHRtbFN0cikge1xuICBjb25zdCBodG1sID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaHRtbCcpXG4gIGh0bWwuaW5uZXJIVE1MID0gaHRtbFN0clxuICBjb25zdCBjZW50ZXJOb2RlID0gaHRtbC5xdWVyeVNlbGVjdG9yKCdjZW50ZXInKVxuICByZXR1cm4gY2VudGVyTm9kZVxufVxuXG5zZWxmLl9oYW5kbGVMb2FkID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gIGNvbnN0IHJlcXVlc3QgPSBldmVudC50YXJnZXRcbiAgaWYgKHJlcXVlc3Quc3RhdHVzIDwgMjAwIHx8IHJlcXVlc3Quc3RhdHVzID49IDQwMCkge1xuICAgIHNlbGYuX2hhbmRsZUVycm9yKGV2ZW50KVxuICAgIHJldHVyblxuICB9XG4gIGNvbnN0IGRvY3VtZW50ID0gc2VsZi5fcGFyc2VNZWV0aW5ncG9pbnRIVE1MKHJlcXVlc3QucmVzcG9uc2UpXG4gIHNlbGYuX3JlbW92ZUNoaWxkcygpXG4gIHNlbGYuX25vZGVzLnNjaGVkdWxlLmFwcGVuZENoaWxkKGRvY3VtZW50KVxuICBzZWxmLl9ub2Rlcy5zY2hlZHVsZS5jbGFzc0xpc3QucmVtb3ZlKCdlcnJvcicpXG4gIHNlbGYuZW1pdCgnbG9hZCcpXG59XG5cbnNlbGYuX2hhbmRsZUVycm9yID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gIGNvbnN0IHJlcXVlc3QgPSBldmVudC50YXJnZXRcbiAgbGV0IGVycm9yXG4gIGlmIChyZXF1ZXN0LnN0YXR1cyA9PT0gNDA0KSB7XG4gICAgZXJyb3IgPSAnU29ycnksIGVyIGlzIChub2cpIGdlZW4gcm9vc3RlciB2b29yIGRlemUgd2Vlay4nXG4gIH0gZWxzZSB7XG4gICAgZXJyb3IgPSAnU29ycnksIGVyIGlzIGlldHMgbWlzIGdlZ2FhbiB0aWpkZW5zIGhldCBsYWRlbiB2YW4gZGV6ZSB3ZWVrLidcbiAgfVxuICBzZWxmLl9yZW1vdmVDaGlsZHMoKVxuICBzZWxmLl9ub2Rlcy5zY2hlZHVsZS50ZXh0Q29udGVudCA9IGVycm9yXG4gIHNlbGYuX25vZGVzLnNjaGVkdWxlLmNsYXNzTGlzdC5hZGQoJ2Vycm9yJylcbiAgc2VsZi5lbWl0KCdsb2FkJylcbn1cblxuc2VsZi5fZ2V0VVJMT2ZVc2VyID0gZnVuY3Rpb24gKHdlZWssIHVzZXIpIHtcbiAgcmV0dXJuIGAvZ2V0LyR7dXNlci50eXBlfS8ke3VzZXIudmFsdWV9P3dlZWs9JHt3ZWVrfWBcbn1cblxuc2VsZi5fcmVtb3ZlQ2hpbGRzID0gZnVuY3Rpb24gKCkge1xuICB3aGlsZSAoc2VsZi5fbm9kZXMuc2NoZWR1bGUuZmlyc3RDaGlsZCkge1xuICAgIHNlbGYuX25vZGVzLnNjaGVkdWxlLnJlbW92ZUNoaWxkKHNlbGYuX25vZGVzLnNjaGVkdWxlLmZpcnN0Q2hpbGQpXG4gIH1cbn1cblxuc2VsZi52aWV3SXRlbSA9IGZ1bmN0aW9uICh3ZWVrLCBzZWxlY3RlZFVzZXIpIHtcbiAgaWYgKHNlbGVjdGVkVXNlciA9PSBudWxsKSB7XG4gICAgc2VsZi5fcmVtb3ZlQ2hpbGRzKClcbiAgICBzZWFyY2gudXBkYXRlRG9tKHNlbGVjdGVkVXNlcilcbiAgfSBlbHNlIGlmIChWQUxJRF9XRUVLX05VTUJFUlMuaW5kZXhPZih3ZWVrKSA9PT0gLTEpIHtcbiAgICBzZWxmLl9oYW5kbGVFcnJvcih7IHRhcmdldDogeyBzdGF0dXM6IDQwNCB9IH0pO1xuICAgIHJldHVyblxuICB9IGVsc2Uge1xuICAgIGNvbnN0IHVybCA9IHNlbGYuX2dldFVSTE9mVXNlcih3ZWVrLCBzZWxlY3RlZFVzZXIpXG5cbiAgICBzZWxmLl9yZW1vdmVDaGlsZHMoKVxuXG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyB3aW5kb3cuWE1MSHR0cFJlcXVlc3QoKVxuICAgIHJlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIHNlbGYuX2hhbmRsZUxvYWQpXG4gICAgcmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIHNlbGYuX2hhbmRsZUVycm9yKVxuICAgIHJlcXVlc3Qub3BlbignR0VUJywgdXJsLCB0cnVlKVxuICAgIHJlcXVlc3Quc2VuZCgpXG5cbiAgICBzZWFyY2gudXBkYXRlRG9tKHNlbGVjdGVkVXNlcilcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNlbGZcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBwdWJsaWMvamF2YXNjcmlwdHMvc2NoZWR1bGUuanMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBREE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1\n");
+
+/***/ }),
+/* 2 */
+/*!**************************************!*\
+ !*** ./public/javascripts/search.js ***!
+ \**************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\n/* global USERS */\n\nvar EventEmitter = __webpack_require__(/*! events */ 0);\nvar fuzzy = __webpack_require__(/*! fuzzy */ 7);\nvar autocomplete = __webpack_require__(/*! ./autocomplete */ 8);\nvar browserFixToolkit = __webpack_require__(/*! ./browserFixToolkit */ 3);\n\nvar self = new EventEmitter();\n\nself._nodes = {\n search: document.querySelector('#search'),\n input: document.querySelector('input[type=\"search\"]')\n};\n\nself.submit = function () {\n var selectedUser = autocomplete.getSelectedUser();\n if (selectedUser == null) return;\n\n console.log(selectedUser);\n\n self._nodes.input.blur();\n document.body.classList.remove('week-selector-not-visible'); // Safari bug\n\n self.emit('search', selectedUser);\n};\n\nself.updateDom = function (selectedUser) {\n if (selectedUser == null) {\n self._nodes.input.value = '';\n autocomplete.removeAllItems();\n document.body.classList.add('no-input');\n document.body.classList.remove('searched');\n } else {\n self._nodes.input.value = selectedUser.value;\n autocomplete.removeAllItems();\n document.body.classList.remove('no-input');\n document.body.classList.add('searched');\n }\n};\n\nself.focus = function () {\n self._nodes.input.focus();\n};\n\nself._handleSubmit = function (event) {\n event.preventDefault();\n self.submit();\n};\n\nself._calculate = function (searchTerm) {\n var allResults = fuzzy.filter(searchTerm, USERS, {\n extract: function extract(user) {\n return user.value;\n }\n });\n var firstResults = allResults.slice(0, 7);\n\n var originalResults = firstResults.map(function (result) {\n return result.original;\n });\n\n return originalResults;\n};\n\nself._handleTextUpdate = function () {\n var results = self._calculate(self._nodes.input.value);\n\n autocomplete.removeAllItems();\n for (var i = 0; i < results.length; i++) {\n autocomplete.addItem(results[i]);\n }\n};\n\nself._handleFocus = function () {\n self._nodes.input.select();\n};\n\nself._handleBlur = function () {\n // this will removed the selection without drawing focus on it (safari)\n // this will removed selection even when focusing an iframe (chrome)\n var oldValue = self._nodes.value;\n self._nodes.value = '';\n self._nodes.value = oldValue;\n\n // this will hide the keyboard (iOS safari)\n document.activeElement.blur();\n};\n\nautocomplete.on('select', self.submit);\n\nself._nodes.search.addEventListener('submit', self._handleSubmit);\nself._nodes.input.addEventListener('focus', self._handleFocus);\nself._nodes.input.addEventListener('blur', self._handleBlur);\nself._nodes.input.addEventListener(browserFixToolkit.inputEvent, self._handleTextUpdate);\n\nmodule.exports = self;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9wdWJsaWMvamF2YXNjcmlwdHMvc2VhcmNoLmpzPzljNzgiXSwic291cmNlc0NvbnRlbnQiOlsiLyogZ2xvYmFsIFVTRVJTICovXG5cbmNvbnN0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ2V2ZW50cycpXG5jb25zdCBmdXp6eSA9IHJlcXVpcmUoJ2Z1enp5JylcbmNvbnN0IGF1dG9jb21wbGV0ZSA9IHJlcXVpcmUoJy4vYXV0b2NvbXBsZXRlJylcbmNvbnN0IGJyb3dzZXJGaXhUb29sa2l0ID0gcmVxdWlyZSgnLi9icm93c2VyRml4VG9vbGtpdCcpXG5cbmNvbnN0IHNlbGYgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuc2VsZi5fbm9kZXMgPSB7XG4gIHNlYXJjaDogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3NlYXJjaCcpLFxuICBpbnB1dDogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbdHlwZT1cInNlYXJjaFwiXScpXG59XG5cbnNlbGYuc3VibWl0ID0gZnVuY3Rpb24gKCkge1xuICBjb25zdCBzZWxlY3RlZFVzZXIgPSBhdXRvY29tcGxldGUuZ2V0U2VsZWN0ZWRVc2VyKClcbiAgaWYgKHNlbGVjdGVkVXNlciA9PSBudWxsKSByZXR1cm5cblxuICBjb25zb2xlLmxvZyhzZWxlY3RlZFVzZXIpXG5cbiAgc2VsZi5fbm9kZXMuaW5wdXQuYmx1cigpXG4gIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnd2Vlay1zZWxlY3Rvci1ub3QtdmlzaWJsZScpIC8vIFNhZmFyaSBidWdcblxuICBzZWxmLmVtaXQoJ3NlYXJjaCcsIHNlbGVjdGVkVXNlcilcbn1cblxuc2VsZi51cGRhdGVEb20gPSBmdW5jdGlvbiAoc2VsZWN0ZWRVc2VyKSB7XG4gIGlmIChzZWxlY3RlZFVzZXIgPT0gbnVsbCkge1xuICAgIHNlbGYuX25vZGVzLmlucHV0LnZhbHVlID0gJydcbiAgICBhdXRvY29tcGxldGUucmVtb3ZlQWxsSXRlbXMoKVxuICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnbm8taW5wdXQnKVxuICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnc2VhcmNoZWQnKVxuICB9IGVsc2Uge1xuICAgIHNlbGYuX25vZGVzLmlucHV0LnZhbHVlID0gc2VsZWN0ZWRVc2VyLnZhbHVlXG4gICAgYXV0b2NvbXBsZXRlLnJlbW92ZUFsbEl0ZW1zKClcbiAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ25vLWlucHV0JylcbiAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ3NlYXJjaGVkJylcbiAgfVxufVxuXG5zZWxmLmZvY3VzID0gZnVuY3Rpb24gKCkge1xuICBzZWxmLl9ub2Rlcy5pbnB1dC5mb2N1cygpXG59XG5cbnNlbGYuX2hhbmRsZVN1Ym1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpXG4gIHNlbGYuc3VibWl0KClcbn1cblxuc2VsZi5fY2FsY3VsYXRlID0gZnVuY3Rpb24gKHNlYXJjaFRlcm0pIHtcbiAgY29uc3QgYWxsUmVzdWx0cyA9IGZ1enp5LmZpbHRlcihzZWFyY2hUZXJtLCBVU0VSUywge1xuICAgIGV4dHJhY3Q6IGZ1bmN0aW9uICh1c2VyKSB7IHJldHVybiB1c2VyLnZhbHVlIH1cbiAgfSlcbiAgY29uc3QgZmlyc3RSZXN1bHRzID0gYWxsUmVzdWx0cy5zbGljZSgwLCA3KVxuXG4gIGNvbnN0IG9yaWdpbmFsUmVzdWx0cyA9IGZpcnN0UmVzdWx0cy5tYXAoZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgIHJldHVybiByZXN1bHQub3JpZ2luYWxcbiAgfSlcblxuICByZXR1cm4gb3JpZ2luYWxSZXN1bHRzXG59XG5cbnNlbGYuX2hhbmRsZVRleHRVcGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IHJlc3VsdHMgPSBzZWxmLl9jYWxjdWxhdGUoc2VsZi5fbm9kZXMuaW5wdXQudmFsdWUpXG5cbiAgYXV0b2NvbXBsZXRlLnJlbW92ZUFsbEl0ZW1zKClcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRzLmxlbmd0aDsgaSsrKSB7XG4gICAgYXV0b2NvbXBsZXRlLmFkZEl0ZW0ocmVzdWx0c1tpXSlcbiAgfVxufVxuXG5zZWxmLl9oYW5kbGVGb2N1cyA9IGZ1bmN0aW9uICgpIHtcbiAgc2VsZi5fbm9kZXMuaW5wdXQuc2VsZWN0KClcbn1cblxuc2VsZi5faGFuZGxlQmx1ciA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gdGhpcyB3aWxsIHJlbW92ZWQgdGhlIHNlbGVjdGlvbiB3aXRob3V0IGRyYXdpbmcgZm9jdXMgb24gaXQgKHNhZmFyaSlcbiAgLy8gdGhpcyB3aWxsIHJlbW92ZWQgc2VsZWN0aW9uIGV2ZW4gd2hlbiBmb2N1c2luZyBhbiBpZnJhbWUgKGNocm9tZSlcbiAgY29uc3Qgb2xkVmFsdWUgPSBzZWxmLl9ub2Rlcy52YWx1ZVxuICBzZWxmLl9ub2Rlcy52YWx1ZSA9ICcnXG4gIHNlbGYuX25vZGVzLnZhbHVlID0gb2xkVmFsdWVcblxuICAvLyB0aGlzIHdpbGwgaGlkZSB0aGUga2V5Ym9hcmQgKGlPUyBzYWZhcmkpXG4gIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQuYmx1cigpXG59XG5cbmF1dG9jb21wbGV0ZS5vbignc2VsZWN0Jywgc2VsZi5zdWJtaXQpXG5cbnNlbGYuX25vZGVzLnNlYXJjaC5hZGRFdmVudExpc3RlbmVyKCdzdWJtaXQnLCBzZWxmLl9oYW5kbGVTdWJtaXQpXG5zZWxmLl9ub2Rlcy5pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdmb2N1cycsIHNlbGYuX2hhbmRsZUZvY3VzKVxuc2VsZi5fbm9kZXMuaW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsIHNlbGYuX2hhbmRsZUJsdXIpXG5zZWxmLl9ub2Rlcy5pbnB1dC5hZGRFdmVudExpc3RlbmVyKGJyb3dzZXJGaXhUb29sa2l0LmlucHV0RXZlbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2hhbmRsZVRleHRVcGRhdGUpXG5cbm1vZHVsZS5leHBvcnRzID0gc2VsZlxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIHB1YmxpYy9qYXZhc2NyaXB0cy9zZWFyY2guanMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2\n");
+
+/***/ }),
+/* 3 */
+/*!*************************************************!*\
+ !*** ./public/javascripts/browserFixToolkit.js ***!
+ \*************************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\nvar self = {};\n\nself.isIE = navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0;\n\nif (self.isIE) {\n self.inputEvent = 'textinput';\n} else {\n self.inputEvent = 'input';\n}\n\nmodule.exports = self;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9wdWJsaWMvamF2YXNjcmlwdHMvYnJvd3NlckZpeFRvb2xraXQuanM/MjJlNyJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBzZWxmID0ge31cblxuc2VsZi5pc0lFID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdNU0lFJykgIT09IC0xIHx8XG4gICAgICAgICAgICBuYXZpZ2F0b3IuYXBwVmVyc2lvbi5pbmRleE9mKCdUcmlkZW50LycpID4gMFxuXG5pZiAoc2VsZi5pc0lFKSB7XG4gIHNlbGYuaW5wdXRFdmVudCA9ICd0ZXh0aW5wdXQnXG59IGVsc2Uge1xuICBzZWxmLmlucHV0RXZlbnQgPSAnaW5wdXQnXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2VsZlxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIHB1YmxpYy9qYXZhc2NyaXB0cy9icm93c2VyRml4VG9vbGtpdC5qcyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3\n");
+
+/***/ }),
+/* 4 */
+/*!************************************!*\
+ !*** ./public/javascripts/main.js ***!
+ \************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\n__webpack_require__(/*! ./featureDetect */ 5).check();\n__webpack_require__(/*! ./zoom */ 6);\n\nvar frontpage = __webpack_require__(/*! ./frontpage */ 9);\nvar search = __webpack_require__(/*! ./search */ 2);\nvar schedule = __webpack_require__(/*! ./schedule */ 1);\nvar weekSelector = __webpack_require__(/*! ./weekSelector */ 10);\nvar favorite = __webpack_require__(/*! ./favorite */ 11);\nvar scrollSnap = __webpack_require__(/*! ./scrollSnap */ 12);\nvar analytics = __webpack_require__(/*! ./analytics */ 14);\nvar url = __webpack_require__(/*! ./url */ 15);\n\nvar state = {};\n\nwindow.state = state;\n\nfrontpage.show();\nweekSelector.updateCurrentWeek();\nscrollSnap.startListening();\n\nif (url.hasSelectedUser()) {\n state.selectedUser = url.getSelectedUser();\n\n favorite.update(state.selectedUser);\n url.update(state.selectedUser);\n analytics.send.search(state.selectedUser);\n\n schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedUser);\n} else if (favorite.get() != null) {\n state.selectedUser = favorite.get();\n\n favorite.update(state.selectedUser);\n url.push(state.selectedUser, false);\n url.update(state.selectedUser);\n analytics.send.search(state.selectedUser, true);\n\n schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedUser);\n} else {\n search.focus();\n}\n\nsearch.on('search', function (selectedUser) {\n state.selectedUser = selectedUser;\n\n favorite.update(state.selectedUser);\n url.push(state.selectedUser);\n url.update(state.selectedUser);\n analytics.send.search(state.selectedUser);\n\n schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedUser);\n});\n\nurl.on('update', function (selectedUser) {\n state.selectedUser = selectedUser;\n\n favorite.update(state.selectedUser);\n url.update(state.selectedUser);\n\n schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedUser);\n});\n\nweekSelector.on('weekChanged', function (newWeek) {\n analytics.send.search(state.selectedUser);\n schedule.viewItem(newWeek, state.selectedUser);\n});\n\nfavorite.on('click', function () {\n favorite.toggle(state.selectedUser);\n});\n\ndocument.body.style.opacity = 1;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9wdWJsaWMvamF2YXNjcmlwdHMvbWFpbi5qcz9kYTJjIl0sInNvdXJjZXNDb250ZW50IjpbInJlcXVpcmUoJy4vZmVhdHVyZURldGVjdCcpLmNoZWNrKClcbnJlcXVpcmUoJy4vem9vbScpXG5cbmNvbnN0IGZyb250cGFnZSA9IHJlcXVpcmUoJy4vZnJvbnRwYWdlJylcbmNvbnN0IHNlYXJjaCA9IHJlcXVpcmUoJy4vc2VhcmNoJylcbmNvbnN0IHNjaGVkdWxlID0gcmVxdWlyZSgnLi9zY2hlZHVsZScpXG5jb25zdCB3ZWVrU2VsZWN0b3IgPSByZXF1aXJlKCcuL3dlZWtTZWxlY3RvcicpXG5jb25zdCBmYXZvcml0ZSA9IHJlcXVpcmUoJy4vZmF2b3JpdGUnKVxuY29uc3Qgc2Nyb2xsU25hcCA9IHJlcXVpcmUoJy4vc2Nyb2xsU25hcCcpXG5jb25zdCBhbmFseXRpY3MgPSByZXF1aXJlKCcuL2FuYWx5dGljcycpXG5jb25zdCB1cmwgPSByZXF1aXJlKCcuL3VybCcpXG5cbmNvbnN0IHN0YXRlID0ge31cblxud2luZG93LnN0YXRlID0gc3RhdGVcblxuZnJvbnRwYWdlLnNob3coKVxud2Vla1NlbGVjdG9yLnVwZGF0ZUN1cnJlbnRXZWVrKClcbnNjcm9sbFNuYXAuc3RhcnRMaXN0ZW5pbmcoKVxuXG5pZiAodXJsLmhhc1NlbGVjdGVkVXNlcigpKSB7XG4gIHN0YXRlLnNlbGVjdGVkVXNlciA9IHVybC5nZXRTZWxlY3RlZFVzZXIoKVxuXG4gIGZhdm9yaXRlLnVwZGF0ZShzdGF0ZS5zZWxlY3RlZFVzZXIpXG4gIHVybC51cGRhdGUoc3RhdGUuc2VsZWN0ZWRVc2VyKVxuICBhbmFseXRpY3Muc2VuZC5zZWFyY2goc3RhdGUuc2VsZWN0ZWRVc2VyKVxuXG4gIHNjaGVkdWxlLnZpZXdJdGVtKHdlZWtTZWxlY3Rvci5nZXRTZWxlY3RlZFdlZWsoKSwgc3RhdGUuc2VsZWN0ZWRVc2VyKVxufSBlbHNlIGlmIChmYXZvcml0ZS5nZXQoKSAhPSBudWxsKSB7XG4gIHN0YXRlLnNlbGVjdGVkVXNlciA9IGZhdm9yaXRlLmdldCgpXG5cbiAgZmF2b3JpdGUudXBkYXRlKHN0YXRlLnNlbGVjdGVkVXNlcilcbiAgdXJsLnB1c2goc3RhdGUuc2VsZWN0ZWRVc2VyLCBmYWxzZSlcbiAgdXJsLnVwZGF0ZShzdGF0ZS5zZWxlY3RlZFVzZXIpXG4gIGFuYWx5dGljcy5zZW5kLnNlYXJjaChzdGF0ZS5zZWxlY3RlZFVzZXIsIHRydWUpXG5cbiAgc2NoZWR1bGUudmlld0l0ZW0od2Vla1NlbGVjdG9yLmdldFNlbGVjdGVkV2VlaygpLCBzdGF0ZS5zZWxlY3RlZFVzZXIpXG59IGVsc2Uge1xuICBzZWFyY2guZm9jdXMoKVxufVxuXG5zZWFyY2gub24oJ3NlYXJjaCcsIGZ1bmN0aW9uIChzZWxlY3RlZFVzZXIpIHtcbiAgc3RhdGUuc2VsZWN0ZWRVc2VyID0gc2VsZWN0ZWRVc2VyXG5cbiAgZmF2b3JpdGUudXBkYXRlKHN0YXRlLnNlbGVjdGVkVXNlcilcbiAgdXJsLnB1c2goc3RhdGUuc2VsZWN0ZWRVc2VyKVxuICB1cmwudXBkYXRlKHN0YXRlLnNlbGVjdGVkVXNlcilcbiAgYW5hbHl0aWNzLnNlbmQuc2VhcmNoKHN0YXRlLnNlbGVjdGVkVXNlcilcblxuICBzY2hlZHVsZS52aWV3SXRlbSh3ZWVrU2VsZWN0b3IuZ2V0U2VsZWN0ZWRXZWVrKCksIHN0YXRlLnNlbGVjdGVkVXNlcilcbn0pXG5cbnVybC5vbigndXBkYXRlJywgZnVuY3Rpb24gKHNlbGVjdGVkVXNlcikge1xuICBzdGF0ZS5zZWxlY3RlZFVzZXIgPSBzZWxlY3RlZFVzZXJcblxuICBmYXZvcml0ZS51cGRhdGUoc3RhdGUuc2VsZWN0ZWRVc2VyKVxuICB1cmwudXBkYXRlKHN0YXRlLnNlbGVjdGVkVXNlcilcblxuICBzY2hlZHVsZS52aWV3SXRlbSh3ZWVrU2VsZWN0b3IuZ2V0U2VsZWN0ZWRXZWVrKCksIHN0YXRlLnNlbGVjdGVkVXNlcilcbn0pXG5cbndlZWtTZWxlY3Rvci5vbignd2Vla0NoYW5nZWQnLCBmdW5jdGlvbiAobmV3V2Vlaykge1xuICBhbmFseXRpY3Muc2VuZC5zZWFyY2goc3RhdGUuc2VsZWN0ZWRVc2VyKVxuICBzY2hlZHVsZS52aWV3SXRlbShuZXdXZWVrLCBzdGF0ZS5zZWxlY3RlZFVzZXIpXG59KVxuXG5mYXZvcml0ZS5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gIGZhdm9yaXRlLnRvZ2dsZShzdGF0ZS5zZWxlY3RlZFVzZXIpXG59KVxuXG5kb2N1bWVudC5ib2R5LnN0eWxlLm9wYWNpdHkgPSAxXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gcHVibGljL2phdmFzY3JpcHRzL21haW4uanMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4\n");
+
+/***/ }),
+/* 5 */
+/*!*********************************************!*\
+ !*** ./public/javascripts/featureDetect.js ***!
+ \*********************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\n/* global FLAGS */\n\nvar self = {};\n\nself._nodes = {\n input: document.querySelector('input[type=\"search\"]'),\n overflowButton: document.querySelector('#overflow-button')\n};\n\nself._shouldCheck = function () {\n return FLAGS.indexOf('NO_FEATURE_DETECT') === -1;\n};\n\nself._redirect = function () {\n window.location.href = 'http://www.meetingpointmco.nl/Roosters-AL/doc/';\n};\n\nself.check = function () {\n if (!self._shouldCheck()) return;\n\n window.onerror = self._redirect;\n\n if (self._nodes.input.getClientRects()[0].top !== self._nodes.overflowButton.getClientRects()[0].top) {\n self._redirect();\n }\n};\n\nmodule.exports = self;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9wdWJsaWMvamF2YXNjcmlwdHMvZmVhdHVyZURldGVjdC5qcz8xZGFkIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIGdsb2JhbCBGTEFHUyAqL1xuXG5jb25zdCBzZWxmID0ge31cblxuc2VsZi5fbm9kZXMgPSB7XG4gIGlucHV0OiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPVwic2VhcmNoXCJdJyksXG4gIG92ZXJmbG93QnV0dG9uOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjb3ZlcmZsb3ctYnV0dG9uJylcbn1cblxuc2VsZi5fc2hvdWxkQ2hlY2sgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBGTEFHUy5pbmRleE9mKCdOT19GRUFUVVJFX0RFVEVDVCcpID09PSAtMVxufVxuXG5zZWxmLl9yZWRpcmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSAnaHR0cDovL3d3dy5tZWV0aW5ncG9pbnRtY28ubmwvUm9vc3RlcnMtQUwvZG9jLydcbn1cblxuc2VsZi5jaGVjayA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCFzZWxmLl9zaG91bGRDaGVjaygpKSByZXR1cm5cblxuICB3aW5kb3cub25lcnJvciA9IHNlbGYuX3JlZGlyZWN0XG5cbiAgaWYgKHNlbGYuX25vZGVzLmlucHV0LmdldENsaWVudFJlY3RzKClbMF0udG9wICE9PVxuICAgICAgc2VsZi5fbm9kZXMub3ZlcmZsb3dCdXR0b24uZ2V0Q2xpZW50UmVjdHMoKVswXS50b3ApIHtcbiAgICBzZWxmLl9yZWRpcmVjdCgpXG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZWxmXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gcHVibGljL2phdmFzY3JpcHRzL2ZlYXR1cmVEZXRlY3QuanMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5\n");
+
+/***/ }),
+/* 6 */
+/*!************************************!*\
+ !*** ./public/javascripts/zoom.js ***!
+ \************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\nvar schedule = __webpack_require__(/*! ./schedule */ 1);\n\nvar self = {};\n\nself._nodes = {\n body: document.body\n};\n\nself._handleResize = function () {\n // the table node may not exist before this function is called\n var tableNode = document.querySelector('center > table');\n\n // infact, it may not even exist when this function is called.\n if (!tableNode) return;\n\n var tableWidth = tableNode.getBoundingClientRect().width;\n var tableGoalWidth = self._nodes.body.getBoundingClientRect().width * 0.9;\n var zoomFactor = tableGoalWidth / tableWidth;\n\n if (zoomFactor < 1) {\n tableNode.style.zoom = '' + zoomFactor;\n } else {\n tableNode.style.zoom = '1';\n }\n};\n\nschedule.on('load', self._handleResize);\nwindow.addEventListener('resize', self._handleResize);\n\nmodule.exports = self;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9wdWJsaWMvamF2YXNjcmlwdHMvem9vbS5qcz9iMzM1Il0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHNjaGVkdWxlID0gcmVxdWlyZSgnLi9zY2hlZHVsZScpXG5cbmNvbnN0IHNlbGYgPSB7fVxuXG5zZWxmLl9ub2RlcyA9IHtcbiAgYm9keTogZG9jdW1lbnQuYm9keVxufVxuXG5zZWxmLl9oYW5kbGVSZXNpemUgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIHRoZSB0YWJsZSBub2RlIG1heSBub3QgZXhpc3QgYmVmb3JlIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkXG4gIGNvbnN0IHRhYmxlTm9kZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2NlbnRlciA+IHRhYmxlJylcblxuICAvLyBpbmZhY3QsIGl0IG1heSBub3QgZXZlbiBleGlzdCB3aGVuIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkLlxuICBpZiAoIXRhYmxlTm9kZSkgcmV0dXJuXG5cbiAgY29uc3QgdGFibGVXaWR0aCA9IHRhYmxlTm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aFxuICBjb25zdCB0YWJsZUdvYWxXaWR0aCA9IHNlbGYuX25vZGVzLmJvZHkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGggKiAwLjlcbiAgY29uc3Qgem9vbUZhY3RvciA9IHRhYmxlR29hbFdpZHRoIC8gdGFibGVXaWR0aFxuXG4gIGlmICh6b29tRmFjdG9yIDwgMSkge1xuICAgIHRhYmxlTm9kZS5zdHlsZS56b29tID0gYCR7em9vbUZhY3Rvcn1gXG4gIH0gZWxzZSB7XG4gICAgdGFibGVOb2RlLnN0eWxlLnpvb20gPSBgMWBcbiAgfVxufVxuXG5zY2hlZHVsZS5vbignbG9hZCcsIHNlbGYuX2hhbmRsZVJlc2l6ZSlcbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBzZWxmLl9oYW5kbGVSZXNpemUpXG5cbm1vZHVsZS5leHBvcnRzID0gc2VsZlxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIHB1YmxpYy9qYXZhc2NyaXB0cy96b29tLmpzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6\n");
+
+/***/ }),
+/* 7 */
+/*!*****************************************!*\
+ !*** ./node_modules/fuzzy/lib/fuzzy.js ***!
+ \*****************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+eval("/*\n * Fuzzy\n * https://github.com/myork/fuzzy\n *\n * Copyright (c) 2012 Matt York\n * Licensed under the MIT license.\n */\n\n(function() {\n\nvar root = this;\n\nvar fuzzy = {};\n\n// Use in node or in browser\nif (true) {\n module.exports = fuzzy;\n} else {\n root.fuzzy = fuzzy;\n}\n\n// Return all elements of `array` that have a fuzzy\n// match against `pattern`.\nfuzzy.simpleFilter = function(pattern, array) {\n return array.filter(function(str) {\n return fuzzy.test(pattern, str);\n });\n};\n\n// Does `pattern` fuzzy match `str`?\nfuzzy.test = function(pattern, str) {\n return fuzzy.match(pattern, str) !== null;\n};\n\n// If `pattern` matches `str`, wrap each matching character\n// in `opts.pre` and `opts.post`. If no match, return null\nfuzzy.match = function(pattern, str, opts) {\n opts = opts || {};\n var patternIdx = 0\n , result = []\n , len = str.length\n , totalScore = 0\n , currScore = 0\n // prefix\n , pre = opts.pre || ''\n // suffix\n , post = opts.post || ''\n // String to compare against. This might be a lowercase version of the\n // raw string\n , compareString = opts.caseSensitive && str || str.toLowerCase()\n , ch;\n\n pattern = opts.caseSensitive && pattern || pattern.toLowerCase();\n\n // For each character in the string, either add it to the result\n // or wrap in template if it's the next string in the pattern\n for(var idx = 0; idx < len; idx++) {\n ch = str[idx];\n if(compareString[idx] === pattern[patternIdx]) {\n ch = pre + ch + post;\n patternIdx += 1;\n\n // consecutive characters should increase the score more than linearly\n currScore += 1 + currScore;\n } else {\n currScore = 0;\n }\n totalScore += currScore;\n result[result.length] = ch;\n }\n\n // return rendered string if we have a match for every char\n if(patternIdx === pattern.length) {\n // if the string is an exact match with pattern, totalScore should be maxed\n totalScore = (compareString === pattern) ? Infinity : totalScore;\n return {rendered: result.join(''), score: totalScore};\n }\n\n return null;\n};\n\n// The normal entry point. Filters `arr` for matches against `pattern`.\n// It returns an array with matching values of the type:\n//\n// [{\n// string: '<b>lah' // The rendered string\n// , index: 2 // The index of the element in `arr`\n// , original: 'blah' // The original element in `arr`\n// }]\n//\n// `opts` is an optional argument bag. Details:\n//\n// opts = {\n// // string to put before a matching character\n// pre: '<b>'\n//\n// // string to put after matching character\n// , post: '</b>'\n//\n// // Optional function. Input is an entry in the given arr`,\n// // output should be the string to test `pattern` against.\n// // In this example, if `arr = [{crying: 'koala'}]` we would return\n// // 'koala'.\n// , extract: function(arg) { return arg.crying; }\n// }\nfuzzy.filter = function(pattern, arr, opts) {\n if(!arr || arr.length === 0) {\n return [];\n }\n if (typeof pattern !== 'string') {\n return arr;\n }\n opts = opts || {};\n return arr\n .reduce(function(prev, element, idx, arr) {\n var str = element;\n if(opts.extract) {\n str = opts.extract(element);\n }\n var rendered = fuzzy.match(pattern, str, opts);\n if(rendered != null) {\n prev[prev.length] = {\n string: rendered.rendered\n , score: rendered.score\n , index: idx\n , original: element\n };\n }\n return prev;\n }, [])\n\n // Sort by score. Browsers are inconsistent wrt stable/unstable\n // sorting, so force stable by using the index in the case of tie.\n // See http://ofb.net/~sethml/is-sort-stable.html\n .sort(function(a,b) {\n var compare = b.score - a.score;\n if(compare) return compare;\n return a.index - b.index;\n });\n};\n\n\n}());\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9mdXp6eS9saWIvZnV6enkuanM/M2VmZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogRnV6enlcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9teW9yay9mdXp6eVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMiBNYXR0IFlvcmtcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cbiAqL1xuXG4oZnVuY3Rpb24oKSB7XG5cbnZhciByb290ID0gdGhpcztcblxudmFyIGZ1enp5ID0ge307XG5cbi8vIFVzZSBpbiBub2RlIG9yIGluIGJyb3dzZXJcbmlmICh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdXp6eTtcbn0gZWxzZSB7XG4gIHJvb3QuZnV6enkgPSBmdXp6eTtcbn1cblxuLy8gUmV0dXJuIGFsbCBlbGVtZW50cyBvZiBgYXJyYXlgIHRoYXQgaGF2ZSBhIGZ1enp5XG4vLyBtYXRjaCBhZ2FpbnN0IGBwYXR0ZXJuYC5cbmZ1enp5LnNpbXBsZUZpbHRlciA9IGZ1bmN0aW9uKHBhdHRlcm4sIGFycmF5KSB7XG4gIHJldHVybiBhcnJheS5maWx0ZXIoZnVuY3Rpb24oc3RyKSB7XG4gICAgcmV0dXJuIGZ1enp5LnRlc3QocGF0dGVybiwgc3RyKTtcbiAgfSk7XG59O1xuXG4vLyBEb2VzIGBwYXR0ZXJuYCBmdXp6eSBtYXRjaCBgc3RyYD9cbmZ1enp5LnRlc3QgPSBmdW5jdGlvbihwYXR0ZXJuLCBzdHIpIHtcbiAgcmV0dXJuIGZ1enp5Lm1hdGNoKHBhdHRlcm4sIHN0cikgIT09IG51bGw7XG59O1xuXG4vLyBJZiBgcGF0dGVybmAgbWF0Y2hlcyBgc3RyYCwgd3JhcCBlYWNoIG1hdGNoaW5nIGNoYXJhY3RlclxuLy8gaW4gYG9wdHMucHJlYCBhbmQgYG9wdHMucG9zdGAuIElmIG5vIG1hdGNoLCByZXR1cm4gbnVsbFxuZnV6enkubWF0Y2ggPSBmdW5jdGlvbihwYXR0ZXJuLCBzdHIsIG9wdHMpIHtcbiAgb3B0cyA9IG9wdHMgfHwge307XG4gIHZhciBwYXR0ZXJuSWR4ID0gMFxuICAgICwgcmVzdWx0ID0gW11cbiAgICAsIGxlbiA9IHN0ci5sZW5ndGhcbiAgICAsIHRvdGFsU2NvcmUgPSAwXG4gICAgLCBjdXJyU2NvcmUgPSAwXG4gICAgLy8gcHJlZml4XG4gICAgLCBwcmUgPSBvcHRzLnByZSB8fCAnJ1xuICAgIC8vIHN1ZmZpeFxuICAgICwgcG9zdCA9IG9wdHMucG9zdCB8fCAnJ1xuICAgIC8vIFN0cmluZyB0byBjb21wYXJlIGFnYWluc3QuIFRoaXMgbWlnaHQgYmUgYSBsb3dlcmNhc2UgdmVyc2lvbiBvZiB0aGVcbiAgICAvLyByYXcgc3RyaW5nXG4gICAgLCBjb21wYXJlU3RyaW5nID0gIG9wdHMuY2FzZVNlbnNpdGl2ZSAmJiBzdHIgfHwgc3RyLnRvTG93ZXJDYXNlKClcbiAgICAsIGNoO1xuXG4gIHBhdHRlcm4gPSBvcHRzLmNhc2VTZW5zaXRpdmUgJiYgcGF0dGVybiB8fCBwYXR0ZXJuLnRvTG93ZXJDYXNlKCk7XG5cbiAgLy8gRm9yIGVhY2ggY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcsIGVpdGhlciBhZGQgaXQgdG8gdGhlIHJlc3VsdFxuICAvLyBvciB3cmFwIGluIHRlbXBsYXRlIGlmIGl0J3MgdGhlIG5leHQgc3RyaW5nIGluIHRoZSBwYXR0ZXJuXG4gIGZvcih2YXIgaWR4ID0gMDsgaWR4IDwgbGVuOyBpZHgrKykge1xuICAgIGNoID0gc3RyW2lkeF07XG4gICAgaWYoY29tcGFyZVN0cmluZ1tpZHhdID09PSBwYXR0ZXJuW3BhdHRlcm5JZHhdKSB7XG4gICAgICBjaCA9IHByZSArIGNoICsgcG9zdDtcbiAgICAgIHBhdHRlcm5JZHggKz0gMTtcblxuICAgICAgLy8gY29uc2VjdXRpdmUgY2hhcmFjdGVycyBzaG91bGQgaW5jcmVhc2UgdGhlIHNjb3JlIG1vcmUgdGhhbiBsaW5lYXJseVxuICAgICAgY3VyclNjb3JlICs9IDEgKyBjdXJyU2NvcmU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJTY29yZSA9IDA7XG4gICAgfVxuICAgIHRvdGFsU2NvcmUgKz0gY3VyclNjb3JlO1xuICAgIHJlc3VsdFtyZXN1bHQubGVuZ3RoXSA9IGNoO1xuICB9XG5cbiAgLy8gcmV0dXJuIHJlbmRlcmVkIHN0cmluZyBpZiB3ZSBoYXZlIGEgbWF0Y2ggZm9yIGV2ZXJ5IGNoYXJcbiAgaWYocGF0dGVybklkeCA9PT0gcGF0dGVybi5sZW5ndGgpIHtcbiAgICAvLyBpZiB0aGUgc3RyaW5nIGlzIGFuIGV4YWN0IG1hdGNoIHdpdGggcGF0dGVybiwgdG90YWxTY29yZSBzaG91bGQgYmUgbWF4ZWRcbiAgICB0b3RhbFNjb3JlID0gKGNvbXBhcmVTdHJpbmcgPT09IHBhdHRlcm4pID8gSW5maW5pdHkgOiB0b3RhbFNjb3JlO1xuICAgIHJldHVybiB7cmVuZGVyZWQ6IHJlc3VsdC5qb2luKCcnKSwgc2NvcmU6IHRvdGFsU2NvcmV9O1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vLyBUaGUgbm9ybWFsIGVudHJ5IHBvaW50LiBGaWx0ZXJzIGBhcnJgIGZvciBtYXRjaGVzIGFnYWluc3QgYHBhdHRlcm5gLlxuLy8gSXQgcmV0dXJucyBhbiBhcnJheSB3aXRoIG1hdGNoaW5nIHZhbHVlcyBvZiB0aGUgdHlwZTpcbi8vXG4vLyAgICAgW3tcbi8vICAgICAgICAgc3RyaW5nOiAgICc8Yj5sYWgnIC8vIFRoZSByZW5kZXJlZCBzdHJpbmdcbi8vICAgICAgICwgaW5kZXg6ICAgIDIgICAgICAgIC8vIFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCBpbiBgYXJyYFxuLy8gICAgICAgLCBvcmlnaW5hbDogJ2JsYWgnICAgLy8gVGhlIG9yaWdpbmFsIGVsZW1lbnQgaW4gYGFycmBcbi8vICAgICB9XVxuLy9cbi8vIGBvcHRzYCBpcyBhbiBvcHRpb25hbCBhcmd1bWVudCBiYWcuIERldGFpbHM6XG4vL1xuLy8gICAgb3B0cyA9IHtcbi8vICAgICAgICAvLyBzdHJpbmcgdG8gcHV0IGJlZm9yZSBhIG1hdGNoaW5nIGNoYXJhY3RlclxuLy8gICAgICAgIHByZTogICAgICc8Yj4nXG4vL1xuLy8gICAgICAgIC8vIHN0cmluZyB0byBwdXQgYWZ0ZXIgbWF0Y2hpbmcgY2hhcmFjdGVyXG4vLyAgICAgICwgcG9zdDogICAgJzwvYj4nXG4vL1xuLy8gICAgICAgIC8vIE9wdGlvbmFsIGZ1bmN0aW9uLiBJbnB1dCBpcyBhbiBlbnRyeSBpbiB0aGUgZ2l2ZW4gYXJyYCxcbi8vICAgICAgICAvLyBvdXRwdXQgc2hvdWxkIGJlIHRoZSBzdHJpbmcgdG8gdGVzdCBgcGF0dGVybmAgYWdhaW5zdC5cbi8vICAgICAgICAvLyBJbiB0aGlzIGV4YW1wbGUsIGlmIGBhcnIgPSBbe2NyeWluZzogJ2tvYWxhJ31dYCB3ZSB3b3VsZCByZXR1cm5cbi8vICAgICAgICAvLyAna29hbGEnLlxuLy8gICAgICAsIGV4dHJhY3Q6IGZ1bmN0aW9uKGFyZykgeyByZXR1cm4gYXJnLmNyeWluZzsgfVxuLy8gICAgfVxuZnV6enkuZmlsdGVyID0gZnVuY3Rpb24ocGF0dGVybiwgYXJyLCBvcHRzKSB7XG4gIGlmKCFhcnIgfHwgYXJyLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBpZiAodHlwZW9mIHBhdHRlcm4gIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGFycjtcbiAgfVxuICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgcmV0dXJuIGFyclxuICAgIC5yZWR1Y2UoZnVuY3Rpb24ocHJldiwgZWxlbWVudCwgaWR4LCBhcnIpIHtcbiAgICAgIHZhciBzdHIgPSBlbGVtZW50O1xuICAgICAgaWYob3B0cy5leHRyYWN0KSB7XG4gICAgICAgIHN0ciA9IG9wdHMuZXh0cmFjdChlbGVtZW50KTtcbiAgICAgIH1cbiAgICAgIHZhciByZW5kZXJlZCA9IGZ1enp5Lm1hdGNoKHBhdHRlcm4sIHN0ciwgb3B0cyk7XG4gICAgICBpZihyZW5kZXJlZCAhPSBudWxsKSB7XG4gICAgICAgIHByZXZbcHJldi5sZW5ndGhdID0ge1xuICAgICAgICAgICAgc3RyaW5nOiByZW5kZXJlZC5yZW5kZXJlZFxuICAgICAgICAgICwgc2NvcmU6IHJlbmRlcmVkLnNjb3JlXG4gICAgICAgICAgLCBpbmRleDogaWR4XG4gICAgICAgICAgLCBvcmlnaW5hbDogZWxlbWVudFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHByZXY7XG4gICAgfSwgW10pXG5cbiAgICAvLyBTb3J0IGJ5IHNjb3JlLiBCcm93c2VycyBhcmUgaW5jb25zaXN0ZW50IHdydCBzdGFibGUvdW5zdGFibGVcbiAgICAvLyBzb3J0aW5nLCBzbyBmb3JjZSBzdGFibGUgYnkgdXNpbmcgdGhlIGluZGV4IGluIHRoZSBjYXNlIG9mIHRpZS5cbiAgICAvLyBTZWUgaHR0cDovL29mYi5uZXQvfnNldGhtbC9pcy1zb3J0LXN0YWJsZS5odG1sXG4gICAgLnNvcnQoZnVuY3Rpb24oYSxiKSB7XG4gICAgICB2YXIgY29tcGFyZSA9IGIuc2NvcmUgLSBhLnNjb3JlO1xuICAgICAgaWYoY29tcGFyZSkgcmV0dXJuIGNvbXBhcmU7XG4gICAgICByZXR1cm4gYS5pbmRleCAtIGIuaW5kZXg7XG4gICAgfSk7XG59O1xuXG5cbn0oKSk7XG5cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2Z1enp5L2xpYi9mdXp6eS5qc1xuLy8gbW9kdWxlIGlkID0gN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7\n");
+
+/***/ }),
+/* 8 */
+/*!********************************************!*\
+ !*** ./public/javascripts/autocomplete.js ***!
+ \********************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\nvar EventEmitter = __webpack_require__(/*! events */ 0);\n\nvar self = new EventEmitter();\n\nself._users = [];\nself._selectedUserIndex = -1;\n\nself._nodes = {\n search: document.querySelector('#search'),\n input: document.querySelector('input[type=\"search\"]'),\n autocomplete: document.querySelector('.autocomplete')\n};\n\nself.getSelectedUser = function () {\n if (self.getItems() === []) return;\n\n if (self.getSelectedUserIndex() === -1) {\n return self.getItems()[0];\n } else {\n return self.getItems()[self.getSelectedUserIndex()];\n }\n};\n\nself.getSelectedUserIndex = function () {\n return self._selectedUserIndex;\n};\n\nself.getItems = function () {\n return self._users;\n};\n\nself.removeAllItems = function () {\n while (self._nodes.autocomplete.firstChild) {\n self._nodes.autocomplete.removeChild(self._nodes.autocomplete.firstChild);\n }\n self._users = [];\n self._selectedUserIndex = -1;\n};\n\nself.addItem = function (user) {\n var listItem = document.createElement('li');\n listItem.textContent = user.value;\n self._nodes.autocomplete.appendChild(listItem);\n self._users.push(user);\n};\n\nself._moveSelected = function (shift) {\n if (self._selectedUserIndex + shift >= self.getItems().length) {\n self._selectedUserIndex = -1;\n } else if (self._selectedUserIndex + shift < -1) {\n self._selectedUserIndex = self.getItems().length - 1;\n } else {\n self._selectedUserIndex += shift;\n }\n\n for (var i = 0; i < self.getItems().length; i++) {\n self._nodes.autocomplete.children[i].classList.remove('selected');\n }\n if (self._selectedUserIndex >= 0) {\n self._nodes.autocomplete.children[self._selectedUserIndex].classList.add('selected');\n }\n};\n\nself._handleItemClick = function (event) {\n if (!self._nodes.autocomplete.contains(event.target)) return;\n var userIndex = Array.prototype.indexOf.call(self._nodes.autocomplete.children, event.target);\n self._selectedUserIndex = userIndex;\n self.emit('select', self.getSelectedUser());\n};\n\nself._handleKeydown = function (event) {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n if (event.key === 'ArrowDown') {\n self._moveSelected(1);\n } else if (event.key === 'ArrowUp') {\n self._moveSelected(-1);\n }\n }\n};\n\nself._nodes.autocomplete.addEventListener('click', self._handleItemClick);\nself._nodes.input.addEventListener('keydown', self._handleKeydown);\n\nmodule.exports = self;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9wdWJsaWMvamF2YXNjcmlwdHMvYXV0b2NvbXBsZXRlLmpzPzY5YzciXSwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJylcblxuY29uc3Qgc2VsZiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG5zZWxmLl91c2VycyA9IFtdXG5zZWxmLl9zZWxlY3RlZFVzZXJJbmRleCA9IC0xXG5cbnNlbGYuX25vZGVzID0ge1xuICBzZWFyY2g6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNzZWFyY2gnKSxcbiAgaW5wdXQ6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W3R5cGU9XCJzZWFyY2hcIl0nKSxcbiAgYXV0b2NvbXBsZXRlOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYXV0b2NvbXBsZXRlJylcbn1cblxuc2VsZi5nZXRTZWxlY3RlZFVzZXIgPSBmdW5jdGlvbiAoKSB7XG4gIGlmIChzZWxmLmdldEl0ZW1zKCkgPT09IFtdKSByZXR1cm5cblxuICBpZiAoc2VsZi5nZXRTZWxlY3RlZFVzZXJJbmRleCgpID09PSAtMSkge1xuICAgIHJldHVybiBzZWxmLmdldEl0ZW1zKClbMF1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc2VsZi5nZXRJdGVtcygpW3NlbGYuZ2V0U2VsZWN0ZWRVc2VySW5kZXgoKV1cbiAgfVxufVxuXG5zZWxmLmdldFNlbGVjdGVkVXNlckluZGV4ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gc2VsZi5fc2VsZWN0ZWRVc2VySW5kZXhcbn1cblxuc2VsZi5nZXRJdGVtcyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHNlbGYuX3VzZXJzXG59XG5cbnNlbGYucmVtb3ZlQWxsSXRlbXMgPSBmdW5jdGlvbiAoKSB7XG4gIHdoaWxlIChzZWxmLl9ub2Rlcy5hdXRvY29tcGxldGUuZmlyc3RDaGlsZCkge1xuICAgIHNlbGYuX25vZGVzLmF1dG9jb21wbGV0ZS5yZW1vdmVDaGlsZChzZWxmLl9ub2Rlcy5hdXRvY29tcGxldGUuZmlyc3RDaGlsZClcbiAgfVxuICBzZWxmLl91c2VycyA9IFtdXG4gIHNlbGYuX3NlbGVjdGVkVXNlckluZGV4ID0gLTFcbn1cblxuc2VsZi5hZGRJdGVtID0gZnVuY3Rpb24gKHVzZXIpIHtcbiAgY29uc3QgbGlzdEl0ZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaScpXG4gIGxpc3RJdGVtLnRleHRDb250ZW50ID0gdXNlci52YWx1ZVxuICBzZWxmLl9ub2Rlcy5hdXRvY29tcGxldGUuYXBwZW5kQ2hpbGQobGlzdEl0ZW0pXG4gIHNlbGYuX3VzZXJzLnB1c2godXNlcilcbn1cblxuc2VsZi5fbW92ZVNlbGVjdGVkID0gZnVuY3Rpb24gKHNoaWZ0KSB7XG4gIGlmIChzZWxmLl9zZWxlY3RlZFVzZXJJbmRleCArIHNoaWZ0ID49IHNlbGYuZ2V0SXRlbXMoKS5sZW5ndGgpIHtcbiAgICBzZWxmLl9zZWxlY3RlZFVzZXJJbmRleCA9IC0xXG4gIH0gZWxzZSBpZiAoc2VsZi5fc2VsZWN0ZWRVc2VySW5kZXggKyBzaGlmdCA8IC0xKSB7XG4gICAgc2VsZi5fc2VsZWN0ZWRVc2VySW5kZXggPSBzZWxmLmdldEl0ZW1zKCkubGVuZ3RoIC0gMVxuICB9IGVsc2Uge1xuICAgIHNlbGYuX3NlbGVjdGVkVXNlckluZGV4ICs9IHNoaWZ0XG4gIH1cblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHNlbGYuZ2V0SXRlbXMoKS5sZW5ndGg7IGkrKykge1xuICAgIHNlbGYuX25vZGVzLmF1dG9jb21wbGV0ZS5jaGlsZHJlbltpXS5jbGFzc0xpc3QucmVtb3ZlKCdzZWxlY3RlZCcpXG4gIH1cbiAgaWYgKHNlbGYuX3NlbGVjdGVkVXNlckluZGV4ID49IDApIHtcbiAgICBzZWxmLl9ub2Rlcy5hdXRvY29tcGxldGVcbiAgICAgICAgLmNoaWxkcmVuW3NlbGYuX3NlbGVjdGVkVXNlckluZGV4XS5jbGFzc0xpc3QuYWRkKCdzZWxlY3RlZCcpXG4gIH1cbn1cblxuc2VsZi5faGFuZGxlSXRlbUNsaWNrID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gIGlmICghc2VsZi5fbm9kZXMuYXV0b2NvbXBsZXRlLmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpIHJldHVyblxuICBjb25zdCB1c2VySW5kZXggPSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZlxuICAgICAgLmNhbGwoc2VsZi5fbm9kZXMuYXV0b2NvbXBsZXRlLmNoaWxkcmVuLCBldmVudC50YXJnZXQpXG4gIHNlbGYuX3NlbGVjdGVkVXNlckluZGV4ID0gdXNlckluZGV4XG4gIHNlbGYuZW1pdCgnc2VsZWN0Jywgc2VsZi5nZXRTZWxlY3RlZFVzZXIoKSlcbn1cblxuc2VsZi5faGFuZGxlS2V5ZG93biA9IGZ1bmN0aW9uIChldmVudCkge1xuICBpZiAoZXZlbnQua2V5ID09PSAnQXJyb3dEb3duJyB8fCBldmVudC5rZXkgPT09ICdBcnJvd1VwJykge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnQXJyb3dEb3duJykge1xuICAgICAgc2VsZi5fbW92ZVNlbGVjdGVkKDEpXG4gICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09ICdBcnJvd1VwJykge1xuICAgICAgc2VsZi5fbW92ZVNlbGVjdGVkKC0xKVxuICAgIH1cbiAgfVxufVxuXG5zZWxmLl9ub2Rlcy5hdXRvY29tcGxldGUuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBzZWxmLl9oYW5kbGVJdGVtQ2xpY2spXG5zZWxmLl9ub2Rlcy5pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgc2VsZi5faGFuZGxlS2V5ZG93bilcblxubW9kdWxlLmV4cG9ydHMgPSBzZWxmXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gcHVibGljL2phdmFzY3JpcHRzL2F1dG9jb21wbGV0ZS5qcyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8\n");
+
+/***/ }),
+/* 9 */
+/*!*****************************************!*\
+ !*** ./public/javascripts/frontpage.js ***!
+ \*****************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\nvar browserFixToolkit = __webpack_require__(/*! ./browserFixToolkit */ 3);\n\nvar self = {};\n\nself._nodes = {\n input: document.querySelector('input[type=\"search\"]')\n};\n\nself.isShown = false;\n\nself.show = function () {\n document.body.classList.add('no-input');\n self.isShown = true;\n};\n\nself.hide = function () {\n document.body.classList.remove('no-input');\n self.isShown = false;\n};\n\nself._nodes.input.addEventListener(browserFixToolkit.inputEvent, self.hide);\n\nmodule.exports = self;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9wdWJsaWMvamF2YXNjcmlwdHMvZnJvbnRwYWdlLmpzP2Y4ZjAiXSwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgYnJvd3NlckZpeFRvb2xraXQgPSByZXF1aXJlKCcuL2Jyb3dzZXJGaXhUb29sa2l0JylcblxuY29uc3Qgc2VsZiA9IHt9XG5cbnNlbGYuX25vZGVzID0ge1xuICBpbnB1dDogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbdHlwZT1cInNlYXJjaFwiXScpXG59XG5cbnNlbGYuaXNTaG93biA9IGZhbHNlXG5cbnNlbGYuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCduby1pbnB1dCcpXG4gIHNlbGYuaXNTaG93biA9IHRydWVcbn1cblxuc2VsZi5oaWRlID0gZnVuY3Rpb24gKCkge1xuICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ25vLWlucHV0JylcbiAgc2VsZi5pc1Nob3duID0gZmFsc2Vcbn1cblxuc2VsZi5fbm9kZXMuaW5wdXQuYWRkRXZlbnRMaXN0ZW5lcihicm93c2VyRml4VG9vbGtpdC5pbnB1dEV2ZW50LCBzZWxmLmhpZGUpXG5cbm1vZHVsZS5leHBvcnRzID0gc2VsZlxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIHB1YmxpYy9qYXZhc2NyaXB0cy9mcm9udHBhZ2UuanMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBREE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9\n");
+
+/***/ }),
+/* 10 */
+/*!********************************************!*\
+ !*** ./public/javascripts/weekSelector.js ***!
+ \********************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\nvar EventEmitter = __webpack_require__(/*! events */ 0);\n\nvar self = new EventEmitter();\n\nself._nodes = {\n prevButton: document.querySelectorAll('#week-selector button')[0],\n nextButton: document.querySelectorAll('#week-selector button')[1],\n currentWeekNode: document.querySelector('#week-selector .current'),\n currentWeekNormalText: document.querySelector('#week-selector .current .no-print'),\n currentWeekPrintText: document.querySelector('#week-selector .current .print')\n};\n\nself._weekOffset = 0;\n\n// copied from http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/untisscripts.js,\n// were using the same code as they do to be sure that we always get the same\n// week number.\nself.getCurrentWeek = function (target) {\n var dayNr = (target.getDay() + 6) % 7;\n target.setDate(target.getDate() - dayNr + 3);\n var firstThursday = target.valueOf();\n target.setMonth(0, 1);\n if (target.getDay() !== 4) {\n target.setMonth(0, 1 + (4 - target.getDay() + 7) % 7);\n }\n\n return 1 + Math.ceil((firstThursday - target) / 604800000);\n};\n\nself.getSelectedWeek = function () {\n var now = new Date();\n var targetDate = new Date(now.getTime() + self._weekOffset * 604800 * 1000 + 86400 * 1000);\n return self.getCurrentWeek(targetDate);\n};\n\nself.updateCurrentWeek = function () {\n var selectedWeekNumber = self.getSelectedWeek();\n if (self.getCurrentWeek(new Date()) !== selectedWeekNumber) {\n self._nodes.currentWeekNode.classList.add('changed');\n } else {\n self._nodes.currentWeekNode.classList.remove('changed');\n }\n self.updateDom();\n self.emit('weekChanged', selectedWeekNumber);\n};\n\nself.updateDom = function () {\n var selectedWeekNumber = self.getSelectedWeek();\n var isSunday = new Date().getDay() === 0;\n var humanReadableWeek = null;\n if (isSunday) {\n switch (self._weekOffset) {\n case 0:\n humanReadableWeek = 'Aanstaande week';\n break;\n case 1:\n humanReadableWeek = 'Volgende week';\n break;\n case -1:\n humanReadableWeek = 'Afgelopen week';\n break;\n }\n } else {\n switch (self._weekOffset) {\n case 0:\n humanReadableWeek = 'Huidige week';\n break;\n case 1:\n humanReadableWeek = 'Volgende week';\n break;\n case -1:\n humanReadableWeek = 'Vorige week';\n break;\n }\n }\n if (humanReadableWeek != null) {\n self._nodes.currentWeekNormalText.textContent = humanReadableWeek + ' • ' + selectedWeekNumber;\n self._nodes.currentWeekPrintText.textContent = 'Week ' + selectedWeekNumber;\n } else {\n self._nodes.currentWeekNormalText.textContent = 'Week ' + selectedWeekNumber;\n self._nodes.currentWeekPrintText.textContent = 'Week ' + selectedWeekNumber;\n }\n};\n\nself._handlePrevButtonClick = function () {\n self._weekOffset -= 1;\n self.updateCurrentWeek();\n};\n\nself._handleNextButtonClick = function () {\n self._weekOffset += 1;\n self.updateCurrentWeek();\n};\n\nself._nodes.prevButton.addEventListener('click', self._handlePrevButtonClick);\nself._nodes.nextButton.addEventListener('click', self._handleNextButtonClick);\n\nmodule.exports = self;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTAuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcHVibGljL2phdmFzY3JpcHRzL3dlZWtTZWxlY3Rvci5qcz85NGQyIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ2V2ZW50cycpXG5cbmNvbnN0IHNlbGYgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuc2VsZi5fbm9kZXMgPSB7XG4gIHByZXZCdXR0b246IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyN3ZWVrLXNlbGVjdG9yIGJ1dHRvbicpWzBdLFxuICBuZXh0QnV0dG9uOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcjd2Vlay1zZWxlY3RvciBidXR0b24nKVsxXSxcbiAgY3VycmVudFdlZWtOb2RlOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjd2Vlay1zZWxlY3RvciAuY3VycmVudCcpLFxuICBjdXJyZW50V2Vla05vcm1hbFRleHQ6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyN3ZWVrLXNlbGVjdG9yIC5jdXJyZW50IC5uby1wcmludCcpLFxuICBjdXJyZW50V2Vla1ByaW50VGV4dDogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3dlZWstc2VsZWN0b3IgLmN1cnJlbnQgLnByaW50Jylcbn1cblxuc2VsZi5fd2Vla09mZnNldCA9IDBcblxuLy8gY29waWVkIGZyb20gaHR0cDovL3d3dy5tZWV0aW5ncG9pbnRtY28ubmwvUm9vc3RlcnMtQUwvZG9jL2RhZ3Jvb3N0ZXJzL3VudGlzc2NyaXB0cy5qcyxcbi8vIHdlcmUgdXNpbmcgdGhlIHNhbWUgY29kZSBhcyB0aGV5IGRvIHRvIGJlIHN1cmUgdGhhdCB3ZSBhbHdheXMgZ2V0IHRoZSBzYW1lXG4vLyB3ZWVrIG51bWJlci5cbnNlbGYuZ2V0Q3VycmVudFdlZWsgPSBmdW5jdGlvbiAodGFyZ2V0KSB7XG4gIGNvbnN0IGRheU5yID0gKHRhcmdldC5nZXREYXkoKSArIDYpICUgN1xuICB0YXJnZXQuc2V0RGF0ZSh0YXJnZXQuZ2V0RGF0ZSgpIC0gZGF5TnIgKyAzKVxuICBjb25zdCBmaXJzdFRodXJzZGF5ID0gdGFyZ2V0LnZhbHVlT2YoKVxuICB0YXJnZXQuc2V0TW9udGgoMCwgMSlcbiAgaWYgKHRhcmdldC5nZXREYXkoKSAhPT0gNCkge1xuICAgIHRhcmdldC5zZXRNb250aCgwLCAxICsgKCg0IC0gdGFyZ2V0LmdldERheSgpKSArIDcpICUgNylcbiAgfVxuXG4gIHJldHVybiAxICsgTWF0aC5jZWlsKChmaXJzdFRodXJzZGF5IC0gdGFyZ2V0KSAvIDYwNDgwMDAwMClcbn1cblxuc2VsZi5nZXRTZWxlY3RlZFdlZWsgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IG5vdyA9IG5ldyBEYXRlKClcbiAgY29uc3QgdGFyZ2V0RGF0ZSA9IG5ldyBEYXRlKG5vdy5nZXRUaW1lKCkgK1xuICAgICAgc2VsZi5fd2Vla09mZnNldCAqIDYwNDgwMCAqIDEwMDAgKyA4NjQwMCAqIDEwMDApXG4gIHJldHVybiBzZWxmLmdldEN1cnJlbnRXZWVrKHRhcmdldERhdGUpXG59XG5cbnNlbGYudXBkYXRlQ3VycmVudFdlZWsgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IHNlbGVjdGVkV2Vla051bWJlciA9IHNlbGYuZ2V0U2VsZWN0ZWRXZWVrKClcbiAgaWYgKHNlbGYuZ2V0Q3VycmVudFdlZWsobmV3IERhdGUoKSkgIT09IHNlbGVjdGVkV2Vla051bWJlcikge1xuICAgIHNlbGYuX25vZGVzLmN1cnJlbnRXZWVrTm9kZS5jbGFzc0xpc3QuYWRkKCdjaGFuZ2VkJylcbiAgfSBlbHNlIHtcbiAgICBzZWxmLl9ub2Rlcy5jdXJyZW50V2Vla05vZGUuY2xhc3NMaXN0LnJlbW92ZSgnY2hhbmdlZCcpXG4gIH1cbiAgc2VsZi51cGRhdGVEb20oKVxuICBzZWxmLmVtaXQoJ3dlZWtDaGFuZ2VkJywgc2VsZWN0ZWRXZWVrTnVtYmVyKVxufVxuXG5zZWxmLnVwZGF0ZURvbSA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3Qgc2VsZWN0ZWRXZWVrTnVtYmVyID0gc2VsZi5nZXRTZWxlY3RlZFdlZWsoKVxuICBjb25zdCBpc1N1bmRheSA9IG5ldyBEYXRlKCkuZ2V0RGF5KCkgPT09IDBcbiAgbGV0IGh1bWFuUmVhZGFibGVXZWVrID0gbnVsbFxuICBpZiAoaXNTdW5kYXkpIHtcbiAgICBzd2l0Y2ggKHNlbGYuX3dlZWtPZmZzZXQpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgaHVtYW5SZWFkYWJsZVdlZWsgPSAnQWFuc3RhYW5kZSB3ZWVrJ1xuICAgICAgICBicmVha1xuICAgICAgY2FzZSAxOlxuICAgICAgICBodW1hblJlYWRhYmxlV2VlayA9ICdWb2xnZW5kZSB3ZWVrJ1xuICAgICAgICBicmVha1xuICAgICAgY2FzZSAtMTpcbiAgICAgICAgaHVtYW5SZWFkYWJsZVdlZWsgPSAnQWZnZWxvcGVuIHdlZWsnXG4gICAgICAgIGJyZWFrXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHN3aXRjaCAoc2VsZi5fd2Vla09mZnNldCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICBodW1hblJlYWRhYmxlV2VlayA9ICdIdWlkaWdlIHdlZWsnXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlIDE6XG4gICAgICAgIGh1bWFuUmVhZGFibGVXZWVrID0gJ1ZvbGdlbmRlIHdlZWsnXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlIC0xOlxuICAgICAgICBodW1hblJlYWRhYmxlV2VlayA9ICdWb3JpZ2Ugd2VlaydcbiAgICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgaWYgKGh1bWFuUmVhZGFibGVXZWVrICE9IG51bGwpIHtcbiAgICBzZWxmLl9ub2Rlcy5jdXJyZW50V2Vla05vcm1hbFRleHQudGV4dENvbnRlbnQgPSBodW1hblJlYWRhYmxlV2VlayArICcg4oCiICcgKyBzZWxlY3RlZFdlZWtOdW1iZXJcbiAgICBzZWxmLl9ub2Rlcy5jdXJyZW50V2Vla1ByaW50VGV4dC50ZXh0Q29udGVudCA9ICdXZWVrICcgKyBzZWxlY3RlZFdlZWtOdW1iZXJcbiAgfSBlbHNlIHtcbiAgICBzZWxmLl9ub2Rlcy5jdXJyZW50V2Vla05vcm1hbFRleHQudGV4dENvbnRlbnQgPSAnV2VlayAnICsgc2VsZWN0ZWRXZWVrTnVtYmVyXG4gICAgc2VsZi5fbm9kZXMuY3VycmVudFdlZWtQcmludFRleHQudGV4dENvbnRlbnQgPSAnV2VlayAnICsgc2VsZWN0ZWRXZWVrTnVtYmVyXG4gIH1cbn1cblxuc2VsZi5faGFuZGxlUHJldkJ1dHRvbkNsaWNrID0gZnVuY3Rpb24gKCkge1xuICBzZWxmLl93ZWVrT2Zmc2V0IC09IDFcbiAgc2VsZi51cGRhdGVDdXJyZW50V2VlaygpXG59XG5cbnNlbGYuX2hhbmRsZU5leHRCdXR0b25DbGljayA9IGZ1bmN0aW9uICgpIHtcbiAgc2VsZi5fd2Vla09mZnNldCArPSAxXG4gIHNlbGYudXBkYXRlQ3VycmVudFdlZWsoKVxufVxuXG5zZWxmLl9ub2Rlcy5wcmV2QnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgc2VsZi5faGFuZGxlUHJldkJ1dHRvbkNsaWNrKVxuc2VsZi5fbm9kZXMubmV4dEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHNlbGYuX2hhbmRsZU5leHRCdXR0b25DbGljaylcblxubW9kdWxlLmV4cG9ydHMgPSBzZWxmXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gcHVibGljL2phdmFzY3JpcHRzL3dlZWtTZWxlY3Rvci5qcyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBQ0E7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVRBO0FBV0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVRBO0FBV0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///10\n");
+
+/***/ }),
+/* 11 */
+/*!****************************************!*\
+ !*** ./public/javascripts/favorite.js ***!
+ \****************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\n/* global USERS */\n\nvar EventEmitter = __webpack_require__(/*! events */ 0);\n\nvar self = new EventEmitter();\n\nself._nodes = {\n toggle: document.querySelector('.fav')\n};\n\nself.get = function () {\n try {\n var localStorageUser = JSON.parse(window.localStorage.getItem('fav'));\n if (localStorageUser == null) return;\n\n var correctedUser = USERS.filter(function (user) {\n return user.type === localStorageUser.type && user.value === localStorageUser.value;\n })[0];\n return correctedUser;\n } catch (e) {\n self.delete();\n return;\n }\n};\n\nself.set = function (user) {\n window.localStorage.setItem('fav', JSON.stringify(user));\n self._nodes.innerHTML = '&#xE838;';\n};\n\nself.delete = function () {\n window.localStorage.removeItem('fav');\n};\n\nself.updateDom = function (isFavorite) {\n if (isFavorite) {\n self._nodes.toggle.innerHTML = '&#xE838;';\n } else {\n self._nodes.toggle.innerHTML = '&#xE83A';\n }\n};\n\nself.update = function (selectedUser) {\n var currentUser = self.get();\n\n if (currentUser == null || selectedUser == null) {\n self.updateDom(false);\n return;\n }\n\n var isEqual = currentUser.type === selectedUser.type && currentUser.index === selectedUser.index;\n\n self.updateDom(isEqual);\n};\n\nself.toggle = function (selectedUser) {\n var currentUser = self.get();\n var isEqual = currentUser != null && currentUser.type === selectedUser.type && currentUser.index === selectedUser.index;\n\n if (isEqual) {\n self.delete();\n self.updateDom(false);\n } else {\n self.set(selectedUser);\n self.updateDom(true);\n }\n};\n\nself._handleClick = function () {\n self.emit('click');\n};\n\nself._nodes.toggle.addEventListener('click', self._handleClick);\n\nmodule.exports = self;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTEuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcHVibGljL2phdmFzY3JpcHRzL2Zhdm9yaXRlLmpzPzMxOTEiXSwic291cmNlc0NvbnRlbnQiOlsiLyogZ2xvYmFsIFVTRVJTICovXG5cbmNvbnN0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ2V2ZW50cycpXG5cbmNvbnN0IHNlbGYgPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuc2VsZi5fbm9kZXMgPSB7XG4gIHRvZ2dsZTogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmZhdicpXG59XG5cbnNlbGYuZ2V0ID0gZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIGNvbnN0IGxvY2FsU3RvcmFnZVVzZXIgPSBKU09OLnBhcnNlKHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnZmF2JykpXG4gICAgaWYgKGxvY2FsU3RvcmFnZVVzZXIgPT0gbnVsbCkgcmV0dXJuXG5cbiAgICBjb25zdCBjb3JyZWN0ZWRVc2VyID0gVVNFUlMuZmlsdGVyKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICByZXR1cm4gdXNlci50eXBlID09PSBsb2NhbFN0b3JhZ2VVc2VyLnR5cGUgJiZcbiAgICAgICAgICAgICB1c2VyLnZhbHVlID09PSBsb2NhbFN0b3JhZ2VVc2VyLnZhbHVlXG4gICAgfSlbMF1cbiAgICByZXR1cm4gY29ycmVjdGVkVXNlclxuICB9IGNhdGNoIChlKSB7XG4gICAgc2VsZi5kZWxldGUoKVxuICAgIHJldHVyblxuICB9XG59XG5cbnNlbGYuc2V0ID0gZnVuY3Rpb24gKHVzZXIpIHtcbiAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKCdmYXYnLCBKU09OLnN0cmluZ2lmeSh1c2VyKSlcbiAgc2VsZi5fbm9kZXMuaW5uZXJIVE1MID0gJyYjeEU4Mzg7J1xufVxuXG5zZWxmLmRlbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgd2luZG93LmxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKCdmYXYnKVxufVxuXG5zZWxmLnVwZGF0ZURvbSA9IGZ1bmN0aW9uIChpc0Zhdm9yaXRlKSB7XG4gIGlmIChpc0Zhdm9yaXRlKSB7XG4gICAgc2VsZi5fbm9kZXMudG9nZ2xlLmlubmVySFRNTCA9ICcmI3hFODM4OydcbiAgfSBlbHNlIHtcbiAgICBzZWxmLl9ub2Rlcy50b2dnbGUuaW5uZXJIVE1MID0gJyYjeEU4M0EnXG4gIH1cbn1cblxuc2VsZi51cGRhdGUgPSBmdW5jdGlvbiAoc2VsZWN0ZWRVc2VyKSB7XG4gIGNvbnN0IGN1cnJlbnRVc2VyID0gc2VsZi5nZXQoKVxuXG4gIGlmIChjdXJyZW50VXNlciA9PSBudWxsIHx8IHNlbGVjdGVkVXNlciA9PSBudWxsKSB7XG4gICAgc2VsZi51cGRhdGVEb20oZmFsc2UpXG4gICAgcmV0dXJuXG4gIH1cblxuICBjb25zdCBpc0VxdWFsID0gY3VycmVudFVzZXIudHlwZSA9PT0gc2VsZWN0ZWRVc2VyLnR5cGUgJiZcbiAgICAgICAgICAgICAgICAgIGN1cnJlbnRVc2VyLmluZGV4ID09PSBzZWxlY3RlZFVzZXIuaW5kZXhcblxuICBzZWxmLnVwZGF0ZURvbShpc0VxdWFsKVxufVxuXG5zZWxmLnRvZ2dsZSA9IGZ1bmN0aW9uIChzZWxlY3RlZFVzZXIpIHtcbiAgY29uc3QgY3VycmVudFVzZXIgPSBzZWxmLmdldCgpXG4gIGNvbnN0IGlzRXF1YWwgPSBjdXJyZW50VXNlciAhPSBudWxsICYmXG4gICAgICAgICAgICAgICAgICBjdXJyZW50VXNlci50eXBlID09PSBzZWxlY3RlZFVzZXIudHlwZSAmJlxuICAgICAgICAgICAgICAgICAgY3VycmVudFVzZXIuaW5kZXggPT09IHNlbGVjdGVkVXNlci5pbmRleFxuXG4gIGlmIChpc0VxdWFsKSB7XG4gICAgc2VsZi5kZWxldGUoKVxuICAgIHNlbGYudXBkYXRlRG9tKGZhbHNlKVxuICB9IGVsc2Uge1xuICAgIHNlbGYuc2V0KHNlbGVjdGVkVXNlcilcbiAgICBzZWxmLnVwZGF0ZURvbSh0cnVlKVxuICB9XG59XG5cbnNlbGYuX2hhbmRsZUNsaWNrID0gZnVuY3Rpb24gKCkge1xuICBzZWxmLmVtaXQoJ2NsaWNrJylcbn1cblxuc2VsZi5fbm9kZXMudG9nZ2xlLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgc2VsZi5faGFuZGxlQ2xpY2spXG5cbm1vZHVsZS5leHBvcnRzID0gc2VsZlxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIHB1YmxpYy9qYXZhc2NyaXB0cy9mYXZvcml0ZS5qcyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBREE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///11\n");
+
+/***/ }),
+/* 12 */
+/*!******************************************!*\
+ !*** ./public/javascripts/scrollSnap.js ***!
+ \******************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\n__webpack_require__(/*! smoothscroll-polyfill */ 13).polyfill();\n\nvar self = {};\nvar schedule = __webpack_require__(/*! ./schedule */ 1);\n\nself._nodes = {\n search: document.querySelector('#search'),\n weekSelector: document.querySelector('#week-selector')\n};\n\nself._timeoutID = null;\n\nself._getScrollPosition = function () {\n return document.documentElement && document.documentElement.scrollTop || document.body.scrollTop;\n};\n\nself._handleDoneScrolling = function () {\n var scrollPosition = self._getScrollPosition();\n var weekSelectorHeight = self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight;\n if (scrollPosition < weekSelectorHeight && scrollPosition > 0) {\n window.scroll({ top: weekSelectorHeight, left: 0, behavior: 'smooth' });\n }\n};\n\nself._handleScroll = function () {\n if (self._timeoutID != null) window.clearTimeout(self._timeoutID);\n self._timeoutID = window.setTimeout(self._handleDoneScrolling, 500);\n\n var scrollPosition = self._getScrollPosition();\n var weekSelectorHeight = self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight;\n if (scrollPosition >= weekSelectorHeight) {\n document.body.classList.add('week-selector-not-visible');\n } else {\n document.body.classList.remove('week-selector-not-visible');\n }\n};\n\nself._handleWindowResize = function () {\n var weekSelectorHeight = self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight;\n var extraPixelsNeeded = weekSelectorHeight - (document.body.clientHeight - window.innerHeight);\n if (extraPixelsNeeded > 0) {\n document.body.style.marginBottom = extraPixelsNeeded + 'px';\n } else {\n document.body.style.marginBottom = null;\n }\n};\n\nself.startListening = function () {\n window.addEventListener('scroll', self._handleScroll);\n};\n\nschedule.on('load', self._handleWindowResize);\nwindow.addEventListener('resize', self._handleWindowResize);\nmodule.exports = self;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTIuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcHVibGljL2phdmFzY3JpcHRzL3Njcm9sbFNuYXAuanM/NzFkMiJdLCJzb3VyY2VzQ29udGVudCI6WyJyZXF1aXJlKCdzbW9vdGhzY3JvbGwtcG9seWZpbGwnKS5wb2x5ZmlsbCgpXG5cbmNvbnN0IHNlbGYgPSB7fVxuY29uc3Qgc2NoZWR1bGUgPSByZXF1aXJlKCcuL3NjaGVkdWxlJylcblxuc2VsZi5fbm9kZXMgPSB7XG4gIHNlYXJjaDogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3NlYXJjaCcpLFxuICB3ZWVrU2VsZWN0b3I6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyN3ZWVrLXNlbGVjdG9yJylcbn1cblxuc2VsZi5fdGltZW91dElEID0gbnVsbFxuXG5zZWxmLl9nZXRTY3JvbGxQb3NpdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCkgfHxcbiAgICAgICAgIGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wXG59XG5cbnNlbGYuX2hhbmRsZURvbmVTY3JvbGxpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IHNjcm9sbFBvc2l0aW9uID0gc2VsZi5fZ2V0U2Nyb2xsUG9zaXRpb24oKVxuICBjb25zdCB3ZWVrU2VsZWN0b3JIZWlnaHQgPVxuICAgICAgc2VsZi5fbm9kZXMud2Vla1NlbGVjdG9yLmNsaWVudEhlaWdodCAtIHNlbGYuX25vZGVzLnNlYXJjaC5jbGllbnRIZWlnaHRcbiAgaWYgKHNjcm9sbFBvc2l0aW9uIDwgd2Vla1NlbGVjdG9ySGVpZ2h0ICYmIHNjcm9sbFBvc2l0aW9uID4gMCkge1xuICAgIHdpbmRvdy5zY3JvbGwoeyB0b3A6IHdlZWtTZWxlY3RvckhlaWdodCwgbGVmdDogMCwgYmVoYXZpb3I6ICdzbW9vdGgnIH0pXG4gIH1cbn1cblxuc2VsZi5faGFuZGxlU2Nyb2xsID0gZnVuY3Rpb24gKCkge1xuICBpZiAoc2VsZi5fdGltZW91dElEICE9IG51bGwpIHdpbmRvdy5jbGVhclRpbWVvdXQoc2VsZi5fdGltZW91dElEKVxuICBzZWxmLl90aW1lb3V0SUQgPSB3aW5kb3cuc2V0VGltZW91dChzZWxmLl9oYW5kbGVEb25lU2Nyb2xsaW5nLCA1MDApXG5cbiAgY29uc3Qgc2Nyb2xsUG9zaXRpb24gPSBzZWxmLl9nZXRTY3JvbGxQb3NpdGlvbigpXG4gIGNvbnN0IHdlZWtTZWxlY3RvckhlaWdodCA9XG4gICAgICBzZWxmLl9ub2Rlcy53ZWVrU2VsZWN0b3IuY2xpZW50SGVpZ2h0IC0gc2VsZi5fbm9kZXMuc2VhcmNoLmNsaWVudEhlaWdodFxuICBpZiAoc2Nyb2xsUG9zaXRpb24gPj0gd2Vla1NlbGVjdG9ySGVpZ2h0KSB7XG4gICAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCd3ZWVrLXNlbGVjdG9yLW5vdC12aXNpYmxlJylcbiAgfSBlbHNlIHtcbiAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ3dlZWstc2VsZWN0b3Itbm90LXZpc2libGUnKVxuICB9XG59XG5cbnNlbGYuX2hhbmRsZVdpbmRvd1Jlc2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3Qgd2Vla1NlbGVjdG9ySGVpZ2h0ID1cbiAgICAgIHNlbGYuX25vZGVzLndlZWtTZWxlY3Rvci5jbGllbnRIZWlnaHQgLSBzZWxmLl9ub2Rlcy5zZWFyY2guY2xpZW50SGVpZ2h0XG4gIGNvbnN0IGV4dHJhUGl4ZWxzTmVlZGVkID1cbiAgICAgIHdlZWtTZWxlY3RvckhlaWdodCAtIChkb2N1bWVudC5ib2R5LmNsaWVudEhlaWdodCAtIHdpbmRvdy5pbm5lckhlaWdodClcbiAgaWYgKGV4dHJhUGl4ZWxzTmVlZGVkID4gMCkge1xuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUubWFyZ2luQm90dG9tID0gZXh0cmFQaXhlbHNOZWVkZWQgKyAncHgnXG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuYm9keS5zdHlsZS5tYXJnaW5Cb3R0b20gPSBudWxsXG4gIH1cbn1cblxuc2VsZi5zdGFydExpc3RlbmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHNlbGYuX2hhbmRsZVNjcm9sbClcbn1cblxuc2NoZWR1bGUub24oJ2xvYWQnLCBzZWxmLl9oYW5kbGVXaW5kb3dSZXNpemUpXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgc2VsZi5faGFuZGxlV2luZG93UmVzaXplKVxubW9kdWxlLmV4cG9ydHMgPSBzZWxmXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gcHVibGljL2phdmFzY3JpcHRzL3Njcm9sbFNuYXAuanMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///12\n");
+
+/***/ }),
+/* 13 */
+/*!*****************************************************************!*\
+ !*** ./node_modules/smoothscroll-polyfill/dist/smoothscroll.js ***!
+ \*****************************************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+eval("/*\n * smoothscroll polyfill - v0.3.5\n * https://iamdustan.github.io/smoothscroll\n * 2016 (c) Dustan Kasten, Jeremias Menichelli - MIT License\n */\n\n(function(w, d, undefined) {\n 'use strict';\n\n /*\n * aliases\n * w: window global object\n * d: document\n * undefined: undefined\n */\n\n // polyfill\n function polyfill() {\n // return when scrollBehavior interface is supported\n if ('scrollBehavior' in d.documentElement.style) {\n return;\n }\n\n /*\n * globals\n */\n var Element = w.HTMLElement || w.Element;\n var SCROLL_TIME = 468;\n\n /*\n * object gathering original scroll methods\n */\n var original = {\n scroll: w.scroll || w.scrollTo,\n scrollBy: w.scrollBy,\n elScroll: Element.prototype.scroll || scrollElement,\n scrollIntoView: Element.prototype.scrollIntoView\n };\n\n /*\n * define timing method\n */\n var now = w.performance && w.performance.now\n ? w.performance.now.bind(w.performance) : Date.now;\n\n /**\n * changes scroll position inside an element\n * @method scrollElement\n * @param {Number} x\n * @param {Number} y\n */\n function scrollElement(x, y) {\n this.scrollLeft = x;\n this.scrollTop = y;\n }\n\n /**\n * returns result of applying ease math function to a number\n * @method ease\n * @param {Number} k\n * @returns {Number}\n */\n function ease(k) {\n return 0.5 * (1 - Math.cos(Math.PI * k));\n }\n\n /**\n * indicates if a smooth behavior should be applied\n * @method shouldBailOut\n * @param {Number|Object} x\n * @returns {Boolean}\n */\n function shouldBailOut(x) {\n if (typeof x !== 'object'\n || x === null\n || x.behavior === undefined\n || x.behavior === 'auto'\n || x.behavior === 'instant') {\n // first arg not an object/null\n // or behavior is auto, instant or undefined\n return true;\n }\n\n if (typeof x === 'object'\n && x.behavior === 'smooth') {\n // first argument is an object and behavior is smooth\n return false;\n }\n\n // throw error when behavior is not supported\n throw new TypeError('behavior not valid');\n }\n\n /**\n * finds scrollable parent of an element\n * @method findScrollableParent\n * @param {Node} el\n * @returns {Node} el\n */\n function findScrollableParent(el) {\n var isBody;\n var hasScrollableSpace;\n var hasVisibleOverflow;\n\n do {\n el = el.parentNode;\n\n // set condition variables\n isBody = el === d.body;\n hasScrollableSpace =\n el.clientHeight < el.scrollHeight ||\n el.clientWidth < el.scrollWidth;\n hasVisibleOverflow =\n w.getComputedStyle(el, null).overflow === 'visible';\n } while (!isBody && !(hasScrollableSpace && !hasVisibleOverflow));\n\n isBody = hasScrollableSpace = hasVisibleOverflow = null;\n\n return el;\n }\n\n /**\n * self invoked function that, given a context, steps through scrolling\n * @method step\n * @param {Object} context\n */\n function step(context) {\n var time = now();\n var value;\n var currentX;\n var currentY;\n var elapsed = (time - context.startTime) / SCROLL_TIME;\n\n // avoid elapsed times higher than one\n elapsed = elapsed > 1 ? 1 : elapsed;\n\n // apply easing to elapsed time\n value = ease(elapsed);\n\n currentX = context.startX + (context.x - context.startX) * value;\n currentY = context.startY + (context.y - context.startY) * value;\n\n context.method.call(context.scrollable, currentX, currentY);\n\n // scroll more if we have not reached our destination\n if (currentX !== context.x || currentY !== context.y) {\n w.requestAnimationFrame(step.bind(w, context));\n }\n }\n\n /**\n * scrolls window with a smooth behavior\n * @method smoothScroll\n * @param {Object|Node} el\n * @param {Number} x\n * @param {Number} y\n */\n function smoothScroll(el, x, y) {\n var scrollable;\n var startX;\n var startY;\n var method;\n var startTime = now();\n\n // define scroll context\n if (el === d.body) {\n scrollable = w;\n startX = w.scrollX || w.pageXOffset;\n startY = w.scrollY || w.pageYOffset;\n method = original.scroll;\n } else {\n scrollable = el;\n startX = el.scrollLeft;\n startY = el.scrollTop;\n method = scrollElement;\n }\n\n // scroll looping over a frame\n step({\n scrollable: scrollable,\n method: method,\n startTime: startTime,\n startX: startX,\n startY: startY,\n x: x,\n y: y\n });\n }\n\n /*\n * ORIGINAL METHODS OVERRIDES\n */\n\n // w.scroll and w.scrollTo\n w.scroll = w.scrollTo = function() {\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0])) {\n original.scroll.call(\n w,\n arguments[0].left || arguments[0],\n arguments[0].top || arguments[1]\n );\n return;\n }\n\n // LET THE SMOOTHNESS BEGIN!\n smoothScroll.call(\n w,\n d.body,\n ~~arguments[0].left,\n ~~arguments[0].top\n );\n };\n\n // w.scrollBy\n w.scrollBy = function() {\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0])) {\n original.scrollBy.call(\n w,\n arguments[0].left || arguments[0],\n arguments[0].top || arguments[1]\n );\n return;\n }\n\n // LET THE SMOOTHNESS BEGIN!\n smoothScroll.call(\n w,\n d.body,\n ~~arguments[0].left + (w.scrollX || w.pageXOffset),\n ~~arguments[0].top + (w.scrollY || w.pageYOffset)\n );\n };\n\n // Element.prototype.scroll and Element.prototype.scrollTo\n Element.prototype.scroll = Element.prototype.scrollTo = function() {\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0])) {\n original.elScroll.call(\n this,\n arguments[0].left || arguments[0],\n arguments[0].top || arguments[1]\n );\n return;\n }\n\n var left = arguments[0].left;\n var top = arguments[0].top;\n\n // LET THE SMOOTHNESS BEGIN!\n smoothScroll.call(\n this,\n this,\n typeof left === 'number' ? left : this.scrollLeft,\n typeof top === 'number' ? top : this.scrollTop\n );\n };\n\n // Element.prototype.scrollBy\n Element.prototype.scrollBy = function() {\n var arg0 = arguments[0];\n\n if (typeof arg0 === 'object') {\n this.scroll({\n left: arg0.left + this.scrollLeft,\n top: arg0.top + this.scrollTop,\n behavior: arg0.behavior\n });\n } else {\n this.scroll(\n this.scrollLeft + arg0,\n this.scrollTop + arguments[1]\n );\n }\n };\n\n // Element.prototype.scrollIntoView\n Element.prototype.scrollIntoView = function() {\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0])) {\n original.scrollIntoView.call(\n this,\n arguments[0] === undefined ? true : arguments[0]\n );\n return;\n }\n\n // LET THE SMOOTHNESS BEGIN!\n var scrollableParent = findScrollableParent(this);\n var parentRects = scrollableParent.getBoundingClientRect();\n var clientRects = this.getBoundingClientRect();\n\n if (scrollableParent !== d.body) {\n // reveal element inside parent\n smoothScroll.call(\n this,\n scrollableParent,\n scrollableParent.scrollLeft + clientRects.left - parentRects.left,\n scrollableParent.scrollTop + clientRects.top - parentRects.top\n );\n // reveal parent in viewport\n w.scrollBy({\n left: parentRects.left,\n top: parentRects.top,\n behavior: 'smooth'\n });\n } else {\n // reveal element in viewport\n w.scrollBy({\n left: clientRects.left,\n top: clientRects.top,\n behavior: 'smooth'\n });\n }\n };\n }\n\n if (true) {\n // commonjs\n module.exports = { polyfill: polyfill };\n } else {\n // global\n polyfill();\n }\n})(window, document);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvc21vb3Roc2Nyb2xsLXBvbHlmaWxsL2Rpc3Qvc21vb3Roc2Nyb2xsLmpzPzQ1YzgiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIHNtb290aHNjcm9sbCBwb2x5ZmlsbCAtIHYwLjMuNVxuICogaHR0cHM6Ly9pYW1kdXN0YW4uZ2l0aHViLmlvL3Ntb290aHNjcm9sbFxuICogMjAxNiAoYykgRHVzdGFuIEthc3RlbiwgSmVyZW1pYXMgTWVuaWNoZWxsaSAtIE1JVCBMaWNlbnNlXG4gKi9cblxuKGZ1bmN0aW9uKHcsIGQsIHVuZGVmaW5lZCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLypcbiAgICogYWxpYXNlc1xuICAgKiB3OiB3aW5kb3cgZ2xvYmFsIG9iamVjdFxuICAgKiBkOiBkb2N1bWVudFxuICAgKiB1bmRlZmluZWQ6IHVuZGVmaW5lZFxuICAgKi9cblxuICAvLyBwb2x5ZmlsbFxuICBmdW5jdGlvbiBwb2x5ZmlsbCgpIHtcbiAgICAvLyByZXR1cm4gd2hlbiBzY3JvbGxCZWhhdmlvciBpbnRlcmZhY2UgaXMgc3VwcG9ydGVkXG4gICAgaWYgKCdzY3JvbGxCZWhhdmlvcicgaW4gZC5kb2N1bWVudEVsZW1lbnQuc3R5bGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIGdsb2JhbHNcbiAgICAgKi9cbiAgICB2YXIgRWxlbWVudCA9IHcuSFRNTEVsZW1lbnQgfHwgdy5FbGVtZW50O1xuICAgIHZhciBTQ1JPTExfVElNRSA9IDQ2ODtcblxuICAgIC8qXG4gICAgICogb2JqZWN0IGdhdGhlcmluZyBvcmlnaW5hbCBzY3JvbGwgbWV0aG9kc1xuICAgICAqL1xuICAgIHZhciBvcmlnaW5hbCA9IHtcbiAgICAgIHNjcm9sbDogdy5zY3JvbGwgfHwgdy5zY3JvbGxUbyxcbiAgICAgIHNjcm9sbEJ5OiB3LnNjcm9sbEJ5LFxuICAgICAgZWxTY3JvbGw6IEVsZW1lbnQucHJvdG90eXBlLnNjcm9sbCB8fCBzY3JvbGxFbGVtZW50LFxuICAgICAgc2Nyb2xsSW50b1ZpZXc6IEVsZW1lbnQucHJvdG90eXBlLnNjcm9sbEludG9WaWV3XG4gICAgfTtcblxuICAgIC8qXG4gICAgICogZGVmaW5lIHRpbWluZyBtZXRob2RcbiAgICAgKi9cbiAgICB2YXIgbm93ID0gdy5wZXJmb3JtYW5jZSAmJiB3LnBlcmZvcm1hbmNlLm5vd1xuICAgICAgPyB3LnBlcmZvcm1hbmNlLm5vdy5iaW5kKHcucGVyZm9ybWFuY2UpIDogRGF0ZS5ub3c7XG5cbiAgICAvKipcbiAgICAgKiBjaGFuZ2VzIHNjcm9sbCBwb3NpdGlvbiBpbnNpZGUgYW4gZWxlbWVudFxuICAgICAqIEBtZXRob2Qgc2Nyb2xsRWxlbWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHlcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzY3JvbGxFbGVtZW50KHgsIHkpIHtcbiAgICAgIHRoaXMuc2Nyb2xsTGVmdCA9IHg7XG4gICAgICB0aGlzLnNjcm9sbFRvcCA9IHk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogcmV0dXJucyByZXN1bHQgb2YgYXBwbHlpbmcgZWFzZSBtYXRoIGZ1bmN0aW9uIHRvIGEgbnVtYmVyXG4gICAgICogQG1ldGhvZCBlYXNlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGtcbiAgICAgKiBAcmV0dXJucyB7TnVtYmVyfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGVhc2Uoaykge1xuICAgICAgcmV0dXJuIDAuNSAqICgxIC0gTWF0aC5jb3MoTWF0aC5QSSAqIGspKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBpbmRpY2F0ZXMgaWYgYSBzbW9vdGggYmVoYXZpb3Igc2hvdWxkIGJlIGFwcGxpZWRcbiAgICAgKiBAbWV0aG9kIHNob3VsZEJhaWxPdXRcbiAgICAgKiBAcGFyYW0ge051bWJlcnxPYmplY3R9IHhcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzaG91bGRCYWlsT3V0KHgpIHtcbiAgICAgIGlmICh0eXBlb2YgeCAhPT0gJ29iamVjdCdcbiAgICAgICAgICAgIHx8IHggPT09IG51bGxcbiAgICAgICAgICAgIHx8IHguYmVoYXZpb3IgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgfHwgeC5iZWhhdmlvciA9PT0gJ2F1dG8nXG4gICAgICAgICAgICB8fCB4LmJlaGF2aW9yID09PSAnaW5zdGFudCcpIHtcbiAgICAgICAgLy8gZmlyc3QgYXJnIG5vdCBhbiBvYmplY3QvbnVsbFxuICAgICAgICAvLyBvciBiZWhhdmlvciBpcyBhdXRvLCBpbnN0YW50IG9yIHVuZGVmaW5lZFxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiB4ID09PSAnb2JqZWN0J1xuICAgICAgICAgICAgJiYgeC5iZWhhdmlvciA9PT0gJ3Ntb290aCcpIHtcbiAgICAgICAgLy8gZmlyc3QgYXJndW1lbnQgaXMgYW4gb2JqZWN0IGFuZCBiZWhhdmlvciBpcyBzbW9vdGhcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICAvLyB0aHJvdyBlcnJvciB3aGVuIGJlaGF2aW9yIGlzIG5vdCBzdXBwb3J0ZWRcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2JlaGF2aW9yIG5vdCB2YWxpZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGZpbmRzIHNjcm9sbGFibGUgcGFyZW50IG9mIGFuIGVsZW1lbnRcbiAgICAgKiBAbWV0aG9kIGZpbmRTY3JvbGxhYmxlUGFyZW50XG4gICAgICogQHBhcmFtIHtOb2RlfSBlbFxuICAgICAqIEByZXR1cm5zIHtOb2RlfSBlbFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZpbmRTY3JvbGxhYmxlUGFyZW50KGVsKSB7XG4gICAgICB2YXIgaXNCb2R5O1xuICAgICAgdmFyIGhhc1Njcm9sbGFibGVTcGFjZTtcbiAgICAgIHZhciBoYXNWaXNpYmxlT3ZlcmZsb3c7XG5cbiAgICAgIGRvIHtcbiAgICAgICAgZWwgPSBlbC5wYXJlbnROb2RlO1xuXG4gICAgICAgIC8vIHNldCBjb25kaXRpb24gdmFyaWFibGVzXG4gICAgICAgIGlzQm9keSA9IGVsID09PSBkLmJvZHk7XG4gICAgICAgIGhhc1Njcm9sbGFibGVTcGFjZSA9XG4gICAgICAgICAgZWwuY2xpZW50SGVpZ2h0IDwgZWwuc2Nyb2xsSGVpZ2h0IHx8XG4gICAgICAgICAgZWwuY2xpZW50V2lkdGggPCBlbC5zY3JvbGxXaWR0aDtcbiAgICAgICAgaGFzVmlzaWJsZU92ZXJmbG93ID1cbiAgICAgICAgICB3LmdldENvbXB1dGVkU3R5bGUoZWwsIG51bGwpLm92ZXJmbG93ID09PSAndmlzaWJsZSc7XG4gICAgICB9IHdoaWxlICghaXNCb2R5ICYmICEoaGFzU2Nyb2xsYWJsZVNwYWNlICYmICFoYXNWaXNpYmxlT3ZlcmZsb3cpKTtcblxuICAgICAgaXNCb2R5ID0gaGFzU2Nyb2xsYWJsZVNwYWNlID0gaGFzVmlzaWJsZU92ZXJmbG93ID0gbnVsbDtcblxuICAgICAgcmV0dXJuIGVsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHNlbGYgaW52b2tlZCBmdW5jdGlvbiB0aGF0LCBnaXZlbiBhIGNvbnRleHQsIHN0ZXBzIHRocm91Z2ggc2Nyb2xsaW5nXG4gICAgICogQG1ldGhvZCBzdGVwXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdGVwKGNvbnRleHQpIHtcbiAgICAgIHZhciB0aW1lID0gbm93KCk7XG4gICAgICB2YXIgdmFsdWU7XG4gICAgICB2YXIgY3VycmVudFg7XG4gICAgICB2YXIgY3VycmVudFk7XG4gICAgICB2YXIgZWxhcHNlZCA9ICh0aW1lIC0gY29udGV4dC5zdGFydFRpbWUpIC8gU0NST0xMX1RJTUU7XG5cbiAgICAgIC8vIGF2b2lkIGVsYXBzZWQgdGltZXMgaGlnaGVyIHRoYW4gb25lXG4gICAgICBlbGFwc2VkID0gZWxhcHNlZCA+IDEgPyAxIDogZWxhcHNlZDtcblxuICAgICAgLy8gYXBwbHkgZWFzaW5nIHRvIGVsYXBzZWQgdGltZVxuICAgICAgdmFsdWUgPSBlYXNlKGVsYXBzZWQpO1xuXG4gICAgICBjdXJyZW50WCA9IGNvbnRleHQuc3RhcnRYICsgKGNvbnRleHQueCAtIGNvbnRleHQuc3RhcnRYKSAqIHZhbHVlO1xuICAgICAgY3VycmVudFkgPSBjb250ZXh0LnN0YXJ0WSArIChjb250ZXh0LnkgLSBjb250ZXh0LnN0YXJ0WSkgKiB2YWx1ZTtcblxuICAgICAgY29udGV4dC5tZXRob2QuY2FsbChjb250ZXh0LnNjcm9sbGFibGUsIGN1cnJlbnRYLCBjdXJyZW50WSk7XG5cbiAgICAgIC8vIHNjcm9sbCBtb3JlIGlmIHdlIGhhdmUgbm90IHJlYWNoZWQgb3VyIGRlc3RpbmF0aW9uXG4gICAgICBpZiAoY3VycmVudFggIT09IGNvbnRleHQueCB8fCBjdXJyZW50WSAhPT0gY29udGV4dC55KSB7XG4gICAgICAgIHcucmVxdWVzdEFuaW1hdGlvbkZyYW1lKHN0ZXAuYmluZCh3LCBjb250ZXh0KSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogc2Nyb2xscyB3aW5kb3cgd2l0aCBhIHNtb290aCBiZWhhdmlvclxuICAgICAqIEBtZXRob2Qgc21vb3RoU2Nyb2xsXG4gICAgICogQHBhcmFtIHtPYmplY3R8Tm9kZX0gZWxcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5XG4gICAgICovXG4gICAgZnVuY3Rpb24gc21vb3RoU2Nyb2xsKGVsLCB4LCB5KSB7XG4gICAgICB2YXIgc2Nyb2xsYWJsZTtcbiAgICAgIHZhciBzdGFydFg7XG4gICAgICB2YXIgc3RhcnRZO1xuICAgICAgdmFyIG1ldGhvZDtcbiAgICAgIHZhciBzdGFydFRpbWUgPSBub3coKTtcblxuICAgICAgLy8gZGVmaW5lIHNjcm9sbCBjb250ZXh0XG4gICAgICBpZiAoZWwgPT09IGQuYm9keSkge1xuICAgICAgICBzY3JvbGxhYmxlID0gdztcbiAgICAgICAgc3RhcnRYID0gdy5zY3JvbGxYIHx8IHcucGFnZVhPZmZzZXQ7XG4gICAgICAgIHN0YXJ0WSA9IHcuc2Nyb2xsWSB8fCB3LnBhZ2VZT2Zmc2V0O1xuICAgICAgICBtZXRob2QgPSBvcmlnaW5hbC5zY3JvbGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzY3JvbGxhYmxlID0gZWw7XG4gICAgICAgIHN0YXJ0WCA9IGVsLnNjcm9sbExlZnQ7XG4gICAgICAgIHN0YXJ0WSA9IGVsLnNjcm9sbFRvcDtcbiAgICAgICAgbWV0aG9kID0gc2Nyb2xsRWxlbWVudDtcbiAgICAgIH1cblxuICAgICAgLy8gc2Nyb2xsIGxvb3Bpbmcgb3ZlciBhIGZyYW1lXG4gICAgICBzdGVwKHtcbiAgICAgICAgc2Nyb2xsYWJsZTogc2Nyb2xsYWJsZSxcbiAgICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICAgIHN0YXJ0VGltZTogc3RhcnRUaW1lLFxuICAgICAgICBzdGFydFg6IHN0YXJ0WCxcbiAgICAgICAgc3RhcnRZOiBzdGFydFksXG4gICAgICAgIHg6IHgsXG4gICAgICAgIHk6IHlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogT1JJR0lOQUwgTUVUSE9EUyBPVkVSUklERVNcbiAgICAgKi9cblxuICAgIC8vIHcuc2Nyb2xsIGFuZCB3LnNjcm9sbFRvXG4gICAgdy5zY3JvbGwgPSB3LnNjcm9sbFRvID0gZnVuY3Rpb24oKSB7XG4gICAgICAvLyBhdm9pZCBzbW9vdGggYmVoYXZpb3IgaWYgbm90IHJlcXVpcmVkXG4gICAgICBpZiAoc2hvdWxkQmFpbE91dChhcmd1bWVudHNbMF0pKSB7XG4gICAgICAgIG9yaWdpbmFsLnNjcm9sbC5jYWxsKFxuICAgICAgICAgIHcsXG4gICAgICAgICAgYXJndW1lbnRzWzBdLmxlZnQgfHwgYXJndW1lbnRzWzBdLFxuICAgICAgICAgIGFyZ3VtZW50c1swXS50b3AgfHwgYXJndW1lbnRzWzFdXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gTEVUIFRIRSBTTU9PVEhORVNTIEJFR0lOIVxuICAgICAgc21vb3RoU2Nyb2xsLmNhbGwoXG4gICAgICAgIHcsXG4gICAgICAgIGQuYm9keSxcbiAgICAgICAgfn5hcmd1bWVudHNbMF0ubGVmdCxcbiAgICAgICAgfn5hcmd1bWVudHNbMF0udG9wXG4gICAgICApO1xuICAgIH07XG5cbiAgICAvLyB3LnNjcm9sbEJ5XG4gICAgdy5zY3JvbGxCeSA9IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gYXZvaWQgc21vb3RoIGJlaGF2aW9yIGlmIG5vdCByZXF1aXJlZFxuICAgICAgaWYgKHNob3VsZEJhaWxPdXQoYXJndW1lbnRzWzBdKSkge1xuICAgICAgICBvcmlnaW5hbC5zY3JvbGxCeS5jYWxsKFxuICAgICAgICAgIHcsXG4gICAgICAgICAgYXJndW1lbnRzWzBdLmxlZnQgfHwgYXJndW1lbnRzWzBdLFxuICAgICAgICAgIGFyZ3VtZW50c1swXS50b3AgfHwgYXJndW1lbnRzWzFdXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gTEVUIFRIRSBTTU9PVEhORVNTIEJFR0lOIVxuICAgICAgc21vb3RoU2Nyb2xsLmNhbGwoXG4gICAgICAgIHcsXG4gICAgICAgIGQuYm9keSxcbiAgICAgICAgfn5hcmd1bWVudHNbMF0ubGVmdCArICh3LnNjcm9sbFggfHwgdy5wYWdlWE9mZnNldCksXG4gICAgICAgIH5+YXJndW1lbnRzWzBdLnRvcCArICh3LnNjcm9sbFkgfHwgdy5wYWdlWU9mZnNldClcbiAgICAgICk7XG4gICAgfTtcblxuICAgIC8vIEVsZW1lbnQucHJvdG90eXBlLnNjcm9sbCBhbmQgRWxlbWVudC5wcm90b3R5cGUuc2Nyb2xsVG9cbiAgICBFbGVtZW50LnByb3RvdHlwZS5zY3JvbGwgPSBFbGVtZW50LnByb3RvdHlwZS5zY3JvbGxUbyA9IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gYXZvaWQgc21vb3RoIGJlaGF2aW9yIGlmIG5vdCByZXF1aXJlZFxuICAgICAgaWYgKHNob3VsZEJhaWxPdXQoYXJndW1lbnRzWzBdKSkge1xuICAgICAgICBvcmlnaW5hbC5lbFNjcm9sbC5jYWxsKFxuICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgIGFyZ3VtZW50c1swXS5sZWZ0IHx8IGFyZ3VtZW50c1swXSxcbiAgICAgICAgICAgIGFyZ3VtZW50c1swXS50b3AgfHwgYXJndW1lbnRzWzFdXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGxlZnQgPSBhcmd1bWVudHNbMF0ubGVmdDtcbiAgICAgIHZhciB0b3AgPSBhcmd1bWVudHNbMF0udG9wO1xuXG4gICAgICAvLyBMRVQgVEhFIFNNT09USE5FU1MgQkVHSU4hXG4gICAgICBzbW9vdGhTY3JvbGwuY2FsbChcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgdHlwZW9mIGxlZnQgPT09ICdudW1iZXInID8gbGVmdCA6IHRoaXMuc2Nyb2xsTGVmdCxcbiAgICAgICAgICB0eXBlb2YgdG9wID09PSAnbnVtYmVyJyA/IHRvcCA6IHRoaXMuc2Nyb2xsVG9wXG4gICAgICApO1xuICAgIH07XG5cbiAgICAvLyBFbGVtZW50LnByb3RvdHlwZS5zY3JvbGxCeVxuICAgIEVsZW1lbnQucHJvdG90eXBlLnNjcm9sbEJ5ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYXJnMCA9IGFyZ3VtZW50c1swXTtcblxuICAgICAgaWYgKHR5cGVvZiBhcmcwID09PSAnb2JqZWN0Jykge1xuICAgICAgICB0aGlzLnNjcm9sbCh7XG4gICAgICAgICAgbGVmdDogYXJnMC5sZWZ0ICsgdGhpcy5zY3JvbGxMZWZ0LFxuICAgICAgICAgIHRvcDogYXJnMC50b3AgKyB0aGlzLnNjcm9sbFRvcCxcbiAgICAgICAgICBiZWhhdmlvcjogYXJnMC5iZWhhdmlvclxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2Nyb2xsKFxuICAgICAgICAgIHRoaXMuc2Nyb2xsTGVmdCArIGFyZzAsXG4gICAgICAgICAgdGhpcy5zY3JvbGxUb3AgKyBhcmd1bWVudHNbMV1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gRWxlbWVudC5wcm90b3R5cGUuc2Nyb2xsSW50b1ZpZXdcbiAgICBFbGVtZW50LnByb3RvdHlwZS5zY3JvbGxJbnRvVmlldyA9IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gYXZvaWQgc21vb3RoIGJlaGF2aW9yIGlmIG5vdCByZXF1aXJlZFxuICAgICAgaWYgKHNob3VsZEJhaWxPdXQoYXJndW1lbnRzWzBdKSkge1xuICAgICAgICBvcmlnaW5hbC5zY3JvbGxJbnRvVmlldy5jYWxsKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQgPyB0cnVlIDogYXJndW1lbnRzWzBdXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gTEVUIFRIRSBTTU9PVEhORVNTIEJFR0lOIVxuICAgICAgdmFyIHNjcm9sbGFibGVQYXJlbnQgPSBmaW5kU2Nyb2xsYWJsZVBhcmVudCh0aGlzKTtcbiAgICAgIHZhciBwYXJlbnRSZWN0cyA9IHNjcm9sbGFibGVQYXJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICB2YXIgY2xpZW50UmVjdHMgPSB0aGlzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgICBpZiAoc2Nyb2xsYWJsZVBhcmVudCAhPT0gZC5ib2R5KSB7XG4gICAgICAgIC8vIHJldmVhbCBlbGVtZW50IGluc2lkZSBwYXJlbnRcbiAgICAgICAgc21vb3RoU2Nyb2xsLmNhbGwoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBzY3JvbGxhYmxlUGFyZW50LFxuICAgICAgICAgIHNjcm9sbGFibGVQYXJlbnQuc2Nyb2xsTGVmdCArIGNsaWVudFJlY3RzLmxlZnQgLSBwYXJlbnRSZWN0cy5sZWZ0LFxuICAgICAgICAgIHNjcm9sbGFibGVQYXJlbnQuc2Nyb2xsVG9wICsgY2xpZW50UmVjdHMudG9wIC0gcGFyZW50UmVjdHMudG9wXG4gICAgICAgICk7XG4gICAgICAgIC8vIHJldmVhbCBwYXJlbnQgaW4gdmlld3BvcnRcbiAgICAgICAgdy5zY3JvbGxCeSh7XG4gICAgICAgICAgbGVmdDogcGFyZW50UmVjdHMubGVmdCxcbiAgICAgICAgICB0b3A6IHBhcmVudFJlY3RzLnRvcCxcbiAgICAgICAgICBiZWhhdmlvcjogJ3Ntb290aCdcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyByZXZlYWwgZWxlbWVudCBpbiB2aWV3cG9ydFxuICAgICAgICB3LnNjcm9sbEJ5KHtcbiAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0cy5sZWZ0LFxuICAgICAgICAgIHRvcDogY2xpZW50UmVjdHMudG9wLFxuICAgICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJ1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xuICAgIC8vIGNvbW1vbmpzXG4gICAgbW9kdWxlLmV4cG9ydHMgPSB7IHBvbHlmaWxsOiBwb2x5ZmlsbCB9O1xuICB9IGVsc2Uge1xuICAgIC8vIGdsb2JhbFxuICAgIHBvbHlmaWxsKCk7XG4gIH1cbn0pKHdpbmRvdywgZG9jdW1lbnQpO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvc21vb3Roc2Nyb2xsLXBvbHlmaWxsL2Rpc3Qvc21vb3Roc2Nyb2xsLmpzXG4vLyBtb2R1bGUgaWQgPSAxM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///13\n");
+
+/***/ }),
+/* 14 */
+/*!*****************************************!*\
+ !*** ./public/javascripts/analytics.js ***!
+ \*****************************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\n/* global ga */\n\nvar self = {};\n\nself.send = {};\n\nself.send.search = function (selectedUser, favorite) {\n var hitType = 'event';\n\n var eventCategory = favorite ? 'search fav' : 'search';\n\n var eventAction = void 0;\n switch (selectedUser.type) {\n case 'c':\n eventAction = 'Class';\n break;\n case 't':\n eventAction = 'Teacher';\n break;\n case 'r':\n eventAction = 'Room';\n break;\n case 's':\n eventAction = 'Student';\n break;\n }\n\n var eventLabel = selectedUser.value;\n\n ga(function () {\n ga('send', { hitType: hitType, eventCategory: eventCategory, eventAction: eventAction, eventLabel: eventLabel });\n });\n};\n\nmodule.exports = self;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcHVibGljL2phdmFzY3JpcHRzL2FuYWx5dGljcy5qcz85MGMwIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIGdsb2JhbCBnYSAqL1xuXG5jb25zdCBzZWxmID0ge31cblxuc2VsZi5zZW5kID0ge31cblxuc2VsZi5zZW5kLnNlYXJjaCA9IGZ1bmN0aW9uIChzZWxlY3RlZFVzZXIsIGZhdm9yaXRlKSB7XG4gIGNvbnN0IGhpdFR5cGUgPSAnZXZlbnQnXG5cbiAgY29uc3QgZXZlbnRDYXRlZ29yeSA9IGZhdm9yaXRlID8gJ3NlYXJjaCBmYXYnIDogJ3NlYXJjaCdcblxuICBsZXQgZXZlbnRBY3Rpb25cbiAgc3dpdGNoIChzZWxlY3RlZFVzZXIudHlwZSkge1xuICAgIGNhc2UgJ2MnOlxuICAgICAgZXZlbnRBY3Rpb24gPSAnQ2xhc3MnXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3QnOlxuICAgICAgZXZlbnRBY3Rpb24gPSAnVGVhY2hlcidcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAncic6XG4gICAgICBldmVudEFjdGlvbiA9ICdSb29tJ1xuICAgICAgYnJlYWtcbiAgICBjYXNlICdzJzpcbiAgICAgIGV2ZW50QWN0aW9uID0gJ1N0dWRlbnQnXG4gICAgICBicmVha1xuICB9XG5cbiAgY29uc3QgZXZlbnRMYWJlbCA9IHNlbGVjdGVkVXNlci52YWx1ZVxuXG4gIGdhKGZ1bmN0aW9uICgpIHtcbiAgICBnYSgnc2VuZCcsIHsgaGl0VHlwZSwgZXZlbnRDYXRlZ29yeSwgZXZlbnRBY3Rpb24sIGV2ZW50TGFiZWwgfSlcbiAgfSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZWxmXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gcHVibGljL2phdmFzY3JpcHRzL2FuYWx5dGljcy5qcyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVpBO0FBQ0E7QUFjQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///14\n");
+
+/***/ }),
+/* 15 */
+/*!***********************************!*\
+ !*** ./public/javascripts/url.js ***!
+ \***********************************/
+/*! no static exports found */
+/*! all exports used */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\n/* global USERS FLAGS */\n\nvar EventEmitter = __webpack_require__(/*! events */ 0);\n\nvar self = new EventEmitter();\n\nself._getPageTitle = function (selectedUser) {\n var ret = void 0;\n\n if (selectedUser == null) {\n ret = 'Metis Rooster';\n } else {\n ret = 'Metis Rooster - ' + selectedUser.value;\n }\n\n if (FLAGS.indexOf('BETA') !== -1) {\n ret = 'BETA ' + ret;\n }\n\n return ret;\n};\n\nself._getPageURL = function (selectedUser) {\n return '/' + selectedUser.type + '/' + selectedUser.value;\n};\n\nself.push = function (selectedUser, push) {\n if (push == null) push = true;\n var pageTitle = self._getPageTitle(selectedUser);\n var pageURL = self._getPageURL(selectedUser);\n if (push) {\n window.history.pushState(selectedUser, pageTitle, pageURL);\n } else {\n window.history.replaceState(selectedUser, pageTitle, pageURL);\n }\n};\n\nself.update = function (selectedUser) {\n document.title = self._getPageTitle(selectedUser);\n};\n\nself.hasSelectedUser = function () {\n var pageUrl = window.location.pathname;\n return (/^\\/s\\/|^\\/t\\/|^\\/r\\/|^\\/c\\//.test(pageUrl)\n );\n};\n\nself.getSelectedUser = function () {\n var pageUrl = window.location.pathname;\n var pageUrlData = pageUrl.split('/');\n var type = pageUrlData[1];\n var value = pageUrlData[2];\n\n var user = USERS.filter(function (user) {\n return user.type === type && user.value === value;\n })[0];\n\n return user;\n};\n\nself._handleUpdate = function (event) {\n self.emit('update', event.state);\n};\n\nwindow.addEventListener('popstate', self._handleUpdate);\n\nmodule.exports = self;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcHVibGljL2phdmFzY3JpcHRzL3VybC5qcz8xNGIyIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIGdsb2JhbCBVU0VSUyBGTEFHUyAqL1xuXG5jb25zdCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKVxuXG5jb25zdCBzZWxmID0gbmV3IEV2ZW50RW1pdHRlcigpXG5cbnNlbGYuX2dldFBhZ2VUaXRsZSA9IGZ1bmN0aW9uIChzZWxlY3RlZFVzZXIpIHtcbiAgbGV0IHJldFxuXG4gIGlmIChzZWxlY3RlZFVzZXIgPT0gbnVsbCkge1xuICAgIHJldCA9IGBNZXRpcyBSb29zdGVyYFxuICB9IGVsc2Uge1xuICAgIHJldCA9IGBNZXRpcyBSb29zdGVyIC0gJHtzZWxlY3RlZFVzZXIudmFsdWV9YFxuICB9XG5cbiAgaWYgKEZMQUdTLmluZGV4T2YoJ0JFVEEnKSAhPT0gLTEpIHtcbiAgICByZXQgPSBgQkVUQSAke3JldH1gXG4gIH1cblxuICByZXR1cm4gcmV0XG59XG5cbnNlbGYuX2dldFBhZ2VVUkwgPSBmdW5jdGlvbiAoc2VsZWN0ZWRVc2VyKSB7XG4gIHJldHVybiBgLyR7c2VsZWN0ZWRVc2VyLnR5cGV9LyR7c2VsZWN0ZWRVc2VyLnZhbHVlfWBcbn1cblxuc2VsZi5wdXNoID0gZnVuY3Rpb24gKHNlbGVjdGVkVXNlciwgcHVzaCkge1xuICBpZiAocHVzaCA9PSBudWxsKSBwdXNoID0gdHJ1ZVxuICBjb25zdCBwYWdlVGl0bGUgPSBzZWxmLl9nZXRQYWdlVGl0bGUoc2VsZWN0ZWRVc2VyKVxuICBjb25zdCBwYWdlVVJMID0gc2VsZi5fZ2V0UGFnZVVSTChzZWxlY3RlZFVzZXIpXG4gIGlmIChwdXNoKSB7XG4gICAgd2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKHNlbGVjdGVkVXNlciwgcGFnZVRpdGxlLCBwYWdlVVJMKVxuICB9IGVsc2Uge1xuICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZShzZWxlY3RlZFVzZXIsIHBhZ2VUaXRsZSwgcGFnZVVSTClcbiAgfVxufVxuXG5zZWxmLnVwZGF0ZSA9IGZ1bmN0aW9uIChzZWxlY3RlZFVzZXIpIHtcbiAgZG9jdW1lbnQudGl0bGUgPSBzZWxmLl9nZXRQYWdlVGl0bGUoc2VsZWN0ZWRVc2VyKVxufVxuXG5zZWxmLmhhc1NlbGVjdGVkVXNlciA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgcGFnZVVybCA9IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZVxuICByZXR1cm4gL15cXC9zXFwvfF5cXC90XFwvfF5cXC9yXFwvfF5cXC9jXFwvLy50ZXN0KHBhZ2VVcmwpXG59XG5cbnNlbGYuZ2V0U2VsZWN0ZWRVc2VyID0gZnVuY3Rpb24gKCkge1xuICBjb25zdCBwYWdlVXJsID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lXG4gIGNvbnN0IHBhZ2VVcmxEYXRhID0gcGFnZVVybC5zcGxpdCgnLycpXG4gIGNvbnN0IHR5cGUgPSBwYWdlVXJsRGF0YVsxXVxuICBjb25zdCB2YWx1ZSA9IHBhZ2VVcmxEYXRhWzJdXG5cbiAgY29uc3QgdXNlciA9IFVTRVJTLmZpbHRlcihmdW5jdGlvbiAodXNlcikge1xuICAgIHJldHVybiB1c2VyLnR5cGUgPT09IHR5cGUgJiZcbiAgICAgICAgICAgdXNlci52YWx1ZSA9PT0gdmFsdWVcbiAgfSlbMF1cblxuICByZXR1cm4gdXNlclxufVxuXG5zZWxmLl9oYW5kbGVVcGRhdGUgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgc2VsZi5lbWl0KCd1cGRhdGUnLCBldmVudC5zdGF0ZSlcbn1cblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3BvcHN0YXRlJywgc2VsZi5faGFuZGxlVXBkYXRlKVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNlbGZcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBwdWJsaWMvamF2YXNjcmlwdHMvdXJsLmpzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///15\n");
+
+/***/ })
+/******/ ]); \ No newline at end of file
diff --git a/public/javascripts/favorite.js b/public/javascripts/favorite.js
index 9edc248..92c87f7 100644
--- a/public/javascripts/favorite.js
+++ b/public/javascripts/favorite.js
@@ -44,7 +44,7 @@ self.updateDom = function (isFavorite) {
self.update = function (selectedUser) {
const currentUser = self.get()
- if (currentUser == null) {
+ if (currentUser == null || selectedUser == null) {
self.updateDom(false)
return
}
diff --git a/public/javascripts/main.bak.js b/public/javascripts/main.bak.js
deleted file mode 100644
index 895dd3f..0000000
--- a/public/javascripts/main.bak.js
+++ /dev/null
@@ -1,244 +0,0 @@
-/* global ga FLAGS USERS */
-
-require('flexibility')
-
-const fuzzy = require('fuzzy')
-// const getUsers = require('./getUsers')
-const getURLOfUser = require('./getURLOfUser')
-const removeDiacritics = require('diacritics').remove
-const getWeek = require('./getWeek')
-const easterEggs = require('./easterEggs')
-
-const searchNode = document.querySelector('#search')
-const inputNode = searchNode.querySelector('input[type="search"]')
-const autocompleteNode = document.querySelector('.autocomplete')
-const scheduleIframe = document.querySelector('#schedule')
-const prevButton = document.querySelectorAll('#week-selector button')[0]
-const nextButton = document.querySelectorAll('#week-selector button')[1]
-const currentWeekNode = document.querySelector('.current')
-const favNode = document.querySelector('.fav')
-
-if (FLAGS.indexOf('NO_FEATURE_DETECT') === -1) {
- if (document.querySelector('#schedule').getClientRects()[0].bottom !==
- document.body.getClientRects()[0].bottom) {
- window.location = 'http://www.meetingpointmco.nl/Roosters-AL/doc/'
- } else {
- window.onerror = function () {
- window.location = 'http://www.meetingpointmco.nl/Roosters-AL/doc/'
- }
- }
-} else {
- console.log('feature detection is OFF')
-}
-
-let selectedResult = -1
-let selectedUser
-let results = []
-let offset = 0
-
-function getCurrentFav () {
- if (!window.localStorage.getItem('fav')) return
- const favCode = window.localStorage.getItem('fav').split(':')
- const fav = USERS.filter(user => user.type === favCode[0] && user.index === Number(favCode[1]))
- return fav[0]
-}
-
-function changeFav (isFav) {
- if (!selectedUser) return
- if (isFav) {
- window.localStorage.setItem('fav', selectedUser.type + ':' + selectedUser.index)
- } else {
- window.localStorage.removeItem('fav')
- }
- updateFavNode()
-}
-
-function usersEqual (user1, user2) {
- if (user1 == null || user2 == null) return false
- return user1.type === user2.type && user1.index === user2.index
-}
-
-function updateFavNode () {
- if (usersEqual(getCurrentFav(), selectedUser)) {
- favNode.innerHTML = '&#xE838;'
- } else {
- favNode.innerHTML = '&#xE83A'
- }
-}
-
-function updateWeekText () {
- if (offset === 0) currentWeekNode.innerHTML = `Week ${getWeek() + offset}`
- else currentWeekNode.innerHTML = `<strong>Week ${getWeek() + offset}</strong>`
-}
-
-updateWeekText()
-
-searchNode.addEventListener('keydown', function (e) {
- if ((results.length !== 0) && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
- e.preventDefault()
-
- if (document.querySelector('.selected')) document.querySelector('.selected').classList.remove('selected')
-
- const change = e.key === 'ArrowDown' ? 1 : -1
- selectedResult += change
- if (selectedResult < -1) selectedResult = results.length - 1
- else if (selectedResult > results.length - 1) selectedResult = -1
-
- if (selectedResult !== -1) autocompleteNode.children[selectedResult].classList.add('selected')
- }
-})
-
-let inputEventStr
-if (navigator.userAgent.indexOf('MSIE') !== -1 ||
- navigator.appVersion.indexOf('Trident/') > 0) {
- inputEventStr = 'textinput' // IE 6-11
-} else {
- inputEventStr = 'input' // normal browsers
-}
-
-searchNode.addEventListener(inputEventStr, function (e) {
- document.body.classList.remove('no-input')
- autocompleteNode.innerHTML = ''
- if (inputNode.value.trim() === '') return
-
- selectedResult = -1
- results = fuzzy.filter(removeDiacritics(inputNode.value), USERS, {
- extract: function (el) { return removeDiacritics(el.value) }
- }).slice(0, 7)
-
- results.forEach(function (result) {
- const resultNode = document.createElement('li')
- resultNode.innerHTML = `${result.original.value}`
- autocompleteNode.appendChild(resultNode)
- })
-})
-
-searchNode.addEventListener('submit', submitForm)
-
-function submitForm (e) {
- if (e) e.preventDefault()
- if (results.length !== 0) {
- const indexInResult = selectedResult === -1 ? 0 : selectedResult
- selectedUser = USERS[results[indexInResult].index]
- }
- if (selectedUser == null) return
-
- document.body.classList.add('searched')
-
- updateFavNode()
-
- inputNode.value = selectedUser.value
- autocompleteNode.innerHTML = ''
-
- inputNode.blur()
-
- scheduleIframe.src = getURLOfUser(offset, selectedUser.type, selectedUser.index + 1)
-
- let eventAction
- switch (selectedUser.type) {
- case 'c':
- eventAction = 'Class'
- break
- case 't':
- eventAction = 'Teacher'
- break
- case 'r':
- eventAction = 'Room'
- break
- case 's':
- eventAction = 'Student'
- break
- }
- const eventLabel = selectedUser.value
-
- ga(function () {
- ga('send', { hitType: 'event', eventCategory: 'search', eventAction, eventLabel })
- })
-}
-
-autocompleteNode.addEventListener('click', function (e) {
- if (autocompleteNode.contains(e.target)) {
- selectedResult = Array.prototype.indexOf.call(e.target.parentElement.childNodes, e.target)
- submitForm()
- }
-})
-
-prevButton.addEventListener('click', function () {
- offset--
- updateWeekText()
- submitForm()
-})
-
-nextButton.addEventListener('click', function () {
- offset++
- updateWeekText()
- submitForm()
-})
-
-inputNode.addEventListener('click', function () {
- inputNode.select()
-})
-
-window.addEventListener('blur', function () {
- // this will removed the selection without drawing focus on it (safari)
- // this will removed selection even when focusing an iframe (chrome)
- const oldValue = inputNode.value
- inputNode.value = ''
- inputNode.value = oldValue
-
- // this will hide the keyboard (iOS safari)
- document.activeElement.blur()
-})
-
-searchNode.addEventListener('blur', function (e) {
- autocompleteNode.innerHTML = ''
-})
-
-favNode.addEventListener('click', function () {
- if (usersEqual(getCurrentFav(), selectedUser)) {
- changeFav(false)
- } else {
- changeFav(true)
- }
-})
-
-const currentFav = getCurrentFav()
-
-if (currentFav) {
- selectedUser = currentFav
- inputNode.value = selectedUser.value
- scheduleIframe.src = getURLOfUser(offset, selectedUser.type, selectedUser.index + 1)
- updateFavNode()
-
- let eventAction
- switch (selectedUser.type) {
- case 'c':
- eventAction = 'Class'
- break
- case 't':
- eventAction = 'Teacher'
- break
- case 'r':
- eventAction = 'Room'
- break
- case 's':
- eventAction = 'Student'
- break
- }
- const eventLabel = selectedUser.value
-
- ga(function () {
- ga('send', { hitType: 'event', eventCategory: 'search fav', eventAction, eventLabel })
- })
-} else if (inputNode.value === '') {
- document.body.classList.add('no-input')
- inputNode.focus()
-}
-
-if (scheduleIframe.src !== '') {
- document.body.classList.add('searched')
-}
-
-document.body.style.opacity = '1'
-
-window.easterEggs = easterEggs
diff --git a/public/javascripts/main.js b/public/javascripts/main.js
index 6f99621..0d125cb 100644
--- a/public/javascripts/main.js
+++ b/public/javascripts/main.js
@@ -1,4 +1,5 @@
require('./featureDetect').check()
+require('./zoom')
const frontpage = require('./frontpage')
const search = require('./search')
@@ -7,39 +8,64 @@ const weekSelector = require('./weekSelector')
const favorite = require('./favorite')
const scrollSnap = require('./scrollSnap')
const analytics = require('./analytics')
+const url = require('./url')
const state = {}
window.state = state
-window.require = require
frontpage.show()
weekSelector.updateCurrentWeek()
scrollSnap.startListening()
-if (favorite.get() != null) {
- state.selectedItem = favorite.get()
- favorite.update(state.selectedItem)
- analytics.send.search(state.selectedItem, true)
- schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedItem)
+if (url.hasSelectedUser()) {
+ state.selectedUser = url.getSelectedUser()
+
+ favorite.update(state.selectedUser)
+ url.update(state.selectedUser)
+ analytics.send.search(state.selectedUser)
+
+ schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedUser)
+} else if (favorite.get() != null) {
+ state.selectedUser = favorite.get()
+
+ favorite.update(state.selectedUser)
+ url.push(state.selectedUser, false)
+ url.update(state.selectedUser)
+ analytics.send.search(state.selectedUser, true)
+
+ schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedUser)
} else {
search.focus()
}
-search.on('search', function (selectedItem) {
- state.selectedItem = selectedItem
- favorite.update(state.selectedItem)
- analytics.send.search(state.selectedItem)
- schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedItem)
+search.on('search', function (selectedUser) {
+ state.selectedUser = selectedUser
+
+ favorite.update(state.selectedUser)
+ url.push(state.selectedUser)
+ url.update(state.selectedUser)
+ analytics.send.search(state.selectedUser)
+
+ schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedUser)
+})
+
+url.on('update', function (selectedUser) {
+ state.selectedUser = selectedUser
+
+ favorite.update(state.selectedUser)
+ url.update(state.selectedUser)
+
+ schedule.viewItem(weekSelector.getSelectedWeek(), state.selectedUser)
})
weekSelector.on('weekChanged', function (newWeek) {
- analytics.send.search(state.selectedItem)
- schedule.viewItem(newWeek, state.selectedItem)
+ analytics.send.search(state.selectedUser)
+ schedule.viewItem(newWeek, state.selectedUser)
})
favorite.on('click', function () {
- favorite.toggle(state.selectedItem)
+ favorite.toggle(state.selectedUser)
})
document.body.style.opacity = 1
diff --git a/public/javascripts/schedule.js b/public/javascripts/schedule.js
index 73e2a54..38ad66d 100644
--- a/public/javascripts/schedule.js
+++ b/public/javascripts/schedule.js
@@ -1,7 +1,6 @@
/* global VALID_WEEK_NUMBERS */
const EventEmitter = require('events')
-const leftPad = require('left-pad')
const search = require('./search')
const self = new EventEmitter()
@@ -44,10 +43,8 @@ self._handleError = function (event) {
self.emit('load')
}
-self._getURLOfUsers = function (week, type, index) {
- const id = index + 1
- return '//' + window.location.host + '/meetingpointProxy/Roosters-AL%2Fdoc%2Fdagroosters%2F' +
- leftPad(week, 2, '0') + '%2F' + type + '%2F' + type + leftPad(id, 5, '0') + '.htm'
+self._getURLOfUser = function (week, user) {
+ return `/get/${user.type}/${user.value}?week=${week}`
}
self._removeChilds = function () {
@@ -57,21 +54,25 @@ self._removeChilds = function () {
}
self.viewItem = function (week, selectedUser) {
- if (VALID_WEEK_NUMBERS.indexOf(week) === -1) {
+ if (selectedUser == null) {
+ self._removeChilds()
+ search.updateDom(selectedUser)
+ } else if (VALID_WEEK_NUMBERS.indexOf(week) === -1) {
self._handleError({ target: { status: 404 } });
return
- }
- const url = self._getURLOfUsers(week, selectedUser.type, selectedUser.index)
+ } else {
+ const url = self._getURLOfUser(week, selectedUser)
- self._removeChilds()
+ self._removeChilds()
- const request = new window.XMLHttpRequest()
- request.addEventListener('load', self._handleLoad)
- request.addEventListener('error', self._handleError)
- request.open('GET', url, true)
- request.send()
+ const request = new window.XMLHttpRequest()
+ request.addEventListener('load', self._handleLoad)
+ request.addEventListener('error', self._handleError)
+ request.open('GET', url, true)
+ request.send()
- search.updateDom(selectedUser)
+ search.updateDom(selectedUser)
+ }
}
module.exports = self
diff --git a/public/javascripts/scrollSnap.js b/public/javascripts/scrollSnap.js
index 167f0c1..afee979 100644
--- a/public/javascripts/scrollSnap.js
+++ b/public/javascripts/scrollSnap.js
@@ -12,12 +12,13 @@ self._timeoutID = null
self._getScrollPosition = function () {
return (document.documentElement && document.documentElement.scrollTop) ||
- document.body.scrollTop
+ document.body.scrollTop
}
self._handleDoneScrolling = function () {
const scrollPosition = self._getScrollPosition()
- const weekSelectorHeight = self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight
+ const weekSelectorHeight =
+ self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight
if (scrollPosition < weekSelectorHeight && scrollPosition > 0) {
window.scroll({ top: weekSelectorHeight, left: 0, behavior: 'smooth' })
}
@@ -28,7 +29,8 @@ self._handleScroll = function () {
self._timeoutID = window.setTimeout(self._handleDoneScrolling, 500)
const scrollPosition = self._getScrollPosition()
- const weekSelectorHeight = self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight
+ const weekSelectorHeight =
+ self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight
if (scrollPosition >= weekSelectorHeight) {
document.body.classList.add('week-selector-not-visible')
} else {
@@ -37,8 +39,10 @@ self._handleScroll = function () {
}
self._handleWindowResize = function () {
- const weekSelectorHeight = self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight
- const extraPixelsNeeded = weekSelectorHeight - (document.body.clientHeight - window.innerHeight)
+ const weekSelectorHeight =
+ self._nodes.weekSelector.clientHeight - self._nodes.search.clientHeight
+ const extraPixelsNeeded =
+ weekSelectorHeight - (document.body.clientHeight - window.innerHeight)
if (extraPixelsNeeded > 0) {
document.body.style.marginBottom = extraPixelsNeeded + 'px'
} else {
diff --git a/public/javascripts/search.js b/public/javascripts/search.js
index a07d6dd..96413b0 100644
--- a/public/javascripts/search.js
+++ b/public/javascripts/search.js
@@ -13,22 +13,29 @@ self._nodes = {
}
self.submit = function () {
- const selectedItem = autocomplete.getSelectedItem()
- if (selectedItem == null) return
+ const selectedUser = autocomplete.getSelectedUser()
+ if (selectedUser == null) return
- console.log(selectedItem)
+ console.log(selectedUser)
self._nodes.input.blur()
document.body.classList.remove('week-selector-not-visible') // Safari bug
- self.emit('search', selectedItem)
+ self.emit('search', selectedUser)
}
-self.updateDom = function (selectedItem) {
- self._nodes.input.value = selectedItem.value
- autocomplete.removeAllItems()
- document.body.classList.remove('no-input')
- document.body.classList.add('searched')
+self.updateDom = function (selectedUser) {
+ if (selectedUser == null) {
+ self._nodes.input.value = ''
+ autocomplete.removeAllItems()
+ document.body.classList.add('no-input')
+ document.body.classList.remove('searched')
+ } else {
+ self._nodes.input.value = selectedUser.value
+ autocomplete.removeAllItems()
+ document.body.classList.remove('no-input')
+ document.body.classList.add('searched')
+ }
}
self.focus = function () {
@@ -42,7 +49,7 @@ self._handleSubmit = function (event) {
self._calculate = function (searchTerm) {
const allResults = fuzzy.filter(searchTerm, USERS, {
- extract: function (item) { return item.value }
+ extract: function (user) { return user.value }
})
const firstResults = allResults.slice(0, 7)
diff --git a/public/javascripts/url.js b/public/javascripts/url.js
new file mode 100644
index 0000000..17ab7c8
--- /dev/null
+++ b/public/javascripts/url.js
@@ -0,0 +1,67 @@
+/* global USERS FLAGS */
+
+const EventEmitter = require('events')
+
+const self = new EventEmitter()
+
+self._getPageTitle = function (selectedUser) {
+ let ret
+
+ if (selectedUser == null) {
+ ret = `Metis Rooster`
+ } else {
+ ret = `Metis Rooster - ${selectedUser.value}`
+ }
+
+ if (FLAGS.indexOf('BETA') !== -1) {
+ ret = `BETA ${ret}`
+ }
+
+ return ret
+}
+
+self._getPageURL = function (selectedUser) {
+ return `/${selectedUser.type}/${selectedUser.value}`
+}
+
+self.push = function (selectedUser, push) {
+ if (push == null) push = true
+ const pageTitle = self._getPageTitle(selectedUser)
+ const pageURL = self._getPageURL(selectedUser)
+ if (push) {
+ window.history.pushState(selectedUser, pageTitle, pageURL)
+ } else {
+ window.history.replaceState(selectedUser, pageTitle, pageURL)
+ }
+}
+
+self.update = function (selectedUser) {
+ document.title = self._getPageTitle(selectedUser)
+}
+
+self.hasSelectedUser = function () {
+ const pageUrl = window.location.pathname
+ return /^\/s\/|^\/t\/|^\/r\/|^\/c\//.test(pageUrl)
+}
+
+self.getSelectedUser = function () {
+ const pageUrl = window.location.pathname
+ const pageUrlData = pageUrl.split('/')
+ const type = pageUrlData[1]
+ const value = pageUrlData[2]
+
+ const user = USERS.filter(function (user) {
+ return user.type === type &&
+ user.value === value
+ })[0]
+
+ return user
+}
+
+self._handleUpdate = function (event) {
+ self.emit('update', event.state)
+}
+
+window.addEventListener('popstate', self._handleUpdate)
+
+module.exports = self
diff --git a/public/javascripts/zoom.js b/public/javascripts/zoom.js
new file mode 100644
index 0000000..59b80db
--- /dev/null
+++ b/public/javascripts/zoom.js
@@ -0,0 +1,30 @@
+const schedule = require('./schedule')
+
+const self = {}
+
+self._nodes = {
+ body: document.body
+}
+
+self._handleResize = function () {
+ // the table node may not exist before this function is called
+ const tableNode = document.querySelector('center > table')
+
+ // infact, it may not even exist when this function is called.
+ if (!tableNode) return
+
+ const tableWidth = tableNode.getBoundingClientRect().width
+ const tableGoalWidth = self._nodes.body.getBoundingClientRect().width * 0.9
+ const zoomFactor = tableGoalWidth / tableWidth
+
+ if (zoomFactor < 1) {
+ tableNode.style.zoom = `${zoomFactor}`
+ } else {
+ tableNode.style.zoom = `1`
+ }
+}
+
+schedule.on('load', self._handleResize)
+window.addEventListener('resize', self._handleResize)
+
+module.exports = self