├── .babelrc ├── .eslintrc ├── .gitignore ├── LICENSE ├── README.md ├── dist ├── jquery.dashboard.core.js ├── jquery.dashboard.core.js.map ├── jquery.dashboard.core.min.js ├── jquery.dashboard.jqueryui.js ├── jquery.dashboard.jqueryui.js.map ├── jquery.dashboard.jqueryui.min.js ├── jquery.dashboard.samples.js ├── jquery.dashboard.samples.js.map ├── jquery.dashboard.samples.min.js ├── jquery.dashboard.templates.js ├── jquery.dashboard.templates.js.map └── jquery.dashboard.templates.min.js ├── docs └── index.html ├── package.json ├── src └── modules │ ├── core │ ├── index.js │ ├── services │ │ ├── DataService.js │ │ ├── LocalStorageDataService.js │ │ └── Service.js │ └── widgets │ │ └── Widget.js │ ├── jquery-ui │ ├── functions │ │ ├── fClassList.js │ │ └── fListGroupFilter.js │ ├── handlebars │ │ ├── addWidgetsDialog.handlebars │ │ └── listGroupItem.handlebars │ ├── index.js │ └── views │ │ ├── AddWidgetsDialog.js │ │ └── DashboardView.js │ ├── samples │ ├── handlebars │ │ ├── widgetChuckNorris.handlebars │ │ └── widgetChuckNorrisConfiguration.handlebars │ ├── index.js │ └── widgets │ │ └── ChuckWidget.js │ └── templates │ ├── handlebars │ ├── configurationLayout.handlebars │ └── layout.handlebars │ └── index.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"], 3 | "plugins": ["babel-plugin-add-module-exports"] 4 | } -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "ecmaFeatures": { 3 | "globalReturn": true, 4 | "jsx": true, 5 | "modules": true 6 | }, 7 | 8 | "env": { 9 | "browser": true, 10 | "es6": true, 11 | "node": true 12 | }, 13 | 14 | "globals": { 15 | "document": false, 16 | "escape": false, 17 | "navigator": false, 18 | "unescape": false, 19 | "window": false, 20 | "describe": true, 21 | "before": true, 22 | "it": true, 23 | "expect": true, 24 | "sinon": true 25 | }, 26 | 27 | "parser": "babel-eslint", 28 | 29 | "plugins": [ 30 | 31 | ], 32 | 33 | "rules": { 34 | "block-scoped-var": 2, 35 | "brace-style": [2, "1tbs", { "allowSingleLine": true }], 36 | "camelcase": [2, { "properties": "always" }], 37 | "comma-dangle": [2, "never"], 38 | "comma-spacing": [2, { "before": false, "after": true }], 39 | "comma-style": [2, "last"], 40 | "complexity": 0, 41 | "consistent-return": 2, 42 | "consistent-this": 0, 43 | "curly": [2, "multi-line"], 44 | "default-case": 0, 45 | "dot-location": [2, "property"], 46 | "dot-notation": 0, 47 | "eol-last": 2, 48 | "eqeqeq": [2, "allow-null"], 49 | "func-names": 0, 50 | "func-style": 0, 51 | "generator-star-spacing": [2, "both"], 52 | "guard-for-in": 0, 53 | "handle-callback-err": [2, "^(err|error|anySpecificError)$" ], 54 | "indent": [2, 2, { "SwitchCase": 1 }], 55 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }], 56 | "linebreak-style": 0, 57 | "max-depth": 0, 58 | "max-len": [2, 120, 4], 59 | "max-nested-callbacks": 0, 60 | "max-params": 0, 61 | "max-statements": 0, 62 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }], 63 | "newline-after-var": [2, "always"], 64 | "new-parens": 2, 65 | "no-alert": 0, 66 | "no-array-constructor": 2, 67 | "no-bitwise": 0, 68 | "no-caller": 2, 69 | "no-catch-shadow": 0, 70 | "no-cond-assign": 2, 71 | "no-console": 0, 72 | "no-constant-condition": 0, 73 | "no-continue": 0, 74 | "no-control-regex": 2, 75 | "no-debugger": 2, 76 | "no-delete-var": 2, 77 | "no-div-regex": 0, 78 | "no-dupe-args": 2, 79 | "no-dupe-keys": 2, 80 | "no-duplicate-case": 2, 81 | "no-else-return": 2, 82 | "no-empty": 0, 83 | "no-empty-character-class": 2, 84 | "no-empty-label": 2, 85 | "no-eq-null": 0, 86 | "no-eval": 2, 87 | "no-ex-assign": 2, 88 | "no-extend-native": 2, 89 | "no-extra-bind": 2, 90 | "no-extra-boolean-cast": 2, 91 | "no-extra-parens": 0, 92 | "no-extra-semi": 0, 93 | "no-extra-strict": 0, 94 | "no-fallthrough": 2, 95 | "no-floating-decimal": 2, 96 | "no-func-assign": 2, 97 | "no-implied-eval": 2, 98 | "no-inline-comments": 0, 99 | "no-inner-declarations": [2, "functions"], 100 | "no-invalid-regexp": 2, 101 | "no-irregular-whitespace": 2, 102 | "no-iterator": 2, 103 | "no-label-var": 2, 104 | "no-labels": 2, 105 | "no-lone-blocks": 0, 106 | "no-lonely-if": 0, 107 | "no-loop-func": 0, 108 | "no-mixed-requires": 0, 109 | "no-mixed-spaces-and-tabs": [2, false], 110 | "no-multi-spaces": 2, 111 | "no-multi-str": 2, 112 | "no-multiple-empty-lines": [2, { "max": 1 }], 113 | "no-native-reassign": 2, 114 | "no-negated-in-lhs": 2, 115 | "no-nested-ternary": 0, 116 | "no-new": 2, 117 | "no-new-func": 2, 118 | "no-new-object": 2, 119 | "no-new-require": 2, 120 | "no-new-wrappers": 2, 121 | "no-obj-calls": 2, 122 | "no-octal": 2, 123 | "no-octal-escape": 2, 124 | "no-path-concat": 0, 125 | "no-plusplus": 0, 126 | "no-process-env": 0, 127 | "no-process-exit": 0, 128 | "no-proto": 2, 129 | "no-redeclare": 2, 130 | "no-regex-spaces": 2, 131 | "no-reserved-keys": 0, 132 | "no-restricted-modules": 0, 133 | "no-return-assign": 2, 134 | "no-script-url": 0, 135 | "no-self-compare": 2, 136 | "no-sequences": 2, 137 | "no-shadow": 0, 138 | "no-shadow-restricted-names": 2, 139 | "no-spaced-func": 2, 140 | "no-sparse-arrays": 2, 141 | "no-sync": 0, 142 | "no-ternary": 0, 143 | "no-throw-literal": 2, 144 | "no-trailing-spaces": 2, 145 | "no-undef": 2, 146 | "no-undef-init": 2, 147 | "no-undefined": 0, 148 | "no-underscore-dangle": 0, 149 | "no-unneeded-ternary": 2, 150 | "no-unreachable": 2, 151 | "no-unused-expressions": 0, 152 | "no-unused-vars": [2, { "vars": "all", "args": "none" }], 153 | "no-use-before-define": 2, 154 | "no-var": 0, 155 | "no-void": 0, 156 | "no-warning-comments": 0, 157 | "no-with": 2, 158 | "one-var": 0, 159 | "operator-assignment": 0, 160 | "operator-linebreak": [2, "after"], 161 | "padded-blocks": 0, 162 | "quote-props": 0, 163 | "quotes": [2, "single", "avoid-escape"], 164 | "radix": 2, 165 | "semi": [2, "always"], 166 | "semi-spacing": 0, 167 | "sort-vars": 0, 168 | "space-after-keywords": [2, "always"], 169 | "space-before-blocks": [2, "always"], 170 | "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}], 171 | "space-in-brackets": 0, 172 | "space-in-parens": [2, "never"], 173 | "space-infix-ops": 2, 174 | "space-return-throw-case": 2, 175 | "space-unary-ops": [2, { "words": true, "nonwords": false }], 176 | "spaced-comment": [2, "always"], 177 | "strict": 0, 178 | "use-isnan": 2, 179 | "valid-jsdoc": 0, 180 | "valid-typeof": 2, 181 | "vars-on-top": 2, 182 | "wrap-iife": [2, "any"], 183 | "wrap-regex": 0, 184 | "yoda": [2, "never"] 185 | } 186 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | 39 | .idea 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Benjamin Rosenberger 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jquery-dashboard 2 | 3 | Demo: see https://brosenberger.github.io/jquery-dashboard/docs/index.html 4 | 5 | This library provides a framework for showing a Jira-Like Dashboard and easy creating Widgets. 6 | 7 | **Usage** 8 | 9 | Install via npm: 10 | ```js 11 | npm install jquery-dashboard --save 12 | ``` 13 | 14 | As library embedd dependencies (e.g. with cdn links): 15 | 16 | ```html 17 | 18 | 19 | 20 | 21 | 22 | 23 | ``` 24 | 25 | and dashboard components (styles not yet included, see docs/index.html for inline styling): 26 | 27 | ```html 28 | 29 | 30 | 31 | 32 | ``` 33 | 34 | initialize components: 35 | 36 | ```js 37 | $(document).ready(function () { 38 | // initialize dashboard services 39 | var service = Dashboard.core.default(); 40 | // register sample widgets 41 | Dashboard.samples.default(service); 42 | 43 | // create dashboard view and refresh list 44 | var dashboard = $('.dashboard-sortable').dashboard({ 45 | dashboardService: service 46 | }).dashboard("refresh"); 47 | // initialize widget add dialog 48 | $('h1 .fa.fa-plus-square').dashboardWidgetDialog({ 49 | dashboardService: service, 50 | addCallback: function(widgetData) { 51 | dashboard.dashboard("addWidget", widgetData); 52 | } 53 | }); 54 | 55 | }); 56 | ``` 57 | 58 | **Creating your own Widgets** 59 | 60 | This is possible with standard require/extension mechanism like within the sample, but also without all js environment. 61 | 62 | e.g. a Welcome Widget, just showing some welcome message: 63 | 64 | ```js 65 | var WelcomeWidget = function () { 66 | this.type = WelcomeWidget.type; 67 | this.widgetTemplate= Dashboard.widgetWelcome; 68 | this.sizeConfiguration= 'col-xs-12 col-md-6'; 69 | }; 70 | WelcomeWidget.type = 'welcomeWidget'; 71 | WelcomeWidget.prototype = $.extend(Dashboard.core.Widget.prototype, { 72 | description: { 73 | title: 'Welcome Widget', 74 | description: 'Gives you a warm welcome' 75 | }, 76 | initialize: function (widgetElement) { 77 | console.log('welcome widget initialized'); 78 | } 79 | }); 80 | ``` 81 | 82 | Handlebarlayouts have to initialized when embedding as library: 83 | ```js 84 | handlebarsLayouts.register(Handlebars); 85 | Handlebars.registerPartial('widget-layout', Dashboard.templates.layout); 86 | Handlebars.registerPartial('widget-configuration-layout', Dashboard.templates.configurationLayout); 87 | ``` 88 | 89 | Register the widget within the service: 90 | ```js 91 | dashboardService.registerWidget(new WelcomeWidget()); 92 | ``` -------------------------------------------------------------------------------- /dist/jquery.dashboard.core.min.js: -------------------------------------------------------------------------------- 1 | !function(n,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("core",[],t):"object"==typeof exports?exports.core=t():(n.Dashboard=n.Dashboard||{},n.Dashboard.core=t())}(this,function(){return function(n){function t(e){if(r[e])return r[e].exports;var u=r[e]={i:e,l:!1,exports:{}};return n[e].call(u.exports,u,u.exports,t),u.l=!0,u.exports}var r={};return t.m=n,t.c=r,t.i=function(n){return n},t.d=function(n,r,e){t.o(n,r)||Object.defineProperty(n,r,{configurable:!1,enumerable:!0,get:e})},t.n=function(n){var r=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(r,"a",r),r},t.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},t.p="",t(t.s=26)}({26:function(n,t,r){"use strict";function e(){var n=new Dashboard.core.LocalStorageDataService("storage");return new Dashboard.core.Service(n)}Object.defineProperty(t,"__esModule",{value:!0});var u=r(7);Object.defineProperty(t,"Widget",{enumerable:!0,get:function(){return u.Widget}});var i=r(6);Object.defineProperty(t,"DataService",{enumerable:!0,get:function(){return i.DataService}});var o=r(27);Object.defineProperty(t,"LocalStorageDataService",{enumerable:!0,get:function(){return o.LocalStorageDataService}});var f=r(28);Object.defineProperty(t,"Service",{enumerable:!0,get:function(){return f.Service}}),t.default=e},27:function(n,t,r){"use strict";function e(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}function u(n,t){if(!n)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?n:t}function i(n,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);n.prototype=Object.create(t&&t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(n,t):n.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0}),t.LocalStorageDataService=void 0;var o=function(){function n(n,t){for(var r=0;r=this.length)for(var e=t-this.length;1+e--;)r.push(void 0);r.splice(t,0,r.splice(n,1)[0]),this._saveStoredWidgets(r)}},{key:"saveWidgetConfiguration",value:function(n,t){var r=this;return new Promise(function(e,u){var i=r._findStoredWidgets();i.forEach(function(r){r.id===n&&(r.configuration=t)}),r._saveStoredWidgets(i),e(t)})}},{key:"_findStoredWidgets",value:function(){var n=localStorage.getItem(this.storageLocation);return n=void 0===n||null===n?[]:JSON.parse(n)}},{key:"_loadStoredWidget",value:function(n){this._findStoredWidgets()}},{key:"_saveStoredWidgets",value:function(n){localStorage.setItem(this.storageLocation,JSON.stringify(n))}},{key:"_generateRandomWidgetData",value:function(n){return{id:this._generateUUID(),type:n}}},{key:"_generateUUID",value:function(){var n=(new Date).getTime();return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(t){var r=(n+16*Math.random())%16|0;return n=Math.floor(n/16),("x"==t?r:3&r|8).toString(16)})}}]),t}(f.DataService)},28:function(n,t,r){"use strict";function e(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.Service=void 0;var u=function(){function n(n,t){for(var r=0;r-1}function v(n,t,r){for(var e=-1,u=null==n?0:n.length;++e-1;);return r}function M(n,t){for(var r=n.length;r--&&k(t,n[r],0)>-1;);return r}function B(n,t){for(var r=n.length,e=0;r--;)n[r]===t&&++e;return e}function $(n){return"\\"+xr[n]}function N(n,t){return null==n?un:n[t]}function F(n){return pr.test(n)}function q(n){return vr.test(n)}function Z(n){for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}function V(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n]}),r}function K(n,t){return function(r){return n(t(r))}}function G(n,t){for(var r=-1,e=n.length,u=0,i=[];++r>>1,Bn=[["ary",kn],["bind",dn],["bindKey",yn],["curry",wn],["curryRight",mn],["flip",Wn],["partial",xn],["partialRight",jn],["rearg",Sn]],$n="[object Arguments]",Nn="[object Array]",Fn="[object AsyncFunction]",qn="[object Boolean]",Zn="[object Date]",Vn="[object DOMException]",Kn="[object Error]",Gn="[object Function]",Jn="[object GeneratorFunction]",Hn="[object Map]",Yn="[object Number]",Qn="[object Null]",Xn="[object Object]",nt="[object Proxy]",tt="[object RegExp]",rt="[object Set]",et="[object String]",ut="[object Symbol]",it="[object Undefined]",ot="[object WeakMap]",ft="[object WeakSet]",at="[object ArrayBuffer]",ct="[object DataView]",lt="[object Float32Array]",st="[object Float64Array]",ht="[object Int8Array]",pt="[object Int16Array]",vt="[object Int32Array]",_t="[object Uint8Array]",gt="[object Uint8ClampedArray]",dt="[object Uint16Array]",yt="[object Uint32Array]",bt=/\b__p \+= '';/g,wt=/\b(__p \+=) '' \+/g,mt=/(__e\(.*?\)|\b__t\)) \+\n'';/g,xt=/&(?:amp|lt|gt|quot|#39);/g,jt=/[&<>"']/g,kt=RegExp(xt.source),St=RegExp(jt.source),Wt=/<%=([\s\S]+?)%>/g,Ot=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,At=/^\w*$/,Ct=/^\./,It=/[\\^$.*+?()[\]{}|]/g,zt=RegExp(It.source),Et=/^\s+|\s+$/g,Rt=/^\s+/,Dt=/\s+$/,Pt=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Lt=/\{\n\/\* \[wrapped with (.+)\] \*/,Tt=/,? & /,Ut=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,Mt=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,Bt=/\w*$/,$t=/^[-+]0x[0-9a-f]+$/i,Nt=/^0b[01]+$/i,Ft=/^\[object .+?Constructor\]$/,qt=/^0o[0-7]+$/i,Zt=/^(?:0|[1-9]\d*)$/,Vt=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,Kt=/($^)/,Gt=/['\n\r\u2028\u2029\\]/g,Jt="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",Ht="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",Yt="["+Jt+"]",Qt="[a-z\\xdf-\\xf6\\xf8-\\xff]",Xt="[^\\ud800-\\udfff"+Ht+"\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde]",nr="\\ud83c[\\udffb-\\udfff]",tr="(?:\\ud83c[\\udde6-\\uddff]){2}",rr="[\\ud800-\\udbff][\\udc00-\\udfff]",er="[A-Z\\xc0-\\xd6\\xd8-\\xde]",ur="(?:"+Yt+"|"+nr+")?",ir="(?:\\u200d(?:"+["[^\\ud800-\\udfff]",tr,rr].join("|")+")[\\ufe0e\\ufe0f]?"+ur+")*",or="[\\ufe0e\\ufe0f]?"+ur+ir,fr="(?:"+["[\\u2700-\\u27bf]",tr,rr].join("|")+")"+or,ar="(?:"+["[^\\ud800-\\udfff]"+Yt+"?",Yt,tr,rr,"[\\ud800-\\udfff]"].join("|")+")",cr=RegExp("['’]","g"),lr=RegExp(Yt,"g"),sr=RegExp(nr+"(?="+nr+")|"+ar+or,"g"),hr=RegExp([er+"?"+Qt+"+(?:['’](?:d|ll|m|re|s|t|ve))?(?="+["["+Ht+"]",er,"$"].join("|")+")","(?:"+er+"|"+Xt+")+(?:['’](?:D|LL|M|RE|S|T|VE))?(?="+["["+Ht+"]",er+"(?:"+Qt+"|"+Xt+")","$"].join("|")+")",er+"?(?:"+Qt+"|"+Xt+")+(?:['’](?:d|ll|m|re|s|t|ve))?",er+"+(?:['’](?:D|LL|M|RE|S|T|VE))?","\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)","\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)","\\d+",fr].join("|"),"g"),pr=RegExp("[\\u200d\\ud800-\\udfff"+Jt+"\\ufe0e\\ufe0f]"),vr=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,_r=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],gr=-1,dr={};dr[lt]=dr[st]=dr[ht]=dr[pt]=dr[vt]=dr[_t]=dr[gt]=dr[dt]=dr[yt]=!0,dr[$n]=dr[Nn]=dr[at]=dr[qn]=dr[ct]=dr[Zn]=dr[Kn]=dr[Gn]=dr[Hn]=dr[Yn]=dr[Xn]=dr[tt]=dr[rt]=dr[et]=dr[ot]=!1;var yr={};yr[$n]=yr[Nn]=yr[at]=yr[ct]=yr[qn]=yr[Zn]=yr[lt]=yr[st]=yr[ht]=yr[pt]=yr[vt]=yr[Hn]=yr[Yn]=yr[Xn]=yr[tt]=yr[rt]=yr[et]=yr[ut]=yr[_t]=yr[gt]=yr[dt]=yr[yt]=!0,yr[Kn]=yr[Gn]=yr[ot]=!1;var br={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"},wr={"&":"&","<":"<",">":">",'"':""","'":"'"},mr={"&":"&","<":"<",">":">",""":'"',"'":"'"},xr={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},jr=parseFloat,kr=parseInt,Sr="object"==typeof n&&n&&n.Object===Object&&n,Wr="object"==typeof self&&self&&self.Object===Object&&self,Or=Sr||Wr||Function("return this")(),Ar="object"==typeof t&&t&&!t.nodeType&&t,Cr=Ar&&"object"==typeof e&&e&&!e.nodeType&&e,Ir=Cr&&Cr.exports===Ar,zr=Ir&&Sr.process,Er=function(){try{return zr&&zr.binding&&zr.binding("util")}catch(n){}}(),Rr=Er&&Er.isArrayBuffer,Dr=Er&&Er.isDate,Pr=Er&&Er.isMap,Lr=Er&&Er.isRegExp,Tr=Er&&Er.isSet,Ur=Er&&Er.isTypedArray,Mr=A("length"),Br=C(br),$r=C(wr),Nr=C(mr),Fr=function n(t){function r(n){if(ra(n)&&!ph(n)&&!(n instanceof w)){if(n instanceof u)return n;if(pl.call(n,"__wrapped__"))return Yi(n)}return new u(n)}function e(){}function u(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=un}function w(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=Tn,this.__views__=[]}function C(){var n=new w(this.__wrapped__);return n.__actions__=Ru(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Ru(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Ru(this.__views__),n}function Y(){if(this.__filtered__){var n=new w(this);n.__dir__=-1,n.__filtered__=!0}else n=this.clone(),n.__dir__*=-1;return n}function tn(){var n=this.__wrapped__.value(),t=this.__dir__,r=ph(n),e=t<0,u=r?n.length:0,i=xi(0,u,this.__views__),o=i.start,f=i.end,a=f-o,c=e?f:o-1,l=this.__iteratees__,s=l.length,h=0,p=Fl(a,this.__takeCount__);if(!r||!e&&u==a&&p==a)return vu(n,this.__actions__);var v=[];n:for(;a--&&h-1}function ur(n,t){var r=this.__data__,e=Vr(r,n);return e<0?(++this.size,r.push([n,t])):r[e][1]=t,this}function ir(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t=t?n:t)),n}function Xr(n,t,r,e,u,i){var o,f=t&hn,a=t&pn,l=t&vn;if(r&&(o=u?r(n,e,u,i):r(n)),o!==un)return o;if(!ta(n))return n;var s=ph(n);if(s){if(o=Si(n),!f)return Ru(n,o)}else{var h=js(n),p=h==Gn||h==Jn;if(_h(n))return mu(n,f);if(h==Xn||h==$n||p&&!u){if(o=a||p?{}:Wi(n),!f)return a?Lu(n,Jr(o,n)):Pu(n,Gr(o,n))}else{if(!yr[h])return u?n:{};o=Oi(n,h,Xr,f)}}i||(i=new wr);var v=i.get(n);if(v)return v;i.set(n,o);var _=l?a?vi:pi:a?Ua:Ta,g=s?un:_(n);return c(g||n,function(e,u){g&&(u=e,e=n[u]),Zr(o,u,Xr(e,t,r,u,n,i))}),o}function ne(n){var t=Ta(n);return function(r){return te(r,n,t)}}function te(n,t,r){var e=r.length;if(null==n)return!e;for(n=ul(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===un&&!(u in n)||!i(o))return!1}return!0}function re(n,t,r){if("function"!=typeof n)throw new fl(an);return Ws(function(){n.apply(un,r)},t)}function ee(n,t,r,e){var u=-1,i=p,o=!0,f=n.length,a=[],c=t.length;if(!f)return a;r&&(t=_(t,P(r))),e?(i=v,o=!1):t.length>=on&&(i=T,o=!1,t=new pr(t));n:for(;++uu?0:u+r),e=e===un||e>u?u:ba(e),e<0&&(e+=u),e=r>e?0:wa(e);r0&&r(f)?t>1?ae(f,t-1,r,e,u):g(u,f):e||(u[u.length]=f)}return u}function ce(n,t){return n&&ps(n,t,Ta)}function le(n,t){return n&&vs(n,t,Ta)}function se(n,t){return h(t,function(t){return Qf(n[t])})}function he(n,t){t=bu(t,n);for(var r=0,e=t.length;null!=n&&rt}function ge(n,t){return null!=n&&pl.call(n,t)}function de(n,t){return null!=n&&t in ul(n)}function ye(n,t,r){return n>=Fl(t,r)&&n=120&&l.length>=120)?new pr(o&&l):un}l=n[0];var s=-1,h=f[0];n:for(;++s-1;)f!==n&&Ol.call(f,a,1),Ol.call(n,a,1);return n}function Ge(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r];if(r==e||u!==i){var i=u;Ii(u)?Ol.call(n,u,1):su(n,u)}}return n}function Je(n,t){return n+Ll(Vl()*(t-n+1))}function He(n,t,r,e){for(var u=-1,i=Nl(Pl((t-n)/(r||1)),0),o=Xc(i);i--;)o[e?i:++u]=n,n+=r;return o}function Ye(n,t){var r="";if(!n||t<1||t>Dn)return r;do{t%2&&(r+=n),(t=Ll(t/2))&&(n+=n)}while(t);return r}function Qe(n,t){return Os(Ni(n,t,Oc),n+"")}function Xe(n){return zr(Ha(n))}function nu(n,t){var r=Ha(n);return Ki(r,Qr(t,0,r.length))}function tu(n,t,r,e){if(!ta(n))return n;t=bu(t,n);for(var u=-1,i=t.length,o=i-1,f=n;null!=f&&++uu?0:u+t),r=r>u?u:r,r<0&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0;for(var i=Xc(u);++e>>1,o=n[i];null!==o&&!pa(o)&&(r?o<=t:o=on){var c=t?null:bs(n);if(c)return J(c);o=!1,u=T,a=new pr}else a=t?[]:f;n:for(;++e=e?n:eu(n,t,r)}function mu(n,t){if(t)return n.slice();var r=n.length,e=jl?jl(r):new n.constructor(r);return n.copy(e),e}function xu(n){var t=new n.constructor(n.byteLength);return new xl(t).set(new xl(n)),t}function ju(n,t){var r=t?xu(n.buffer):n.buffer;return new n.constructor(r,n.byteOffset,n.byteLength)}function ku(n,t,r){return d(t?r(V(n),hn):V(n),i,new n.constructor)}function Su(n){var t=new n.constructor(n.source,Bt.exec(n));return t.lastIndex=n.lastIndex,t}function Wu(n,t,r){return d(t?r(J(n),hn):J(n),o,new n.constructor)}function Ou(n){return as?ul(as.call(n)):{}}function Au(n,t){var r=t?xu(n.buffer):n.buffer;return new n.constructor(r,n.byteOffset,n.length)}function Cu(n,t){if(n!==t){var r=n!==un,e=null===n,u=n===n,i=pa(n),o=t!==un,f=null===t,a=t===t,c=pa(t);if(!f&&!c&&!i&&n>t||i&&o&&a&&!f&&!c||e&&o&&a||!r&&a||!u)return 1;if(!e&&!i&&!c&&n=f)return a;return a*("desc"==r[e]?-1:1)}}return n.index-t.index}function zu(n,t,r,e){for(var u=-1,i=n.length,o=r.length,f=-1,a=t.length,c=Nl(i-o,0),l=Xc(a+c),s=!e;++f1?r[u-1]:un,o=u>2?r[2]:un;for(i=n.length>3&&"function"==typeof i?(u--,i):un,o&&zi(r[0],r[1],o)&&(i=u<3?un:i,u=1),t=ul(t);++e-1?u[i?t[o]:o]:un}}function Ku(n){return hi(function(t){var r=t.length,e=r,i=u.prototype.thru;for(n&&t.reverse();e--;){var o=t[e];if("function"!=typeof o)throw new fl(an);if(i&&!f&&"wrapper"==_i(o))var f=new u([],!0)}for(e=f?e:r;++e1&&y.reverse(),s&&af))return!1;var c=i.get(n);if(c&&i.get(t))return c==t;var l=-1,s=!0,h=r&gn?new pr:un;for(i.set(n,t),i.set(t,n);++l1?"& ":"")+t[e],t=t.join(r>2?", ":" "),n.replace(Pt,"{\n/* [wrapped with "+t+"] */\n")}function Ci(n){return ph(n)||hh(n)||!!(Al&&n&&n[Al])}function Ii(n,t){return!!(t=null==t?Dn:t)&&("number"==typeof n||Zt.test(n))&&n>-1&&n%1==0&&n0){if(++t>=Cn)return arguments[0]}else t=0;return n.apply(un,arguments)}}function Ki(n,t){var r=-1,e=n.length,u=e-1;for(t=t===un?e:t;++r=this.__values__.length;return{done:n,value:n?un:this.__values__[this.__index__++]}}function Qo(){return this}function Xo(n){for(var t,r=this;r instanceof e;){var u=Yi(r);u.__index__=0,u.__values__=un,t?i.__wrapped__=u:t=u;var i=u;r=r.__wrapped__}return i.__wrapped__=n,t}function nf(){var n=this.__wrapped__;if(n instanceof w){var t=n;return this.__actions__.length&&(t=new w(this)),t=t.reverse(),t.__actions__.push({func:Go,args:[ko],thisArg:un}),new u(t,this.__chain__)}return this.thru(ko)}function tf(){return vu(this.__wrapped__,this.__actions__)}function rf(n,t,r){var e=ph(n)?s:ue;return r&&zi(n,t,r)&&(t=un),e(n,di(t,3))}function ef(n,t){return(ph(n)?h:fe)(n,di(t,3))}function uf(n,t){return ae(sf(n,t),1)}function of(n,t){return ae(sf(n,t),Rn)}function ff(n,t,r){return r=r===un?1:ba(r),ae(sf(n,t),r)}function af(n,t){return(ph(n)?c:ss)(n,di(t,3))}function cf(n,t){return(ph(n)?l:hs)(n,di(t,3))}function lf(n,t,r,e){n=Ff(n)?n:Ha(n),r=r&&!e?ba(r):0;var u=n.length;return r<0&&(r=Nl(u+r,0)),ha(n)?r<=u&&n.indexOf(t,r)>-1:!!u&&k(n,t,r)>-1}function sf(n,t){return(ph(n)?_:Te)(n,di(t,3))}function hf(n,t,r,e){return null==n?[]:(ph(t)||(t=null==t?[]:[t]),r=e?un:r,ph(r)||(r=null==r?[]:[r]),Fe(n,t,r))}function pf(n,t,r){var e=ph(n)?d:I,u=arguments.length<3;return e(n,di(t,4),r,u,ss)}function vf(n,t,r){var e=ph(n)?y:I,u=arguments.length<3;return e(n,di(t,4),r,u,hs)}function _f(n,t){return(ph(n)?h:fe)(n,Cf(di(t,3)))}function gf(n){return(ph(n)?zr:Xe)(n)}function df(n,t,r){return t=(r?zi(n,t,r):t===un)?1:ba(t),(ph(n)?Er:nu)(n,t)}function yf(n){return(ph(n)?Mr:ru)(n)}function bf(n){if(null==n)return 0;if(Ff(n))return ha(n)?X(n):n.length;var t=js(n);return t==Hn||t==rt?n.size:De(n).length}function wf(n,t,r){var e=ph(n)?b:uu;return r&&zi(n,t,r)&&(t=un),e(n,di(t,3))}function mf(n,t){if("function"!=typeof t)throw new fl(an);return n=ba(n),function(){if(--n<1)return t.apply(this,arguments)}}function xf(n,t,r){return t=r?un:t,t=n&&null==t?n.length:t,ii(n,kn,un,un,un,un,t)}function jf(n,t){var r;if("function"!=typeof t)throw new fl(an);return n=ba(n),function(){return--n>0&&(r=t.apply(this,arguments)),n<=1&&(t=un),r}}function kf(n,t,r){t=r?un:t;var e=ii(n,wn,un,un,un,un,un,t);return e.placeholder=kf.placeholder,e}function Sf(n,t,r){t=r?un:t;var e=ii(n,mn,un,un,un,un,un,t);return e.placeholder=Sf.placeholder,e}function Wf(n,t,r){function e(t){var r=h,e=p;return h=p=un,y=t,_=n.apply(e,r)}function u(n){return y=n,g=Ws(f,t),b?e(n):_}function i(n){var r=n-d,e=n-y,u=t-r;return w?Fl(u,v-e):u}function o(n){var r=n-d,e=n-y;return d===un||r>=t||r<0||w&&e>=v}function f(){var n=th();if(o(n))return a(n);g=Ws(f,i(n))}function a(n){return g=un,m&&h?e(n):(h=p=un,_)}function c(){g!==un&&ys(g),y=0,h=d=p=g=un}function l(){return g===un?_:a(th())}function s(){var n=th(),r=o(n);if(h=arguments,p=this,d=n,r){if(g===un)return u(d);if(w)return g=Ws(f,t),e(d)}return g===un&&(g=Ws(f,t)),_}var h,p,v,_,g,d,y=0,b=!1,w=!1,m=!0;if("function"!=typeof n)throw new fl(an);return t=ma(t)||0,ta(r)&&(b=!!r.leading,w="maxWait"in r,v=w?Nl(ma(r.maxWait)||0,t):v,m="trailing"in r?!!r.trailing:m),s.cancel=c,s.flush=l,s}function Of(n){return ii(n,Wn)}function Af(n,t){if("function"!=typeof n||null!=t&&"function"!=typeof t)throw new fl(an);var r=function(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;if(i.has(u))return i.get(u);var o=n.apply(this,e);return r.cache=i.set(u,o)||i,o};return r.cache=new(Af.Cache||ir),r}function Cf(n){if("function"!=typeof n)throw new fl(an);return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function If(n){return jf(2,n)}function zf(n,t){if("function"!=typeof n)throw new fl(an);return t=t===un?t:ba(t),Qe(n,t)}function Ef(n,t){if("function"!=typeof n)throw new fl(an);return t=null==t?0:Nl(ba(t),0),Qe(function(r){var e=r[t],u=wu(r,0,t);return e&&g(u,e),f(n,this,u)})}function Rf(n,t,r){var e=!0,u=!0;if("function"!=typeof n)throw new fl(an);return ta(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),Wf(n,t,{leading:e,maxWait:t,trailing:u})}function Df(n){return xf(n,1)}function Pf(n,t){return fh(yu(t),n)}function Lf(){if(!arguments.length)return[];var n=arguments[0];return ph(n)?n:[n]}function Tf(n){return Xr(n,vn)}function Uf(n,t){return t="function"==typeof t?t:un,Xr(n,vn,t)}function Mf(n){return Xr(n,hn|vn)}function Bf(n,t){return t="function"==typeof t?t:un,Xr(n,hn|vn,t)}function $f(n,t){return null==t||te(n,t,Ta(t))}function Nf(n,t){return n===t||n!==n&&t!==t}function Ff(n){return null!=n&&na(n.length)&&!Qf(n)}function qf(n){return ra(n)&&Ff(n)}function Zf(n){return!0===n||!1===n||ra(n)&&ve(n)==qn}function Vf(n){return ra(n)&&1===n.nodeType&&!la(n)}function Kf(n){if(null==n)return!0;if(Ff(n)&&(ph(n)||"string"==typeof n||"function"==typeof n.splice||_h(n)||wh(n)||hh(n)))return!n.length;var t=js(n);if(t==Hn||t==rt)return!n.size;if(Li(n))return!De(n).length;for(var r in n)if(pl.call(n,r))return!1;return!0}function Gf(n,t){return Se(n,t)}function Jf(n,t,r){r="function"==typeof r?r:un;var e=r?r(n,t):un;return e===un?Se(n,t,un,r):!!e}function Hf(n){if(!ra(n))return!1;var t=ve(n);return t==Kn||t==Vn||"string"==typeof n.message&&"string"==typeof n.name&&!la(n)}function Yf(n){return"number"==typeof n&&Ml(n)}function Qf(n){if(!ta(n))return!1;var t=ve(n);return t==Gn||t==Jn||t==Fn||t==nt}function Xf(n){return"number"==typeof n&&n==ba(n)}function na(n){return"number"==typeof n&&n>-1&&n%1==0&&n<=Dn}function ta(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function ra(n){return null!=n&&"object"==typeof n}function ea(n,t){return n===t||Ae(n,t,bi(t))}function ua(n,t,r){return r="function"==typeof r?r:un,Ae(n,t,bi(t),r)}function ia(n){return ca(n)&&n!=+n}function oa(n){if(ks(n))throw new tl(fn);return Ce(n)}function fa(n){return null===n}function aa(n){return null==n}function ca(n){return"number"==typeof n||ra(n)&&ve(n)==Yn}function la(n){if(!ra(n)||ve(n)!=Xn)return!1;var t=kl(n);if(null===t)return!0;var r=pl.call(t,"constructor")&&t.constructor;return"function"==typeof r&&r instanceof r&&hl.call(r)==dl}function sa(n){return Xf(n)&&n>=-Dn&&n<=Dn}function ha(n){return"string"==typeof n||!ph(n)&&ra(n)&&ve(n)==et}function pa(n){return"symbol"==typeof n||ra(n)&&ve(n)==ut}function va(n){return n===un}function _a(n){return ra(n)&&js(n)==ot}function ga(n){return ra(n)&&ve(n)==ft}function da(n){if(!n)return[];if(Ff(n))return ha(n)?nn(n):Ru(n);if(Cl&&n[Cl])return Z(n[Cl]());var t=js(n);return(t==Hn?V:t==rt?J:Ha)(n)}function ya(n){if(!n)return 0===n?n:0;if((n=ma(n))===Rn||n===-Rn){return(n<0?-1:1)*Pn}return n===n?n:0}function ba(n){var t=ya(n),r=t%1;return t===t?r?t-r:t:0}function wa(n){return n?Qr(ba(n),0,Tn):0}function ma(n){if("number"==typeof n)return n;if(pa(n))return Ln;if(ta(n)){var t="function"==typeof n.valueOf?n.valueOf():n;n=ta(t)?t+"":t}if("string"!=typeof n)return 0===n?n:+n;n=n.replace(Et,"");var r=Nt.test(n);return r||qt.test(n)?kr(n.slice(2),r?2:8):$t.test(n)?Ln:+n}function xa(n){return Du(n,Ua(n))}function ja(n){return n?Qr(ba(n),-Dn,Dn):0===n?n:0}function ka(n){return null==n?"":cu(n)}function Sa(n,t){var r=ls(n);return null==t?r:Gr(r,t)}function Wa(n,t){return x(n,di(t,3),ce)}function Oa(n,t){return x(n,di(t,3),le)}function Aa(n,t){return null==n?n:ps(n,di(t,3),Ua)}function Ca(n,t){return null==n?n:vs(n,di(t,3),Ua)}function Ia(n,t){return n&&ce(n,di(t,3))}function za(n,t){return n&&le(n,di(t,3))}function Ea(n){return null==n?[]:se(n,Ta(n))}function Ra(n){return null==n?[]:se(n,Ua(n))}function Da(n,t,r){var e=null==n?un:he(n,t);return e===un?r:e}function Pa(n,t){return null!=n&&ki(n,t,ge)}function La(n,t){return null!=n&&ki(n,t,de)}function Ta(n){return Ff(n)?Cr(n):De(n)}function Ua(n){return Ff(n)?Cr(n,!0):Pe(n)}function Ma(n,t){var r={};return t=di(t,3),ce(n,function(n,e,u){Hr(r,t(n,e,u),n)}),r}function Ba(n,t){var r={};return t=di(t,3),ce(n,function(n,e,u){Hr(r,e,t(n,e,u))}),r}function $a(n,t){return Na(n,Cf(di(t)))}function Na(n,t){if(null==n)return{};var r=_(vi(n),function(n){return[n]});return t=di(t),Ze(n,r,function(n,r){return t(n,r[0])})}function Fa(n,t,r){t=bu(t,n);var e=-1,u=t.length;for(u||(u=1,n=un);++et){var e=n;n=t,t=e}if(r||n%1||t%1){var u=Vl();return Fl(n+u*(t-n+jr("1e-"+((u+"").length-1))),t)}return Je(n,t)}function tc(n){return Vh(ka(n).toLowerCase())}function rc(n){return(n=ka(n))&&n.replace(Vt,Br).replace(lr,"")}function ec(n,t,r){n=ka(n),t=cu(t);var e=n.length;r=r===un?e:Qr(ba(r),0,e);var u=r;return(r-=t.length)>=0&&n.slice(r,u)==t}function uc(n){return n=ka(n),n&&St.test(n)?n.replace(jt,$r):n}function ic(n){return n=ka(n),n&&zt.test(n)?n.replace(It,"\\$&"):n}function oc(n,t,r){n=ka(n),t=ba(t);var e=t?X(n):0;if(!t||e>=t)return n;var u=(t-e)/2;return Qu(Ll(u),r)+n+Qu(Pl(u),r)}function fc(n,t,r){n=ka(n),t=ba(t);var e=t?X(n):0;return t&&e>>0)?(n=ka(n),n&&("string"==typeof t||null!=t&&!yh(t))&&!(t=cu(t))&&F(n)?wu(nn(n),0,r):n.split(t,r)):[]}function pc(n,t,r){return n=ka(n),r=null==r?0:Qr(ba(r),0,n.length),t=cu(t),n.slice(r,r+t.length)==t}function vc(n,t,e){var u=r.templateSettings;e&&zi(n,t,e)&&(t=un),n=ka(n),t=Sh({},t,u,oi);var i,o,f=Sh({},t.imports,u.imports,oi),a=Ta(f),c=L(f,a),l=0,s=t.interpolate||Kt,h="__p += '",p=il((t.escape||Kt).source+"|"+s.source+"|"+(s===Wt?Mt:Kt).source+"|"+(t.evaluate||Kt).source+"|$","g"),v="//# sourceURL="+("sourceURL"in t?t.sourceURL:"lodash.templateSources["+ ++gr+"]")+"\n";n.replace(p,function(t,r,e,u,f,a){return e||(e=u),h+=n.slice(l,a).replace(Gt,$),r&&(i=!0,h+="' +\n__e("+r+") +\n'"),f&&(o=!0,h+="';\n"+f+";\n__p += '"),e&&(h+="' +\n((__t = ("+e+")) == null ? '' : __t) +\n'"),l=a+t.length,t}),h+="';\n";var _=t.variable;_||(h="with (obj) {\n"+h+"\n}\n"),h=(o?h.replace(bt,""):h).replace(wt,"$1").replace(mt,"$1;"),h="function("+(_||"obj")+") {\n"+(_?"":"obj || (obj = {});\n")+"var __t, __p = ''"+(i?", __e = _.escape":"")+(o?", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n":";\n")+h+"return __p\n}";var g=Kh(function(){return rl(a,v+"return "+h).apply(un,c)});if(g.source=h,Hf(g))throw g;return g}function _c(n){return ka(n).toLowerCase()}function gc(n){return ka(n).toUpperCase()}function dc(n,t,r){if((n=ka(n))&&(r||t===un))return n.replace(Et,"");if(!n||!(t=cu(t)))return n;var e=nn(n),u=nn(t);return wu(e,U(e,u),M(e,u)+1).join("")}function yc(n,t,r){if((n=ka(n))&&(r||t===un))return n.replace(Dt,"");if(!n||!(t=cu(t)))return n;var e=nn(n);return wu(e,0,M(e,nn(t))+1).join("")}function bc(n,t,r){if((n=ka(n))&&(r||t===un))return n.replace(Rt,"");if(!n||!(t=cu(t)))return n;var e=nn(n);return wu(e,U(e,nn(t))).join("")}function wc(n,t){var r=On,e=An;if(ta(t)){var u="separator"in t?t.separator:u;r="length"in t?ba(t.length):r,e="omission"in t?cu(t.omission):e}n=ka(n);var i=n.length;if(F(n)){var o=nn(n);i=o.length}if(r>=i)return n;var f=r-X(e);if(f<1)return e;var a=o?wu(o,0,f).join(""):n.slice(0,f);if(u===un)return a+e;if(o&&(f+=a.length-f),yh(u)){if(n.slice(f).search(u)){var c,l=a;for(u.global||(u=il(u.source,ka(Bt.exec(u))+"g")),u.lastIndex=0;c=u.exec(l);)var s=c.index;a=a.slice(0,s===un?f:s)}}else if(n.indexOf(cu(u),f)!=f){var h=a.lastIndexOf(u);h>-1&&(a=a.slice(0,h))}return a+e}function mc(n){return n=ka(n),n&&kt.test(n)?n.replace(xt,Nr):n}function xc(n,t,r){return n=ka(n),t=r?un:t,t===un?q(n)?en(n):m(n):n.match(t)||[]}function jc(n){var t=null==n?0:n.length,r=di();return n=t?_(n,function(n){if("function"!=typeof n[1])throw new fl(an);return[r(n[0]),n[1]]}):[],Qe(function(r){for(var e=-1;++eDn)return[];var r=Tn,e=Fl(n,Tn);t=di(t),n-=Tn;for(var u=R(e,t);++r/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:Wt,variable:"",imports:{_:r}},r.prototype=e.prototype,r.prototype.constructor=r,u.prototype=ls(e.prototype),u.prototype.constructor=u,w.prototype=ls(e.prototype),w.prototype.constructor=w,rn.prototype.clear=Ut,rn.prototype.delete=Jt,rn.prototype.get=Ht,rn.prototype.has=Yt,rn.prototype.set=Qt,Xt.prototype.clear=nr,Xt.prototype.delete=tr,Xt.prototype.get=rr,Xt.prototype.has=er,Xt.prototype.set=ur,ir.prototype.clear=or,ir.prototype.delete=fr,ir.prototype.get=ar,ir.prototype.has=sr,ir.prototype.set=hr,pr.prototype.add=pr.prototype.push=vr,pr.prototype.has=br,wr.prototype.clear=mr,wr.prototype.delete=xr,wr.prototype.get=Sr,wr.prototype.has=Wr,wr.prototype.set=Ar;var ss=Mu(ce),hs=Mu(le,!0),ps=Bu(),vs=Bu(!0),_s=ns?function(n,t){return ns.set(n,t),n}:Oc,gs=zl?function(n,t){return zl(n,"toString",{configurable:!0,enumerable:!1,value:Sc(t),writable:!0})}:Oc,ds=Qe,ys=El||function(n){return Or.clearTimeout(n)},bs=Yl&&1/J(new Yl([,-0]))[1]==Rn?function(n){return new Yl(n)}:Rc,ws=ns?function(n){return ns.get(n)}:Rc,ms=Tl?function(n){return null==n?[]:(n=ul(n),h(Tl(n),function(t){return Wl.call(n,t)}))}:Tc,xs=Tl?function(n){for(var t=[];n;)g(t,ms(n)),n=kl(n);return t}:Tc,js=ve;(Gl&&js(new Gl(new ArrayBuffer(1)))!=ct||Jl&&js(new Jl)!=Hn||Hl&&"[object Promise]"!=js(Hl.resolve())||Yl&&js(new Yl)!=rt||Ql&&js(new Ql)!=ot)&&(js=function(n){var t=ve(n),r=t==Xn?n.constructor:un,e=r?Ji(r):"";if(e)switch(e){case rs:return ct;case es:return Hn;case us:return"[object Promise]";case is:return rt;case os:return ot}return t});var ks=sl?Qf:Uc,Ss=Vi(_s),Ws=Dl||function(n,t){return Or.setTimeout(n,t)},Os=Vi(gs),As=function(n){var t=Af(n,function(n){return r.size===ln&&r.clear(),n}),r=t.cache;return t}(function(n){var t=[];return Ct.test(n)&&t.push(""),n.replace(/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,function(n,r,e,u){t.push(e?u.replace(/\\(\\)?/g,"$1"):r||n)}),t}),Cs=Qe(function(n,t){return qf(n)?ee(n,ae(t,1,qf,!0)):[]}),Is=Qe(function(n,t){var r=go(t);return qf(r)&&(r=un),qf(n)?ee(n,ae(t,1,qf,!0),di(r,2)):[]}),zs=Qe(function(n,t){var r=go(t);return qf(r)&&(r=un),qf(n)?ee(n,ae(t,1,qf,!0),un,r):[]}),Es=Qe(function(n){var t=_(n,du);return t.length&&t[0]===n[0]?be(t):[]}),Rs=Qe(function(n){var t=go(n),r=_(n,du);return t===go(r)?t=un:r.pop(),r.length&&r[0]===n[0]?be(r,di(t,2)):[]}),Ds=Qe(function(n){var t=go(n),r=_(n,du);return t="function"==typeof t?t:un,t&&r.pop(),r.length&&r[0]===n[0]?be(r,un,t):[]}),Ps=Qe(wo),Ls=hi(function(n,t){var r=null==n?0:n.length,e=Yr(n,t);return Ge(n,_(t,function(n){return Ii(n,r)?+n:n}).sort(Cu)),e}),Ts=Qe(function(n){return lu(ae(n,1,qf,!0))}),Us=Qe(function(n){var t=go(n);return qf(t)&&(t=un),lu(ae(n,1,qf,!0),di(t,2))}),Ms=Qe(function(n){var t=go(n);return t="function"==typeof t?t:un,lu(ae(n,1,qf,!0),un,t)}),Bs=Qe(function(n,t){return qf(n)?ee(n,t):[]}),$s=Qe(function(n){return _u(h(n,qf))}),Ns=Qe(function(n){var t=go(n);return qf(t)&&(t=un),_u(h(n,qf),di(t,2))}),Fs=Qe(function(n){var t=go(n);return t="function"==typeof t?t:un,_u(h(n,qf),un,t)}),qs=Qe(No),Zs=Qe(function(n){var t=n.length,r=t>1?n[t-1]:un;return r="function"==typeof r?(n.pop(),r):un,Fo(n,r)}),Vs=hi(function(n){var t=n.length,r=t?n[0]:0,e=this.__wrapped__,i=function(t){return Yr(t,n)};return!(t>1||this.__actions__.length)&&e instanceof w&&Ii(r)?(e=e.slice(r,+r+(t?1:0)),e.__actions__.push({func:Go,args:[i],thisArg:un}),new u(e,this.__chain__).thru(function(n){return t&&!n.length&&n.push(un),n})):this.thru(i)}),Ks=Tu(function(n,t,r){pl.call(n,r)?++n[r]:Hr(n,r,1)}),Gs=Vu(oo),Js=Vu(fo),Hs=Tu(function(n,t,r){pl.call(n,r)?n[r].push(t):Hr(n,r,[t])}),Ys=Qe(function(n,t,r){var e=-1,u="function"==typeof t,i=Ff(n)?Xc(n.length):[];return ss(n,function(n){i[++e]=u?f(t,n,r):me(n,t,r)}),i}),Qs=Tu(function(n,t,r){Hr(n,r,t)}),Xs=Tu(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),nh=Qe(function(n,t){if(null==n)return[];var r=t.length;return r>1&&zi(n,t[0],t[1])?t=[]:r>2&&zi(t[0],t[1],t[2])&&(t=[t[0]]),Fe(n,ae(t,1),[])}),th=Rl||function(){return Or.Date.now()},rh=Qe(function(n,t,r){var e=dn;if(r.length){var u=G(r,gi(rh));e|=xn}return ii(n,e,t,r,u)}),eh=Qe(function(n,t,r){var e=dn|yn;if(r.length){var u=G(r,gi(eh));e|=xn}return ii(t,e,n,r,u)}),uh=Qe(function(n,t){return re(n,1,t)}),ih=Qe(function(n,t,r){return re(n,ma(t)||0,r)});Af.Cache=ir;var oh=ds(function(n,t){t=1==t.length&&ph(t[0])?_(t[0],P(di())):_(ae(t,1),P(di()));var r=t.length;return Qe(function(e){for(var u=-1,i=Fl(e.length,r);++u=t}),hh=xe(function(){return arguments}())?xe:function(n){return ra(n)&&pl.call(n,"callee")&&!Wl.call(n,"callee")},ph=Xc.isArray,vh=Rr?P(Rr):je,_h=Ul||Uc,gh=Dr?P(Dr):ke,dh=Pr?P(Pr):Oe,yh=Lr?P(Lr):Ie,bh=Tr?P(Tr):ze,wh=Ur?P(Ur):Ee,mh=ti(Le),xh=ti(function(n,t){return n<=t}),jh=Uu(function(n,t){if(Li(t)||Ff(t))return void Du(t,Ta(t),n);for(var r in t)pl.call(t,r)&&Zr(n,r,t[r])}),kh=Uu(function(n,t){Du(t,Ua(t),n)}),Sh=Uu(function(n,t,r,e){Du(t,Ua(t),n,e)}),Wh=Uu(function(n,t,r,e){Du(t,Ta(t),n,e)}),Oh=hi(Yr),Ah=Qe(function(n){return n.push(un,oi),f(Sh,un,n)}),Ch=Qe(function(n){return n.push(un,fi),f(Dh,un,n)}),Ih=Ju(function(n,t,r){n[t]=r},Sc(Oc)),zh=Ju(function(n,t,r){pl.call(n,t)?n[t].push(r):n[t]=[r]},di),Eh=Qe(me),Rh=Uu(function(n,t,r){Be(n,t,r)}),Dh=Uu(function(n,t,r,e){Be(n,t,r,e)}),Ph=hi(function(n,t){var r={};if(null==n)return r;var e=!1;t=_(t,function(t){return t=bu(t,n),e||(e=t.length>1),t}),Du(n,vi(n),r),e&&(r=Xr(r,hn|pn|vn,ai));for(var u=t.length;u--;)su(r,t[u]);return r}),Lh=hi(function(n,t){return null==n?{}:qe(n,t)}),Th=ui(Ta),Uh=ui(Ua),Mh=Fu(function(n,t,r){return t=t.toLowerCase(),n+(r?tc(t):t)}),Bh=Fu(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),$h=Fu(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),Nh=Nu("toLowerCase"),Fh=Fu(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}),qh=Fu(function(n,t,r){return n+(r?" ":"")+Vh(t)}),Zh=Fu(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),Vh=Nu("toUpperCase"),Kh=Qe(function(n,t){try{return f(n,un,t)}catch(n){return Hf(n)?n:new tl(n)}}),Gh=hi(function(n,t){return c(t,function(t){t=Gi(t),Hr(n,t,rh(n[t],n))}),n}),Jh=Ku(),Hh=Ku(!0),Yh=Qe(function(n,t){return function(r){return me(r,n,t)}}),Qh=Qe(function(n,t){return function(r){return me(n,r,t)}}),Xh=Yu(_),np=Yu(s),tp=Yu(b),rp=ni(),ep=ni(!0),up=Hu(function(n,t){return n+t},0),ip=ei("ceil"),op=Hu(function(n,t){return n/t},1),fp=ei("floor"),ap=Hu(function(n,t){return n*t},1),cp=ei("round"),lp=Hu(function(n,t){return n-t},0);return r.after=mf,r.ary=xf,r.assign=jh,r.assignIn=kh,r.assignInWith=Sh,r.assignWith=Wh,r.at=Oh,r.before=jf,r.bind=rh,r.bindAll=Gh,r.bindKey=eh,r.castArray=Lf,r.chain=Vo,r.chunk=Qi,r.compact=Xi,r.concat=no,r.cond=jc,r.conforms=kc,r.constant=Sc,r.countBy=Ks,r.create=Sa,r.curry=kf,r.curryRight=Sf,r.debounce=Wf,r.defaults=Ah,r.defaultsDeep=Ch,r.defer=uh,r.delay=ih,r.difference=Cs,r.differenceBy=Is,r.differenceWith=zs,r.drop=to,r.dropRight=ro,r.dropRightWhile=eo,r.dropWhile=uo,r.fill=io,r.filter=ef,r.flatMap=uf,r.flatMapDeep=of,r.flatMapDepth=ff,r.flatten=ao,r.flattenDeep=co,r.flattenDepth=lo,r.flip=Of,r.flow=Jh,r.flowRight=Hh,r.fromPairs=so,r.functions=Ea,r.functionsIn=Ra,r.groupBy=Hs,r.initial=vo,r.intersection=Es,r.intersectionBy=Rs,r.intersectionWith=Ds,r.invert=Ih,r.invertBy=zh,r.invokeMap=Ys,r.iteratee=Ac,r.keyBy=Qs,r.keys=Ta,r.keysIn=Ua,r.map=sf,r.mapKeys=Ma,r.mapValues=Ba,r.matches=Cc,r.matchesProperty=Ic,r.memoize=Af,r.merge=Rh,r.mergeWith=Dh,r.method=Yh,r.methodOf=Qh,r.mixin=zc,r.negate=Cf,r.nthArg=Dc,r.omit=Ph,r.omitBy=$a,r.once=If,r.orderBy=hf,r.over=Xh,r.overArgs=oh,r.overEvery=np,r.overSome=tp,r.partial=fh,r.partialRight=ah,r.partition=Xs,r.pick=Lh,r.pickBy=Na,r.property=Pc,r.propertyOf=Lc,r.pull=Ps,r.pullAll=wo,r.pullAllBy=mo,r.pullAllWith=xo,r.pullAt=Ls,r.range=rp,r.rangeRight=ep,r.rearg=ch,r.reject=_f,r.remove=jo,r.rest=zf,r.reverse=ko,r.sampleSize=df,r.set=qa,r.setWith=Za,r.shuffle=yf,r.slice=So,r.sortBy=nh,r.sortedUniq=Eo,r.sortedUniqBy=Ro,r.split=hc,r.spread=Ef,r.tail=Do,r.take=Po,r.takeRight=Lo,r.takeRightWhile=To,r.takeWhile=Uo,r.tap=Ko,r.throttle=Rf,r.thru=Go,r.toArray=da,r.toPairs=Th,r.toPairsIn=Uh,r.toPath=Fc,r.toPlainObject=xa,r.transform=Va,r.unary=Df,r.union=Ts,r.unionBy=Us,r.unionWith=Ms,r.uniq=Mo,r.uniqBy=Bo,r.uniqWith=$o,r.unset=Ka,r.unzip=No,r.unzipWith=Fo,r.update=Ga,r.updateWith=Ja,r.values=Ha,r.valuesIn=Ya,r.without=Bs,r.words=xc,r.wrap=Pf,r.xor=$s,r.xorBy=Ns,r.xorWith=Fs,r.zip=qs,r.zipObject=qo,r.zipObjectDeep=Zo,r.zipWith=Zs,r.entries=Th,r.entriesIn=Uh,r.extend=kh,r.extendWith=Sh,zc(r,r),r.add=up,r.attempt=Kh,r.camelCase=Mh,r.capitalize=tc,r.ceil=ip,r.clamp=Qa,r.clone=Tf,r.cloneDeep=Mf,r.cloneDeepWith=Bf,r.cloneWith=Uf,r.conformsTo=$f,r.deburr=rc,r.defaultTo=Wc,r.divide=op,r.endsWith=ec,r.eq=Nf,r.escape=uc,r.escapeRegExp=ic,r.every=rf,r.find=Gs,r.findIndex=oo,r.findKey=Wa,r.findLast=Js,r.findLastIndex=fo,r.findLastKey=Oa,r.floor=fp,r.forEach=af,r.forEachRight=cf,r.forIn=Aa,r.forInRight=Ca,r.forOwn=Ia,r.forOwnRight=za,r.get=Da,r.gt=lh,r.gte=sh,r.has=Pa,r.hasIn=La,r.head=ho,r.identity=Oc,r.includes=lf,r.indexOf=po,r.inRange=Xa,r.invoke=Eh,r.isArguments=hh,r.isArray=ph,r.isArrayBuffer=vh,r.isArrayLike=Ff,r.isArrayLikeObject=qf,r.isBoolean=Zf,r.isBuffer=_h,r.isDate=gh,r.isElement=Vf,r.isEmpty=Kf,r.isEqual=Gf,r.isEqualWith=Jf,r.isError=Hf,r.isFinite=Yf,r.isFunction=Qf,r.isInteger=Xf,r.isLength=na,r.isMap=dh,r.isMatch=ea,r.isMatchWith=ua,r.isNaN=ia,r.isNative=oa,r.isNil=aa,r.isNull=fa,r.isNumber=ca,r.isObject=ta,r.isObjectLike=ra,r.isPlainObject=la,r.isRegExp=yh,r.isSafeInteger=sa,r.isSet=bh,r.isString=ha,r.isSymbol=pa,r.isTypedArray=wh,r.isUndefined=va,r.isWeakMap=_a,r.isWeakSet=ga,r.join=_o,r.kebabCase=Bh,r.last=go,r.lastIndexOf=yo,r.lowerCase=$h,r.lowerFirst=Nh,r.lt=mh,r.lte=xh,r.max=Zc,r.maxBy=Vc,r.mean=Kc,r.meanBy=Gc,r.min=Jc,r.minBy=Hc,r.stubArray=Tc,r.stubFalse=Uc,r.stubObject=Mc,r.stubString=Bc,r.stubTrue=$c,r.multiply=ap,r.nth=bo,r.noConflict=Ec,r.noop=Rc,r.now=th,r.pad=oc,r.padEnd=fc,r.padStart=ac,r.parseInt=cc,r.random=nc,r.reduce=pf,r.reduceRight=vf,r.repeat=lc,r.replace=sc,r.result=Fa,r.round=cp,r.runInContext=n,r.sample=gf,r.size=bf,r.snakeCase=Fh,r.some=wf,r.sortedIndex=Wo,r.sortedIndexBy=Oo,r.sortedIndexOf=Ao,r.sortedLastIndex=Co,r.sortedLastIndexBy=Io,r.sortedLastIndexOf=zo,r.startCase=qh,r.startsWith=pc,r.subtract=lp,r.sum=Yc,r.sumBy=Qc,r.template=vc,r.times=Nc,r.toFinite=ya,r.toInteger=ba,r.toLength=wa,r.toLower=_c,r.toNumber=ma,r.toSafeInteger=ja,r.toString=ka,r.toUpper=gc,r.trim=dc,r.trimEnd=yc,r.trimStart=bc,r.truncate=wc,r.unescape=mc,r.uniqueId=qc,r.upperCase=Zh,r.upperFirst=Vh,r.each=af,r.eachRight=cf,r.first=ho,zc(r,function(){var n={};return ce(r,function(t,e){pl.call(r.prototype,e)||(n[e]=t)}),n}(),{chain:!1}),r.VERSION="4.17.4",c(["bind","bindKey","curry","curryRight","partial","partialRight"],function(n){r[n].placeholder=r}),c(["drop","take"],function(n,t){w.prototype[n]=function(r){r=r===un?1:Nl(ba(r),0);var e=this.__filtered__&&!t?new w(this):this.clone();return e.__filtered__?e.__takeCount__=Fl(r,e.__takeCount__):e.__views__.push({size:Fl(r,Tn),type:n+(e.__dir__<0?"Right":"")}),e},w.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),c(["filter","map","takeWhile"],function(n,t){var r=t+1,e=r==zn||3==r;w.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:di(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),c(["head","last"],function(n,t){var r="take"+(t?"Right":"");w.prototype[n]=function(){return this[r](1).value()[0]}}),c(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");w.prototype[n]=function(){return this.__filtered__?new w(this):this[r](1)}}),w.prototype.compact=function(){return this.filter(Oc)},w.prototype.find=function(n){return this.filter(n).head()},w.prototype.findLast=function(n){return this.reverse().find(n)},w.prototype.invokeMap=Qe(function(n,t){return"function"==typeof n?new w(this):this.map(function(r){return me(r,n,t)})}),w.prototype.reject=function(n){return this.filter(Cf(di(n)))},w.prototype.slice=function(n,t){n=ba(n);var r=this;return r.__filtered__&&(n>0||t<0)?new w(r):(n<0?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==un&&(t=ba(t),r=t<0?r.dropRight(-t):r.take(t-n)),r)},w.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},w.prototype.toArray=function(){return this.take(Tn)},ce(w.prototype,function(n,t){var e=/^(?:filter|find|map|reject)|While$/.test(t),i=/^(?:head|last)$/.test(t),o=r[i?"take"+("last"==t?"Right":""):t],f=i||/^find/.test(t);o&&(r.prototype[t]=function(){var t=this.__wrapped__,a=i?[1]:arguments,c=t instanceof w,l=a[0],s=c||ph(t),h=function(n){var t=o.apply(r,g([n],a));return i&&p?t[0]:t};s&&e&&"function"==typeof l&&1!=l.length&&(c=s=!1);var p=this.__chain__,v=!!this.__actions__.length,_=f&&!p,d=c&&!v;if(!f&&s){t=d?t:new w(this);var y=n.apply(t,a);return y.__actions__.push({func:Go,args:[h],thisArg:un}),new u(y,p)}return _&&d?n.apply(this,a):(y=this.thru(h),_?i?y.value()[0]:y.value():y)})}),c(["pop","push","shift","sort","splice","unshift"],function(n){var t=al[n],e=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",u=/^(?:pop|shift)$/.test(n);r.prototype[n]=function(){var n=arguments;if(u&&!this.__chain__){var r=this.value();return t.apply(ph(r)?r:[],n)}return this[e](function(r){return t.apply(ph(r)?r:[],n)})}}),ce(w.prototype,function(n,t){var e=r[t];if(e){var u=e.name+"";(ts[u]||(ts[u]=[])).push({name:t,func:e})}}),ts[Gu(un,yn).name]=[{name:"wrapper",func:un}],w.prototype.clone=C,w.prototype.reverse=Y,w.prototype.value=tn,r.prototype.at=Vs,r.prototype.chain=Jo,r.prototype.commit=Ho,r.prototype.next=Yo,r.prototype.plant=Xo,r.prototype.reverse=nf,r.prototype.toJSON=r.prototype.valueOf=r.prototype.value=tf,r.prototype.first=r.prototype.head,Cl&&(r.prototype[Cl]=Qo),r}();Or._=Fr,(u=function(){return Fr}.call(t,r,t,e))!==un&&(e.exports=u)}).call(this)}).call(t,r(4),r(30)(n))},30:function(n,t){n.exports=function(n){return n.webpackPolyfill||(n.deprecate=function(){},n.paths=[],n.children||(n.children=[]),Object.defineProperty(n,"loaded",{enumerable:!0,get:function(){return n.l}}),Object.defineProperty(n,"id",{enumerable:!0,get:function(){return n.i}}),n.webpackPolyfill=1),n}},4:function(n,t){var r;r=function(){return this}();try{r=r||Function("return this")()||(0,eval)("this")}catch(n){"object"==typeof window&&(r=window)}n.exports=r},6:function(n,t,r){"use strict";function e(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var u=function(){function n(n,t){for(var r=0;r":">",'"':""","'":"'","`":"`","=":"="},d=/[&<>"'`=]/g,p=/[&<>"'`=]/,h=Object.prototype.toString;t.toString=h;var v=function(e){return"function"==typeof e};v(/x/)&&(t.isFunction=v=function(e){return"function"==typeof e&&"[object Function]"===h.call(e)}),t.isFunction=v;var g=Array.isArray||function(e){return!(!e||"object"!=typeof e)&&"[object Array]"===h.call(e)};t.isArray=g},function(e,t,n){"use strict";function r(e,t){var n=t&&t.loc,o=void 0,i=void 0;n&&(o=n.start.line,i=n.start.column,e+=" - "+o+":"+i);for(var l=Error.prototype.constructor.call(this,e),u=0;u= 2.0.0-beta.1",7:">= 4.0.0"};t.REVISION_CHANGES=d;a.prototype={constructor:a,logger:f.default,log:f.default.log,registerHelper:function(e,t){if("[object Object]"===o.toString.call(e)){if(t)throw new l.default("Arg not supported with multiple helpers");o.extend(this.helpers,e)}else this.helpers[e]=t},unregisterHelper:function(e){delete this.helpers[e]},registerPartial:function(e,t){if("[object Object]"===o.toString.call(e))o.extend(this.partials,e);else{if(void 0===t)throw new l.default('Attempting to register a partial called "'+e+'" as undefined');this.partials[e]=t}},unregisterPartial:function(e){delete this.partials[e]},registerDecorator:function(e,t){if("[object Object]"===o.toString.call(e)){if(t)throw new l.default("Arg not supported with multiple decorators");o.extend(this.decorators,e)}else this.decorators[e]=t},unregisterDecorator:function(e){delete this.decorators[e]}};var p=f.default.log;t.log=p,t.createFrame=o.createFrame,t.logger=f.default},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),t.configurationLayout=t.layout=void 0;var a=n(2),o=r(a),i=n(8),l=r(i),u=t.layout=n(10),s=t.configurationLayout=n(9);l.default.register(o.default),o.default.registerPartial("widget-layout",u),o.default.registerPartial("widget-configuration-layout",s)},,function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n= 4.0.0"],main:function(e,t,n,r,a){var o;return'
\r\n '+(null!=(o=(n.block||t&&t.block||n.helperMissing).call(null!=t?t:{},"settings",{name:"block",hash:{},fn:e.program(1,a,0),inverse:e.noop,data:a}))?o:"")+"\r\n
"},useData:!0})},function(e,t,n){var r=n(2);e.exports=(r.default||r).template({1:function(e,t,n,r,a){return""},3:function(e,t,n,r,a){return' \r\n'},5:function(e,t,n,r,a){return' \r\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,a){var o,i,l=null!=t?t:{},u=n.helperMissing,s=e.escapeExpression;return'"},useData:!0})},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}function o(){var e=new l.HandlebarsEnvironment;return p.extend(e,l),e.SafeString=s.default,e.Exception=f.default,e.Utils=p,e.escapeExpression=p.escapeExpression,e.VM=v,e.template=function(t){return v.template(t,e)},e}t.__esModule=!0;var i=n(3),l=a(i),u=n(25),s=r(u),c=n(1),f=r(c),d=n(0),p=a(d),h=n(24),v=a(h),g=n(23),m=r(g),y=o();y.create=o,m.default(y),y.default=y,t.default=y,e.exports=t.default},function(e,t,n){"use strict";function r(e){o.default(e)}t.__esModule=!0,t.registerDefaultDecorators=r;var a=n(13),o=function(e){return e&&e.__esModule?e:{default:e}}(a)},function(e,t,n){"use strict";t.__esModule=!0;var r=n(0);t.default=function(e){e.registerDecorator("inline",function(e,t,n,a){var o=e;return t.partials||(t.partials={},o=function(a,o){var i=n.partials;n.partials=r.extend({},i,t.partials);var l=e(a,o);return n.partials=i,l}),t.partials[a.args[0]]=a.fn,o})},e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){i.default(e),u.default(e),c.default(e),d.default(e),h.default(e),g.default(e),y.default(e)}t.__esModule=!0,t.registerDefaultHelpers=a;var o=n(15),i=r(o),l=n(16),u=r(l),s=n(17),c=r(s),f=n(18),d=r(f),p=n(19),h=r(p),v=n(20),g=r(v),m=n(21),y=r(m)},function(e,t,n){"use strict";t.__esModule=!0;var r=n(0);t.default=function(e){e.registerHelper("blockHelperMissing",function(t,n){var a=n.inverse,o=n.fn;if(!0===t)return o(this);if(!1===t||null==t)return a(this);if(r.isArray(t))return t.length>0?(n.ids&&(n.ids=[n.name]),e.helpers.each(t,n)):a(this);if(n.data&&n.ids){var i=r.createFrame(n.data);i.contextPath=r.appendContextPath(n.data.contextPath,n.name),n={data:i}}return o(t,n)})},e.exports=t.default},function(e,t,n){"use strict";t.__esModule=!0;var r=n(0),a=n(1),o=function(e){return e&&e.__esModule?e:{default:e}}(a);t.default=function(e){e.registerHelper("each",function(e,t){function n(t,n,o){s&&(s.key=t,s.index=n,s.first=0===n,s.last=!!o,c&&(s.contextPath=c+t)),u+=a(e[t],{data:s,blockParams:r.blockParams([e[t],t],[c+t,null])})}if(!t)throw new o.default("Must pass iterator to #each");var a=t.fn,i=t.inverse,l=0,u="",s=void 0,c=void 0;if(t.data&&t.ids&&(c=r.appendContextPath(t.data.contextPath,t.ids[0])+"."),r.isFunction(e)&&(e=e.call(this)),t.data&&(s=r.createFrame(t.data)),e&&"object"==typeof e)if(r.isArray(e))for(var f=e.length;l=0?t:parseInt(e,10)}return e},log:function(e){if(e=a.lookupLevel(e),"undefined"!=typeof console&&a.lookupLevel(a.level)<=e){var t=a.methodMap[e];console[t]||(t="log");for(var n=arguments.length,r=Array(n>1?n-1:0),o=1;o= 4.0.0"],main:function(e,t,n,r,a){var o;return null!=(o=(n.extend||t&&t.extend||n.helperMissing).call(null!=t?t:{},"widget-layout",{name:"extend",hash:{},fn:e.program(1,a,0),inverse:e.noop,data:a}))?o:""},useData:!0})},function(e,t,n){var r=n(2);e.exports=(r.default||r).template({1:function(e,t,n,r,a){var o;return null!=(o=(n.content||t&&t.content||n.helperMissing).call(null!=t?t:{},"settings",{name:"content",hash:{},fn:e.program(2,a,0),inverse:e.noop,data:a}))?o:""},2:function(e,t,n,r,a){return'
\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,a){var o;return null!=(o=(n.extend||t&&t.extend||n.helperMissing).call(null!=t?t:{},"widget-configuration-layout",{name:"extend",hash:{},fn:e.program(1,a,0),inverse:e.noop,data:a}))?o:""},useData:!0})}])}); -------------------------------------------------------------------------------- /dist/jquery.dashboard.templates.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("templates",[],t):"object"==typeof exports?exports.templates=t():(e.Dashboard=e.Dashboard||{},e.Dashboard.templates=t())}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var a=r[n]={i:n,l:!1,exports:{}};return e[n].call(a.exports,a,a.exports,t),a.l=!0,a.exports}var r={};return t.m=e,t.c=r,t.i=function(e){return e},t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=5)}([function(e,t,r){"use strict";function n(e){return f[e]}function a(e){for(var t=1;t":">",'"':""","'":"'","`":"`","=":"="},d=/[&<>"'`=]/g,p=/[&<>"'`=]/,h=Object.prototype.toString;t.toString=h;var v=function(e){return"function"==typeof e};v(/x/)&&(t.isFunction=v=function(e){return"function"==typeof e&&"[object Function]"===h.call(e)}),t.isFunction=v;var m=Array.isArray||function(e){return!(!e||"object"!=typeof e)&&"[object Array]"===h.call(e)};t.isArray=m},function(e,t,r){"use strict";function n(e,t){var r=t&&t.loc,o=void 0,i=void 0;r&&(o=r.start.line,i=r.start.column,e+=" - "+o+":"+i);for(var l=Error.prototype.constructor.call(this,e),u=0;u= 2.0.0-beta.1",7:">= 4.0.0"};t.REVISION_CHANGES=d;a.prototype={constructor:a,logger:f.default,log:f.default.log,registerHelper:function(e,t){if("[object Object]"===o.toString.call(e)){if(t)throw new l.default("Arg not supported with multiple helpers");o.extend(this.helpers,e)}else this.helpers[e]=t},unregisterHelper:function(e){delete this.helpers[e]},registerPartial:function(e,t){if("[object Object]"===o.toString.call(e))o.extend(this.partials,e);else{if(void 0===t)throw new l.default('Attempting to register a partial called "'+e+'" as undefined');this.partials[e]=t}},unregisterPartial:function(e){delete this.partials[e]},registerDecorator:function(e,t){if("[object Object]"===o.toString.call(e)){if(t)throw new l.default("Arg not supported with multiple decorators");o.extend(this.decorators,e)}else this.decorators[e]=t},unregisterDecorator:function(e){delete this.decorators[e]}};var p=f.default.log;t.log=p,t.createFrame=o.createFrame,t.logger=f.default},function(e,t){var r;r=function(){return this}();try{r=r||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(r=window)}e.exports=r},function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),t.configurationLayout=t.layout=void 0;var a=r(2),o=n(a),i=r(8),l=n(i),u=t.layout=r(10),s=t.configurationLayout=r(9);l.default.register(o.default),o.default.registerPartial("widget-layout",u),o.default.registerPartial("widget-configuration-layout",s)},,,function(e,t,r){"use strict";function n(){return""}function a(e){return e.$$layoutStack||(e.$$layoutStack=[])}function o(e){for(var t=a(e);t.length;)t.shift()(e)}function i(e){return e.$$layoutActions||(e.$$layoutActions={})}function l(e,t){var r=i(e);return r[t]||(r[t]=[])}function u(e,t){function r(){return t.fn(n,t.options)}var n=this;switch(t.mode){case"append":return e+r();case"prepend":return r()+e;case"replace":return r();default:return e}}function s(e){for(var t,r,n=arguments.length,a=1;a= 4.0.0"],main:function(e,t,r,n,a){var o;return'
\r\n '+(null!=(o=(r.block||t&&t.block||r.helperMissing).call(null!=t?t:{},"settings",{name:"block",hash:{},fn:e.program(1,a,0),inverse:e.noop,data:a}))?o:"")+"\r\n
"},useData:!0})},function(e,t,r){var n=r(2);e.exports=(n.default||n).template({1:function(e,t,r,n,a){return""},3:function(e,t,r,n,a){return' \r\n'},5:function(e,t,r,n,a){return' \r\n'},compiler:[7,">= 4.0.0"],main:function(e,t,r,n,a){var o,i,l=null!=t?t:{},u=r.helperMissing,s=e.escapeExpression;return'"},useData:!0})},function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function a(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}function o(){var e=new l.HandlebarsEnvironment;return p.extend(e,l),e.SafeString=s.default,e.Exception=f.default,e.Utils=p,e.escapeExpression=p.escapeExpression,e.VM=v,e.template=function(t){return v.template(t,e)},e}t.__esModule=!0;var i=r(3),l=a(i),u=r(25),s=n(u),c=r(1),f=n(c),d=r(0),p=a(d),h=r(24),v=a(h),m=r(23),g=n(m),y=o();y.create=o,g.default(y),y.default=y,t.default=y,e.exports=t.default},function(e,t,r){"use strict";function n(e){o.default(e)}t.__esModule=!0,t.registerDefaultDecorators=n;var a=r(13),o=function(e){return e&&e.__esModule?e:{default:e}}(a)},function(e,t,r){"use strict";t.__esModule=!0;var n=r(0);t.default=function(e){e.registerDecorator("inline",function(e,t,r,a){var o=e;return t.partials||(t.partials={},o=function(a,o){var i=r.partials;r.partials=n.extend({},i,t.partials);var l=e(a,o);return r.partials=i,l}),t.partials[a.args[0]]=a.fn,o})},e.exports=t.default},function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function a(e){i.default(e),u.default(e),c.default(e),d.default(e),h.default(e),m.default(e),y.default(e)}t.__esModule=!0,t.registerDefaultHelpers=a;var o=r(15),i=n(o),l=r(16),u=n(l),s=r(17),c=n(s),f=r(18),d=n(f),p=r(19),h=n(p),v=r(20),m=n(v),g=r(21),y=n(g)},function(e,t,r){"use strict";t.__esModule=!0;var n=r(0);t.default=function(e){e.registerHelper("blockHelperMissing",function(t,r){var a=r.inverse,o=r.fn;if(!0===t)return o(this);if(!1===t||null==t)return a(this);if(n.isArray(t))return t.length>0?(r.ids&&(r.ids=[r.name]),e.helpers.each(t,r)):a(this);if(r.data&&r.ids){var i=n.createFrame(r.data);i.contextPath=n.appendContextPath(r.data.contextPath,r.name),r={data:i}}return o(t,r)})},e.exports=t.default},function(e,t,r){"use strict";t.__esModule=!0;var n=r(0),a=r(1),o=function(e){return e&&e.__esModule?e:{default:e}}(a);t.default=function(e){e.registerHelper("each",function(e,t){function r(t,r,o){s&&(s.key=t,s.index=r,s.first=0===r,s.last=!!o,c&&(s.contextPath=c+t)),u+=a(e[t],{data:s,blockParams:n.blockParams([e[t],t],[c+t,null])})}if(!t)throw new o.default("Must pass iterator to #each");var a=t.fn,i=t.inverse,l=0,u="",s=void 0,c=void 0;if(t.data&&t.ids&&(c=n.appendContextPath(t.data.contextPath,t.ids[0])+"."),n.isFunction(e)&&(e=e.call(this)),t.data&&(s=n.createFrame(t.data)),e&&"object"==typeof e)if(n.isArray(e))for(var f=e.length;l=0?t:parseInt(e,10)}return e},log:function(e){if(e=a.lookupLevel(e),"undefined"!=typeof console&&a.lookupLevel(a.level)<=e){var t=a.methodMap[e];console[t]||(t="log");for(var r=arguments.length,n=Array(r>1?r-1:0),o=1;o 2 | 3 | 4 | jquery Dashboard Demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 47 | 48 | 49 | 50 |
51 |
52 |
53 |

54 | Dashboard 55 | 56 |

57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | 66 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-dashboard", 3 | "version": "1.1.4", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "webpack-dev-server", 9 | "build": "webpack --env build", 10 | "buildSample": "webpack --env sample", 11 | "dev": "webpack --progress --colors --watch --env dev" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/brosenberger/jquery-dashboard.git" 16 | }, 17 | "author": "Benjamin Rosenberger", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/brosenberger/jquery-dashboard/issues" 21 | }, 22 | "homepage": "https://github.com/brosenberger/jquery-dashboard#readme", 23 | "dependencies": { 24 | "handlebars": "^4.0.6", 25 | "handlebars-layouts": "^3.1.4", 26 | "jquery": "^3.2.1", 27 | "lodash": "^4.17.4" 28 | }, 29 | "devDependencies": { 30 | "babel-core": "^6.24.1", 31 | "babel-loader": "^6.4.1", 32 | "babel-eslint": "7.1.1", 33 | "babel-preset-es2015": "^6.24.1", 34 | "babel-plugin-add-module-exports": "0.1.2", 35 | "handlebars-template-loader": "^0.7.0", 36 | "eslint": "1.7.2", 37 | "eslint-loader": "1.6.1", 38 | "css-loader": "^0.28.0", 39 | "extract-text-webpack-plugin": "^2.1.0", 40 | "grunt": "^1.0.1", 41 | "grunt-contrib-handlebars": "^1.0.0", 42 | "less": "^2.7.2", 43 | "less-loader": "^4.0.3", 44 | "style-loader": "^0.16.1", 45 | "webpack": "^2.3.3", 46 | "webpack-dev-server": "^2.4.2", 47 | "yargs": "6.6.0" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/modules/core/index.js: -------------------------------------------------------------------------------- 1 | export {Widget} from './widgets/Widget'; 2 | export {DataService} from './services/DataService'; 3 | export {LocalStorageDataService} from './services/LocalStorageDataService'; 4 | export {Service} from './services/Service'; 5 | 6 | 7 | export default function initializeDashboardDefaults() { 8 | let dataService = new Dashboard.core.LocalStorageDataService('storage'); 9 | let service = new Dashboard.core.Service(dataService); 10 | return service; 11 | } -------------------------------------------------------------------------------- /src/modules/core/services/DataService.js: -------------------------------------------------------------------------------- 1 | 2 | export class DataService { 3 | createWidgetConfiguration (widgetType) { 4 | throw 'createWigetConfiguration not implemented'; 5 | } 6 | findWidgetConfigurations () { 7 | throw 'findWidgetConfigurations not implemented'; 8 | } 9 | removeWidgetConfiguration (widgetId) { 10 | throw 'removeWidgetConfiguration not implemented'; 11 | } 12 | sortWidgetConfiguration(from, to) { 13 | throw 'sortWidgetConfiguration not implemented'; 14 | } 15 | saveWidgetConfiguration(widgetId, configuration) { 16 | throw 'saveWidgetConfiguration not implemented'; 17 | } 18 | } -------------------------------------------------------------------------------- /src/modules/core/services/LocalStorageDataService.js: -------------------------------------------------------------------------------- 1 | import {DataService} from "./DataService"; 2 | 3 | export class LocalStorageDataService extends DataService{ 4 | constructor(storageLocation) { 5 | super(); 6 | this.storageLocation = storageLocation; 7 | } 8 | 9 | createWidgetConfiguration (widgetType) { 10 | let that = this; 11 | 12 | return new Promise(function (resolve, reject) { 13 | let widgetData = that._generateRandomWidgetData(widgetType); 14 | let widgets = that._findStoredWidgets(); 15 | widgets.push(widgetData); 16 | that._saveStoredWidgets(widgets); 17 | 18 | resolve(widgetData); 19 | }); 20 | } 21 | 22 | findWidgetConfigurations () { 23 | let that = this; 24 | return new Promise(function (resolve, reject) { 25 | resolve(that._findStoredWidgets()); 26 | }); 27 | } 28 | 29 | removeWidgetConfiguration (widgetId) { 30 | let widgetList = this._findStoredWidgets(); 31 | widgetList = widgetList.filter(function (widgetData) { 32 | return widgetData.id !== widgetId; 33 | }); 34 | this._saveStoredWidgets(widgetList); 35 | } 36 | sortWidgetConfiguration(from, to) { 37 | let widgetList = this._findStoredWidgets(); 38 | while (from < 0) { 39 | from += this.length; 40 | } 41 | while (to < 0) { 42 | to += this.length; 43 | } 44 | if (to >= this.length) { 45 | let k = to - this.length; 46 | while ((k--) + 1) { 47 | widgetList.push(undefined); 48 | } 49 | } 50 | widgetList.splice(to, 0, widgetList.splice(from, 1)[0]); 51 | 52 | this._saveStoredWidgets(widgetList); 53 | } 54 | saveWidgetConfiguration(widgetId, configuration) { 55 | let that = this; 56 | return new Promise(function(resolve, reject) { 57 | 58 | let widgets = that._findStoredWidgets(); 59 | widgets.forEach(function (w) { 60 | if (w.id === widgetId) { 61 | w.configuration = configuration; 62 | } 63 | }); 64 | that._saveStoredWidgets(widgets); 65 | 66 | resolve(configuration); 67 | }); 68 | } 69 | _findStoredWidgets () { 70 | let widgets = localStorage.getItem(this.storageLocation); 71 | if (widgets === undefined || widgets === null) { 72 | widgets = []; 73 | } else { 74 | widgets = JSON.parse(widgets); 75 | } 76 | return widgets; 77 | } 78 | _loadStoredWidget(widgetId) { 79 | let widgets = this._findStoredWidgets(); 80 | 81 | } 82 | 83 | _saveStoredWidgets (widgets) { 84 | localStorage.setItem(this.storageLocation, JSON.stringify(widgets)); 85 | } 86 | 87 | _generateRandomWidgetData (widgetType) { 88 | return { 89 | id: this._generateUUID(), 90 | type: widgetType 91 | }; 92 | } 93 | _generateUUID () { 94 | let d = new Date().getTime(); 95 | let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 96 | let r = (d + Math.random() * 16) % 16 | 0; 97 | d = Math.floor(d / 16); 98 | return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16); 99 | }); 100 | return uuid; 101 | } 102 | } -------------------------------------------------------------------------------- /src/modules/core/services/Service.js: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | 3 | export class Service { 4 | constructor(dataService) { 5 | this.dataService = dataService; 6 | this._availableWidgets = []; 7 | } 8 | registerWidget (widgetConfiguration) { 9 | this._availableWidgets[widgetConfiguration.type] = _.clone(widgetConfiguration); 10 | } 11 | findWidgets () { 12 | return _.extend({}, this._availableWidgets); 13 | } 14 | findWidgetData () { 15 | let that = this; 16 | return new Promise(function (resolve, reject) { 17 | that.dataService.findWidgetConfigurations().then(function (widgets) { 18 | resolve(widgets.map(function (widget) { 19 | return that._enrichWidgetData(widget); 20 | })); 21 | }); 22 | }); 23 | } 24 | removeWidgetData (widgetId) { 25 | this.dataService.removeWidgetConfiguration(widgetId); 26 | } 27 | createWidgetData (widgetType) { 28 | this._checkWidgetType(widgetType); 29 | 30 | let that = this; 31 | return new Promise(function (resolve, reject) { 32 | // call data service to generate base data 33 | that.dataService.createWidgetConfiguration(widgetType) 34 | .then(function (widgetData) { 35 | if (widgetType === 'sampleWidget') { 36 | widgetData = _.extend(widgetData, { 37 | configurationTitle: 'Config #' + widgetData.id, 38 | configurable: Math.round(Math.random()), 39 | refreshable: Math.round(Math.random()) 40 | }); 41 | } 42 | resolve(that._enrichWidgetData(widgetData)); 43 | }); 44 | 45 | }); 46 | } 47 | sortWidgetData (from, to) { 48 | this.dataService.sortWidgetConfiguration(from, to); 49 | } 50 | saveConfiguration(widgetId, configurationData) { 51 | return this.dataService.saveWidgetConfiguration(widgetId, configurationData); 52 | } 53 | _enrichWidgetData (widgetData) { 54 | this._checkWidgetType(widgetData.type); 55 | // the widget prototype has to be copied to a new arrays as extend does mutate the original object! 56 | return _.extend(_.clone(this._availableWidgets[widgetData.type]), widgetData); 57 | } 58 | _checkWidgetType (widgetType) { 59 | if (!this._availableWidgets[widgetType]) { 60 | throw 'no widget configuration found for type \'' + widgetType + '\''; 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /src/modules/core/widgets/Widget.js: -------------------------------------------------------------------------------- 1 | 2 | export class Widget { 3 | 4 | constructor(type) { 5 | this.type = type; 6 | this.sizeConfiguration = "col-xs-12 col-md-4"; 7 | this.configurable = false; 8 | this.refreshable = false; 9 | this.configurationTitle = "Configure me"; 10 | } 11 | initialize(widgetElement) { 12 | throw 'initialize - I have to be implemented by the widget!' 13 | } 14 | configurationValues (widgetElement) { 15 | let transformed = {}; 16 | widgetElement.find('form').serializeArray().forEach(function(element){ 17 | transformed[element.name] = element.value; 18 | }); 19 | return transformed; 20 | } 21 | initializeConfigurationValues(configurationDialog) { 22 | for (var key in this.configuration) { 23 | configurationDialog.find('[name="'+key+'"]').val(this.configuration[key]).trigger('change'); 24 | } 25 | } 26 | showConfigurationOverlay(widgetElement) { 27 | widgetElement.find('.panel-body').fadeOut(300, function() { 28 | widgetElement.find('.panel-notconfigured').fadeIn(500); 29 | }); 30 | } 31 | hideConfigurationOverlay(widgetElement) { 32 | widgetElement.find('.panel-notconfigured').fadeOut(300, function() { 33 | widgetElement.find('.panel-body').fadeIn(500); 34 | }); 35 | } 36 | initializeContent(widgetElement) { 37 | if (this.configurable && this.configuration === undefined) { 38 | this.showConfigurationOverlay(widgetElement); 39 | } else { 40 | this.initialize(widgetElement); 41 | } 42 | } 43 | refreshContent(widgetElement) { 44 | if (this.refreshable && this.refresh === undefined) { 45 | throw 'refresh - i have to have a refresh method!'; 46 | } else { 47 | this.refresh(widgetElement); 48 | } 49 | } 50 | showProgressSpinner(widgetElement) { 51 | return new Promise(function (resolve, reject) { 52 | widgetElement.find('.panel-body').fadeOut(300, function() { 53 | widgetElement.find('.panel-loading').fadeIn(500, function() { 54 | resolve(); 55 | }); 56 | }); 57 | }); 58 | } 59 | progress(widgetElement, callback) { 60 | let that = this; 61 | this.showProgressSpinner(widgetElement).then(function() { 62 | callback().then(function() { 63 | that.hideProgressSpinner(widgetElement); 64 | }); 65 | }); 66 | } 67 | hideProgressSpinner(widgetElement) { 68 | return new Promise(function (resolve, reject) { 69 | widgetElement.find('.panel-loading').fadeOut(300, function () { 70 | widgetElement.find('.panel-body').fadeIn(500, function() { 71 | resolve(); 72 | }); 73 | }); 74 | }); 75 | } 76 | updateConfiguration(widgetElement, configuration) { 77 | this.configuration = configuration; 78 | this.initialize(widgetElement); 79 | } 80 | } -------------------------------------------------------------------------------- /src/modules/jquery-ui/functions/fClassList.js: -------------------------------------------------------------------------------- 1 | 2 | (function ($) { 3 | $.fn.extend({ 4 | classList: function (prefix) { 5 | var list = this[0].className.split(/\s+/); 6 | if (prefix) { 7 | var prefixed = []; 8 | $.each(list, function (index, item) { 9 | if (item.startsWith(prefix)) { 10 | prefixed[index] = item; 11 | } 12 | }); 13 | return prefixed; 14 | } else { 15 | return list; 16 | } 17 | } 18 | }); 19 | }(jQuery)); -------------------------------------------------------------------------------- /src/modules/jquery-ui/functions/fListGroupFilter.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | $.fn.extend({ 3 | listGroupFilter: function (listToFilter) { 4 | var that = this; 5 | that.on('keyup', function () { 6 | var li; 7 | var filterValue = that.val().toUpperCase(); 8 | var listItems = $(listToFilter).find('.list-group-item-heading, .list-group-item-text'); 9 | listItems.filter(function () { 10 | return $(this).text().toUpperCase().indexOf(filterValue) > -1; 11 | }).parent('.list-group-item').show().attr('data-search', filterValue); 12 | listItems.parent('.list-group-item:not([data-search=\'' + filterValue + '\'])').hide(); 13 | }); 14 | return this; 15 | } 16 | }); 17 | })(jQuery); -------------------------------------------------------------------------------- /src/modules/jquery-ui/handlebars/addWidgetsDialog.handlebars: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/modules/jquery-ui/handlebars/listGroupItem.handlebars: -------------------------------------------------------------------------------- 1 |
2 |

3 | {{description.title}} 4 | 5 |

6 |

{{description.description}}

7 |
-------------------------------------------------------------------------------- /src/modules/jquery-ui/index.js: -------------------------------------------------------------------------------- 1 | 2 | require('../core'); 3 | require('../templates'); 4 | 5 | require('./views/DashboardView.js'); 6 | require('./views/AddWidgetsDialog.js'); -------------------------------------------------------------------------------- /src/modules/jquery-ui/views/AddWidgetsDialog.js: -------------------------------------------------------------------------------- 1 | require('./../functions/fListGroupFilter.js'); 2 | 3 | (function ($) { 4 | $.widget('brocode.dashboardWidgetDialog', { 5 | options: { 6 | dashboardService: undefined, 7 | addCallback: function(widgetData) { 8 | $(document).trigger('widget.added'); 9 | }, 10 | widgetModal: '#widget-add-modal', 11 | modalTemplate: require('./../handlebars/addWidgetsDialog.handlebars'), 12 | listItemTemplate: require('./../handlebars/listGroupItem.handlebars') 13 | }, 14 | _create: function() { 15 | var that = this; 16 | var widgetModal = $(this.options.widgetModal); 17 | if (widgetModal.length===0) { 18 | $('body').append(this.options.modalTemplate()); 19 | } 20 | widgetModal = $(this.options.widgetModal); 21 | widgetModal.find('#widget-search').listGroupFilter('#widget-list'); 22 | widgetModal.on('click', '.list-group-item .fa.fa-plus', function () { 23 | that.options.dashboardService.createWidgetData($(this).parents('.list-group-item').data('type')).then(function (widgetData) { 24 | that.options.addCallback(widgetData); 25 | }); 26 | }); 27 | 28 | this.element.click(function () { 29 | widgetModal.find('.list-group-item').remove(); 30 | widgetModal.find('#widget-search').val(''); 31 | widgetModal.modal('show'); 32 | var modalList = widgetModal.find('.list-group'); 33 | var widgetList = that.options.dashboardService.findWidgets(); 34 | for (var widgetType in widgetList) { 35 | if (widgetList.hasOwnProperty(widgetType)) { 36 | modalList.append(that.options.listItemTemplate(widgetList[widgetType])); 37 | } 38 | } 39 | }) 40 | } 41 | }); 42 | }(jQuery)); -------------------------------------------------------------------------------- /src/modules/jquery-ui/views/DashboardView.js: -------------------------------------------------------------------------------- 1 | require('./../functions/fClassList.js'); 2 | 3 | (function ($) { 4 | $.widget('brocode.dashboard', { 5 | _grid: undefined, 6 | _widgets: [], 7 | options: { 8 | dashboardService: undefined 9 | }, 10 | _create: function () { 11 | this._initDashboard(this.element); 12 | this._initRefreshAction(this.element); 13 | this._initRemoveAction(this.element); 14 | this._initConfigureAction(this.element); 15 | }, 16 | addWidget: function (widgetData) { 17 | this._widgets[widgetData.id] = widgetData; 18 | var widgetElement = this.element.append(widgetData.widgetTemplate(widgetData)) 19 | .sortable('refresh') 20 | .find('.widget.widget-' + widgetData.id) 21 | .show(400); 22 | widgetData.initializeContent(widgetElement); 23 | this.element.trigger('widget.added', widgetData); 24 | }, 25 | refresh: function () { 26 | var that = this; 27 | this.element.html(''); 28 | this._widgets = []; 29 | this.options.dashboardService.findWidgetData().then(function (widgets) { 30 | widgets.forEach(function (w) { 31 | that.addWidget(w); 32 | }); 33 | }); 34 | 35 | }, 36 | _initRemoveAction: function (grid) { 37 | var that = this; 38 | grid.on('click', '.fa.fa-trash', function () { 39 | var widget = $(this).parents('.widget'); 40 | widget.hide(400, function () { 41 | var widgetId = widget.data('widgetId'); 42 | widget.remove(); 43 | grid.trigger('widget.removed', that._widgets[widgetId]); 44 | that.options.dashboardService.removeWidgetData(widgetId); 45 | }); 46 | }); 47 | return this; 48 | }, 49 | _initRefreshAction: function (grid) { 50 | var that = this; 51 | grid.on('click', '.fa.fa-refresh', function () { 52 | var widgetData = that._widgets[$(this).parents('.widget').data('widgetId')]; 53 | widgetData.refreshContent($(this).parents('.widget')); 54 | grid.trigger('widget.refreshed', widgetData); 55 | }); 56 | return this; 57 | }, 58 | _initConfigureAction: function (grid) { 59 | var that = this; 60 | grid.on('click', '.fa.fa-cog', function () { 61 | var widgetElement = $(this).parents('.widget'); 62 | var widgetData = that._widgets[widgetElement.data('widgetId')]; 63 | var dialog = bootbox.dialog({ 64 | title: widgetData.configurationTitle, 65 | message: widgetData.configurationTemplate({ 66 | id: widgetData.id, 67 | value: 'ein wert' 68 | }), 69 | size: 'large', 70 | onEscape: true, 71 | buttons: { 72 | save: { 73 | label: 'Speichern', 74 | className: 'btn-primary', 75 | callback: function (event) { 76 | return that.options.dashboardService.saveConfiguration(widgetData.id, widgetData.configurationValues(dialog)).then( 77 | function(result) { 78 | widgetData.updateConfiguration(widgetElement, result); 79 | } 80 | ); 81 | } 82 | } 83 | } 84 | }); 85 | dialog.on("shown.bs.modal", function() { 86 | widgetData.initializeConfigurationValues(dialog); // todo 87 | }); 88 | }); 89 | return this; 90 | }, 91 | _initDashboard: function (grid) { 92 | let that = this; 93 | grid.sortable({ 94 | placeholder: { 95 | element: function (currentItem) { 96 | return '
'; 97 | }, 98 | update: function (contianer, p) { 99 | } 100 | }, 101 | scroll: true, 102 | handle: '.panel-heading', 103 | tolerance: 'pointer', 104 | update: function (event, ui) { 105 | var startIndex = ui.item.data('startIndex'); 106 | var endIndex = ui.item.index(); 107 | 108 | grid.trigger('widget.sorted', {from: startIndex, to: endIndex}); 109 | that.options.dashboardService.sortWidgetData(startIndex, endIndex); 110 | }, 111 | start: function (e, ui) { 112 | ui.item.data('startIndex', ui.item.index()); 113 | ui.placeholder.height(ui.item.find('.panel').innerHeight()); 114 | ui.placeholder.width(ui.item.find('.panel').width()); 115 | }, 116 | forcePlaceholderSize: true 117 | }); 118 | return this; 119 | } 120 | }); 121 | }(jQuery)); -------------------------------------------------------------------------------- /src/modules/samples/handlebars/widgetChuckNorris.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "widget-layout"}} 2 | {{#content "header"}} 3 | A little story of Chuck 4 | {{/content}} 5 | {{#content "content"}} 6 | 7 | {{/content}} 8 | {{/extend}} -------------------------------------------------------------------------------- /src/modules/samples/handlebars/widgetChuckNorrisConfiguration.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "widget-configuration-layout"}} 2 | {{#content "settings"}} 3 |
4 |
5 |
6 | 7 | 12 |
13 |
14 |
15 | {{/content}} 16 | {{/extend}} -------------------------------------------------------------------------------- /src/modules/samples/index.js: -------------------------------------------------------------------------------- 1 | require('../templates') 2 | 3 | export {ChuckNorrisWidget} from './widgets/ChuckWidget'; 4 | 5 | export default function initializeDefault(service) { 6 | service.registerWidget(new Dashboard.samples.ChuckNorrisWidget()); 7 | } -------------------------------------------------------------------------------- /src/modules/samples/widgets/ChuckWidget.js: -------------------------------------------------------------------------------- 1 | import {Widget} from './../../core/widgets/Widget'; 2 | 3 | export class ChuckNorrisWidget extends Widget { 4 | constructor() { 5 | super('chuckNorrisWidget'); 6 | this.widgetTemplate = require('./../handlebars/widgetChuckNorris.handlebars'); 7 | this.configurationTemplate = require('./../handlebars/widgetChuckNorrisConfiguration.handlebars'); 8 | this.description = { 9 | title: 'A little story about Chuck', 10 | description: 'Tells you some random fact about Chuck Norris' 11 | }; 12 | this.sizeConfiguration = 'col-xs-12 col-md-4'; 13 | this.refreshable = true; 14 | this.configurable = true; 15 | this.configuration = {}; 16 | } 17 | 18 | initialize(widgetElement) { 19 | let that = this; 20 | this.progress(widgetElement, function() { 21 | return new Promise(function (resolve, reject) { 22 | let options = {}; 23 | if (that.configuration["chuck_category"] !== undefined) { 24 | options["category"] = that.configuration["chuck_category"]; 25 | } 26 | $.get('https://api.chucknorris.io/jokes/random', options).then(function (data) { 27 | widgetElement.find('.panel-body').html(data.value); 28 | resolve(); 29 | }); 30 | }); 31 | }); 32 | } 33 | 34 | refresh(widgetElement) { 35 | this.initialize(widgetElement); 36 | } 37 | } -------------------------------------------------------------------------------- /src/modules/templates/handlebars/configurationLayout.handlebars: -------------------------------------------------------------------------------- 1 |
2 | {{#block "settings"}}{{/block}} 3 |
-------------------------------------------------------------------------------- /src/modules/templates/handlebars/layout.handlebars: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/modules/templates/index.js: -------------------------------------------------------------------------------- 1 | 2 | import Handlebars from 'handlebars'; 3 | import HandlebarLayouts from 'handlebars-layouts'; 4 | 5 | export const layout = require('./handlebars/layout.handlebars'); 6 | export const configurationLayout = require('./handlebars/configurationLayout.handlebars'); 7 | 8 | HandlebarLayouts.register(Handlebars); 9 | Handlebars.registerPartial('widget-layout', layout); 10 | Handlebars.registerPartial('widget-configuration-layout', configurationLayout); 11 | 12 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /*global __dirname, require, module*/ 2 | 3 | const webpack = require('webpack'); 4 | const UglifyJsPlugin = webpack.optimize.UglifyJsPlugin; 5 | const path = require('path'); 6 | const env = require('yargs').argv.env; // use --env with webpack 2 7 | 8 | let libraryName = 'jquery.dashboard'; 9 | 10 | let plugins = [], outputFile, entryFile = 'index.js', library = 'Dashboard'; 11 | 12 | if (env === 'build') { 13 | plugins.push(new UglifyJsPlugin({minimize: true})); 14 | outputFile = '.min.js'; 15 | } else { 16 | outputFile = '.js'; 17 | } 18 | 19 | const config = { 20 | entry: { 21 | core: __dirname + '/src/modules/core/index.js', 22 | templates: __dirname + '/src/modules/templates/index.js', 23 | jqueryui: __dirname + '/src/modules/jquery-ui/index.js', 24 | samples: __dirname + '/src/modules/samples/index.js', 25 | }, 26 | devtool: 'source-map', 27 | output: { 28 | path: __dirname + '/dist', 29 | filename: libraryName+".[name]"+outputFile, 30 | library: ["Dashboard", "[name]"], 31 | libraryTarget: 'umd', 32 | umdNamedDefine: true 33 | }, 34 | module: { 35 | rules: [ 36 | { 37 | test: /(\.jsx|\.js)$/, 38 | loader: 'babel-loader', 39 | exclude: /(node_modules|bower_components)/ 40 | }, 41 | { 42 | test: /\.handlebars/, 43 | loader: "handlebars-template-loader" 44 | } 45 | ] 46 | }, 47 | resolve: { 48 | modules: [path.resolve('./node_modules'), path.resolve('./modules')], 49 | extensions: ['.json', '.js', '.handlebars'], 50 | alias: { 51 | 'handlebars': 'handlebars/runtime.js' 52 | } 53 | }, 54 | plugins: plugins 55 | }; 56 | 57 | module.exports = config; --------------------------------------------------------------------------------