renaming the plugin to app notifications, adding database script. do not install...
authorAnthony Talarico <talarico@gaslightmedia.com>
Thu, 25 Jul 2019 21:37:12 +0000 (17:37 -0400)
committerAnthony Talarico <talarico@gaslightmedia.com>
Thu, 25 Jul 2019 21:37:12 +0000 (17:37 -0400)
32 files changed:
activate.php
deactivate.php
defines.php
dist/css/glma-mobile-notifications.min.css
dist/js/glma-mobile-notifications.js
gulpfile.js
index.php
js/Util.js
js/components/container/DashboardContainer.jsx
js/components/container/NewNotification.jsx
js/components/functional/ImageContainer.jsx
js/init.js
models/admin/init/index.php
package-lock.json
package.json
readme.txt
sass/_main.scss
sass/_utility.scss
setup/adminHooks.php
setup/adminMenus.php
setup/adminTabs.php
setup/databaseScripts/create_database_V0.0.1.sql [new file with mode: 0755]
setup/databaseScripts/dbVersions.php [new file with mode: 0755]
setup/databaseScripts/drop_database_V0.0.1.sql [new file with mode: 0755]
setup/databaseScripts/readme.txt [new file with mode: 0755]
setup/frontHooks.php
setup/rolesAndCapabilities.php
setup/shortcodes.php
setup/validActions.php
uninstall.php
views/admin/init/index.html
webpack.config.js

index 60979d0..c9cd91e 100755 (executable)
@@ -1,13 +1,13 @@
 <?php
 
 /**
- * GLMA Mobile Notifications
+ * GLMA App Notifications
  * Activate Plugin Tasks
  *
  * PHP version 5.5
  *
  * @category glmWordPressPlugin
- * @package  glmMembersMobileNotifications
+ * @package  glmMembersAppNotifications
  * @author   Chuck Scott <cscott@gaslightmedia.com>
  * @license  http://www.gaslightmedia.com Gaslightmedia
  * @release  activate.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
@@ -27,7 +27,7 @@ if (!defined('ABSPATH')) {
  * Currently the only actions are to add role capability to display and modify
  * prototypes.
  */
-class glmMembersMobileNotificationsPluginActivate
+class glmMembersAppNotificationsPluginActivate
 {
 
     /**
@@ -68,10 +68,10 @@ class glmMembersMobileNotificationsPluginActivate
         $this->config = $config;
 
         // Set current plugin version
-        update_option('glmMembersMobileNotificationsPluginVersion', GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_VERSION);
+        update_option('glmMembersAppNotificationsPluginVersion', GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_VERSION);
 
         // Set Roles and Capabilities for this plugin
-        require_once GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SETUP_PATH.'/rolesAndCapabilities.php';
+        require_once GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SETUP_PATH.'/rolesAndCapabilities.php';
     }
 
     /*
index 886e1c8..37b9ee0 100755 (executable)
@@ -1,12 +1,12 @@
 <?php
 /**
- * GLMA Mobile Notifications
+ * GLMA App Notifications
  * Deactivate Plugin Tasks
  *
  * PHP version 5.5
  *
  * @category glmWordPressPlugin
- * @package  glmMembersMobileNotifications
+ * @package  glmMembersAppNotifications
  * @author   Chuck Scott <cscott@gaslightmedia.com>
  * @license  http://www.gaslightmedia.com Gaslightmedia
  * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
@@ -23,7 +23,7 @@ if (!defined('ABSPATH')) {
  * This class performs all necessary additional work when this
  * plugin is deactivated.
  */
-class glmMembersMobileNotificationsPluginDeactivate
+class glmMembersAppNotificationsPluginDeactivate
 {
 
     /**
@@ -56,7 +56,7 @@ class glmMembersMobileNotificationsPluginDeactivate
         $this->config = $config;
 */
         // Delete our version from WordPress Options
-        delete_option('glmMembersMobileNotificationsPluginVersion');
+        delete_option('glmMembersAppNotificationsPluginVersion');
     }
 
 }
index 79c33e1..becbc38 100755 (executable)
@@ -13,28 +13,28 @@ if (!defined('ABSPATH')) {
 
 // NOTE: Plugin & Database versions are defined in "/glm-member-db.php".
 
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_NAME', 'GLMA Mobile Notifications');
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SHORT_NAME', 'Mobile Notifications');
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG', 'glm-member-db-mobile-notifications');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_NAME', 'GLMA App Notifications');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SHORT_NAME', 'App Notifications');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG', 'glm-member-db-app-notifications');
 
 // Database table prefixes - change if using add-on tables
 global $wpdb;
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_DB_PREFIX', $wpdb->prefix.'glm_membersMobileNotifications');
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_ACTIVE_DB_OPTION', 'glmMembersMobileNotificationsDbVersion');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_DB_PREFIX', $wpdb->prefix.'glm_members_app_notifications_');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_ACTIVE_DB_OPTION', 'glmMembersAppNotificationsDbVersion');
 
 // Determine which system we're running on - If not provided, assume PRODUCTION
 $host = getenv('GLM_HOST_ID');
 if (trim($host) == '') {
     $host = 'PRODUCTION';
 }
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_HOST', $host);
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_HOST', $host);
 
 // Determine current http/https protocol
 $pageProtocol = 'http';
 if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443') {
     $pageProtocol = 'https';
 }
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_HTTP_PROTOCOL', $pageProtocol);
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_HTTP_PROTOCOL', $pageProtocol);
 
 // Get various pieces of the URL
 $urlParts = parse_url(get_bloginfo('url'));
@@ -46,26 +46,27 @@ $WPUploadDir = wp_upload_dir();
  *  Create a copy of the plugin slug that can be used as a variable prefix used to keep
  *  global instances from clashing with instances in other plugins.
  */
-$vprefix = str_replace('-', '_', GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG);
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PREFIX', $vprefix.'_');
+$vprefix = str_replace('-', '_', GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG);
+
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PREFIX', $vprefix.'_');
 
 // URLs
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_SITE_BASE_URL', home_url('/') );
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_URL', plugin_dir_url(__FILE__));
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_ADMIN_URL', admin_url('admin.php'));
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_BASE_URL', WP_PLUGIN_URL.'/'.GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG);
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_CURRENT_URL', $urlParts['scheme'].'://'.$urlParts['host'].$pageUri[0]);
+define('GLM_MEMBERS_APP_NOTIFICATIONS_SITE_BASE_URL', home_url('/') );
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_URL', plugin_dir_url(__FILE__));
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_ADMIN_URL', admin_url('admin.php'));
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_BASE_URL', WP_PLUGIN_URL.'/'.GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG);
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_CURRENT_URL', $urlParts['scheme'].'://'.$urlParts['host'].$pageUri[0]);
 
 // Directories
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PATH', dirname(__FILE__));
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SETUP_PATH', GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PATH.'/setup');
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_DB_SCRIPTS', GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SETUP_PATH.'/databaseScripts');
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_CLASS_PATH', GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PATH.'/classes');
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_CONFIG_PATH', GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PATH.'/config');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PATH', dirname(__FILE__));
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SETUP_PATH', GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PATH.'/setup');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_DB_SCRIPTS', GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SETUP_PATH.'/databaseScripts');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_CLASS_PATH', GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PATH.'/classes');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_CONFIG_PATH', GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PATH.'/config');
 
 // Parameters related to the Main GLM Member DB plugin - Depending on what's going on these may already defined by the main plugin
-$pluginsPath = str_replace(GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG, '', GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PATH);
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_MAIN_PLUGIN_PATH', $pluginsPath.'/glm-member-db');
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_MAIN_PLUGIN_LIB_PATH', GLM_MEMBERS_MOBILE_NOTIFICATIONS_MAIN_PLUGIN_PATH.'/lib');
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_LIB_PATH', GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PATH.'/lib');
+$pluginsPath = str_replace(GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG, '', GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PATH);
+define('GLM_MEMBERS_APP_NOTIFICATIONS_MAIN_PLUGIN_PATH', $pluginsPath.'/glm-member-db');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_MAIN_PLUGIN_LIB_PATH', GLM_MEMBERS_APP_NOTIFICATIONS_MAIN_PLUGIN_PATH.'/lib');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_LIB_PATH', GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PATH.'/lib');
 
index 3631a4e..d451760 100755 (executable)
@@ -1 +1 @@
-.flex{display:flex}.flex.row{flex-direction:'row'}.flex.column{flex-direction:'column'}.active-link{background:rgba(0,0,0,0.2)}#wpcontent #glma-mobile-notifications-mount{padding-top:60px}#wpcontent #glma-mobile-notifications-mount #glma-notifications-container{height:78vh}@media (min-width: 783px){#wpcontent #glma-mobile-notifications-mount #glma-notifications-container{padding-right:20px}}#wpcontent #glma-mobile-notifications-mount #glma-notifications-container #glma-notifications-lower{height:100%}@media (min-width: 701px){body #wpcontent #glma-notifications-container header.MuiAppBar-root{display:none}}#glma-notifications-dashboard{background:white;flex:5}#glma-notifications-dashboard label{background:white}#glma-notifications-sidebar{margin-right:20px;background:transparent;width:250px}@media (max-width: 700px){#glma-notifications-sidebar{display:none}}#glma-notifications-sidebar a:hover{background:rgba(0,0,0,0.2);color:white}
+.flex{display:flex}.flex.row{flex-direction:'row'}.flex.column{flex-direction:'column'}.active-link{background:rgba(0,0,0,0.2)}.hide{display:none !important}#wpcontent #glma-app-notifications-mount{padding-top:60px}#wpcontent #glma-app-notifications-mount #glma-notifications-container{height:78vh}@media (min-width: 783px){#wpcontent #glma-app-notifications-mount #glma-notifications-container{padding-right:20px}}#wpcontent #glma-app-notifications-mount #glma-notifications-container #glma-notifications-lower{height:100%}@media (min-width: 701px){body #wpcontent #glma-notifications-container header.MuiAppBar-root{display:none}}#glma-notifications-dashboard{background:white;flex:5}#glma-notifications-dashboard label{background:white}#glma-notifications-sidebar{margin-right:20px;background:transparent;width:250px}@media (max-width: 700px){#glma-notifications-sidebar{display:none}}#glma-notifications-sidebar a:hover{background:rgba(0,0,0,0.2);color:white}
index cf1edfb..7b7be68 100755 (executable)
@@ -106,7 +106,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) *
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n  MediaLibrary: function MediaLibrary() {\n    jQuery(function ($) {\n      // Set all variables to be used in scope\n      var frame,\n          addImgLink = $('.upload-custom-img'),\n          delImgLink = $('.delete-custom-img'),\n          imgContainer = $('.custom-img-container'),\n          imgIdInput = $('.custom-img-id'); // ADD IMAGE LINK\n\n      addImgLink.on('click', function (event) {\n        event.preventDefault(); // If the media frame already exists, reopen it.\n\n        if (frame) {\n          frame.open();\n          return;\n        } // Create a new media frame\n\n\n        frame = wp.media({\n          title: 'Select or Upload an Image',\n          button: {\n            text: 'Use this image'\n          },\n          multiple: false // Set to true to allow multiple files to be selected\n\n        });\n        console.log(wp); // When an image is selected in the media frame...\n\n        frame.on('select', function () {\n          // Get media attachment details from the frame state\n          var attachment = frame.state().get('selection').first().toJSON(); // Send the attachment URL to our custom image input field.\n\n          imgContainer.append('<img src=\"' + attachment.url + '\" alt=\"\" style=\"height: auto;max-width:100%;\"/>'); // Send the attachment id to our hidden input\n\n          imgIdInput.val(attachment.id); // Hide the add image link\n\n          addImgLink.addClass('hidden'); // Unhide the remove image link\n\n          delImgLink.removeClass('hidden');\n        }); // Finally, open the modal on click\n\n        frame.open();\n      }); // DELETE IMAGE LINK\n\n      delImgLink.on('click', function (event) {\n        event.preventDefault(); // Clear out the preview image\n\n        imgContainer.html(''); // Un-hide the add image link\n\n        addImgLink.removeClass('hidden'); // Hide the delete image link\n\n        delImgLink.addClass('hidden'); // Delete the image id from the hidden input\n\n        imgIdInput.val('');\n      });\n    });\n  }\n});\n\n//# sourceURL=webpack:///./js/Util.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n  MediaLibrary: function MediaLibrary() {\n    jQuery(function ($) {\n      // Set all variables to be used in scope\n      var frame,\n          addImgLink = $('.upload-custom-img'),\n          delImgLink = $('.delete-custom-img'),\n          imgContainer = $('.custom-img-container'),\n          imgIdInput = $('.custom-img-id'); // ADD IMAGE LINK\n\n      addImgLink.on('click', function (event) {\n        event.preventDefault(); // If the media frame already exists, reopen it.\n\n        if (frame) {\n          frame.open();\n          return;\n        } // Create a new media frame\n\n\n        frame = wp.media({\n          title: 'Select or Upload an Image',\n          button: {\n            text: 'Use this image'\n          },\n          multiple: false // Set to true to allow multiple files to be selected\n\n        });\n        console.log(wp); // When an image is selected in the media frame...\n\n        frame.on('select', function () {\n          // Get media attachment details from the frame state\n          var attachment = frame.state().get('selection').first().toJSON(); // Send the attachment URL to our custom image input field.\n\n          imgContainer.append('<img src=\"' + attachment.url + '\" alt=\"\" style=\"height: auto;max-width:100%;\"/>'); // Send the attachment id to our hidden input\n\n          imgIdInput.val(attachment.id); // Hide the add image link\n\n          addImgLink.addClass('hide'); // Unhide the remove image link\n\n          delImgLink.removeClass('hide');\n        }); // Finally, open the modal on click\n\n        frame.open();\n      }); // DELETE IMAGE LINK\n\n      delImgLink.on('click', function (event) {\n        event.preventDefault(); // Clear out the preview image\n\n        imgContainer.html(''); // Un-hide the add image link\n\n        addImgLink.removeClass('hide'); // Hide the delete image link\n\n        delImgLink.addClass('hide'); // Delete the image id from the hidden input\n\n        imgIdInput.val('');\n      });\n    });\n  }\n});\n\n//# sourceURL=webpack:///./js/Util.js?");
 
 /***/ }),
 
@@ -166,7 +166,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var reac
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ \"./node_modules/react-dom/index.js\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var _store_index__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../store/index */ \"./js/store/index.js\");\n/* harmony import */ var _NotificationList__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./NotificationList */ \"./js/components/container/NotificationList.jsx\");\n/* harmony import */ var _material_ui_core_styles__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @material-ui/core/styles */ \"./node_modules/@material-ui/core/esm/styles/index.js\");\n/* harmony import */ var _material_ui_core_Paper__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @material-ui/core/Paper */ \"./node_modules/@material-ui/core/esm/Paper/index.js\");\n/* harmony import */ var _material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @material-ui/core/Typography */ \"./node_modules/@material-ui/core/esm/Typography/index.js\");\n/* harmony import */ var _functional_Routes__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../functional/Routes */ \"./js/components/functional/Routes.jsx\");\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n\n\n\n\n\n\n\n\n\n\nvar useStyles = Object(_material_ui_core_styles__WEBPACK_IMPORTED_MODULE_6__[\"makeStyles\"])(function (theme) {\n  return {\n    root: {\n      padding: theme.spacing(3, 2),\n      width: '100%',\n      height: '100%'\n    }\n  };\n});\n\nvar DashboardContainer = function DashboardContainer() {\n  /*\n      useState takes a value that is passed to arg1 by default\n      useState has a state update method that is arg2 that acts like setState\n      arg1 : title === this.state.title\n      arg2 : updateTitle === this.setState({title: val})\n  */\n  var _useState = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])('WP Kiosk'),\n      _useState2 = _slicedToArray(_useState, 2),\n      title = _useState2[0],\n      updateTitle = _useState2[1];\n\n  var classes = useStyles();\n  Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n    console.log(\"mount Dashboard\");\n    /* Run cleanup() when the component unmountse */\n\n    return function cleanup() {\n      console.log(\"clean up\");\n    };\n  });\n  return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Paper__WEBPACK_IMPORTED_MODULE_7__[\"default\"], {\n    id: \"glma-notifications-dashboard\"\n  }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_functional_Routes__WEBPACK_IMPORTED_MODULE_9__[\"default\"], null));\n};\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (Object(react_redux__WEBPACK_IMPORTED_MODULE_2__[\"connect\"])(null, null)(DashboardContainer));\n\n//# sourceURL=webpack:///./js/components/container/DashboardContainer.jsx?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ \"./node_modules/react-dom/index.js\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var _store_index__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../store/index */ \"./js/store/index.js\");\n/* harmony import */ var _NotificationList__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./NotificationList */ \"./js/components/container/NotificationList.jsx\");\n/* harmony import */ var _material_ui_core_styles__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @material-ui/core/styles */ \"./node_modules/@material-ui/core/esm/styles/index.js\");\n/* harmony import */ var _material_ui_core_Paper__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @material-ui/core/Paper */ \"./node_modules/@material-ui/core/esm/Paper/index.js\");\n/* harmony import */ var _material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @material-ui/core/Typography */ \"./node_modules/@material-ui/core/esm/Typography/index.js\");\n/* harmony import */ var _functional_Routes__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../functional/Routes */ \"./js/components/functional/Routes.jsx\");\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n\n\n\n\n\n\n\n\n\n\nvar useStyles = Object(_material_ui_core_styles__WEBPACK_IMPORTED_MODULE_6__[\"makeStyles\"])(function (theme) {\n  return {\n    root: {\n      padding: theme.spacing(2, 2),\n      width: '100%',\n      height: '100%'\n    }\n  };\n});\n\nvar DashboardContainer = function DashboardContainer() {\n  /*\n      useState takes a value that is passed to arg1 by default\n      useState has a state update method that is arg2 that acts like setState\n      arg1 : title === this.state.title\n      arg2 : updateTitle === this.setState({title: val})\n  */\n  var _useState = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])('WP Kiosk'),\n      _useState2 = _slicedToArray(_useState, 2),\n      title = _useState2[0],\n      updateTitle = _useState2[1];\n\n  var classes = useStyles();\n  Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n    console.log(\"mount Dashboard\");\n    /* Run cleanup() when the component unmountse */\n\n    return function cleanup() {\n      console.log(\"clean up\");\n    };\n  });\n  return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Paper__WEBPACK_IMPORTED_MODULE_7__[\"default\"], {\n    id: \"glma-notifications-dashboard\",\n    className: [classes.root]\n  }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_functional_Routes__WEBPACK_IMPORTED_MODULE_9__[\"default\"], null));\n};\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (Object(react_redux__WEBPACK_IMPORTED_MODULE_2__[\"connect\"])(null, null)(DashboardContainer));\n\n//# sourceURL=webpack:///./js/components/container/DashboardContainer.jsx?");
 
 /***/ }),
 
@@ -190,7 +190,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var reac
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ \"./node_modules/react-dom/index.js\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var _material_ui_core_TextField__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @material-ui/core/TextField */ \"./node_modules/@material-ui/core/esm/TextField/index.js\");\n/* harmony import */ var _material_ui_core_styles__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @material-ui/core/styles */ \"./node_modules/@material-ui/core/esm/styles/index.js\");\n/* harmony import */ var _material_ui_core_Input__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @material-ui/core/Input */ \"./node_modules/@material-ui/core/esm/Input/index.js\");\n/* harmony import */ var _material_ui_core_OutlinedInput__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @material-ui/core/OutlinedInput */ \"./node_modules/@material-ui/core/esm/OutlinedInput/index.js\");\n/* harmony import */ var _material_ui_core_FilledInput__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @material-ui/core/FilledInput */ \"./node_modules/@material-ui/core/esm/FilledInput/index.js\");\n/* harmony import */ var _material_ui_core_InputLabel__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @material-ui/core/InputLabel */ \"./node_modules/@material-ui/core/esm/InputLabel/index.js\");\n/* harmony import */ var _material_ui_core_MenuItem__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @material-ui/core/MenuItem */ \"./node_modules/@material-ui/core/esm/MenuItem/index.js\");\n/* harmony import */ var _material_ui_core_FormHelperText__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @material-ui/core/FormHelperText */ \"./node_modules/@material-ui/core/esm/FormHelperText/index.js\");\n/* harmony import */ var _material_ui_core_FormControl__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @material-ui/core/FormControl */ \"./node_modules/@material-ui/core/esm/FormControl/index.js\");\n/* harmony import */ var _material_ui_core_Select__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @material-ui/core/Select */ \"./node_modules/@material-ui/core/esm/Select/index.js\");\n/* harmony import */ var _Util__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../Util */ \"./js/Util.js\");\n/* harmony import */ var _material_ui_core_Button__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @material-ui/core/Button */ \"./node_modules/@material-ui/core/esm/Button/index.js\");\n/* harmony import */ var _functional_ImageContainer__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../functional/ImageContainer */ \"./js/components/functional/ImageContainer.jsx\");\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar useStyles = Object(_material_ui_core_styles__WEBPACK_IMPORTED_MODULE_5__[\"makeStyles\"])(function (theme) {\n  return {\n    container: {\n      display: 'flex',\n      flexWrap: 'wrap'\n    },\n    textField: {// marginLeft: theme.spacing(1),\n      // marginRight: theme.spacing(1),\n    },\n    dense: {\n      marginTop: theme.spacing(2)\n    },\n    menu: {\n      width: 200\n    },\n    formControl: {\n      margin: theme.spacing(1),\n      minWidth: 120\n    },\n    selectEmpty: {\n      marginTop: theme.spacing(2)\n    },\n    button: {\n      margin: theme.spacing(1),\n      color: \"white\",\n      background: \"#0568B3\"\n    },\n    input: {\n      display: 'none'\n    }\n  };\n});\n\nvar NewNotification = function NewNotification(props) {\n  var inputLabel = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useRef\"])(null);\n  var classes = useStyles();\n\n  var _useState = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(0),\n      _useState2 = _slicedToArray(_useState, 2),\n      labelWidth = _useState2[0],\n      setLabelWidth = _useState2[1];\n\n  Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n    _Util__WEBPACK_IMPORTED_MODULE_14__[\"default\"].MediaLibrary();\n    setLabelWidth(inputLabel.current.offsetWidth);\n  }, []);\n  /* Categories for each */\n\n  var _useState3 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])({\n    categories: [10]\n  }),\n      _useState4 = _slicedToArray(_useState3, 2),\n      values = _useState4[0],\n      setValues = _useState4[1];\n\n  function handleChange(event) {\n    setValues(function (oldValues) {\n      return _extends({}, oldValues, _defineProperty({}, event.target.name, event.target.value));\n    });\n  }\n\n  return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TextField__WEBPACK_IMPORTED_MODULE_4__[\"default\"], {\n    id: \"outlined-search\",\n    label: \"Notification Headline\",\n    type: \"search\",\n    className: classes.textField,\n    margin: \"normal\",\n    variant: \"outlined\"\n  }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_FormControl__WEBPACK_IMPORTED_MODULE_12__[\"default\"], {\n    variant: \"outlined\",\n    className: classes.formControl\n  }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_InputLabel__WEBPACK_IMPORTED_MODULE_9__[\"default\"], {\n    ref: inputLabel,\n    htmlFor: \"outlined-age-simple\"\n  }, \"Categories\"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Select__WEBPACK_IMPORTED_MODULE_13__[\"default\"], {\n    multiple: true,\n    value: values.categories,\n    onChange: handleChange,\n    input: react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_OutlinedInput__WEBPACK_IMPORTED_MODULE_7__[\"default\"], {\n      labelWidth: labelWidth,\n      name: \"categories\",\n      id: \"outlined-categories\"\n    })\n  }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_MenuItem__WEBPACK_IMPORTED_MODULE_10__[\"default\"], {\n    value: ''\n  }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"em\", null, \"None\")), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_MenuItem__WEBPACK_IMPORTED_MODULE_10__[\"default\"], {\n    value: 10\n  }, \"Tenx\"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_MenuItem__WEBPACK_IMPORTED_MODULE_10__[\"default\"], {\n    value: 20\n  }, \"Twenty\"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_MenuItem__WEBPACK_IMPORTED_MODULE_10__[\"default\"], {\n    value: 30\n  }, \"Thirty\"))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n    id: \"glm-message-image-container\"\n  }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Button__WEBPACK_IMPORTED_MODULE_15__[\"default\"], {\n    variant: \"contained\",\n    className: [\"upload-custom-img\", classes.button]\n  }, \"Add Image\"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_functional_ImageContainer__WEBPACK_IMPORTED_MODULE_16__[\"default\"], null), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Button__WEBPACK_IMPORTED_MODULE_15__[\"default\"], {\n    variant: \"contained\",\n    className: [\"hidden\", \"delete-custom-img\", classes.button]\n  }, \"Remove Image\")), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TextField__WEBPACK_IMPORTED_MODULE_4__[\"default\"], {\n    id: \"outlined-search\",\n    label: \"Notification Message\",\n    type: \"search\",\n    className: classes.textField,\n    margin: \"normal\",\n    variant: \"outlined\",\n    multiline: true,\n    rows: 4,\n    rowsMax: 4,\n    fullWidth: true\n  }));\n};\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (Object(react_redux__WEBPACK_IMPORTED_MODULE_2__[\"connect\"])(null, null)(NewNotification));\n\n//# sourceURL=webpack:///./js/components/container/NewNotification.jsx?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ \"./node_modules/react-dom/index.js\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var _material_ui_core_TextField__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @material-ui/core/TextField */ \"./node_modules/@material-ui/core/esm/TextField/index.js\");\n/* harmony import */ var _material_ui_core_styles__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @material-ui/core/styles */ \"./node_modules/@material-ui/core/esm/styles/index.js\");\n/* harmony import */ var _material_ui_core_Input__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @material-ui/core/Input */ \"./node_modules/@material-ui/core/esm/Input/index.js\");\n/* harmony import */ var _material_ui_core_OutlinedInput__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @material-ui/core/OutlinedInput */ \"./node_modules/@material-ui/core/esm/OutlinedInput/index.js\");\n/* harmony import */ var _material_ui_core_FilledInput__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @material-ui/core/FilledInput */ \"./node_modules/@material-ui/core/esm/FilledInput/index.js\");\n/* harmony import */ var _material_ui_core_InputLabel__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @material-ui/core/InputLabel */ \"./node_modules/@material-ui/core/esm/InputLabel/index.js\");\n/* harmony import */ var _material_ui_core_MenuItem__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @material-ui/core/MenuItem */ \"./node_modules/@material-ui/core/esm/MenuItem/index.js\");\n/* harmony import */ var _material_ui_core_FormHelperText__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @material-ui/core/FormHelperText */ \"./node_modules/@material-ui/core/esm/FormHelperText/index.js\");\n/* harmony import */ var _material_ui_core_FormControl__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @material-ui/core/FormControl */ \"./node_modules/@material-ui/core/esm/FormControl/index.js\");\n/* harmony import */ var _material_ui_core_Select__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @material-ui/core/Select */ \"./node_modules/@material-ui/core/esm/Select/index.js\");\n/* harmony import */ var _Util__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../Util */ \"./js/Util.js\");\n/* harmony import */ var _material_ui_core_Button__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @material-ui/core/Button */ \"./node_modules/@material-ui/core/esm/Button/index.js\");\n/* harmony import */ var _functional_ImageContainer__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../functional/ImageContainer */ \"./js/components/functional/ImageContainer.jsx\");\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar useStyles = Object(_material_ui_core_styles__WEBPACK_IMPORTED_MODULE_5__[\"makeStyles\"])(function (theme) {\n  return {\n    container: {\n      display: 'flex',\n      flexWrap: 'wrap'\n    },\n    textField: {// marginLeft: theme.spacing(1),\n      // marginRight: theme.spacing(1),\n    },\n    dense: {\n      marginTop: theme.spacing(2)\n    },\n    menu: {\n      width: 200\n    },\n    formControl: {\n      margin: theme.spacing(2, 1),\n      minWidth: 120\n    },\n    selectEmpty: {\n      marginTop: theme.spacing(2)\n    },\n    button: {\n      margin: theme.spacing(0, 2),\n      color: \"white\",\n      background: \"#0568B3\",\n      width: \"150px\"\n    },\n    bottom: {\n      position: \"absolute\",\n      bottom: \"-25px\",\n      left: \"43%\",\n      transform: \"translateX(-50%)\"\n    },\n    input: {\n      display: 'none'\n    },\n    hide: {\n      display: \"none !important\"\n    },\n    removeButton: {\n      background: \"#F44336\",\n      \"float\": \"right\"\n    }\n  };\n});\n\nvar NewNotification = function NewNotification(props) {\n  var inputLabel = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useRef\"])(null);\n  var classes = useStyles();\n\n  var _useState = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(0),\n      _useState2 = _slicedToArray(_useState, 2),\n      labelWidth = _useState2[0],\n      setLabelWidth = _useState2[1];\n\n  Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n    _Util__WEBPACK_IMPORTED_MODULE_14__[\"default\"].MediaLibrary();\n    setLabelWidth(inputLabel.current.offsetWidth);\n  }, []);\n  /* Categories for each */\n\n  var _useState3 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])({\n    categories: [10]\n  }),\n      _useState4 = _slicedToArray(_useState3, 2),\n      values = _useState4[0],\n      setValues = _useState4[1];\n\n  function handleChange(event) {\n    setValues(function (oldValues) {\n      return _extends({}, oldValues, _defineProperty({}, event.target.name, event.target.value));\n    });\n  }\n\n  return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_FormControl__WEBPACK_IMPORTED_MODULE_12__[\"default\"], {\n    variant: \"outlined\",\n    className: classes.formControl\n  }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_InputLabel__WEBPACK_IMPORTED_MODULE_9__[\"default\"], {\n    ref: inputLabel,\n    htmlFor: \"outlined-age-simple\"\n  }, \"Categories\"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Select__WEBPACK_IMPORTED_MODULE_13__[\"default\"], {\n    multiple: true,\n    value: values.categories,\n    onChange: handleChange,\n    input: react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_OutlinedInput__WEBPACK_IMPORTED_MODULE_7__[\"default\"], {\n      labelWidth: labelWidth,\n      name: \"categories\",\n      id: \"outlined-categories\"\n    })\n  }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_MenuItem__WEBPACK_IMPORTED_MODULE_10__[\"default\"], {\n    value: ''\n  }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"em\", null, \"None\")), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_MenuItem__WEBPACK_IMPORTED_MODULE_10__[\"default\"], {\n    value: 10\n  }, \"Tenx\"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_MenuItem__WEBPACK_IMPORTED_MODULE_10__[\"default\"], {\n    value: 20\n  }, \"Twenty\"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_MenuItem__WEBPACK_IMPORTED_MODULE_10__[\"default\"], {\n    value: 30\n  }, \"Thirty\"))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n    id: \"glm-message-image-container\",\n    className: [classes.formControl],\n    style: {\n      display: \"inline-block\",\n      position: \"relative\"\n    }\n  }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Button__WEBPACK_IMPORTED_MODULE_15__[\"default\"], {\n    variant: \"contained\",\n    className: [\"upload-custom-img\", classes.button]\n  }, \"Add Image\"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_functional_ImageContainer__WEBPACK_IMPORTED_MODULE_16__[\"default\"], null), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Button__WEBPACK_IMPORTED_MODULE_15__[\"default\"], {\n    variant: \"contained\",\n    className: [classes.bottom, \"hide\", \"delete-custom-img\", classes.button, classes.removeButton]\n  }, \"Remove Image\")), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TextField__WEBPACK_IMPORTED_MODULE_4__[\"default\"], {\n    id: \"outlined-search\",\n    label: \"Notification Headline\",\n    type: \"search\",\n    className: classes.textField,\n    margin: \"normal\",\n    variant: \"outlined\",\n    style: {\n      width: \"50%\",\n      display: \"flex\"\n    }\n  }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TextField__WEBPACK_IMPORTED_MODULE_4__[\"default\"], {\n    id: \"outlined-search\",\n    label: \"Notification Message\",\n    type: \"search\",\n    className: classes.textField,\n    margin: \"normal\",\n    variant: \"outlined\",\n    multiline: true,\n    rows: 4,\n    rowsMax: 4,\n    fullWidth: true\n  }));\n};\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (Object(react_redux__WEBPACK_IMPORTED_MODULE_2__[\"connect\"])(null, null)(NewNotification));\n\n//# sourceURL=webpack:///./js/components/container/NewNotification.jsx?");
 
 /***/ }),
 
@@ -226,7 +226,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var reac
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (function (props) {\n  var height = props.height ? props.height : \"100px\";\n  var width = props.width ? props.width : \"200px\";\n  var imageContainerStyles = {\n    width: width\n  };\n  return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n    style: imageContainerStyles,\n    className: \"custom-img-container\"\n  });\n});\n\n//# sourceURL=webpack:///./js/components/functional/ImageContainer.jsx?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (function (props) {\n  var height = props.height ? props.height : \"100px\";\n  var width = props.width ? props.width : \"200px\";\n  var imageContainerStyles = {\n    width: width,\n    display: \"inline-block\"\n  };\n  return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n    style: imageContainerStyles,\n    className: \"custom-img-container\"\n  });\n});\n\n//# sourceURL=webpack:///./js/components/functional/ImageContainer.jsx?");
 
 /***/ }),
 
@@ -250,7 +250,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var reac
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ \"./node_modules/react-dom/index.js\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _components_Controller_jsx__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/Controller.jsx */ \"./js/components/Controller.jsx\");\n\n\n\nreact_dom__WEBPACK_IMPORTED_MODULE_1___default.a.render(react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_Controller_jsx__WEBPACK_IMPORTED_MODULE_2__[\"default\"], null), document.getElementById('glma-mobile-notifications-mount'));\n\n//# sourceURL=webpack:///./js/init.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ \"./node_modules/react-dom/index.js\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _components_Controller_jsx__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/Controller.jsx */ \"./js/components/Controller.jsx\");\n\n\n\nreact_dom__WEBPACK_IMPORTED_MODULE_1___default.a.render(react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_Controller_jsx__WEBPACK_IMPORTED_MODULE_2__[\"default\"], null), document.getElementById('glma-app-notifications-mount'));\n\n//# sourceURL=webpack:///./js/init.js?");
 
 /***/ }),
 
@@ -744,7 +744,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _bab
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"DELAY_RIPPLE\", function() { return DELAY_RIPPLE; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"styles\", function() { return styles; });\n/* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/extends */ \"./node_modules/@babel/runtime/helpers/extends.js\");\n/* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _babel_runtime_helpers_objectWithoutProperties__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/objectWithoutProperties */ \"./node_modules/@babel/runtime/helpers/objectWithoutProperties.js\");\n/* harmony import */ var _babel_runtime_helpers_objectWithoutProperties__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_objectWithoutProperties__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/toConsumableArray */ \"./node_modules/@babel/runtime/helpers/toConsumableArray.js\");\n/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @babel/runtime/helpers/classCallCheck */ \"./node_modules/@babel/runtime/helpers/classCallCheck.js\");\n/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @babel/runtime/helpers/createClass */ \"./node_modules/@babel/runtime/helpers/createClass.js\");\n/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @babel/runtime/helpers/possibleConstructorReturn */ \"./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js\");\n/* harmony import */ var _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @babel/runtime/helpers/getPrototypeOf */ \"./node_modules/@babel/runtime/helpers/getPrototypeOf.js\");\n/* harmony import */ var _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @babel/runtime/helpers/inherits */ \"./node_modules/@babel/runtime/helpers/inherits.js\");\n/* harmony import */ var _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_7__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_8__);\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! prop-types */ \"./node_modules/prop-types/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_9__);\n/* harmony import */ var react_transition_group__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! react-transition-group */ \"./node_modules/react-transition-group/esm/index.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! clsx */ \"./node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var _styles_withStyles__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../styles/withStyles */ \"./node_modules/@material-ui/core/esm/styles/withStyles.js\");\n/* harmony import */ var _Ripple__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Ripple */ \"./node_modules/@material-ui/core/esm/ButtonBase/Ripple.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar DURATION = 550;\nvar DELAY_RIPPLE = 80;\nvar styles = function styles(theme) {\n  return {\n    /* Styles applied to the root element. */\n    root: {\n      display: 'block',\n      position: 'absolute',\n      overflow: 'hidden',\n      borderRadius: 'inherit',\n      width: '100%',\n      height: '100%',\n      left: 0,\n      top: 0,\n      pointerEvents: 'none',\n      zIndex: 0\n    },\n\n    /* Styles applied to the internal `Ripple` components `ripple` class. */\n    ripple: {\n      opacity: 0,\n      position: 'absolute'\n    },\n\n    /* Styles applied to the internal `Ripple` components `rippleVisible` class. */\n    rippleVisible: {\n      opacity: 0.3,\n      transform: 'scale(1)',\n      animation: \"mui-ripple-enter \".concat(DURATION, \"ms \").concat(theme.transitions.easing.easeInOut),\n      // Backward compatible logic between JSS v9 and v10.\n      // To remove with the release of Material-UI v4\n      animationName: '$mui-ripple-enter'\n    },\n\n    /* Styles applied to the internal `Ripple` components `ripplePulsate` class. */\n    ripplePulsate: {\n      animationDuration: \"\".concat(theme.transitions.duration.shorter, \"ms\")\n    },\n\n    /* Styles applied to the internal `Ripple` components `child` class. */\n    child: {\n      opacity: 1,\n      display: 'block',\n      width: '100%',\n      height: '100%',\n      borderRadius: '50%',\n      backgroundColor: 'currentColor'\n    },\n\n    /* Styles applied to the internal `Ripple` components `childLeaving` class. */\n    childLeaving: {\n      opacity: 0,\n      animation: \"mui-ripple-exit \".concat(DURATION, \"ms \").concat(theme.transitions.easing.easeInOut),\n      // Backward compatible logic between JSS v9 and v10.\n      // To remove with the release of Material-UI v4\n      animationName: '$mui-ripple-exit'\n    },\n\n    /* Styles applied to the internal `Ripple` components `childPulsate` class. */\n    childPulsate: {\n      position: 'absolute',\n      left: 0,\n      top: 0,\n      animation: \"mui-ripple-pulsate 2500ms \".concat(theme.transitions.easing.easeInOut, \" 200ms infinite\"),\n      // Backward compatible logic between JSS v9 and v10.\n      // To remove with the release of Material-UI v4\n      animationName: '$mui-ripple-pulsate'\n    },\n    '@keyframes mui-ripple-enter': {\n      '0%': {\n        transform: 'scale(0)',\n        opacity: 0.1\n      },\n      '100%': {\n        transform: 'scale(1)',\n        opacity: 0.3\n      }\n    },\n    '@keyframes mui-ripple-exit': {\n      '0%': {\n        opacity: 1\n      },\n      '100%': {\n        opacity: 0\n      }\n    },\n    '@keyframes mui-ripple-pulsate': {\n      '0%': {\n        transform: 'scale(1)'\n      },\n      '50%': {\n        transform: 'scale(0.92)'\n      },\n      '100%': {\n        transform: 'scale(1)'\n      }\n    }\n  };\n};\n\nvar TouchRipple =\n/*#__PURE__*/\nfunction (_React$PureComponent) {\n  _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_7___default()(TouchRipple, _React$PureComponent);\n\n  function TouchRipple() {\n    var _getPrototypeOf2;\n\n    var _this;\n\n    _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_3___default()(this, TouchRipple);\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_5___default()(this, (_getPrototypeOf2 = _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_6___default()(TouchRipple)).call.apply(_getPrototypeOf2, [this].concat(args)));\n    _this.state = {\n      nextKey: 0,\n      ripples: []\n    };\n    _this.container = react__WEBPACK_IMPORTED_MODULE_8___default.a.createRef();\n\n    _this.pulsate = function () {\n      _this.start({}, {\n        pulsate: true\n      });\n    };\n\n    _this.start = function () {\n      var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n      var cb = arguments.length > 2 ? arguments[2] : undefined;\n      var _options$pulsate = options.pulsate,\n          pulsate = _options$pulsate === void 0 ? false : _options$pulsate,\n          _options$center = options.center,\n          center = _options$center === void 0 ? _this.props.center || options.pulsate : _options$center,\n          _options$fakeElement = options.fakeElement,\n          fakeElement = _options$fakeElement === void 0 ? false : _options$fakeElement;\n\n      if (event.type === 'mousedown' && _this.ignoringMouseDown) {\n        _this.ignoringMouseDown = false;\n        return;\n      }\n\n      if (event.type === 'touchstart') {\n        _this.ignoringMouseDown = true;\n      }\n\n      var element = fakeElement ? null : _this.container.current;\n      var rect = element ? element.getBoundingClientRect() : {\n        width: 0,\n        height: 0,\n        left: 0,\n        top: 0\n      }; // Get the size of the ripple\n\n      var rippleX;\n      var rippleY;\n      var rippleSize;\n\n      if (center || event.clientX === 0 && event.clientY === 0 || !event.clientX && !event.touches) {\n        rippleX = Math.round(rect.width / 2);\n        rippleY = Math.round(rect.height / 2);\n      } else {\n        var clientX = event.clientX ? event.clientX : event.touches[0].clientX;\n        var clientY = event.clientY ? event.clientY : event.touches[0].clientY;\n        rippleX = Math.round(clientX - rect.left);\n        rippleY = Math.round(clientY - rect.top);\n      }\n\n      if (center) {\n        rippleSize = Math.sqrt((2 * Math.pow(rect.width, 2) + Math.pow(rect.height, 2)) / 3); // For some reason the animation is broken on Mobile Chrome if the size if even.\n\n        if (rippleSize % 2 === 0) {\n          rippleSize += 1;\n        }\n      } else {\n        var sizeX = Math.max(Math.abs((element ? element.clientWidth : 0) - rippleX), rippleX) * 2 + 2;\n        var sizeY = Math.max(Math.abs((element ? element.clientHeight : 0) - rippleY), rippleY) * 2 + 2;\n        rippleSize = Math.sqrt(Math.pow(sizeX, 2) + Math.pow(sizeY, 2));\n      } // Touche devices\n\n\n      if (event.touches) {\n        // Prepare the ripple effect.\n        _this.startTimerCommit = function () {\n          _this.startCommit({\n            pulsate: pulsate,\n            rippleX: rippleX,\n            rippleY: rippleY,\n            rippleSize: rippleSize,\n            cb: cb\n          });\n        }; // Delay the execution of the ripple effect.\n\n\n        _this.startTimer = setTimeout(function () {\n          if (_this.startTimerCommit) {\n            _this.startTimerCommit();\n\n            _this.startTimerCommit = null;\n          }\n        }, DELAY_RIPPLE); // We have to make a tradeoff with this value.\n      } else {\n        _this.startCommit({\n          pulsate: pulsate,\n          rippleX: rippleX,\n          rippleY: rippleY,\n          rippleSize: rippleSize,\n          cb: cb\n        });\n      }\n    };\n\n    _this.startCommit = function (params) {\n      var pulsate = params.pulsate,\n          rippleX = params.rippleX,\n          rippleY = params.rippleY,\n          rippleSize = params.rippleSize,\n          cb = params.cb;\n\n      _this.setState(function (state) {\n        return {\n          nextKey: state.nextKey + 1,\n          ripples: [].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_2___default()(state.ripples), [react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(_Ripple__WEBPACK_IMPORTED_MODULE_13__[\"default\"], {\n            key: state.nextKey,\n            classes: _this.props.classes,\n            timeout: {\n              exit: DURATION,\n              enter: DURATION\n            },\n            pulsate: pulsate,\n            rippleX: rippleX,\n            rippleY: rippleY,\n            rippleSize: rippleSize\n          })])\n        };\n      }, cb);\n    };\n\n    _this.stop = function (event, cb) {\n      clearTimeout(_this.startTimer); // The touch interaction occurs too quickly.\n      // We still want to show ripple effect.\n\n      if (event.type === 'touchend' && _this.startTimerCommit) {\n        event.persist();\n\n        _this.startTimerCommit();\n\n        _this.startTimerCommit = null;\n        _this.startTimer = setTimeout(function () {\n          _this.stop(event, cb);\n        });\n        return;\n      }\n\n      _this.startTimerCommit = null;\n\n      _this.setState(function (_ref) {\n        var ripples = _ref.ripples;\n\n        if (ripples && ripples.length) {\n          return {\n            ripples: ripples.slice(1)\n          };\n        }\n\n        return null;\n      }, cb);\n    };\n\n    return _this;\n  }\n\n  _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_4___default()(TouchRipple, [{\n    key: \"componentWillUnmount\",\n    value: function componentWillUnmount() {\n      clearTimeout(this.startTimer);\n    }\n  }, {\n    key: \"render\",\n    value: function render() {\n      var _this$props = this.props,\n          center = _this$props.center,\n          classes = _this$props.classes,\n          className = _this$props.className,\n          other = _babel_runtime_helpers_objectWithoutProperties__WEBPACK_IMPORTED_MODULE_1___default()(_this$props, [\"center\", \"classes\", \"className\"]);\n\n      return react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(\"span\", _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default()({\n        className: Object(clsx__WEBPACK_IMPORTED_MODULE_11__[\"default\"])(classes.root, className),\n        ref: this.container\n      }, other), react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(react_transition_group__WEBPACK_IMPORTED_MODULE_10__[\"TransitionGroup\"], {\n        component: null,\n        enter: true,\n        exit: true\n      }, this.state.ripples));\n    }\n  }]);\n\n  return TouchRipple;\n}(react__WEBPACK_IMPORTED_MODULE_8___default.a.PureComponent);\n\n false ? undefined : void 0;\nTouchRipple.defaultProps = {\n  center: false\n};\n/* harmony default export */ __webpack_exports__[\"default\"] = (Object(_styles_withStyles__WEBPACK_IMPORTED_MODULE_12__[\"default\"])(styles, {\n  flip: false,\n  name: 'MuiTouchRipple'\n})(TouchRipple));\n\n//# sourceURL=webpack:///./node_modules/@material-ui/core/esm/ButtonBase/TouchRipple.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"DELAY_RIPPLE\", function() { return DELAY_RIPPLE; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"styles\", function() { return styles; });\n/* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/extends */ \"./node_modules/@babel/runtime/helpers/extends.js\");\n/* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _babel_runtime_helpers_objectWithoutProperties__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/objectWithoutProperties */ \"./node_modules/@babel/runtime/helpers/objectWithoutProperties.js\");\n/* harmony import */ var _babel_runtime_helpers_objectWithoutProperties__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_objectWithoutProperties__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/toConsumableArray */ \"./node_modules/@babel/runtime/helpers/toConsumableArray.js\");\n/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @babel/runtime/helpers/classCallCheck */ \"./node_modules/@babel/runtime/helpers/classCallCheck.js\");\n/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @babel/runtime/helpers/createClass */ \"./node_modules/@babel/runtime/helpers/createClass.js\");\n/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @babel/runtime/helpers/possibleConstructorReturn */ \"./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js\");\n/* harmony import */ var _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @babel/runtime/helpers/getPrototypeOf */ \"./node_modules/@babel/runtime/helpers/getPrototypeOf.js\");\n/* harmony import */ var _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @babel/runtime/helpers/inherits */ \"./node_modules/@babel/runtime/helpers/inherits.js\");\n/* harmony import */ var _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_7__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_8__);\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! prop-types */ \"./node_modules/prop-types/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_9__);\n/* harmony import */ var react_transition_group__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! react-transition-group */ \"./node_modules/react-transition-group/esm/index.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! clsx */ \"./node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var _styles_withStyles__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../styles/withStyles */ \"./node_modules/@material-ui/core/esm/styles/withStyles.js\");\n/* harmony import */ var _Ripple__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Ripple */ \"./node_modules/@material-ui/core/esm/ButtonBase/Ripple.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar DURATION = 550;\nvar DELAY_RIPPLE = 80;\nvar styles = function styles(theme) {\n  return {\n    /* Styles applied to the root element. */\n    root: {\n      display: 'block',\n      position: 'absolute',\n      overflow: 'hidden',\n      borderRadius: 'inherit',\n      width: '100%',\n      height: '100%',\n      left: 0,\n      top: 0,\n      pointerEvents: 'none',\n      zIndex: 0\n    },\n\n    /* Styles applied to the internal `Ripple` components `ripple` class. */\n    ripple: {\n      opacity: 0,\n      position: 'absolute'\n    },\n\n    /* Styles applied to the internal `Ripple` components `rippleVisible` class. */\n    rippleVisible: {\n      opacity: 0.3,\n      transform: 'scale(1)',\n      animation: \"mui-ripple-enter \".concat(DURATION, \"ms \").concat(theme.transitions.easing.easeInOut),\n      // Backward compatible logic between JSS v9 and v10.\n      // To remove with the release of Material-UI v4\n      animationName: '$mui-ripple-enter'\n    },\n\n    /* Styles applied to the internal `Ripple` components `ripplePulsate` class. */\n    ripplePulsate: {\n      animationDuration: \"\".concat(theme.transitions.duration.shorter, \"ms\")\n    },\n\n    /* Styles applied to the internal `Ripple` components `child` class. */\n    child: {\n      opacity: 1,\n      display: 'block',\n      width: '100%',\n      height: '100%',\n      borderRadius: '50%',\n      backgroundColor: 'currentColor'\n    },\n\n    /* Styles applied to the internal `Ripple` components `childLeaving` class. */\n    childLeaving: {\n      opacity: 0,\n      animation: \"mui-ripple-exit \".concat(DURATION, \"ms \").concat(theme.transitions.easing.easeInOut),\n      // Backward compatible logic between JSS v9 and v10.\n      // To remove with the release of Material-UI v4\n      animationName: '$mui-ripple-exit'\n    },\n\n    /* Styles applied to the internal `Ripple` components `childPulsate` class. */\n    childPulsate: {\n      position: 'absolute',\n      left: 0,\n      top: 0,\n      animation: \"mui-ripple-pulsate 2500ms \".concat(theme.transitions.easing.easeInOut, \" 200ms infinite\"),\n      // Backward compatible logic between JSS v9 and v10.\n      // To remove with the release of Material-UI v4\n      animationName: '$mui-ripple-pulsate'\n    },\n    '@keyframes mui-ripple-enter': {\n      '0%': {\n        transform: 'scale(0)',\n        opacity: 0.1\n      },\n      '100%': {\n        transform: 'scale(1)',\n        opacity: 0.3\n      }\n    },\n    '@keyframes mui-ripple-exit': {\n      '0%': {\n        opacity: 1\n      },\n      '100%': {\n        opacity: 0\n      }\n    },\n    '@keyframes mui-ripple-pulsate': {\n      '0%': {\n        transform: 'scale(1)'\n      },\n      '50%': {\n        transform: 'scale(0.92)'\n      },\n      '100%': {\n        transform: 'scale(1)'\n      }\n    }\n  };\n};\n\nvar TouchRipple =\n/*#__PURE__*/\nfunction (_React$PureComponent) {\n  _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_7___default()(TouchRipple, _React$PureComponent);\n\n  function TouchRipple() {\n    var _getPrototypeOf2;\n\n    var _this;\n\n    _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_3___default()(this, TouchRipple);\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    _this = _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_5___default()(this, (_getPrototypeOf2 = _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_6___default()(TouchRipple)).call.apply(_getPrototypeOf2, [this].concat(args)));\n    _this.state = {\n      nextKey: 0,\n      ripples: []\n    };\n    _this.container = react__WEBPACK_IMPORTED_MODULE_8___default.a.createRef();\n\n    _this.pulsate = function () {\n      _this.start({}, {\n        pulsate: true\n      });\n    };\n\n    _this.start = function () {\n      var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n      var cb = arguments.length > 2 ? arguments[2] : undefined;\n      var _options$pulsate = options.pulsate,\n          pulsate = _options$pulsate === void 0 ? false : _options$pulsate,\n          _options$center = options.center,\n          center = _options$center === void 0 ? _this.props.center || options.pulsate : _options$center,\n          _options$fakeElement = options.fakeElement,\n          fakeElement = _options$fakeElement === void 0 ? false : _options$fakeElement;\n\n      if (event.type === 'mousedown' && _this.ignoringMouseDown) {\n        _this.ignoringMouseDown = false;\n        return;\n      }\n\n      if (event.type === 'touchstart') {\n        _this.ignoringMouseDown = true;\n      }\n\n      var element = fakeElement ? null : _this.container.current;\n      var rect = element ? element.getBoundingClientRect() : {\n        width: 0,\n        height: 0,\n        left: 0,\n        top: 0\n      }; // Get the size of the ripple\n\n      var rippleX;\n      var rippleY;\n      var rippleSize;\n\n      if (center || event.clientX === 0 && event.clientY === 0 || !event.clientX && !event.touches) {\n        rippleX = Math.round(rect.width / 2);\n        rippleY = Math.round(rect.height / 2);\n      } else {\n        var clientX = event.clientX ? event.clientX : event.touches[0].clientX;\n        var clientY = event.clientY ? event.clientY : event.touches[0].clientY;\n        rippleX = Math.round(clientX - rect.left);\n        rippleY = Math.round(clientY - rect.top);\n      }\n\n      if (center) {\n        rippleSize = Math.sqrt((2 * Math.pow(rect.width, 2) + Math.pow(rect.height, 2)) / 3); // For some reason the animation is broken on App Chrome if the size if even.\n\n        if (rippleSize % 2 === 0) {\n          rippleSize += 1;\n        }\n      } else {\n        var sizeX = Math.max(Math.abs((element ? element.clientWidth : 0) - rippleX), rippleX) * 2 + 2;\n        var sizeY = Math.max(Math.abs((element ? element.clientHeight : 0) - rippleY), rippleY) * 2 + 2;\n        rippleSize = Math.sqrt(Math.pow(sizeX, 2) + Math.pow(sizeY, 2));\n      } // Touche devices\n\n\n      if (event.touches) {\n        // Prepare the ripple effect.\n        _this.startTimerCommit = function () {\n          _this.startCommit({\n            pulsate: pulsate,\n            rippleX: rippleX,\n            rippleY: rippleY,\n            rippleSize: rippleSize,\n            cb: cb\n          });\n        }; // Delay the execution of the ripple effect.\n\n\n        _this.startTimer = setTimeout(function () {\n          if (_this.startTimerCommit) {\n            _this.startTimerCommit();\n\n            _this.startTimerCommit = null;\n          }\n        }, DELAY_RIPPLE); // We have to make a tradeoff with this value.\n      } else {\n        _this.startCommit({\n          pulsate: pulsate,\n          rippleX: rippleX,\n          rippleY: rippleY,\n          rippleSize: rippleSize,\n          cb: cb\n        });\n      }\n    };\n\n    _this.startCommit = function (params) {\n      var pulsate = params.pulsate,\n          rippleX = params.rippleX,\n          rippleY = params.rippleY,\n          rippleSize = params.rippleSize,\n          cb = params.cb;\n\n      _this.setState(function (state) {\n        return {\n          nextKey: state.nextKey + 1,\n          ripples: [].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_2___default()(state.ripples), [react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(_Ripple__WEBPACK_IMPORTED_MODULE_13__[\"default\"], {\n            key: state.nextKey,\n            classes: _this.props.classes,\n            timeout: {\n              exit: DURATION,\n              enter: DURATION\n            },\n            pulsate: pulsate,\n            rippleX: rippleX,\n            rippleY: rippleY,\n            rippleSize: rippleSize\n          })])\n        };\n      }, cb);\n    };\n\n    _this.stop = function (event, cb) {\n      clearTimeout(_this.startTimer); // The touch interaction occurs too quickly.\n      // We still want to show ripple effect.\n\n      if (event.type === 'touchend' && _this.startTimerCommit) {\n        event.persist();\n\n        _this.startTimerCommit();\n\n        _this.startTimerCommit = null;\n        _this.startTimer = setTimeout(function () {\n          _this.stop(event, cb);\n        });\n        return;\n      }\n\n      _this.startTimerCommit = null;\n\n      _this.setState(function (_ref) {\n        var ripples = _ref.ripples;\n\n        if (ripples && ripples.length) {\n          return {\n            ripples: ripples.slice(1)\n          };\n        }\n\n        return null;\n      }, cb);\n    };\n\n    return _this;\n  }\n\n  _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_4___default()(TouchRipple, [{\n    key: \"componentWillUnmount\",\n    value: function componentWillUnmount() {\n      clearTimeout(this.startTimer);\n    }\n  }, {\n    key: \"render\",\n    value: function render() {\n      var _this$props = this.props,\n          center = _this$props.center,\n          classes = _this$props.classes,\n          className = _this$props.className,\n          other = _babel_runtime_helpers_objectWithoutProperties__WEBPACK_IMPORTED_MODULE_1___default()(_this$props, [\"center\", \"classes\", \"className\"]);\n\n      return react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(\"span\", _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default()({\n        className: Object(clsx__WEBPACK_IMPORTED_MODULE_11__[\"default\"])(classes.root, className),\n        ref: this.container\n      }, other), react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(react_transition_group__WEBPACK_IMPORTED_MODULE_10__[\"TransitionGroup\"], {\n        component: null,\n        enter: true,\n        exit: true\n      }, this.state.ripples));\n    }\n  }]);\n\n  return TouchRipple;\n}(react__WEBPACK_IMPORTED_MODULE_8___default.a.PureComponent);\n\n false ? undefined : void 0;\nTouchRipple.defaultProps = {\n  center: false\n};\n/* harmony default export */ __webpack_exports__[\"default\"] = (Object(_styles_withStyles__WEBPACK_IMPORTED_MODULE_12__[\"default\"])(styles, {\n  flip: false,\n  name: 'MuiTouchRipple'\n})(TouchRipple));\n\n//# sourceURL=webpack:///./node_modules/@material-ui/core/esm/ButtonBase/TouchRipple.js?");
 
 /***/ }),
 
@@ -2795,7 +2795,7 @@ eval("// @flow\n\n\nvar key = '__global_unique_id__';\n\nmodule.exports = functi
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"createBrowserHistory\", function() { return createBrowserHistory; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"createHashHistory\", function() { return createHashHistory; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"createMemoryHistory\", function() { return createMemoryHistory; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"createLocation\", function() { return createLocation; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"locationsAreEqual\", function() { return locationsAreEqual; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"parsePath\", function() { return parsePath; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"createPath\", function() { return createPath; });\n/* harmony import */ var _babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/extends */ \"./node_modules/@babel/runtime/helpers/esm/extends.js\");\n/* harmony import */ var resolve_pathname__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! resolve-pathname */ \"./node_modules/resolve-pathname/index.js\");\n/* harmony import */ var value_equal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! value-equal */ \"./node_modules/value-equal/index.js\");\n/* harmony import */ var tiny_warning__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tiny-warning */ \"./node_modules/tiny-warning/dist/tiny-warning.esm.js\");\n/* harmony import */ var tiny_invariant__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! tiny-invariant */ \"./node_modules/tiny-invariant/dist/tiny-invariant.esm.js\");\n\n\n\n\n\n\nfunction addLeadingSlash(path) {\n  return path.charAt(0) === '/' ? path : '/' + path;\n}\nfunction stripLeadingSlash(path) {\n  return path.charAt(0) === '/' ? path.substr(1) : path;\n}\nfunction hasBasename(path, prefix) {\n  return new RegExp('^' + prefix + '(\\\\/|\\\\?|#|$)', 'i').test(path);\n}\nfunction stripBasename(path, prefix) {\n  return hasBasename(path, prefix) ? path.substr(prefix.length) : path;\n}\nfunction stripTrailingSlash(path) {\n  return path.charAt(path.length - 1) === '/' ? path.slice(0, -1) : path;\n}\nfunction parsePath(path) {\n  var pathname = path || '/';\n  var search = '';\n  var hash = '';\n  var hashIndex = pathname.indexOf('#');\n\n  if (hashIndex !== -1) {\n    hash = pathname.substr(hashIndex);\n    pathname = pathname.substr(0, hashIndex);\n  }\n\n  var searchIndex = pathname.indexOf('?');\n\n  if (searchIndex !== -1) {\n    search = pathname.substr(searchIndex);\n    pathname = pathname.substr(0, searchIndex);\n  }\n\n  return {\n    pathname: pathname,\n    search: search === '?' ? '' : search,\n    hash: hash === '#' ? '' : hash\n  };\n}\nfunction createPath(location) {\n  var pathname = location.pathname,\n      search = location.search,\n      hash = location.hash;\n  var path = pathname || '/';\n  if (search && search !== '?') path += search.charAt(0) === '?' ? search : \"?\" + search;\n  if (hash && hash !== '#') path += hash.charAt(0) === '#' ? hash : \"#\" + hash;\n  return path;\n}\n\nfunction createLocation(path, state, key, currentLocation) {\n  var location;\n\n  if (typeof path === 'string') {\n    // Two-arg form: push(path, state)\n    location = parsePath(path);\n    location.state = state;\n  } else {\n    // One-arg form: push(location)\n    location = Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({}, path);\n    if (location.pathname === undefined) location.pathname = '';\n\n    if (location.search) {\n      if (location.search.charAt(0) !== '?') location.search = '?' + location.search;\n    } else {\n      location.search = '';\n    }\n\n    if (location.hash) {\n      if (location.hash.charAt(0) !== '#') location.hash = '#' + location.hash;\n    } else {\n      location.hash = '';\n    }\n\n    if (state !== undefined && location.state === undefined) location.state = state;\n  }\n\n  try {\n    location.pathname = decodeURI(location.pathname);\n  } catch (e) {\n    if (e instanceof URIError) {\n      throw new URIError('Pathname \"' + location.pathname + '\" could not be decoded. ' + 'This is likely caused by an invalid percent-encoding.');\n    } else {\n      throw e;\n    }\n  }\n\n  if (key) location.key = key;\n\n  if (currentLocation) {\n    // Resolve incomplete/relative pathname relative to current location.\n    if (!location.pathname) {\n      location.pathname = currentLocation.pathname;\n    } else if (location.pathname.charAt(0) !== '/') {\n      location.pathname = Object(resolve_pathname__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(location.pathname, currentLocation.pathname);\n    }\n  } else {\n    // When there is no prior location and pathname is empty, set it to /\n    if (!location.pathname) {\n      location.pathname = '/';\n    }\n  }\n\n  return location;\n}\nfunction locationsAreEqual(a, b) {\n  return a.pathname === b.pathname && a.search === b.search && a.hash === b.hash && a.key === b.key && Object(value_equal__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(a.state, b.state);\n}\n\nfunction createTransitionManager() {\n  var prompt = null;\n\n  function setPrompt(nextPrompt) {\n     false ? undefined : void 0;\n    prompt = nextPrompt;\n    return function () {\n      if (prompt === nextPrompt) prompt = null;\n    };\n  }\n\n  function confirmTransitionTo(location, action, getUserConfirmation, callback) {\n    // TODO: If another transition starts while we're still confirming\n    // the previous one, we may end up in a weird state. Figure out the\n    // best way to handle this.\n    if (prompt != null) {\n      var result = typeof prompt === 'function' ? prompt(location, action) : prompt;\n\n      if (typeof result === 'string') {\n        if (typeof getUserConfirmation === 'function') {\n          getUserConfirmation(result, callback);\n        } else {\n           false ? undefined : void 0;\n          callback(true);\n        }\n      } else {\n        // Return false from a transition hook to cancel the transition.\n        callback(result !== false);\n      }\n    } else {\n      callback(true);\n    }\n  }\n\n  var listeners = [];\n\n  function appendListener(fn) {\n    var isActive = true;\n\n    function listener() {\n      if (isActive) fn.apply(void 0, arguments);\n    }\n\n    listeners.push(listener);\n    return function () {\n      isActive = false;\n      listeners = listeners.filter(function (item) {\n        return item !== listener;\n      });\n    };\n  }\n\n  function notifyListeners() {\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    listeners.forEach(function (listener) {\n      return listener.apply(void 0, args);\n    });\n  }\n\n  return {\n    setPrompt: setPrompt,\n    confirmTransitionTo: confirmTransitionTo,\n    appendListener: appendListener,\n    notifyListeners: notifyListeners\n  };\n}\n\nvar canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);\nfunction getConfirmation(message, callback) {\n  callback(window.confirm(message)); // eslint-disable-line no-alert\n}\n/**\n * Returns true if the HTML5 history API is supported. Taken from Modernizr.\n *\n * https://github.com/Modernizr/Modernizr/blob/master/LICENSE\n * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js\n * changed to avoid false negatives for Windows Phones: https://github.com/reactjs/react-router/issues/586\n */\n\nfunction supportsHistory() {\n  var ua = window.navigator.userAgent;\n  if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) return false;\n  return window.history && 'pushState' in window.history;\n}\n/**\n * Returns true if browser fires popstate on hash change.\n * IE10 and IE11 do not.\n */\n\nfunction supportsPopStateOnHashChange() {\n  return window.navigator.userAgent.indexOf('Trident') === -1;\n}\n/**\n * Returns false if using go(n) with hash history causes a full page reload.\n */\n\nfunction supportsGoWithoutReloadUsingHash() {\n  return window.navigator.userAgent.indexOf('Firefox') === -1;\n}\n/**\n * Returns true if a given popstate event is an extraneous WebKit event.\n * Accounts for the fact that Chrome on iOS fires real popstate events\n * containing undefined state when pressing the back button.\n */\n\nfunction isExtraneousPopstateEvent(event) {\n  event.state === undefined && navigator.userAgent.indexOf('CriOS') === -1;\n}\n\nvar PopStateEvent = 'popstate';\nvar HashChangeEvent = 'hashchange';\n\nfunction getHistoryState() {\n  try {\n    return window.history.state || {};\n  } catch (e) {\n    // IE 11 sometimes throws when accessing window.history.state\n    // See https://github.com/ReactTraining/history/pull/289\n    return {};\n  }\n}\n/**\n * Creates a history object that uses the HTML5 history API including\n * pushState, replaceState, and the popstate event.\n */\n\n\nfunction createBrowserHistory(props) {\n  if (props === void 0) {\n    props = {};\n  }\n\n  !canUseDOM ?  false ? undefined : Object(tiny_invariant__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(false) : void 0;\n  var globalHistory = window.history;\n  var canUseHistory = supportsHistory();\n  var needsHashChangeListener = !supportsPopStateOnHashChange();\n  var _props = props,\n      _props$forceRefresh = _props.forceRefresh,\n      forceRefresh = _props$forceRefresh === void 0 ? false : _props$forceRefresh,\n      _props$getUserConfirm = _props.getUserConfirmation,\n      getUserConfirmation = _props$getUserConfirm === void 0 ? getConfirmation : _props$getUserConfirm,\n      _props$keyLength = _props.keyLength,\n      keyLength = _props$keyLength === void 0 ? 6 : _props$keyLength;\n  var basename = props.basename ? stripTrailingSlash(addLeadingSlash(props.basename)) : '';\n\n  function getDOMLocation(historyState) {\n    var _ref = historyState || {},\n        key = _ref.key,\n        state = _ref.state;\n\n    var _window$location = window.location,\n        pathname = _window$location.pathname,\n        search = _window$location.search,\n        hash = _window$location.hash;\n    var path = pathname + search + hash;\n     false ? undefined : void 0;\n    if (basename) path = stripBasename(path, basename);\n    return createLocation(path, state, key);\n  }\n\n  function createKey() {\n    return Math.random().toString(36).substr(2, keyLength);\n  }\n\n  var transitionManager = createTransitionManager();\n\n  function setState(nextState) {\n    Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(history, nextState);\n\n    history.length = globalHistory.length;\n    transitionManager.notifyListeners(history.location, history.action);\n  }\n\n  function handlePopState(event) {\n    // Ignore extraneous popstate events in WebKit.\n    if (isExtraneousPopstateEvent(event)) return;\n    handlePop(getDOMLocation(event.state));\n  }\n\n  function handleHashChange() {\n    handlePop(getDOMLocation(getHistoryState()));\n  }\n\n  var forceNextPop = false;\n\n  function handlePop(location) {\n    if (forceNextPop) {\n      forceNextPop = false;\n      setState();\n    } else {\n      var action = 'POP';\n      transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n        if (ok) {\n          setState({\n            action: action,\n            location: location\n          });\n        } else {\n          revertPop(location);\n        }\n      });\n    }\n  }\n\n  function revertPop(fromLocation) {\n    var toLocation = history.location; // TODO: We could probably make this more reliable by\n    // keeping a list of keys we've seen in sessionStorage.\n    // Instead, we just default to 0 for keys we don't know.\n\n    var toIndex = allKeys.indexOf(toLocation.key);\n    if (toIndex === -1) toIndex = 0;\n    var fromIndex = allKeys.indexOf(fromLocation.key);\n    if (fromIndex === -1) fromIndex = 0;\n    var delta = toIndex - fromIndex;\n\n    if (delta) {\n      forceNextPop = true;\n      go(delta);\n    }\n  }\n\n  var initialLocation = getDOMLocation(getHistoryState());\n  var allKeys = [initialLocation.key]; // Public interface\n\n  function createHref(location) {\n    return basename + createPath(location);\n  }\n\n  function push(path, state) {\n     false ? undefined : void 0;\n    var action = 'PUSH';\n    var location = createLocation(path, state, createKey(), history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var href = createHref(location);\n      var key = location.key,\n          state = location.state;\n\n      if (canUseHistory) {\n        globalHistory.pushState({\n          key: key,\n          state: state\n        }, null, href);\n\n        if (forceRefresh) {\n          window.location.href = href;\n        } else {\n          var prevIndex = allKeys.indexOf(history.location.key);\n          var nextKeys = allKeys.slice(0, prevIndex === -1 ? 0 : prevIndex + 1);\n          nextKeys.push(location.key);\n          allKeys = nextKeys;\n          setState({\n            action: action,\n            location: location\n          });\n        }\n      } else {\n         false ? undefined : void 0;\n        window.location.href = href;\n      }\n    });\n  }\n\n  function replace(path, state) {\n     false ? undefined : void 0;\n    var action = 'REPLACE';\n    var location = createLocation(path, state, createKey(), history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var href = createHref(location);\n      var key = location.key,\n          state = location.state;\n\n      if (canUseHistory) {\n        globalHistory.replaceState({\n          key: key,\n          state: state\n        }, null, href);\n\n        if (forceRefresh) {\n          window.location.replace(href);\n        } else {\n          var prevIndex = allKeys.indexOf(history.location.key);\n          if (prevIndex !== -1) allKeys[prevIndex] = location.key;\n          setState({\n            action: action,\n            location: location\n          });\n        }\n      } else {\n         false ? undefined : void 0;\n        window.location.replace(href);\n      }\n    });\n  }\n\n  function go(n) {\n    globalHistory.go(n);\n  }\n\n  function goBack() {\n    go(-1);\n  }\n\n  function goForward() {\n    go(1);\n  }\n\n  var listenerCount = 0;\n\n  function checkDOMListeners(delta) {\n    listenerCount += delta;\n\n    if (listenerCount === 1 && delta === 1) {\n      window.addEventListener(PopStateEvent, handlePopState);\n      if (needsHashChangeListener) window.addEventListener(HashChangeEvent, handleHashChange);\n    } else if (listenerCount === 0) {\n      window.removeEventListener(PopStateEvent, handlePopState);\n      if (needsHashChangeListener) window.removeEventListener(HashChangeEvent, handleHashChange);\n    }\n  }\n\n  var isBlocked = false;\n\n  function block(prompt) {\n    if (prompt === void 0) {\n      prompt = false;\n    }\n\n    var unblock = transitionManager.setPrompt(prompt);\n\n    if (!isBlocked) {\n      checkDOMListeners(1);\n      isBlocked = true;\n    }\n\n    return function () {\n      if (isBlocked) {\n        isBlocked = false;\n        checkDOMListeners(-1);\n      }\n\n      return unblock();\n    };\n  }\n\n  function listen(listener) {\n    var unlisten = transitionManager.appendListener(listener);\n    checkDOMListeners(1);\n    return function () {\n      checkDOMListeners(-1);\n      unlisten();\n    };\n  }\n\n  var history = {\n    length: globalHistory.length,\n    action: 'POP',\n    location: initialLocation,\n    createHref: createHref,\n    push: push,\n    replace: replace,\n    go: go,\n    goBack: goBack,\n    goForward: goForward,\n    block: block,\n    listen: listen\n  };\n  return history;\n}\n\nvar HashChangeEvent$1 = 'hashchange';\nvar HashPathCoders = {\n  hashbang: {\n    encodePath: function encodePath(path) {\n      return path.charAt(0) === '!' ? path : '!/' + stripLeadingSlash(path);\n    },\n    decodePath: function decodePath(path) {\n      return path.charAt(0) === '!' ? path.substr(1) : path;\n    }\n  },\n  noslash: {\n    encodePath: stripLeadingSlash,\n    decodePath: addLeadingSlash\n  },\n  slash: {\n    encodePath: addLeadingSlash,\n    decodePath: addLeadingSlash\n  }\n};\n\nfunction getHashPath() {\n  // We can't use window.location.hash here because it's not\n  // consistent across browsers - Firefox will pre-decode it!\n  var href = window.location.href;\n  var hashIndex = href.indexOf('#');\n  return hashIndex === -1 ? '' : href.substring(hashIndex + 1);\n}\n\nfunction pushHashPath(path) {\n  window.location.hash = path;\n}\n\nfunction replaceHashPath(path) {\n  var hashIndex = window.location.href.indexOf('#');\n  window.location.replace(window.location.href.slice(0, hashIndex >= 0 ? hashIndex : 0) + '#' + path);\n}\n\nfunction createHashHistory(props) {\n  if (props === void 0) {\n    props = {};\n  }\n\n  !canUseDOM ?  false ? undefined : Object(tiny_invariant__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(false) : void 0;\n  var globalHistory = window.history;\n  var canGoWithoutReload = supportsGoWithoutReloadUsingHash();\n  var _props = props,\n      _props$getUserConfirm = _props.getUserConfirmation,\n      getUserConfirmation = _props$getUserConfirm === void 0 ? getConfirmation : _props$getUserConfirm,\n      _props$hashType = _props.hashType,\n      hashType = _props$hashType === void 0 ? 'slash' : _props$hashType;\n  var basename = props.basename ? stripTrailingSlash(addLeadingSlash(props.basename)) : '';\n  var _HashPathCoders$hashT = HashPathCoders[hashType],\n      encodePath = _HashPathCoders$hashT.encodePath,\n      decodePath = _HashPathCoders$hashT.decodePath;\n\n  function getDOMLocation() {\n    var path = decodePath(getHashPath());\n     false ? undefined : void 0;\n    if (basename) path = stripBasename(path, basename);\n    return createLocation(path);\n  }\n\n  var transitionManager = createTransitionManager();\n\n  function setState(nextState) {\n    Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(history, nextState);\n\n    history.length = globalHistory.length;\n    transitionManager.notifyListeners(history.location, history.action);\n  }\n\n  var forceNextPop = false;\n  var ignorePath = null;\n\n  function handleHashChange() {\n    var path = getHashPath();\n    var encodedPath = encodePath(path);\n\n    if (path !== encodedPath) {\n      // Ensure we always have a properly-encoded hash.\n      replaceHashPath(encodedPath);\n    } else {\n      var location = getDOMLocation();\n      var prevLocation = history.location;\n      if (!forceNextPop && locationsAreEqual(prevLocation, location)) return; // A hashchange doesn't always == location change.\n\n      if (ignorePath === createPath(location)) return; // Ignore this change; we already setState in push/replace.\n\n      ignorePath = null;\n      handlePop(location);\n    }\n  }\n\n  function handlePop(location) {\n    if (forceNextPop) {\n      forceNextPop = false;\n      setState();\n    } else {\n      var action = 'POP';\n      transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n        if (ok) {\n          setState({\n            action: action,\n            location: location\n          });\n        } else {\n          revertPop(location);\n        }\n      });\n    }\n  }\n\n  function revertPop(fromLocation) {\n    var toLocation = history.location; // TODO: We could probably make this more reliable by\n    // keeping a list of paths we've seen in sessionStorage.\n    // Instead, we just default to 0 for paths we don't know.\n\n    var toIndex = allPaths.lastIndexOf(createPath(toLocation));\n    if (toIndex === -1) toIndex = 0;\n    var fromIndex = allPaths.lastIndexOf(createPath(fromLocation));\n    if (fromIndex === -1) fromIndex = 0;\n    var delta = toIndex - fromIndex;\n\n    if (delta) {\n      forceNextPop = true;\n      go(delta);\n    }\n  } // Ensure the hash is encoded properly before doing anything else.\n\n\n  var path = getHashPath();\n  var encodedPath = encodePath(path);\n  if (path !== encodedPath) replaceHashPath(encodedPath);\n  var initialLocation = getDOMLocation();\n  var allPaths = [createPath(initialLocation)]; // Public interface\n\n  function createHref(location) {\n    return '#' + encodePath(basename + createPath(location));\n  }\n\n  function push(path, state) {\n     false ? undefined : void 0;\n    var action = 'PUSH';\n    var location = createLocation(path, undefined, undefined, history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var path = createPath(location);\n      var encodedPath = encodePath(basename + path);\n      var hashChanged = getHashPath() !== encodedPath;\n\n      if (hashChanged) {\n        // We cannot tell if a hashchange was caused by a PUSH, so we'd\n        // rather setState here and ignore the hashchange. The caveat here\n        // is that other hash histories in the page will consider it a POP.\n        ignorePath = path;\n        pushHashPath(encodedPath);\n        var prevIndex = allPaths.lastIndexOf(createPath(history.location));\n        var nextPaths = allPaths.slice(0, prevIndex === -1 ? 0 : prevIndex + 1);\n        nextPaths.push(path);\n        allPaths = nextPaths;\n        setState({\n          action: action,\n          location: location\n        });\n      } else {\n         false ? undefined : void 0;\n        setState();\n      }\n    });\n  }\n\n  function replace(path, state) {\n     false ? undefined : void 0;\n    var action = 'REPLACE';\n    var location = createLocation(path, undefined, undefined, history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var path = createPath(location);\n      var encodedPath = encodePath(basename + path);\n      var hashChanged = getHashPath() !== encodedPath;\n\n      if (hashChanged) {\n        // We cannot tell if a hashchange was caused by a REPLACE, so we'd\n        // rather setState here and ignore the hashchange. The caveat here\n        // is that other hash histories in the page will consider it a POP.\n        ignorePath = path;\n        replaceHashPath(encodedPath);\n      }\n\n      var prevIndex = allPaths.indexOf(createPath(history.location));\n      if (prevIndex !== -1) allPaths[prevIndex] = path;\n      setState({\n        action: action,\n        location: location\n      });\n    });\n  }\n\n  function go(n) {\n     false ? undefined : void 0;\n    globalHistory.go(n);\n  }\n\n  function goBack() {\n    go(-1);\n  }\n\n  function goForward() {\n    go(1);\n  }\n\n  var listenerCount = 0;\n\n  function checkDOMListeners(delta) {\n    listenerCount += delta;\n\n    if (listenerCount === 1 && delta === 1) {\n      window.addEventListener(HashChangeEvent$1, handleHashChange);\n    } else if (listenerCount === 0) {\n      window.removeEventListener(HashChangeEvent$1, handleHashChange);\n    }\n  }\n\n  var isBlocked = false;\n\n  function block(prompt) {\n    if (prompt === void 0) {\n      prompt = false;\n    }\n\n    var unblock = transitionManager.setPrompt(prompt);\n\n    if (!isBlocked) {\n      checkDOMListeners(1);\n      isBlocked = true;\n    }\n\n    return function () {\n      if (isBlocked) {\n        isBlocked = false;\n        checkDOMListeners(-1);\n      }\n\n      return unblock();\n    };\n  }\n\n  function listen(listener) {\n    var unlisten = transitionManager.appendListener(listener);\n    checkDOMListeners(1);\n    return function () {\n      checkDOMListeners(-1);\n      unlisten();\n    };\n  }\n\n  var history = {\n    length: globalHistory.length,\n    action: 'POP',\n    location: initialLocation,\n    createHref: createHref,\n    push: push,\n    replace: replace,\n    go: go,\n    goBack: goBack,\n    goForward: goForward,\n    block: block,\n    listen: listen\n  };\n  return history;\n}\n\nfunction clamp(n, lowerBound, upperBound) {\n  return Math.min(Math.max(n, lowerBound), upperBound);\n}\n/**\n * Creates a history object that stores locations in memory.\n */\n\n\nfunction createMemoryHistory(props) {\n  if (props === void 0) {\n    props = {};\n  }\n\n  var _props = props,\n      getUserConfirmation = _props.getUserConfirmation,\n      _props$initialEntries = _props.initialEntries,\n      initialEntries = _props$initialEntries === void 0 ? ['/'] : _props$initialEntries,\n      _props$initialIndex = _props.initialIndex,\n      initialIndex = _props$initialIndex === void 0 ? 0 : _props$initialIndex,\n      _props$keyLength = _props.keyLength,\n      keyLength = _props$keyLength === void 0 ? 6 : _props$keyLength;\n  var transitionManager = createTransitionManager();\n\n  function setState(nextState) {\n    Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(history, nextState);\n\n    history.length = history.entries.length;\n    transitionManager.notifyListeners(history.location, history.action);\n  }\n\n  function createKey() {\n    return Math.random().toString(36).substr(2, keyLength);\n  }\n\n  var index = clamp(initialIndex, 0, initialEntries.length - 1);\n  var entries = initialEntries.map(function (entry) {\n    return typeof entry === 'string' ? createLocation(entry, undefined, createKey()) : createLocation(entry, undefined, entry.key || createKey());\n  }); // Public interface\n\n  var createHref = createPath;\n\n  function push(path, state) {\n     false ? undefined : void 0;\n    var action = 'PUSH';\n    var location = createLocation(path, state, createKey(), history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var prevIndex = history.index;\n      var nextIndex = prevIndex + 1;\n      var nextEntries = history.entries.slice(0);\n\n      if (nextEntries.length > nextIndex) {\n        nextEntries.splice(nextIndex, nextEntries.length - nextIndex, location);\n      } else {\n        nextEntries.push(location);\n      }\n\n      setState({\n        action: action,\n        location: location,\n        index: nextIndex,\n        entries: nextEntries\n      });\n    });\n  }\n\n  function replace(path, state) {\n     false ? undefined : void 0;\n    var action = 'REPLACE';\n    var location = createLocation(path, state, createKey(), history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      history.entries[history.index] = location;\n      setState({\n        action: action,\n        location: location\n      });\n    });\n  }\n\n  function go(n) {\n    var nextIndex = clamp(history.index + n, 0, history.entries.length - 1);\n    var action = 'POP';\n    var location = history.entries[nextIndex];\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (ok) {\n        setState({\n          action: action,\n          location: location,\n          index: nextIndex\n        });\n      } else {\n        // Mimic the behavior of DOM histories by\n        // causing a render after a cancelled POP.\n        setState();\n      }\n    });\n  }\n\n  function goBack() {\n    go(-1);\n  }\n\n  function goForward() {\n    go(1);\n  }\n\n  function canGo(n) {\n    var nextIndex = history.index + n;\n    return nextIndex >= 0 && nextIndex < history.entries.length;\n  }\n\n  function block(prompt) {\n    if (prompt === void 0) {\n      prompt = false;\n    }\n\n    return transitionManager.setPrompt(prompt);\n  }\n\n  function listen(listener) {\n    return transitionManager.appendListener(listener);\n  }\n\n  var history = {\n    length: entries.length,\n    action: 'POP',\n    location: entries[index],\n    index: index,\n    entries: entries,\n    createHref: createHref,\n    push: push,\n    replace: replace,\n    go: go,\n    goBack: goBack,\n    goForward: goForward,\n    canGo: canGo,\n    block: block,\n    listen: listen\n  };\n  return history;\n}\n\n\n\n\n//# sourceURL=webpack:///./node_modules/history/esm/history.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"createBrowserHistory\", function() { return createBrowserHistory; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"createHashHistory\", function() { return createHashHistory; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"createMemoryHistory\", function() { return createMemoryHistory; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"createLocation\", function() { return createLocation; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"locationsAreEqual\", function() { return locationsAreEqual; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"parsePath\", function() { return parsePath; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"createPath\", function() { return createPath; });\n/* harmony import */ var _babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/esm/extends */ \"./node_modules/@babel/runtime/helpers/esm/extends.js\");\n/* harmony import */ var resolve_pathname__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! resolve-pathname */ \"./node_modules/resolve-pathname/index.js\");\n/* harmony import */ var value_equal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! value-equal */ \"./node_modules/value-equal/index.js\");\n/* harmony import */ var tiny_warning__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tiny-warning */ \"./node_modules/tiny-warning/dist/tiny-warning.esm.js\");\n/* harmony import */ var tiny_invariant__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! tiny-invariant */ \"./node_modules/tiny-invariant/dist/tiny-invariant.esm.js\");\n\n\n\n\n\n\nfunction addLeadingSlash(path) {\n  return path.charAt(0) === '/' ? path : '/' + path;\n}\nfunction stripLeadingSlash(path) {\n  return path.charAt(0) === '/' ? path.substr(1) : path;\n}\nfunction hasBasename(path, prefix) {\n  return new RegExp('^' + prefix + '(\\\\/|\\\\?|#|$)', 'i').test(path);\n}\nfunction stripBasename(path, prefix) {\n  return hasBasename(path, prefix) ? path.substr(prefix.length) : path;\n}\nfunction stripTrailingSlash(path) {\n  return path.charAt(path.length - 1) === '/' ? path.slice(0, -1) : path;\n}\nfunction parsePath(path) {\n  var pathname = path || '/';\n  var search = '';\n  var hash = '';\n  var hashIndex = pathname.indexOf('#');\n\n  if (hashIndex !== -1) {\n    hash = pathname.substr(hashIndex);\n    pathname = pathname.substr(0, hashIndex);\n  }\n\n  var searchIndex = pathname.indexOf('?');\n\n  if (searchIndex !== -1) {\n    search = pathname.substr(searchIndex);\n    pathname = pathname.substr(0, searchIndex);\n  }\n\n  return {\n    pathname: pathname,\n    search: search === '?' ? '' : search,\n    hash: hash === '#' ? '' : hash\n  };\n}\nfunction createPath(location) {\n  var pathname = location.pathname,\n      search = location.search,\n      hash = location.hash;\n  var path = pathname || '/';\n  if (search && search !== '?') path += search.charAt(0) === '?' ? search : \"?\" + search;\n  if (hash && hash !== '#') path += hash.charAt(0) === '#' ? hash : \"#\" + hash;\n  return path;\n}\n\nfunction createLocation(path, state, key, currentLocation) {\n  var location;\n\n  if (typeof path === 'string') {\n    // Two-arg form: push(path, state)\n    location = parsePath(path);\n    location.state = state;\n  } else {\n    // One-arg form: push(location)\n    location = Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[\"default\"])({}, path);\n    if (location.pathname === undefined) location.pathname = '';\n\n    if (location.search) {\n      if (location.search.charAt(0) !== '?') location.search = '?' + location.search;\n    } else {\n      location.search = '';\n    }\n\n    if (location.hash) {\n      if (location.hash.charAt(0) !== '#') location.hash = '#' + location.hash;\n    } else {\n      location.hash = '';\n    }\n\n    if (state !== undefined && location.state === undefined) location.state = state;\n  }\n\n  try {\n    location.pathname = decodeURI(location.pathname);\n  } catch (e) {\n    if (e instanceof URIError) {\n      throw new URIError('Pathname \"' + location.pathname + '\" could not be decoded. ' + 'This is likely caused by an invalid percent-encoding.');\n    } else {\n      throw e;\n    }\n  }\n\n  if (key) location.key = key;\n\n  if (currentLocation) {\n    // Resolve incomplete/relative pathname relative to current location.\n    if (!location.pathname) {\n      location.pathname = currentLocation.pathname;\n    } else if (location.pathname.charAt(0) !== '/') {\n      location.pathname = Object(resolve_pathname__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(location.pathname, currentLocation.pathname);\n    }\n  } else {\n    // When there is no prior location and pathname is empty, set it to /\n    if (!location.pathname) {\n      location.pathname = '/';\n    }\n  }\n\n  return location;\n}\nfunction locationsAreEqual(a, b) {\n  return a.pathname === b.pathname && a.search === b.search && a.hash === b.hash && a.key === b.key && Object(value_equal__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(a.state, b.state);\n}\n\nfunction createTransitionManager() {\n  var prompt = null;\n\n  function setPrompt(nextPrompt) {\n     false ? undefined : void 0;\n    prompt = nextPrompt;\n    return function () {\n      if (prompt === nextPrompt) prompt = null;\n    };\n  }\n\n  function confirmTransitionTo(location, action, getUserConfirmation, callback) {\n    // TODO: If another transition starts while we're still confirming\n    // the previous one, we may end up in a weird state. Figure out the\n    // best way to handle this.\n    if (prompt != null) {\n      var result = typeof prompt === 'function' ? prompt(location, action) : prompt;\n\n      if (typeof result === 'string') {\n        if (typeof getUserConfirmation === 'function') {\n          getUserConfirmation(result, callback);\n        } else {\n           false ? undefined : void 0;\n          callback(true);\n        }\n      } else {\n        // Return false from a transition hook to cancel the transition.\n        callback(result !== false);\n      }\n    } else {\n      callback(true);\n    }\n  }\n\n  var listeners = [];\n\n  function appendListener(fn) {\n    var isActive = true;\n\n    function listener() {\n      if (isActive) fn.apply(void 0, arguments);\n    }\n\n    listeners.push(listener);\n    return function () {\n      isActive = false;\n      listeners = listeners.filter(function (item) {\n        return item !== listener;\n      });\n    };\n  }\n\n  function notifyListeners() {\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    listeners.forEach(function (listener) {\n      return listener.apply(void 0, args);\n    });\n  }\n\n  return {\n    setPrompt: setPrompt,\n    confirmTransitionTo: confirmTransitionTo,\n    appendListener: appendListener,\n    notifyListeners: notifyListeners\n  };\n}\n\nvar canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);\nfunction getConfirmation(message, callback) {\n  callback(window.confirm(message)); // eslint-disable-line no-alert\n}\n/**\n * Returns true if the HTML5 history API is supported. Taken from Modernizr.\n *\n * https://github.com/Modernizr/Modernizr/blob/master/LICENSE\n * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js\n * changed to avoid false negatives for Windows Phones: https://github.com/reactjs/react-router/issues/586\n */\n\nfunction supportsHistory() {\n  var ua = window.navigator.userAgent;\n  if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('App Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) return false;\n  return window.history && 'pushState' in window.history;\n}\n/**\n * Returns true if browser fires popstate on hash change.\n * IE10 and IE11 do not.\n */\n\nfunction supportsPopStateOnHashChange() {\n  return window.navigator.userAgent.indexOf('Trident') === -1;\n}\n/**\n * Returns false if using go(n) with hash history causes a full page reload.\n */\n\nfunction supportsGoWithoutReloadUsingHash() {\n  return window.navigator.userAgent.indexOf('Firefox') === -1;\n}\n/**\n * Returns true if a given popstate event is an extraneous WebKit event.\n * Accounts for the fact that Chrome on iOS fires real popstate events\n * containing undefined state when pressing the back button.\n */\n\nfunction isExtraneousPopstateEvent(event) {\n  event.state === undefined && navigator.userAgent.indexOf('CriOS') === -1;\n}\n\nvar PopStateEvent = 'popstate';\nvar HashChangeEvent = 'hashchange';\n\nfunction getHistoryState() {\n  try {\n    return window.history.state || {};\n  } catch (e) {\n    // IE 11 sometimes throws when accessing window.history.state\n    // See https://github.com/ReactTraining/history/pull/289\n    return {};\n  }\n}\n/**\n * Creates a history object that uses the HTML5 history API including\n * pushState, replaceState, and the popstate event.\n */\n\n\nfunction createBrowserHistory(props) {\n  if (props === void 0) {\n    props = {};\n  }\n\n  !canUseDOM ?  false ? undefined : Object(tiny_invariant__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(false) : void 0;\n  var globalHistory = window.history;\n  var canUseHistory = supportsHistory();\n  var needsHashChangeListener = !supportsPopStateOnHashChange();\n  var _props = props,\n      _props$forceRefresh = _props.forceRefresh,\n      forceRefresh = _props$forceRefresh === void 0 ? false : _props$forceRefresh,\n      _props$getUserConfirm = _props.getUserConfirmation,\n      getUserConfirmation = _props$getUserConfirm === void 0 ? getConfirmation : _props$getUserConfirm,\n      _props$keyLength = _props.keyLength,\n      keyLength = _props$keyLength === void 0 ? 6 : _props$keyLength;\n  var basename = props.basename ? stripTrailingSlash(addLeadingSlash(props.basename)) : '';\n\n  function getDOMLocation(historyState) {\n    var _ref = historyState || {},\n        key = _ref.key,\n        state = _ref.state;\n\n    var _window$location = window.location,\n        pathname = _window$location.pathname,\n        search = _window$location.search,\n        hash = _window$location.hash;\n    var path = pathname + search + hash;\n     false ? undefined : void 0;\n    if (basename) path = stripBasename(path, basename);\n    return createLocation(path, state, key);\n  }\n\n  function createKey() {\n    return Math.random().toString(36).substr(2, keyLength);\n  }\n\n  var transitionManager = createTransitionManager();\n\n  function setState(nextState) {\n    Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(history, nextState);\n\n    history.length = globalHistory.length;\n    transitionManager.notifyListeners(history.location, history.action);\n  }\n\n  function handlePopState(event) {\n    // Ignore extraneous popstate events in WebKit.\n    if (isExtraneousPopstateEvent(event)) return;\n    handlePop(getDOMLocation(event.state));\n  }\n\n  function handleHashChange() {\n    handlePop(getDOMLocation(getHistoryState()));\n  }\n\n  var forceNextPop = false;\n\n  function handlePop(location) {\n    if (forceNextPop) {\n      forceNextPop = false;\n      setState();\n    } else {\n      var action = 'POP';\n      transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n        if (ok) {\n          setState({\n            action: action,\n            location: location\n          });\n        } else {\n          revertPop(location);\n        }\n      });\n    }\n  }\n\n  function revertPop(fromLocation) {\n    var toLocation = history.location; // TODO: We could probably make this more reliable by\n    // keeping a list of keys we've seen in sessionStorage.\n    // Instead, we just default to 0 for keys we don't know.\n\n    var toIndex = allKeys.indexOf(toLocation.key);\n    if (toIndex === -1) toIndex = 0;\n    var fromIndex = allKeys.indexOf(fromLocation.key);\n    if (fromIndex === -1) fromIndex = 0;\n    var delta = toIndex - fromIndex;\n\n    if (delta) {\n      forceNextPop = true;\n      go(delta);\n    }\n  }\n\n  var initialLocation = getDOMLocation(getHistoryState());\n  var allKeys = [initialLocation.key]; // Public interface\n\n  function createHref(location) {\n    return basename + createPath(location);\n  }\n\n  function push(path, state) {\n     false ? undefined : void 0;\n    var action = 'PUSH';\n    var location = createLocation(path, state, createKey(), history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var href = createHref(location);\n      var key = location.key,\n          state = location.state;\n\n      if (canUseHistory) {\n        globalHistory.pushState({\n          key: key,\n          state: state\n        }, null, href);\n\n        if (forceRefresh) {\n          window.location.href = href;\n        } else {\n          var prevIndex = allKeys.indexOf(history.location.key);\n          var nextKeys = allKeys.slice(0, prevIndex === -1 ? 0 : prevIndex + 1);\n          nextKeys.push(location.key);\n          allKeys = nextKeys;\n          setState({\n            action: action,\n            location: location\n          });\n        }\n      } else {\n         false ? undefined : void 0;\n        window.location.href = href;\n      }\n    });\n  }\n\n  function replace(path, state) {\n     false ? undefined : void 0;\n    var action = 'REPLACE';\n    var location = createLocation(path, state, createKey(), history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var href = createHref(location);\n      var key = location.key,\n          state = location.state;\n\n      if (canUseHistory) {\n        globalHistory.replaceState({\n          key: key,\n          state: state\n        }, null, href);\n\n        if (forceRefresh) {\n          window.location.replace(href);\n        } else {\n          var prevIndex = allKeys.indexOf(history.location.key);\n          if (prevIndex !== -1) allKeys[prevIndex] = location.key;\n          setState({\n            action: action,\n            location: location\n          });\n        }\n      } else {\n         false ? undefined : void 0;\n        window.location.replace(href);\n      }\n    });\n  }\n\n  function go(n) {\n    globalHistory.go(n);\n  }\n\n  function goBack() {\n    go(-1);\n  }\n\n  function goForward() {\n    go(1);\n  }\n\n  var listenerCount = 0;\n\n  function checkDOMListeners(delta) {\n    listenerCount += delta;\n\n    if (listenerCount === 1 && delta === 1) {\n      window.addEventListener(PopStateEvent, handlePopState);\n      if (needsHashChangeListener) window.addEventListener(HashChangeEvent, handleHashChange);\n    } else if (listenerCount === 0) {\n      window.removeEventListener(PopStateEvent, handlePopState);\n      if (needsHashChangeListener) window.removeEventListener(HashChangeEvent, handleHashChange);\n    }\n  }\n\n  var isBlocked = false;\n\n  function block(prompt) {\n    if (prompt === void 0) {\n      prompt = false;\n    }\n\n    var unblock = transitionManager.setPrompt(prompt);\n\n    if (!isBlocked) {\n      checkDOMListeners(1);\n      isBlocked = true;\n    }\n\n    return function () {\n      if (isBlocked) {\n        isBlocked = false;\n        checkDOMListeners(-1);\n      }\n\n      return unblock();\n    };\n  }\n\n  function listen(listener) {\n    var unlisten = transitionManager.appendListener(listener);\n    checkDOMListeners(1);\n    return function () {\n      checkDOMListeners(-1);\n      unlisten();\n    };\n  }\n\n  var history = {\n    length: globalHistory.length,\n    action: 'POP',\n    location: initialLocation,\n    createHref: createHref,\n    push: push,\n    replace: replace,\n    go: go,\n    goBack: goBack,\n    goForward: goForward,\n    block: block,\n    listen: listen\n  };\n  return history;\n}\n\nvar HashChangeEvent$1 = 'hashchange';\nvar HashPathCoders = {\n  hashbang: {\n    encodePath: function encodePath(path) {\n      return path.charAt(0) === '!' ? path : '!/' + stripLeadingSlash(path);\n    },\n    decodePath: function decodePath(path) {\n      return path.charAt(0) === '!' ? path.substr(1) : path;\n    }\n  },\n  noslash: {\n    encodePath: stripLeadingSlash,\n    decodePath: addLeadingSlash\n  },\n  slash: {\n    encodePath: addLeadingSlash,\n    decodePath: addLeadingSlash\n  }\n};\n\nfunction getHashPath() {\n  // We can't use window.location.hash here because it's not\n  // consistent across browsers - Firefox will pre-decode it!\n  var href = window.location.href;\n  var hashIndex = href.indexOf('#');\n  return hashIndex === -1 ? '' : href.substring(hashIndex + 1);\n}\n\nfunction pushHashPath(path) {\n  window.location.hash = path;\n}\n\nfunction replaceHashPath(path) {\n  var hashIndex = window.location.href.indexOf('#');\n  window.location.replace(window.location.href.slice(0, hashIndex >= 0 ? hashIndex : 0) + '#' + path);\n}\n\nfunction createHashHistory(props) {\n  if (props === void 0) {\n    props = {};\n  }\n\n  !canUseDOM ?  false ? undefined : Object(tiny_invariant__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(false) : void 0;\n  var globalHistory = window.history;\n  var canGoWithoutReload = supportsGoWithoutReloadUsingHash();\n  var _props = props,\n      _props$getUserConfirm = _props.getUserConfirmation,\n      getUserConfirmation = _props$getUserConfirm === void 0 ? getConfirmation : _props$getUserConfirm,\n      _props$hashType = _props.hashType,\n      hashType = _props$hashType === void 0 ? 'slash' : _props$hashType;\n  var basename = props.basename ? stripTrailingSlash(addLeadingSlash(props.basename)) : '';\n  var _HashPathCoders$hashT = HashPathCoders[hashType],\n      encodePath = _HashPathCoders$hashT.encodePath,\n      decodePath = _HashPathCoders$hashT.decodePath;\n\n  function getDOMLocation() {\n    var path = decodePath(getHashPath());\n     false ? undefined : void 0;\n    if (basename) path = stripBasename(path, basename);\n    return createLocation(path);\n  }\n\n  var transitionManager = createTransitionManager();\n\n  function setState(nextState) {\n    Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(history, nextState);\n\n    history.length = globalHistory.length;\n    transitionManager.notifyListeners(history.location, history.action);\n  }\n\n  var forceNextPop = false;\n  var ignorePath = null;\n\n  function handleHashChange() {\n    var path = getHashPath();\n    var encodedPath = encodePath(path);\n\n    if (path !== encodedPath) {\n      // Ensure we always have a properly-encoded hash.\n      replaceHashPath(encodedPath);\n    } else {\n      var location = getDOMLocation();\n      var prevLocation = history.location;\n      if (!forceNextPop && locationsAreEqual(prevLocation, location)) return; // A hashchange doesn't always == location change.\n\n      if (ignorePath === createPath(location)) return; // Ignore this change; we already setState in push/replace.\n\n      ignorePath = null;\n      handlePop(location);\n    }\n  }\n\n  function handlePop(location) {\n    if (forceNextPop) {\n      forceNextPop = false;\n      setState();\n    } else {\n      var action = 'POP';\n      transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n        if (ok) {\n          setState({\n            action: action,\n            location: location\n          });\n        } else {\n          revertPop(location);\n        }\n      });\n    }\n  }\n\n  function revertPop(fromLocation) {\n    var toLocation = history.location; // TODO: We could probably make this more reliable by\n    // keeping a list of paths we've seen in sessionStorage.\n    // Instead, we just default to 0 for paths we don't know.\n\n    var toIndex = allPaths.lastIndexOf(createPath(toLocation));\n    if (toIndex === -1) toIndex = 0;\n    var fromIndex = allPaths.lastIndexOf(createPath(fromLocation));\n    if (fromIndex === -1) fromIndex = 0;\n    var delta = toIndex - fromIndex;\n\n    if (delta) {\n      forceNextPop = true;\n      go(delta);\n    }\n  } // Ensure the hash is encoded properly before doing anything else.\n\n\n  var path = getHashPath();\n  var encodedPath = encodePath(path);\n  if (path !== encodedPath) replaceHashPath(encodedPath);\n  var initialLocation = getDOMLocation();\n  var allPaths = [createPath(initialLocation)]; // Public interface\n\n  function createHref(location) {\n    return '#' + encodePath(basename + createPath(location));\n  }\n\n  function push(path, state) {\n     false ? undefined : void 0;\n    var action = 'PUSH';\n    var location = createLocation(path, undefined, undefined, history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var path = createPath(location);\n      var encodedPath = encodePath(basename + path);\n      var hashChanged = getHashPath() !== encodedPath;\n\n      if (hashChanged) {\n        // We cannot tell if a hashchange was caused by a PUSH, so we'd\n        // rather setState here and ignore the hashchange. The caveat here\n        // is that other hash histories in the page will consider it a POP.\n        ignorePath = path;\n        pushHashPath(encodedPath);\n        var prevIndex = allPaths.lastIndexOf(createPath(history.location));\n        var nextPaths = allPaths.slice(0, prevIndex === -1 ? 0 : prevIndex + 1);\n        nextPaths.push(path);\n        allPaths = nextPaths;\n        setState({\n          action: action,\n          location: location\n        });\n      } else {\n         false ? undefined : void 0;\n        setState();\n      }\n    });\n  }\n\n  function replace(path, state) {\n     false ? undefined : void 0;\n    var action = 'REPLACE';\n    var location = createLocation(path, undefined, undefined, history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var path = createPath(location);\n      var encodedPath = encodePath(basename + path);\n      var hashChanged = getHashPath() !== encodedPath;\n\n      if (hashChanged) {\n        // We cannot tell if a hashchange was caused by a REPLACE, so we'd\n        // rather setState here and ignore the hashchange. The caveat here\n        // is that other hash histories in the page will consider it a POP.\n        ignorePath = path;\n        replaceHashPath(encodedPath);\n      }\n\n      var prevIndex = allPaths.indexOf(createPath(history.location));\n      if (prevIndex !== -1) allPaths[prevIndex] = path;\n      setState({\n        action: action,\n        location: location\n      });\n    });\n  }\n\n  function go(n) {\n     false ? undefined : void 0;\n    globalHistory.go(n);\n  }\n\n  function goBack() {\n    go(-1);\n  }\n\n  function goForward() {\n    go(1);\n  }\n\n  var listenerCount = 0;\n\n  function checkDOMListeners(delta) {\n    listenerCount += delta;\n\n    if (listenerCount === 1 && delta === 1) {\n      window.addEventListener(HashChangeEvent$1, handleHashChange);\n    } else if (listenerCount === 0) {\n      window.removeEventListener(HashChangeEvent$1, handleHashChange);\n    }\n  }\n\n  var isBlocked = false;\n\n  function block(prompt) {\n    if (prompt === void 0) {\n      prompt = false;\n    }\n\n    var unblock = transitionManager.setPrompt(prompt);\n\n    if (!isBlocked) {\n      checkDOMListeners(1);\n      isBlocked = true;\n    }\n\n    return function () {\n      if (isBlocked) {\n        isBlocked = false;\n        checkDOMListeners(-1);\n      }\n\n      return unblock();\n    };\n  }\n\n  function listen(listener) {\n    var unlisten = transitionManager.appendListener(listener);\n    checkDOMListeners(1);\n    return function () {\n      checkDOMListeners(-1);\n      unlisten();\n    };\n  }\n\n  var history = {\n    length: globalHistory.length,\n    action: 'POP',\n    location: initialLocation,\n    createHref: createHref,\n    push: push,\n    replace: replace,\n    go: go,\n    goBack: goBack,\n    goForward: goForward,\n    block: block,\n    listen: listen\n  };\n  return history;\n}\n\nfunction clamp(n, lowerBound, upperBound) {\n  return Math.min(Math.max(n, lowerBound), upperBound);\n}\n/**\n * Creates a history object that stores locations in memory.\n */\n\n\nfunction createMemoryHistory(props) {\n  if (props === void 0) {\n    props = {};\n  }\n\n  var _props = props,\n      getUserConfirmation = _props.getUserConfirmation,\n      _props$initialEntries = _props.initialEntries,\n      initialEntries = _props$initialEntries === void 0 ? ['/'] : _props$initialEntries,\n      _props$initialIndex = _props.initialIndex,\n      initialIndex = _props$initialIndex === void 0 ? 0 : _props$initialIndex,\n      _props$keyLength = _props.keyLength,\n      keyLength = _props$keyLength === void 0 ? 6 : _props$keyLength;\n  var transitionManager = createTransitionManager();\n\n  function setState(nextState) {\n    Object(_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(history, nextState);\n\n    history.length = history.entries.length;\n    transitionManager.notifyListeners(history.location, history.action);\n  }\n\n  function createKey() {\n    return Math.random().toString(36).substr(2, keyLength);\n  }\n\n  var index = clamp(initialIndex, 0, initialEntries.length - 1);\n  var entries = initialEntries.map(function (entry) {\n    return typeof entry === 'string' ? createLocation(entry, undefined, createKey()) : createLocation(entry, undefined, entry.key || createKey());\n  }); // Public interface\n\n  var createHref = createPath;\n\n  function push(path, state) {\n     false ? undefined : void 0;\n    var action = 'PUSH';\n    var location = createLocation(path, state, createKey(), history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      var prevIndex = history.index;\n      var nextIndex = prevIndex + 1;\n      var nextEntries = history.entries.slice(0);\n\n      if (nextEntries.length > nextIndex) {\n        nextEntries.splice(nextIndex, nextEntries.length - nextIndex, location);\n      } else {\n        nextEntries.push(location);\n      }\n\n      setState({\n        action: action,\n        location: location,\n        index: nextIndex,\n        entries: nextEntries\n      });\n    });\n  }\n\n  function replace(path, state) {\n     false ? undefined : void 0;\n    var action = 'REPLACE';\n    var location = createLocation(path, state, createKey(), history.location);\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (!ok) return;\n      history.entries[history.index] = location;\n      setState({\n        action: action,\n        location: location\n      });\n    });\n  }\n\n  function go(n) {\n    var nextIndex = clamp(history.index + n, 0, history.entries.length - 1);\n    var action = 'POP';\n    var location = history.entries[nextIndex];\n    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) {\n      if (ok) {\n        setState({\n          action: action,\n          location: location,\n          index: nextIndex\n        });\n      } else {\n        // Mimic the behavior of DOM histories by\n        // causing a render after a cancelled POP.\n        setState();\n      }\n    });\n  }\n\n  function goBack() {\n    go(-1);\n  }\n\n  function goForward() {\n    go(1);\n  }\n\n  function canGo(n) {\n    var nextIndex = history.index + n;\n    return nextIndex >= 0 && nextIndex < history.entries.length;\n  }\n\n  function block(prompt) {\n    if (prompt === void 0) {\n      prompt = false;\n    }\n\n    return transitionManager.setPrompt(prompt);\n  }\n\n  function listen(listener) {\n    return transitionManager.appendListener(listener);\n  }\n\n  var history = {\n    length: entries.length,\n    action: 'POP',\n    location: entries[index],\n    index: index,\n    entries: entries,\n    createHref: createHref,\n    push: push,\n    replace: replace,\n    go: go,\n    goBack: goBack,\n    goForward: goForward,\n    canGo: canGo,\n    block: block,\n    listen: listen\n  };\n  return history;\n}\n\n\n\n\n//# sourceURL=webpack:///./node_modules/history/esm/history.js?");
 
 /***/ }),
 
index 8e84f34..356bb21 100755 (executable)
@@ -15,7 +15,7 @@ gulp.task('sass', function () {
         .pipe(sass({
             outputStyle: 'compressed'
         })).on('error', swallowError)
-        .pipe(rename('glma-mobile-notifications.min.css'))
+        .pipe(rename('glma-app-notifications.min.css'))
         .pipe(gulp.dest('dist/css'));
 });
 
index caf1c5c..b2458fa 100755 (executable)
--- a/index.php
+++ b/index.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * Plugin Name: GLM Associate - Mobile Notifications Add-On
+ * Plugin Name: GLM Associate - App Notifications Add-On
  * Plugin URI: http://www.gaslightmedia.com/
- * Description: An add-on for creating and submitting notifications to mobile apps
+ * Description: An add-on for creating and submitting notifications to app apps
  * Version: 0.0.1
  * Author: Gaslight Media
  * Author URI: http://www.gaslightmedia.com/
  */
 
 /**
- * GLMA Mobile Notifications
+ * GLMA App Notifications
  * Index
  *
  * PHP version 5.5
  *
  * @category glmWordPressPluginChil
- * @package glmMembersMobileNotificationsAddOn
+ * @package glmMembersAppNotificationsAddOn
  * @author Chuck Scott <cscott@gaslightmedia.com>
  * @license http://www.gaslightmedia.com Gaslightmedia
  * @version 0.0.1
@@ -43,15 +43,15 @@ if (!defined('ABSPATH')) {
  *  so that we're sure the other add-ons see an up to date
  *  version from this plugin.
  */
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_VERSION', '0.0.1');
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_DB_VERSION', '0.0.1');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_VERSION', '0.0.1');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_DB_VERSION', '0.0.1');
 
 // This is the minimum version of the GLM Members DB plugin require for this plugin.
-define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION', '2.8.0');
+define('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION', '2.8.0');
 
 // Check if plugin version is not current in WordPress option and if needed updated it
-if (GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_VERSION != get_option('glmMembersMobileNotificationsPluginVersion')) {
-    update_option('glmMembersMobileNotificationsPluginVersion', GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_VERSION);
+if (GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_VERSION != get_option('glmMembersAppNotificationsPluginVersion')) {
+    update_option('glmMembersAppNotificationsPluginVersion', GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_VERSION);
 }
 
 /*
@@ -91,7 +91,7 @@ include_once ABSPATH . 'wp-admin/includes/plugin.php';
  */
 
 // Check if database version should be defined and it isn't - This would be a plugin/add-on setup issue
-if (is_file(GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PATH.'/setup/databaseScripts/dbVersions.php') && !defined('GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_DB_VERSION')) {
+if (is_file(GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PATH.'/setup/databaseScripts/dbVersions.php') && !defined('GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_DB_VERSION')) {
     die('You have database scripts but have not defined a current database version at the top of index.php for this plugin/add-on!');
 }
 
@@ -100,46 +100,46 @@ if (is_file(GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PATH.'/setup/databaseScripts
  */
 
 // Check for main plugin and that it's active
-function glmMembersMobileNotificationsPluginRequired() {
+function glmMembersAppNotificationsPluginRequired() {
     echo '
         <div class="error">
-            <p>The '.GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_NAME.' add-on requires the base GLM Member DB plugin to be installed and active!</p>
-            <p>The '.GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_NAME.' plugin has been de-activated.</p>
+            <p>The '.GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_NAME.' add-on requires the base GLM Member DB plugin to be installed and active!</p>
+            <p>The '.GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_NAME.' plugin has been de-activated.</p>
         </div>
     ';
 }
 $plugin_name = 'glm-member-db/index.php';
 $is_active = is_plugin_active($plugin_name);
 if ($is_active != '1') {
-    add_action( 'admin_notices', 'glmMembersMobileNotificationsPluginRequired' );
-    deactivate_plugins('/'.GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG.'/index.php');
+    add_action( 'admin_notices', 'glmMembersAppNotificationsPluginRequired' );
+    deactivate_plugins('/'.GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG.'/index.php');
 }
 
 // Check for Minimum DB version for main Member DB
-function glmMembersMobileNotificationsMinVerRequired() {
+function glmMembersAppNotificationsMinVerRequired() {
     echo '
         <div class="error">
-            <p>The '.GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_NAME.' requires that the main GLM Member DB plugin version be no older than '
-                    .GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION.'!<br>
-                    '.GLM_MEMBERS_MOBILE_NOTIFICATIONS_MIN_VERSION_NOTE.'</p>
-            <p>The '.GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_NAME.' plugin has been de-activated.</p>
+            <p>The '.GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_NAME.' requires that the main GLM Member DB plugin version be no older than '
+                    .GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION.'!<br>
+                    '.GLM_MEMBERS_APP_NOTIFICATIONS_MIN_VERSION_NOTE.'</p>
+            <p>The '.GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_NAME.' plugin has been de-activated.</p>
         </div>
     ';
 }
 $glmMembersDatabasePluginVersion = get_option('glmMembersDatabasePluginVersion');
-if (version_compare($glmMembersDatabasePluginVersion, GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION) < 0) {
-    define('GLM_MEMBERS_MOBILE_NOTIFICATIONS_MIN_VERSION_NOTE', "Members DB: $glmMembersDatabasePluginVersion, Mobile Notifications Requires: ".GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION);
-    add_action( 'admin_notices', 'glmMembersMobileNotificationsMinVerRequired');
-    deactivate_plugins('/'.GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG.'/'.GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG.'.php');
+if (version_compare($glmMembersDatabasePluginVersion, GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION) < 0) {
+    define('GLM_MEMBERS_APP_NOTIFICATIONS_MIN_VERSION_NOTE', "Members DB: $glmMembersDatabasePluginVersion, App Notifications Requires: ".GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION);
+    add_action( 'admin_notices', 'glmMembersAppNotificationsMinVerRequired');
+    deactivate_plugins('/'.GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG.'/'.GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG.'.php');
 }
 
 /*
  * Register this add-on with the main GLM Member DB plugin and get information on all add-ons loaded.
  */
-require_once GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SETUP_PATH.'/validActions.php';
-require_once GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SETUP_PATH.'/shortcodes.php';
-if (is_file(GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_DB_SCRIPTS.'/dbVersions.php')) {
-    require_once GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_DB_SCRIPTS.'/dbVersions.php';
+require_once GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SETUP_PATH.'/validActions.php';
+require_once GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SETUP_PATH.'/shortcodes.php';
+if (is_file(GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_DB_SCRIPTS.'/dbVersions.php')) {
+    require_once GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_DB_SCRIPTS.'/dbVersions.php';
 }
 
 /*
@@ -152,62 +152,62 @@ if (is_file(GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_DB_SCRIPTS.'/dbVersions.php'
  */
 
 // Management
-// $glmMembersMobileNotificationsManagementSettings = $wpdb->get_row( "SELECT * FROM ".GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_DB_PREFIX."management WHERE id = 1", ARRAY_A );
-// unset($glmMembersMobileNotificationsManagementSettings['id']);
+// $glmMembersAppNotificationsManagementSettings = $wpdb->get_row( "SELECT * FROM ".GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_DB_PREFIX."management WHERE id = 1", ARRAY_A );
+// unset($glmMembersAppNotificationsManagementSettings['id']);
 
 // Settings
-// $glmMembersMobileNotificationsSettingsTerms = $wpdb->get_row( "SELECT * FROM ".GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_DB_PREFIX."settings_terms WHERE id = 1", ARRAY_A );
-// unset($glmMembersMobileNotificationsSettingsTerms['id']);
+// $glmMembersAppNotificationsSettingsTerms = $wpdb->get_row( "SELECT * FROM ".GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_DB_PREFIX."settings_terms WHERE id = 1", ARRAY_A );
+// unset($glmMembersAppNotificationsSettingsTerms['id']);
 
 
 
-function glmMembersMobileNotificationsRegisterAddOn($addOns) {
+function glmMembersAppNotificationsRegisterAddOn($addOns) {
 
     // Add this add-on to the add-ons array
-    $addOns[GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG] =  array(
-        'dir' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PATH,
-        'name' =>  GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_NAME,
-        'short_name' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SHORT_NAME,
-        'slug' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG,
-        'actions' => $GLOBALS['glmMembersMobileNotificationsAddOnValidActions'],
+    $addOns[GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG] =  array(
+        'dir' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PATH,
+        'name' =>  GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_NAME,
+        'short_name' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SHORT_NAME,
+        'slug' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG,
+        'actions' => $GLOBALS['glmMembersAppNotificationsAddOnValidActions'],
         'config' => array(
-//            'settings' => $GLOBALS['glmMembersMobileNotificationsManagementSettings'],
-//            'terms' => $GLOBALS['glmMembersMobileNotificationsSettingsTerms']
+//            'settings' => $GLOBALS['glmMembersAppNotificationsManagementSettings'],
+//            'terms' => $GLOBALS['glmMembersAppNotificationsSettingsTerms']
         ),
-        'shortcodes' => $GLOBALS['glmMembersMobileNotificationsShortcodes'],
-        'shortcodesDescription' => $GLOBALS['glmMembersMobileNotificationsShortcodesDescription']
+        'shortcodes' => $GLOBALS['glmMembersAppNotificationsShortcodes'],
+        'shortcodesDescription' => $GLOBALS['glmMembersAppNotificationsShortcodesDescription']
     );
 
     // If we have database tables for this plugin/addon, provide that data also
-    if (isset($GLOBALS['glmMembersMobileNotificationsDbVersions'])) {
-        $addOns[GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG]['database'] = array(
-            'dbPrefix' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_DB_PREFIX,
-            'dbCurrentVersion' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_DB_VERSION,
-            'dbActiveVersionOption' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_ACTIVE_DB_OPTION,
-            'dbScriptPath' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_DB_SCRIPTS,
-            'dbVersions' => $GLOBALS['glmMembersMobileNotificationsDbVersions']
+    if (isset($GLOBALS['glmMembersAppNotificationsDbVersions'])) {
+        $addOns[GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG]['database'] = array(
+            'dbPrefix' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_DB_PREFIX,
+            'dbCurrentVersion' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_DB_VERSION,
+            'dbActiveVersionOption' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_ACTIVE_DB_OPTION,
+            'dbScriptPath' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_DB_SCRIPTS,
+            'dbVersions' => $GLOBALS['glmMembersAppNotificationsDbVersions']
         );
     } else {
-        $addOns[GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG]['database'] = false;
+        $addOns[GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG]['database'] = false;
     }
 
     // Return the array with our data added
     return $addOns;
 }
-add_filter('glm-member-db-register-addon','glmMembersMobileNotificationsRegisterAddOn', 10, 1);
+add_filter('glm-member-db-register-addon','glmMembersAppNotificationsRegisterAddOn', 10, 1);
 
 /*
  * Plugin Update Support - uses Gaslight Media update server
  */
 /* Not functional yet - Need to resolve JavaScript conflicts with this feature in other plugins
-require GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_LIB_PATH.'/opentools-update-checker/opentools-update-checker.php';
-${GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PREFIX."updateChecker"} = new OpenToolsPluginUpdateChecker(
-     'http://www.gaslightmedia.com/update_server/?action=get_metadata&slug='.GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG,
+require GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_LIB_PATH.'/opentools-update-checker/opentools-update-checker.php';
+${GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PREFIX."updateChecker"} = new OpenToolsPluginUpdateChecker(
+     'http://www.gaslightmedia.com/update_server/?action=get_metadata&slug='.GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG,
     __FILE__,
-    GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG
+    GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG
 );
 
-${GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PREFIX."updateChecker"}->declareCredentials(array(
+${GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PREFIX."updateChecker"}->declareCredentials(array(
   'license_key' => __('License Key:')
 ));
 */
@@ -219,26 +219,26 @@ ${GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PREFIX."updateChecker"}->declareCreden
  */
 
  // Activate
- function glmMembersMobileNotificationsPluginActivate ()
+ function glmMembersAppNotificationsPluginActivate ()
  {
      global $wpdb, $config;
-     require_once GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PATH . '/activate.php';
-     new glmMembersMobileNotificationsPluginActivate($wpdb, $config);
+     require_once GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PATH . '/activate.php';
+     new glmMembersAppNotificationsPluginActivate($wpdb, $config);
  }
- register_activation_hook(__FILE__, 'glmMembersMobileNotificationsPluginActivate');
+ register_activation_hook(__FILE__, 'glmMembersAppNotificationsPluginActivate');
 
  // Deactivate
- function glmMembersMobileNotificationsPluginDeactivate ()
+ function glmMembersAppNotificationsPluginDeactivate ()
  {
      global $wpdb, $config;
-     require_once GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PATH . '/deactivate.php';
-     $x = new glmMembersMobileNotificationsPluginDeactivate($wpdb, $config);
+     require_once GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PATH . '/deactivate.php';
+     $x = new glmMembersAppNotificationsPluginDeactivate($wpdb, $config);
      return false;
  }
- register_deactivation_hook(__FILE__, 'glmMembersMobileNotificationsPluginDeactivate');
+ register_deactivation_hook(__FILE__, 'glmMembersAppNotificationsPluginDeactivate');
 
 /*
  * Hooks for testing capabilities provided by this add-on
  */
-require_once GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SETUP_PATH.'/permissions.php';
+require_once GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SETUP_PATH.'/permissions.php';
 
index ec2a22c..d0945ee 100644 (file)
@@ -42,10 +42,10 @@ export default {
                     imgIdInput.val(attachment.id);
 
                     // Hide the add image link
-                    addImgLink.addClass('hidden');
+                    addImgLink.addClass('hide');
 
                     // Unhide the remove image link
-                    delImgLink.removeClass('hidden');
+                    delImgLink.removeClass('hide');
                 });
 
                 // Finally, open the modal on click
@@ -62,10 +62,10 @@ export default {
                 imgContainer.html('');
 
                 // Un-hide the add image link
-                addImgLink.removeClass('hidden');
+                addImgLink.removeClass('hide');
 
                 // Hide the delete image link
-                delImgLink.addClass('hidden');
+                delImgLink.addClass('hide');
 
                 // Delete the image id from the hidden input
                 imgIdInput.val('');
index 11d769a..dd47395 100755 (executable)
@@ -11,7 +11,7 @@ import Routes from '../functional/Routes';
 
 const useStyles = makeStyles(theme => ({
     root: {
-      padding: theme.spacing(3, 2),
+      padding: theme.spacing(2, 2),
       width: '100%',
       height: '100%',
     }
@@ -35,7 +35,7 @@ const DashboardContainer = () => {
     });
     
     return (
-        <Paper id="glma-notifications-dashboard">
+        <Paper id="glma-notifications-dashboard" className={[classes.root]}>
             <Routes />
         </Paper>
     )
index a892a2a..6bbd1c6 100755 (executable)
@@ -32,20 +32,34 @@ const useStyles = makeStyles(theme => ({
                width: 200,
        },
        formControl: {
-               margin: theme.spacing(1),
+               margin: theme.spacing(2, 1),
                minWidth: 120,
        },
        selectEmpty: {
                marginTop: theme.spacing(2),
        },
        button: {
-               margin: theme.spacing(1),
+               margin: theme.spacing(0, 2),
                color: "white",
-               background: "#0568B3"
+               background: "#0568B3",
+               width: "150px"
+       },
+       bottom: {
+               position: "absolute",
+               bottom: "-25px",
+               left: "43%",
+               transform: "translateX(-50%)"
        },
        input: {
                display: 'none',
        },
+       hide: {
+               display: "none !important"
+       },
+       removeButton: {
+               background: "#F44336",
+               float: "right"
+       }
 }));
 
 const NewNotification = (props) => {
@@ -71,14 +85,7 @@ const NewNotification = (props) => {
        }
        return (
                <React.Fragment>
-                       <TextField
-                               id="outlined-search"
-                               label="Notification Headline"
-                               type="search"
-                               className={classes.textField}
-                               margin="normal"
-                               variant="outlined"
-                       />
+       
                        
                        <FormControl variant="outlined" className={classes.formControl}>
                                <InputLabel ref={inputLabel} htmlFor="outlined-age-simple">
@@ -98,11 +105,20 @@ const NewNotification = (props) => {
                                        <MenuItem value={30}>Thirty</MenuItem>
                                </Select>
                        </FormControl>
-                       <div id="glm-message-image-container">
+                       <span id="glm-message-image-container" className={[classes.formControl]} style={{display: "inline-block", position:"relative"}}>
                                <Button variant="contained" className={["upload-custom-img", classes.button]}>Add Image</Button>
                                <ImageContainer />
-                               <Button variant="contained" className={["hidden","delete-custom-img", classes.button]}>Remove Image</Button>
-                       </div>
+                               <Button variant="contained" className={[classes.bottom,"hide","delete-custom-img", classes.button, classes.removeButton]}>Remove Image</Button>
+                       </span>
+                       <TextField
+                               id="outlined-search"
+                               label="Notification Headline"
+                               type="search"
+                               className={classes.textField}
+                               margin="normal"
+                               variant="outlined"
+                               style={{width: "50%", display: "flex"}}
+                       />
                        <TextField
                                id="outlined-search"
                                label="Notification Message"
@@ -115,6 +131,7 @@ const NewNotification = (props) => {
                                rowsMax={4}
                                fullWidth
                        />
+
                </React.Fragment>
        )
 }
index 31f424a..a994548 100644 (file)
@@ -5,8 +5,9 @@ export default (props) => {
     const width = (props.width) ? props.width : "200px";
     const imageContainerStyles = {
         width: width,
+        display: "inline-block"
     }
     return (
-        <div style={imageContainerStyles} className="custom-img-container"></div>
+        <span style={imageContainerStyles} className="custom-img-container"></span>
     )
 }
\ No newline at end of file
index b4696a1..49208ce 100755 (executable)
@@ -2,4 +2,4 @@ import React from 'react';
 import ReactDOM from 'react-dom';
 import Controller from './components/Controller.jsx';
 
-ReactDOM.render(<Controller />, document.getElementById('glma-mobile-notifications-mount'));
\ No newline at end of file
+ReactDOM.render(<Controller />, document.getElementById('glma-app-notifications-mount'));
\ No newline at end of file
index e9fcacb..ca8968a 100755 (executable)
@@ -93,11 +93,11 @@ class GlmMembersAdmin_init_index
      *
      */
     public function modelAction ( $actionData = false ){
-        wp_register_script( 'glma_admin_js', GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_URL.'dist/js/glma-mobile-notifications.js' , false, '1.0.0' );
+        wp_register_script( 'glma_admin_js', GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_URL.'dist/js/glma-app-notifications.js' , false, '1.0.0' );
         wp_enqueue_script( 'glma_admin_js' );
-        wp_register_style( 'glma_admin_css', GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_URL.'dist/css/lib.min.css');
+        wp_register_style( 'glma_admin_css', GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_URL.'dist/css/lib.min.css');
         wp_enqueue_style( 'glma_admin_css' );
-        wp_register_style( 'glma_admin_lib_css',GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_URL.'dist/css/glma-mobile-notifications.min.css');
+        wp_register_style( 'glma_admin_lib_css',GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_URL.'dist/css/glma-app-notifications.min.css');
         wp_enqueue_style( 'glma_admin_lib_css' );
         wp_enqueue_media( );
         // Compile template data.
@@ -107,7 +107,7 @@ class GlmMembersAdmin_init_index
 
         // Return status, suggested view, and data to controller.
         return array(
-            'status'           => $success,
+            'status'           => true,
             'menuItemRedirect' => false,
             'modelRedirect'    => false,
             'view'             => 'admin/init/index.html',
index 97a9a49..65105bb 100755 (executable)
@@ -1,5 +1,5 @@
 {
-    "name": "glm-member-db-mobile-notifications",
+    "name": "glm-member-db-app-notifications",
     "version": "1.0.0",
     "lockfileVersion": 1,
     "requires": true,
index 3e80429..841ce4e 100755 (executable)
@@ -1,5 +1,5 @@
 {
-    "name": "glm-member-db-mobile-notifications",
+    "name": "glm-member-db-app-notifications",
     "version": "1.0.0",
     "description": "A GLM Package",
     "scripts": {
index 78066bd..15dc0ed 100755 (executable)
@@ -1,18 +1,18 @@
-=== GLMA Mobile Notifications ===
+=== GLMA App Notifications ===
 Contributors: cscott@gaslightmedia.com
 Donate link: http://www.gaslightmedia.com
-Tags: Gaslight Media,Plugin,Mobile Notifications
+Tags: Gaslight Media,Plugin,App Notifications
 Requires at least: 3.0.1
 Tested up to: 3.4
 Stable tag: 4.3
 License: GPLv2 or later
 License URI: http://www.gnu.org/licenses/gpl-2.0.html
 
-This is the GLMA Mobile Notifications.
+This is the GLMA App Notifications.
 
 == Description ==
 
-The GLMA Mobile Notifications is an add-on to the Gaslight Media Members Database,
+The GLMA App Notifications is an add-on to the Gaslight Media Members Database,
 which is required to install and run this plugin
 
 == Installation ==
index 34a23f9..61826fd 100755 (executable)
@@ -2,7 +2,7 @@
     * {
         // box-sizing: border-box;
     }
-    #glma-mobile-notifications-mount{
+    #glma-app-notifications-mount{
         padding-top: 60px;
         #glma-notifications-container{
             height: 78vh;
index 9210b65..c0844f6 100755 (executable)
@@ -9,4 +9,7 @@
 }
 .active-link{
     background: rgba(0, 0, 0, 0.2);
+}
+.hide{
+    display: none !important;
 }
\ No newline at end of file
index efc3d14..dea9e9c 100755 (executable)
@@ -1,6 +1,6 @@
 <?php
 /**
- * GLMA Mobile Notifications
+ * GLMA App Notifications
  * GLM Members Misc Admin Hooks and Filters
  *
  * PHP version 5.5
@@ -30,7 +30,7 @@
 add_filter('glm-member-db-admin-management-hooksHelp', function($content) {
 
         // Read in this plugin/addon hook help file
-        $fname = GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_PATH.'/setup/hooksHelp.html';
+        $fname = GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_PATH.'/setup/hooksHelp.html';
         if (is_file($fname)) {
             $hooksHelp = file_get_contents($fname);
             if ($hooksHelp != false) {
index dddaefe..7285918 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /**
- * GLMA Mobile Notifications
- * GLM Members DB - Mobile Notifications - Admin Menus
+ * GLMA App Notifications
+ * GLM Members DB - App Notifications - Admin Menus
  *
  * PHP version 5.5
  *
@@ -53,8 +53,8 @@
 if (isset($this->config['loggedInUser']) && isset($this->config['loggedInUser']['contactUser']) && $this->config['loggedInUser']['contactUser']) {
     add_submenu_page(
         $mainMenuSlug,                   // Parent slug
-        'Mobile Notifications',                              // Page title
-        'Mobile Notifications',                             // Menu Title
+        'App Notifications',                              // Page title
+        'App Notifications',                             // Menu Title
         'glm_members_edit_my_entity',                                 // Capability required
         'glm-members-admin-menu-init-index',                    // Menu slug
         function() {$this->controller('init', 'index');}
@@ -65,8 +65,8 @@ if (isset($this->config['loggedInUser']) && isset($this->config['loggedInUser'][
 
     add_submenu_page(
         $mainMenuSlug,                   // Parent slug
-        'Mobile Notifications',                              // Page title
-        'Mobile Notifications',                             // Menu Title
+        'App Notifications',                              // Page title
+        'App Notifications',                             // Menu Title
         'glm_members_members',                                 // Capability required
         'glm-members-admin-menu-init-index',                    // Menu slug
         function() {$this->controller('init', 'index');}
index 9145633..2210441 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /**
- * GLMA Mobile Notifications
- * GLM Members DB - Mobile Notifications - Admin Tabs
+ * GLMA App Notifications
+ * GLM Members DB - App Notifications - Admin Tabs
  *
  * PHP version 5.5
  *
diff --git a/setup/databaseScripts/create_database_V0.0.1.sql b/setup/databaseScripts/create_database_V0.0.1.sql
new file mode 100755 (executable)
index 0000000..aa69161
--- /dev/null
@@ -0,0 +1,24 @@
+-- Gaslight Media Members Database App Notifications
+-- File Created: 12/29/16 12:06:00
+-- Database Version: 0.0.1
+-- Database Creation Script
+--
+-- To permit each query below to be executed separately,
+-- all queries must be separated by a line with four dashes
+--
+-- **** BE SURE TO ALSO UPDATE drop_database_Vxxx.sql FILE WHEN CHANGING TABLES ****
+--
+
+-- Notifications
+CREATE TABLE {prefix}notifications (
+  id INT NOT NULL AUTO_INCREMENT,
+  member_id INT NULL,                         -- Associated member id
+  notification_headline TEXT NULL,            -- Header / Subject of the notification
+  notification_body TEXT NULL,                -- Notification contents
+  notification_image TEXT NULL,           -- Optional attached image to the notification.
+  notification_type INT NULL,                 -- Type of notification: Event, Location, Promotional Deal
+  type_category TEXT NULL,                    -- Category associated with the type: Event category, member category, package category
+  notification_status TINYTEXT NULL,           -- Status for "Sent, Draft or Trashed"
+  notification_date DATETIME NULL,                         -- Date the notification was created
+  PRIMARY KEY (id)
+);
\ No newline at end of file
diff --git a/setup/databaseScripts/dbVersions.php b/setup/databaseScripts/dbVersions.php
new file mode 100755 (executable)
index 0000000..0efee82
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Gaslight Media Members Database
+ * GLM Members Packaging DB Versions
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  dbVersions.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/**
+ * Database Versions
+ *
+ * *** PLEASE NOW INCLUDE A DATE FOR EACH DATABASE VERSION ***
+ *  '1.1.2' => array('version' => '1.1.2', 'tables' => 14, 'date' => '4/11/16')
+ *
+ * An array of past and current Member Database versions.
+ *
+ * Each entry below uses a key so code can find data on
+ * a specific version and in the values are the version
+ * again and the proper number of tables that should
+ * exist with that version.
+ */
+
+$glmMembersAppNotificationsDbVersions = array(
+    '0.0.1' => array('version' => '0.0.1', 'tables' => 1,'date' => '7/24/19'),
+);
diff --git a/setup/databaseScripts/drop_database_V0.0.1.sql b/setup/databaseScripts/drop_database_V0.0.1.sql
new file mode 100755 (executable)
index 0000000..059ff5f
--- /dev/null
@@ -0,0 +1,8 @@
+-- Gaslight Media Members Database
+-- File Created: 12/09/14 15:27:15
+-- Database Version: 0.0.1
+-- Database Deletion Script
+-- Note: Tables with DELETE CASCADE must appear before referenced table
+
+DROP TABLE IF EXISTS
+    {prefix}notifications;
\ No newline at end of file
diff --git a/setup/databaseScripts/readme.txt b/setup/databaseScripts/readme.txt
new file mode 100755 (executable)
index 0000000..f1c238e
--- /dev/null
@@ -0,0 +1,44 @@
+This directory contains database creation and update scripts for this add-on.
+
+The files in this directory are checked by the glmCheckDatabase() function in the
+main plugin classes/glmPluginSupport.php file.
+
+This directory is optional. If there are no data tables that need to be created
+for this add-on, there should be no files in this directory. The directory may
+also be deleted. 
+
+See the "examples" directory for a sample of what can go in this directory.
+Procedure to update database
+-----------------------------
+
+0) Make a backup copy of the site's database.
+
+1) Rename "create_database_Vx.x.x.sql" to new version number.
+    example: create_database_V0.0.9.sql -> create_database_V0.0.10.sql
+
+2) Edit renamed create database file and make desired changes
+
+3) Add a new "update_database_Vx.x.x.sql" named with the correct version #.
+
+4) Edit new update database files with SQL script to make the necessary changes
+   from the previous version to the new version. (i.e. to add new fields,
+   rename fields, insert records, ...)
+
+5) Optionally add an "update_database_Vx.x.x.php" file if PHP scripting is
+   needed to update database content. (i.e. to make changes to database content)
+
+6) Edit the "dbVersions.php" file and add a new line for the new version.
+   *** Now please be sure to add a date for each entry ***
+   i.e. '1.1.2' => array('version' => '1.1.2', 'tables' => 14, 'date' => '4/11/16')
+
+7) When this is all done, edit the index.php file for the plugin/add-on and 
+   change "GLM_MEMBERS_{addon}_PLUGIN_DB_VERSION" defined parameter where
+   {addon} is the add-on name.
+
+8) Go to an admin menu item for the main member db plugin or any add-on. If all
+   goes well, the main plugin should have detected the change and updated the
+   database. If not, restore the database and try again.
+
+9) Check the database to make sure the changes to fields and data are correct.
+
+10) Rename the drop_database_Vx.x.x.sql to new version number (same as create)
index 24a2798..059b755 100755 (executable)
@@ -1,6 +1,6 @@
 <?php
 /**
- * GLMA Mobile Notifications
+ * GLMA App Notifications
  * Misc Hooks and Filters
  *
  * PHP version 5.5
index 3b8f14d..2e7f72f 100755 (executable)
@@ -1,12 +1,12 @@
 <?php
 /**
- * GLMA Mobile Notifications
+ * GLMA App Notifications
  * Roles & Capabilities
  *
  * PHP version 5.5
  *
  * @category glmWordPressPlugin
- * @package  glmMembersMobileNotifications
+ * @package  glmMembersAppNotifications
  * @author   Chuck Scott <cscott@gaslightmedia.com>
  * @license  http://www.gaslightmedia.com Gaslightmedia
  * @release  rolesAndPermissions.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
index 20a6af9..637a4dd 100755 (executable)
@@ -1,12 +1,12 @@
 <?php
 /**
- * GLMA Mobile Notifications
+ * GLMA App Notifications
  * Short Codes
  *
  * PHP version 5.5
  *
  * @category glmWordPressPlugin
- * @package  glmMembersMobileNotifications
+ * @package  glmMembersAppNotifications
  * @author   Chuck Scott <cscott@gaslightmedia.com>
  * @license  http://www.gaslightmedia.com Gaslightmedia
  * @release  shortcodes.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
@@ -87,8 +87,8 @@
  *       </tr>
  */
 
-$glmMembersMobileNotificationsShortcodes = array(
+$glmMembersAppNotificationsShortcodes = array(
 );
 
-$glmMembersMobileNotificationsShortcodesDescription = '';
+$glmMembersAppNotificationsShortcodesDescription = '';
 
index ed53bb0..28a00c0 100755 (executable)
@@ -1,12 +1,12 @@
 <?php
 /**
- * GLMA Mobile Notifications
+ * GLMA App Notifications
  * Valid Actions
  *
  * PHP version 5.5
  *
  * @category glmWordPressPlugin
- * @package  glmMembersMobileNotifications
+ * @package  glmMembersAppNotifications
  * @author   Chuck Scott <cscott@gaslightmedia.com>
  * @license  http://www.gaslightmedia.com Gaslightmedia
  * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
  *
  * EXAMPLE
  *
- * $glmMembersMobileNotificationsAddOnValidActions = array(
+ * $glmMembersAppNotificationsAddOnValidActions = array(
  *     'adminActions' => array(
  *         'members' => array(
- *             'sample' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG,
+ *             'sample' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG,
  *         ),
  *         'sample' => array(
- *             'index' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG,
- *             'more' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG,
+ *             'index' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG,
+ *             'more' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG,
  *         ),
  *         'info' => array(
- *             'index' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG
+ *             'index' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG
  *         )
  *     ),
  *     'frontActions' => array(
  *         'sample' => array(
- *             'list' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG,
- *             'detail' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG
+ *             'list' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG,
+ *             'detail' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG
  *         )
  *     )
  * );
  *
  */
 
-$glmMembersMobileNotificationsAddOnValidActions = array(
+$glmMembersAppNotificationsAddOnValidActions = array(
     'adminActions' => array(
         'ajax' => array(
-            'requests' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG
+            'requests' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG
         ),
         'init' => array(
-            'index' => GLM_MEMBERS_MOBILE_NOTIFICATIONS_PLUGIN_SLUG
+            'index' => GLM_MEMBERS_APP_NOTIFICATIONS_PLUGIN_SLUG
         )
     ),
     'frontActions' => array(
index 2d1ceab..c91d763 100755 (executable)
@@ -3,13 +3,13 @@
 die('uninstall not configured - See plugin uninstall.php script!');
 
 /**
- * GLMA Mobile Notifications
+ * GLMA App Notifications
  * Uninstall Plugin
  *
  * PHP version 5.5
  *
  * @category glmWordPressPlugin
- * @package  glmMembersMobileNotifications
+ * @package  glmMembersAppNotifications
  * @author   Chuck Scott <cscott@gaslightmedia.com>
  * @license  http://www.gaslightmedia.com Gaslightmedia
  * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
index b72f742..6a85973 100755 (executable)
@@ -1 +1 @@
-<div id="glma-mobile-notifications-mount"></div>
\ No newline at end of file
+<div id="glma-app-notifications-mount"></div>
\ No newline at end of file
index f334899..6f7a80c 100755 (executable)
@@ -13,7 +13,7 @@ var config = {
        },
        output: {
                path: APP_DIR,
-               filename: 'glma-mobile-notifications.js'
+               filename: 'glma-app-notifications.js'
        },
        module: {
                rules: [