├── .babelrc ├── .gitignore ├── LICENSE ├── README.md ├── build ├── 1.0.0 │ ├── build.js │ └── build.js.map └── index.html ├── package.json ├── src ├── index.html ├── index.js ├── links │ ├── about.js │ └── home.js ├── selectors.js ├── site │ ├── constants │ │ └── paths.js │ ├── selected-page.js │ ├── site-header.js │ └── url.js └── todos │ └── todos.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-0"] 3 | } -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Baz 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 | *See [Extreme Decoupling 2 | React, Redux, Selectors ](http://www.thinkloop.com/article/extreme-decoupling-react-redux-selectors/) for more details.* 3 | 4 | # Todo App: Selectors (Integration) 5 | This project integrates the [todo view layer](https://github.com/thinkloop/todo-react-components) project and the [todo state container](https://github.com/thinkloop/todo-redux-state) project to create a functional todo app. Its primary task is to take flat, normalized, shallow state provided by the state container, and transform it into the nested, denormalized, hierarchical structures that the view demands. The mechanism by which it does this is called [selectors](https://github.com/thinkloop/selectors). 6 | 7 | ## Run 8 | 9 | To run the full todo app, clone the repo and start the webserver: 10 | 11 | ``` 12 | > git clone https://github.com/thinkloop/todo-app 13 | > npm start 14 | 15 | // open localhost url 16 | ``` 17 | 18 | ## License 19 | 20 | Released under an MIT license. 21 | 22 | ## Related 23 | - [todo-react-components](https://github.com/thinkloop/todo-react-components): React components for extreme decoupling todo app example 24 | - [todo-redux-state](https://github.com/thinkloop/todo-redux-state): Redux state container for extreme decoupling todo app example 25 | 26 | ## Other 27 | - [memoizerific](https://github.com/thinkloop/memoizerific/): Fast, small, efficient JavaScript memoization to memoize JS functions 28 | - [link-react](https://github.com/thinkloop/link-react/): A generalized link component that allows client-side navigation while taking into account exceptions 29 | - [spa-webserver](https://github.com/thinkloop/spa-webserver/): Webserver that redirects to root index.html if path is missing for client-side SPA navigation 30 | 31 | Like it? Star It 32 | -------------------------------------------------------------------------------- /build/1.0.0/build.js: -------------------------------------------------------------------------------- 1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o { 4 | Object.defineProperty(p, selectorKey, { 5 | get: function() { return selectors[selectorKey](getState(), ...args) }, 6 | enumerable: true 7 | }); 8 | return p; 9 | }, {}); 10 | }; 11 | 12 | },{}],2:[function(require,module,exports){ 13 | (function (process){ 14 | if (typeof Map !== 'function' || (process && process.env && process.env.TEST_MAPORSIMILAR === 'true')) { 15 | module.exports = require('./similar'); 16 | } 17 | else { 18 | module.exports = Map; 19 | } 20 | }).call(this,require('_process')) 21 | 22 | },{"./similar":3,"_process":5}],3:[function(require,module,exports){ 23 | function Similar() { 24 | this.list = []; 25 | this.lastItem = undefined; 26 | this.size = 0; 27 | 28 | return this; 29 | } 30 | 31 | Similar.prototype.get = function(key) { 32 | var index; 33 | 34 | if (this.lastItem && this.isEqual(this.lastItem.key, key)) { 35 | return this.lastItem.val; 36 | } 37 | 38 | index = this.indexOf(key); 39 | if (index >= 0) { 40 | this.lastItem = this.list[index]; 41 | return this.list[index].val; 42 | } 43 | 44 | return undefined; 45 | }; 46 | 47 | Similar.prototype.set = function(key, val) { 48 | var index; 49 | 50 | if (this.lastItem && this.isEqual(this.lastItem.key, key)) { 51 | this.lastItem.val = val; 52 | return this; 53 | } 54 | 55 | index = this.indexOf(key); 56 | if (index >= 0) { 57 | this.lastItem = this.list[index]; 58 | this.list[index].val = val; 59 | return this; 60 | } 61 | 62 | this.lastItem = { key: key, val: val }; 63 | this.list.push(this.lastItem); 64 | this.size++; 65 | 66 | return this; 67 | }; 68 | 69 | Similar.prototype.delete = function(key) { 70 | var index; 71 | 72 | if (this.lastItem && this.isEqual(this.lastItem.key, key)) { 73 | this.lastItem = undefined; 74 | } 75 | 76 | index = this.indexOf(key); 77 | if (index >= 0) { 78 | this.size--; 79 | return this.list.splice(index, 1)[0]; 80 | } 81 | 82 | return undefined; 83 | }; 84 | 85 | 86 | // important that has() doesn't use get() in case an existing key has a falsy value, in which case has() would return false 87 | Similar.prototype.has = function(key) { 88 | var index; 89 | 90 | if (this.lastItem && this.isEqual(this.lastItem.key, key)) { 91 | return true; 92 | } 93 | 94 | index = this.indexOf(key); 95 | if (index >= 0) { 96 | this.lastItem = this.list[index]; 97 | return true; 98 | } 99 | 100 | return false; 101 | }; 102 | 103 | Similar.prototype.forEach = function(callback, thisArg) { 104 | var i; 105 | for (i = 0; i < this.size; i++) { 106 | callback.call(thisArg || this, this.list[i].val, this.list[i].key, this); 107 | } 108 | }; 109 | 110 | Similar.prototype.indexOf = function(key) { 111 | var i; 112 | for (i = 0; i < this.size; i++) { 113 | if (this.isEqual(this.list[i].key, key)) { 114 | return i; 115 | } 116 | } 117 | return -1; 118 | }; 119 | 120 | // check if the numbers are equal, or whether they are both precisely NaN (isNaN returns true for all non-numbers) 121 | Similar.prototype.isEqual = function(val1, val2) { 122 | return val1 === val2 || (val1 !== val1 && val2 !== val2); 123 | }; 124 | 125 | module.exports = Similar; 126 | },{}],4:[function(require,module,exports){ 127 | var MapOrSimilar = require('map-or-similar'); 128 | 129 | module.exports = function (limit) { 130 | var cache = new MapOrSimilar(), 131 | lru = []; 132 | 133 | return function (fn) { 134 | var memoizerific = function () { 135 | var currentCache = cache, 136 | newMap, 137 | fnResult, 138 | argsLengthMinusOne = arguments.length - 1, 139 | lruPath = Array(argsLengthMinusOne + 1), 140 | isMemoized = true, 141 | i; 142 | 143 | if ((memoizerific.numArgs || memoizerific.numArgs === 0) && memoizerific.numArgs !== argsLengthMinusOne + 1) { 144 | throw new Error('Memoizerific functions should always be called with the same number of arguments'); 145 | } 146 | 147 | // loop through each argument to traverse the map tree 148 | for (i = 0; i < argsLengthMinusOne; i++) { 149 | lruPath[i] = { 150 | cacheItem: currentCache, 151 | arg: arguments[i] 152 | }; 153 | 154 | // climb through the hierarchical map tree until the second-last argument has been found, or an argument is missing. 155 | // if all arguments up to the second-last have been found, this will potentially be a cache hit (determined below) 156 | if (currentCache.has(arguments[i])) { 157 | currentCache = currentCache.get(arguments[i]); 158 | continue; 159 | } 160 | 161 | isMemoized = false; 162 | 163 | // make maps until last value 164 | newMap = new MapOrSimilar(); 165 | currentCache.set(arguments[i], newMap); 166 | currentCache = newMap; 167 | } 168 | 169 | // we are at the last arg, check if it is really memoized 170 | if (isMemoized) { 171 | if (currentCache.has(arguments[argsLengthMinusOne])) { 172 | fnResult = currentCache.get(arguments[argsLengthMinusOne]); 173 | } 174 | else { 175 | isMemoized = false; 176 | } 177 | } 178 | 179 | if (!isMemoized) { 180 | fnResult = fn.apply(null, arguments); 181 | currentCache.set(arguments[argsLengthMinusOne], fnResult); 182 | } 183 | 184 | if (limit > 0) { 185 | lruPath[argsLengthMinusOne] = { 186 | cacheItem: currentCache, 187 | arg: arguments[argsLengthMinusOne] 188 | }; 189 | 190 | if (isMemoized) { 191 | moveToMostRecentLru(lru, lruPath); 192 | } 193 | else { 194 | lru.push(lruPath); 195 | } 196 | 197 | if (lru.length > limit) { 198 | removeCachedResult(lru.shift()); 199 | } 200 | } 201 | 202 | memoizerific.wasMemoized = isMemoized; 203 | memoizerific.numArgs = argsLengthMinusOne + 1; 204 | 205 | return fnResult; 206 | }; 207 | 208 | memoizerific.limit = limit; 209 | memoizerific.wasMemoized = false; 210 | memoizerific.cache = cache; 211 | memoizerific.lru = lru; 212 | 213 | return memoizerific; 214 | }; 215 | }; 216 | 217 | // move current args to most recent position 218 | function moveToMostRecentLru(lru, lruPath) { 219 | var lruLen = lru.length, 220 | lruPathLen = lruPath.length, 221 | isMatch, 222 | i, ii; 223 | 224 | for (i = 0; i < lruLen; i++) { 225 | isMatch = true; 226 | for (ii = 0; ii < lruPathLen; ii++) { 227 | if (!isEqual(lru[i][ii].arg, lruPath[ii].arg)) { 228 | isMatch = false; 229 | break; 230 | } 231 | } 232 | if (isMatch) { 233 | break; 234 | } 235 | } 236 | 237 | lru.push(lru.splice(i, 1)[0]); 238 | } 239 | 240 | // remove least recently used cache item and all dead branches 241 | function removeCachedResult(removedLru) { 242 | var removedLruLen = removedLru.length, 243 | currentLru = removedLru[removedLruLen - 1], 244 | tmp, 245 | i; 246 | 247 | currentLru.cacheItem.delete(currentLru.arg); 248 | 249 | // walk down the tree removing dead branches (size 0) along the way 250 | for (i = removedLruLen - 2; i >= 0; i--) { 251 | currentLru = removedLru[i]; 252 | tmp = currentLru.cacheItem.get(currentLru.arg); 253 | 254 | if (!tmp || !tmp.size) { 255 | currentLru.cacheItem.delete(currentLru.arg); 256 | } else { 257 | break; 258 | } 259 | } 260 | } 261 | 262 | // check if the numbers are equal, or whether they are both precisely NaN (isNaN returns true for all non-numbers) 263 | function isEqual(val1, val2) { 264 | return val1 === val2 || (val1 !== val1 && val2 !== val2); 265 | } 266 | },{"map-or-similar":2}],5:[function(require,module,exports){ 267 | // shim for using process in browser 268 | var process = module.exports = {}; 269 | 270 | // cached from whatever global is present so that test runners that stub it 271 | // don't break things. But we need to wrap it in a try catch in case it is 272 | // wrapped in strict mode code which doesn't define any globals. It's inside a 273 | // function because try/catches deoptimize in certain engines. 274 | 275 | var cachedSetTimeout; 276 | var cachedClearTimeout; 277 | 278 | function defaultSetTimout() { 279 | throw new Error('setTimeout has not been defined'); 280 | } 281 | function defaultClearTimeout () { 282 | throw new Error('clearTimeout has not been defined'); 283 | } 284 | (function () { 285 | try { 286 | if (typeof setTimeout === 'function') { 287 | cachedSetTimeout = setTimeout; 288 | } else { 289 | cachedSetTimeout = defaultSetTimout; 290 | } 291 | } catch (e) { 292 | cachedSetTimeout = defaultSetTimout; 293 | } 294 | try { 295 | if (typeof clearTimeout === 'function') { 296 | cachedClearTimeout = clearTimeout; 297 | } else { 298 | cachedClearTimeout = defaultClearTimeout; 299 | } 300 | } catch (e) { 301 | cachedClearTimeout = defaultClearTimeout; 302 | } 303 | } ()) 304 | function runTimeout(fun) { 305 | if (cachedSetTimeout === setTimeout) { 306 | //normal enviroments in sane situations 307 | return setTimeout(fun, 0); 308 | } 309 | // if setTimeout wasn't available but was latter defined 310 | if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { 311 | cachedSetTimeout = setTimeout; 312 | return setTimeout(fun, 0); 313 | } 314 | try { 315 | // when when somebody has screwed with setTimeout but no I.E. maddness 316 | return cachedSetTimeout(fun, 0); 317 | } catch(e){ 318 | try { 319 | // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 320 | return cachedSetTimeout.call(null, fun, 0); 321 | } catch(e){ 322 | // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error 323 | return cachedSetTimeout.call(this, fun, 0); 324 | } 325 | } 326 | 327 | 328 | } 329 | function runClearTimeout(marker) { 330 | if (cachedClearTimeout === clearTimeout) { 331 | //normal enviroments in sane situations 332 | return clearTimeout(marker); 333 | } 334 | // if clearTimeout wasn't available but was latter defined 335 | if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { 336 | cachedClearTimeout = clearTimeout; 337 | return clearTimeout(marker); 338 | } 339 | try { 340 | // when when somebody has screwed with setTimeout but no I.E. maddness 341 | return cachedClearTimeout(marker); 342 | } catch (e){ 343 | try { 344 | // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 345 | return cachedClearTimeout.call(null, marker); 346 | } catch (e){ 347 | // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. 348 | // Some versions of I.E. have different rules for clearTimeout vs setTimeout 349 | return cachedClearTimeout.call(this, marker); 350 | } 351 | } 352 | 353 | 354 | 355 | } 356 | var queue = []; 357 | var draining = false; 358 | var currentQueue; 359 | var queueIndex = -1; 360 | 361 | function cleanUpNextTick() { 362 | if (!draining || !currentQueue) { 363 | return; 364 | } 365 | draining = false; 366 | if (currentQueue.length) { 367 | queue = currentQueue.concat(queue); 368 | } else { 369 | queueIndex = -1; 370 | } 371 | if (queue.length) { 372 | drainQueue(); 373 | } 374 | } 375 | 376 | function drainQueue() { 377 | if (draining) { 378 | return; 379 | } 380 | var timeout = runTimeout(cleanUpNextTick); 381 | draining = true; 382 | 383 | var len = queue.length; 384 | while(len) { 385 | currentQueue = queue; 386 | queue = []; 387 | while (++queueIndex < len) { 388 | if (currentQueue) { 389 | currentQueue[queueIndex].run(); 390 | } 391 | } 392 | queueIndex = -1; 393 | len = queue.length; 394 | } 395 | currentQueue = null; 396 | draining = false; 397 | runClearTimeout(timeout); 398 | } 399 | 400 | process.nextTick = function (fun) { 401 | var args = new Array(arguments.length - 1); 402 | if (arguments.length > 1) { 403 | for (var i = 1; i < arguments.length; i++) { 404 | args[i - 1] = arguments[i]; 405 | } 406 | } 407 | queue.push(new Item(fun, args)); 408 | if (queue.length === 1 && !draining) { 409 | runTimeout(drainQueue); 410 | } 411 | }; 412 | 413 | // v8 likes predictible objects 414 | function Item(fun, array) { 415 | this.fun = fun; 416 | this.array = array; 417 | } 418 | Item.prototype.run = function () { 419 | this.fun.apply(null, this.array); 420 | }; 421 | process.title = 'browser'; 422 | process.browser = true; 423 | process.env = {}; 424 | process.argv = []; 425 | process.version = ''; // empty string to avoid regexp issues 426 | process.versions = {}; 427 | 428 | function noop() {} 429 | 430 | process.on = noop; 431 | process.addListener = noop; 432 | process.once = noop; 433 | process.off = noop; 434 | process.removeListener = noop; 435 | process.removeAllListeners = noop; 436 | process.emit = noop; 437 | 438 | process.binding = function (name) { 439 | throw new Error('process.binding is not supported'); 440 | }; 441 | 442 | process.cwd = function () { return '/' }; 443 | process.chdir = function (dir) { 444 | throw new Error('process.chdir is not supported'); 445 | }; 446 | process.umask = function() { return 0; }; 447 | 448 | },{}],6:[function(require,module,exports){ 449 | (function (global){ 450 | !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.todoReactComponents=e()}}(function(){var e;return function e(t,a,n){function o(s,r){if(!a[s]){if(!t[s]){var u="function"==typeof require&&require;if(!r&&u)return u(s,!0);if(l)return l(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var d=a[s]={exports:{}};t[s][0].call(d.exports,function(e){var a=t[s][1][e];return o(a?a:e)},d,d.exports,e,t,a,n)}return a[s].exports}for(var l="function"==typeof require&&require,s=0;s 0) { 636 | return 'Unexpected ' + (unexpectedKeys.length > 1 ? 'keys' : 'key') + ' ' + ('"' + unexpectedKeys.join('", "') + '" found in ' + argumentName + '. ') + 'Expected to find one of the known reducer keys instead: ' + ('"' + reducerKeys.join('", "') + '". Unexpected keys will be ignored.'); 637 | } 638 | } 639 | 640 | function assertReducerSanity(reducers) { 641 | Object.keys(reducers).forEach(function (key) { 642 | var reducer = reducers[key]; 643 | var initialState = reducer(undefined, { type: _createStore.ActionTypes.INIT }); 644 | 645 | if (typeof initialState === 'undefined') { 646 | throw new Error('Reducer "' + key + '" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined.'); 647 | } 648 | 649 | var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math.random().toString(36).substring(7).split('').join('.'); 650 | if (typeof reducer(undefined, { type: type }) === 'undefined') { 651 | throw new Error('Reducer "' + key + '" returned undefined when probed with a random type. ' + ('Don\'t try to handle ' + _createStore.ActionTypes.INIT + ' or other actions in "redux/*" ') + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined.'); 652 | } 653 | }); 654 | } 655 | 656 | /** 657 | * Turns an object whose values are different reducer functions, into a single 658 | * reducer function. It will call every child reducer, and gather their results 659 | * into a single state object, whose keys correspond to the keys of the passed 660 | * reducer functions. 661 | * 662 | * @param {Object} reducers An object whose values correspond to different 663 | * reducer functions that need to be combined into one. One handy way to obtain 664 | * it is to use ES6 `import * as reducers` syntax. The reducers may never return 665 | * undefined for any action. Instead, they should return their initial state 666 | * if the state passed to them was undefined, and the current state for any 667 | * unrecognized action. 668 | * 669 | * @returns {Function} A reducer function that invokes every reducer inside the 670 | * passed object, and builds a state object with the same shape. 671 | */ 672 | function combineReducers(reducers) { 673 | var reducerKeys = Object.keys(reducers); 674 | var finalReducers = {}; 675 | for (var i = 0; i < reducerKeys.length; i++) { 676 | var key = reducerKeys[i]; 677 | 678 | if ("development" !== 'production') { 679 | if (typeof reducers[key] === 'undefined') { 680 | (0, _warning2['default'])('No reducer provided for key "' + key + '"'); 681 | } 682 | } 683 | 684 | if (typeof reducers[key] === 'function') { 685 | finalReducers[key] = reducers[key]; 686 | } 687 | } 688 | var finalReducerKeys = Object.keys(finalReducers); 689 | 690 | if ("development" !== 'production') { 691 | var unexpectedKeyCache = {}; 692 | } 693 | 694 | var sanityError; 695 | try { 696 | assertReducerSanity(finalReducers); 697 | } catch (e) { 698 | sanityError = e; 699 | } 700 | 701 | return function combination() { 702 | var state = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 703 | var action = arguments[1]; 704 | 705 | if (sanityError) { 706 | throw sanityError; 707 | } 708 | 709 | if ("development" !== 'production') { 710 | var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache); 711 | if (warningMessage) { 712 | (0, _warning2['default'])(warningMessage); 713 | } 714 | } 715 | 716 | var hasChanged = false; 717 | var nextState = {}; 718 | for (var i = 0; i < finalReducerKeys.length; i++) { 719 | var key = finalReducerKeys[i]; 720 | var reducer = finalReducers[key]; 721 | var previousStateForKey = state[key]; 722 | var nextStateForKey = reducer(previousStateForKey, action); 723 | if (typeof nextStateForKey === 'undefined') { 724 | var errorMessage = getUndefinedStateErrorMessage(key, action); 725 | throw new Error(errorMessage); 726 | } 727 | nextState[key] = nextStateForKey; 728 | hasChanged = hasChanged || nextStateForKey !== previousStateForKey; 729 | } 730 | return hasChanged ? nextState : state; 731 | }; 732 | } 733 | },{"./createStore":6,"./utils/warning":8,"lodash/isPlainObject":12}],5:[function(_dereq_,module,exports){ 734 | "use strict"; 735 | 736 | exports.__esModule = true; 737 | exports["default"] = compose; 738 | /** 739 | * Composes single-argument functions from right to left. The rightmost 740 | * function can take multiple arguments as it provides the signature for 741 | * the resulting composite function. 742 | * 743 | * @param {...Function} funcs The functions to compose. 744 | * @returns {Function} A function obtained by composing the argument functions 745 | * from right to left. For example, compose(f, g, h) is identical to doing 746 | * (...args) => f(g(h(...args))). 747 | */ 748 | 749 | function compose() { 750 | for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) { 751 | funcs[_key] = arguments[_key]; 752 | } 753 | 754 | if (funcs.length === 0) { 755 | return function (arg) { 756 | return arg; 757 | }; 758 | } 759 | 760 | if (funcs.length === 1) { 761 | return funcs[0]; 762 | } 763 | 764 | var last = funcs[funcs.length - 1]; 765 | var rest = funcs.slice(0, -1); 766 | return function () { 767 | return rest.reduceRight(function (composed, f) { 768 | return f(composed); 769 | }, last.apply(undefined, arguments)); 770 | }; 771 | } 772 | },{}],6:[function(_dereq_,module,exports){ 773 | 'use strict'; 774 | 775 | exports.__esModule = true; 776 | exports.ActionTypes = undefined; 777 | exports['default'] = createStore; 778 | 779 | var _isPlainObject = _dereq_('lodash/isPlainObject'); 780 | 781 | var _isPlainObject2 = _interopRequireDefault(_isPlainObject); 782 | 783 | var _symbolObservable = _dereq_('symbol-observable'); 784 | 785 | var _symbolObservable2 = _interopRequireDefault(_symbolObservable); 786 | 787 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 788 | 789 | /** 790 | * These are private action types reserved by Redux. 791 | * For any unknown actions, you must return the current state. 792 | * If the current state is undefined, you must return the initial state. 793 | * Do not reference these action types directly in your code. 794 | */ 795 | var ActionTypes = exports.ActionTypes = { 796 | INIT: '@@redux/INIT' 797 | }; 798 | 799 | /** 800 | * Creates a Redux store that holds the state tree. 801 | * The only way to change the data in the store is to call `dispatch()` on it. 802 | * 803 | * There should only be a single store in your app. To specify how different 804 | * parts of the state tree respond to actions, you may combine several reducers 805 | * into a single reducer function by using `combineReducers`. 806 | * 807 | * @param {Function} reducer A function that returns the next state tree, given 808 | * the current state tree and the action to handle. 809 | * 810 | * @param {any} [preloadedState] The initial state. You may optionally specify it 811 | * to hydrate the state from the server in universal apps, or to restore a 812 | * previously serialized user session. 813 | * If you use `combineReducers` to produce the root reducer function, this must be 814 | * an object with the same shape as `combineReducers` keys. 815 | * 816 | * @param {Function} enhancer The store enhancer. You may optionally specify it 817 | * to enhance the store with third-party capabilities such as middleware, 818 | * time travel, persistence, etc. The only store enhancer that ships with Redux 819 | * is `applyMiddleware()`. 820 | * 821 | * @returns {Store} A Redux store that lets you read the state, dispatch actions 822 | * and subscribe to changes. 823 | */ 824 | function createStore(reducer, preloadedState, enhancer) { 825 | var _ref2; 826 | 827 | if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') { 828 | enhancer = preloadedState; 829 | preloadedState = undefined; 830 | } 831 | 832 | if (typeof enhancer !== 'undefined') { 833 | if (typeof enhancer !== 'function') { 834 | throw new Error('Expected the enhancer to be a function.'); 835 | } 836 | 837 | return enhancer(createStore)(reducer, preloadedState); 838 | } 839 | 840 | if (typeof reducer !== 'function') { 841 | throw new Error('Expected the reducer to be a function.'); 842 | } 843 | 844 | var currentReducer = reducer; 845 | var currentState = preloadedState; 846 | var currentListeners = []; 847 | var nextListeners = currentListeners; 848 | var isDispatching = false; 849 | 850 | function ensureCanMutateNextListeners() { 851 | if (nextListeners === currentListeners) { 852 | nextListeners = currentListeners.slice(); 853 | } 854 | } 855 | 856 | /** 857 | * Reads the state tree managed by the store. 858 | * 859 | * @returns {any} The current state tree of your application. 860 | */ 861 | function getState() { 862 | return currentState; 863 | } 864 | 865 | /** 866 | * Adds a change listener. It will be called any time an action is dispatched, 867 | * and some part of the state tree may potentially have changed. You may then 868 | * call `getState()` to read the current state tree inside the callback. 869 | * 870 | * You may call `dispatch()` from a change listener, with the following 871 | * caveats: 872 | * 873 | * 1. The subscriptions are snapshotted just before every `dispatch()` call. 874 | * If you subscribe or unsubscribe while the listeners are being invoked, this 875 | * will not have any effect on the `dispatch()` that is currently in progress. 876 | * However, the next `dispatch()` call, whether nested or not, will use a more 877 | * recent snapshot of the subscription list. 878 | * 879 | * 2. The listener should not expect to see all state changes, as the state 880 | * might have been updated multiple times during a nested `dispatch()` before 881 | * the listener is called. It is, however, guaranteed that all subscribers 882 | * registered before the `dispatch()` started will be called with the latest 883 | * state by the time it exits. 884 | * 885 | * @param {Function} listener A callback to be invoked on every dispatch. 886 | * @returns {Function} A function to remove this change listener. 887 | */ 888 | function subscribe(listener) { 889 | if (typeof listener !== 'function') { 890 | throw new Error('Expected listener to be a function.'); 891 | } 892 | 893 | var isSubscribed = true; 894 | 895 | ensureCanMutateNextListeners(); 896 | nextListeners.push(listener); 897 | 898 | return function unsubscribe() { 899 | if (!isSubscribed) { 900 | return; 901 | } 902 | 903 | isSubscribed = false; 904 | 905 | ensureCanMutateNextListeners(); 906 | var index = nextListeners.indexOf(listener); 907 | nextListeners.splice(index, 1); 908 | }; 909 | } 910 | 911 | /** 912 | * Dispatches an action. It is the only way to trigger a state change. 913 | * 914 | * The `reducer` function, used to create the store, will be called with the 915 | * current state tree and the given `action`. Its return value will 916 | * be considered the **next** state of the tree, and the change listeners 917 | * will be notified. 918 | * 919 | * The base implementation only supports plain object actions. If you want to 920 | * dispatch a Promise, an Observable, a thunk, or something else, you need to 921 | * wrap your store creating function into the corresponding middleware. For 922 | * example, see the documentation for the `redux-thunk` package. Even the 923 | * middleware will eventually dispatch plain object actions using this method. 924 | * 925 | * @param {Object} action A plain object representing “what changed”. It is 926 | * a good idea to keep actions serializable so you can record and replay user 927 | * sessions, or use the time travelling `redux-devtools`. An action must have 928 | * a `type` property which may not be `undefined`. It is a good idea to use 929 | * string constants for action types. 930 | * 931 | * @returns {Object} For convenience, the same action object you dispatched. 932 | * 933 | * Note that, if you use a custom middleware, it may wrap `dispatch()` to 934 | * return something else (for example, a Promise you can await). 935 | */ 936 | function dispatch(action) { 937 | if (!(0, _isPlainObject2['default'])(action)) { 938 | throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.'); 939 | } 940 | 941 | if (typeof action.type === 'undefined') { 942 | throw new Error('Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?'); 943 | } 944 | 945 | if (isDispatching) { 946 | throw new Error('Reducers may not dispatch actions.'); 947 | } 948 | 949 | try { 950 | isDispatching = true; 951 | currentState = currentReducer(currentState, action); 952 | } finally { 953 | isDispatching = false; 954 | } 955 | 956 | var listeners = currentListeners = nextListeners; 957 | for (var i = 0; i < listeners.length; i++) { 958 | listeners[i](); 959 | } 960 | 961 | return action; 962 | } 963 | 964 | /** 965 | * Replaces the reducer currently used by the store to calculate the state. 966 | * 967 | * You might need this if your app implements code splitting and you want to 968 | * load some of the reducers dynamically. You might also need this if you 969 | * implement a hot reloading mechanism for Redux. 970 | * 971 | * @param {Function} nextReducer The reducer for the store to use instead. 972 | * @returns {void} 973 | */ 974 | function replaceReducer(nextReducer) { 975 | if (typeof nextReducer !== 'function') { 976 | throw new Error('Expected the nextReducer to be a function.'); 977 | } 978 | 979 | currentReducer = nextReducer; 980 | dispatch({ type: ActionTypes.INIT }); 981 | } 982 | 983 | /** 984 | * Interoperability point for observable/reactive libraries. 985 | * @returns {observable} A minimal observable of state changes. 986 | * For more information, see the observable proposal: 987 | * https://github.com/zenparsing/es-observable 988 | */ 989 | function observable() { 990 | var _ref; 991 | 992 | var outerSubscribe = subscribe; 993 | return _ref = { 994 | /** 995 | * The minimal observable subscription method. 996 | * @param {Object} observer Any object that can be used as an observer. 997 | * The observer object should have a `next` method. 998 | * @returns {subscription} An object with an `unsubscribe` method that can 999 | * be used to unsubscribe the observable from the store, and prevent further 1000 | * emission of values from the observable. 1001 | */ 1002 | subscribe: function subscribe(observer) { 1003 | if (typeof observer !== 'object') { 1004 | throw new TypeError('Expected the observer to be an object.'); 1005 | } 1006 | 1007 | function observeState() { 1008 | if (observer.next) { 1009 | observer.next(getState()); 1010 | } 1011 | } 1012 | 1013 | observeState(); 1014 | var unsubscribe = outerSubscribe(observeState); 1015 | return { unsubscribe: unsubscribe }; 1016 | } 1017 | }, _ref[_symbolObservable2['default']] = function () { 1018 | return this; 1019 | }, _ref; 1020 | } 1021 | 1022 | // When a store is created, an "INIT" action is dispatched so that every 1023 | // reducer returns their initial state. This effectively populates 1024 | // the initial state tree. 1025 | dispatch({ type: ActionTypes.INIT }); 1026 | 1027 | return _ref2 = { 1028 | dispatch: dispatch, 1029 | subscribe: subscribe, 1030 | getState: getState, 1031 | replaceReducer: replaceReducer 1032 | }, _ref2[_symbolObservable2['default']] = observable, _ref2; 1033 | } 1034 | },{"lodash/isPlainObject":12,"symbol-observable":13}],7:[function(_dereq_,module,exports){ 1035 | 'use strict'; 1036 | 1037 | exports.__esModule = true; 1038 | exports.compose = exports.applyMiddleware = exports.bindActionCreators = exports.combineReducers = exports.createStore = undefined; 1039 | 1040 | var _createStore = _dereq_('./createStore'); 1041 | 1042 | var _createStore2 = _interopRequireDefault(_createStore); 1043 | 1044 | var _combineReducers = _dereq_('./combineReducers'); 1045 | 1046 | var _combineReducers2 = _interopRequireDefault(_combineReducers); 1047 | 1048 | var _bindActionCreators = _dereq_('./bindActionCreators'); 1049 | 1050 | var _bindActionCreators2 = _interopRequireDefault(_bindActionCreators); 1051 | 1052 | var _applyMiddleware = _dereq_('./applyMiddleware'); 1053 | 1054 | var _applyMiddleware2 = _interopRequireDefault(_applyMiddleware); 1055 | 1056 | var _compose = _dereq_('./compose'); 1057 | 1058 | var _compose2 = _interopRequireDefault(_compose); 1059 | 1060 | var _warning = _dereq_('./utils/warning'); 1061 | 1062 | var _warning2 = _interopRequireDefault(_warning); 1063 | 1064 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 1065 | 1066 | /* 1067 | * This is a dummy function to check if the function name has been altered by minification. 1068 | * If the function has been minified and NODE_ENV !== 'production', warn the user. 1069 | */ 1070 | function isCrushed() {} 1071 | 1072 | if ("development" !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') { 1073 | (0, _warning2['default'])('You are currently using minified code outside of NODE_ENV === \'production\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.'); 1074 | } 1075 | 1076 | exports.createStore = _createStore2['default']; 1077 | exports.combineReducers = _combineReducers2['default']; 1078 | exports.bindActionCreators = _bindActionCreators2['default']; 1079 | exports.applyMiddleware = _applyMiddleware2['default']; 1080 | exports.compose = _compose2['default']; 1081 | },{"./applyMiddleware":2,"./bindActionCreators":3,"./combineReducers":4,"./compose":5,"./createStore":6,"./utils/warning":8}],8:[function(_dereq_,module,exports){ 1082 | 'use strict'; 1083 | 1084 | exports.__esModule = true; 1085 | exports['default'] = warning; 1086 | /** 1087 | * Prints a warning in the console if it exists. 1088 | * 1089 | * @param {String} message The warning message. 1090 | * @returns {void} 1091 | */ 1092 | function warning(message) { 1093 | /* eslint-disable no-console */ 1094 | if (typeof console !== 'undefined' && typeof console.error === 'function') { 1095 | console.error(message); 1096 | } 1097 | /* eslint-enable no-console */ 1098 | try { 1099 | // This error was thrown as a convenience so that if you enable 1100 | // "break on all exceptions" in your console, 1101 | // it would pause the execution at this line. 1102 | throw new Error(message); 1103 | /* eslint-disable no-empty */ 1104 | } catch (e) {} 1105 | /* eslint-enable no-empty */ 1106 | } 1107 | },{}],9:[function(_dereq_,module,exports){ 1108 | var overArg = _dereq_('./_overArg'); 1109 | 1110 | /** Built-in value references. */ 1111 | var getPrototype = overArg(Object.getPrototypeOf, Object); 1112 | 1113 | module.exports = getPrototype; 1114 | 1115 | },{"./_overArg":10}],10:[function(_dereq_,module,exports){ 1116 | /** 1117 | * Creates a unary function that invokes `func` with its argument transformed. 1118 | * 1119 | * @private 1120 | * @param {Function} func The function to wrap. 1121 | * @param {Function} transform The argument transform. 1122 | * @returns {Function} Returns the new function. 1123 | */ 1124 | function overArg(func, transform) { 1125 | return function(arg) { 1126 | return func(transform(arg)); 1127 | }; 1128 | } 1129 | 1130 | module.exports = overArg; 1131 | 1132 | },{}],11:[function(_dereq_,module,exports){ 1133 | /** 1134 | * Checks if `value` is object-like. A value is object-like if it's not `null` 1135 | * and has a `typeof` result of "object". 1136 | * 1137 | * @static 1138 | * @memberOf _ 1139 | * @since 4.0.0 1140 | * @category Lang 1141 | * @param {*} value The value to check. 1142 | * @returns {boolean} Returns `true` if `value` is object-like, else `false`. 1143 | * @example 1144 | * 1145 | * _.isObjectLike({}); 1146 | * // => true 1147 | * 1148 | * _.isObjectLike([1, 2, 3]); 1149 | * // => true 1150 | * 1151 | * _.isObjectLike(_.noop); 1152 | * // => false 1153 | * 1154 | * _.isObjectLike(null); 1155 | * // => false 1156 | */ 1157 | function isObjectLike(value) { 1158 | return value != null && typeof value == 'object'; 1159 | } 1160 | 1161 | module.exports = isObjectLike; 1162 | 1163 | },{}],12:[function(_dereq_,module,exports){ 1164 | var getPrototype = _dereq_('./_getPrototype'), 1165 | isObjectLike = _dereq_('./isObjectLike'); 1166 | 1167 | /** `Object#toString` result references. */ 1168 | var objectTag = '[object Object]'; 1169 | 1170 | /** Used for built-in method references. */ 1171 | var funcProto = Function.prototype, 1172 | objectProto = Object.prototype; 1173 | 1174 | /** Used to resolve the decompiled source of functions. */ 1175 | var funcToString = funcProto.toString; 1176 | 1177 | /** Used to check objects for own properties. */ 1178 | var hasOwnProperty = objectProto.hasOwnProperty; 1179 | 1180 | /** Used to infer the `Object` constructor. */ 1181 | var objectCtorString = funcToString.call(Object); 1182 | 1183 | /** 1184 | * Used to resolve the 1185 | * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) 1186 | * of values. 1187 | */ 1188 | var objectToString = objectProto.toString; 1189 | 1190 | /** 1191 | * Checks if `value` is a plain object, that is, an object created by the 1192 | * `Object` constructor or one with a `[[Prototype]]` of `null`. 1193 | * 1194 | * @static 1195 | * @memberOf _ 1196 | * @since 0.8.0 1197 | * @category Lang 1198 | * @param {*} value The value to check. 1199 | * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. 1200 | * @example 1201 | * 1202 | * function Foo() { 1203 | * this.a = 1; 1204 | * } 1205 | * 1206 | * _.isPlainObject(new Foo); 1207 | * // => false 1208 | * 1209 | * _.isPlainObject([1, 2, 3]); 1210 | * // => false 1211 | * 1212 | * _.isPlainObject({ 'x': 0, 'y': 0 }); 1213 | * // => true 1214 | * 1215 | * _.isPlainObject(Object.create(null)); 1216 | * // => true 1217 | */ 1218 | function isPlainObject(value) { 1219 | if (!isObjectLike(value) || objectToString.call(value) != objectTag) { 1220 | return false; 1221 | } 1222 | var proto = getPrototype(value); 1223 | if (proto === null) { 1224 | return true; 1225 | } 1226 | var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; 1227 | return (typeof Ctor == 'function' && 1228 | Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); 1229 | } 1230 | 1231 | module.exports = isPlainObject; 1232 | 1233 | },{"./_getPrototype":9,"./isObjectLike":11}],13:[function(_dereq_,module,exports){ 1234 | module.exports = _dereq_('./lib/index'); 1235 | 1236 | },{"./lib/index":14}],14:[function(_dereq_,module,exports){ 1237 | 'use strict'; 1238 | 1239 | Object.defineProperty(exports, "__esModule", { 1240 | value: true 1241 | }); 1242 | 1243 | var _ponyfill = _dereq_('./ponyfill'); 1244 | 1245 | var _ponyfill2 = _interopRequireDefault(_ponyfill); 1246 | 1247 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 1248 | 1249 | var root = undefined; /* global window */ 1250 | 1251 | if (typeof global !== 'undefined') { 1252 | root = global; 1253 | } else if (typeof window !== 'undefined') { 1254 | root = window; 1255 | } 1256 | 1257 | var result = (0, _ponyfill2['default'])(root); 1258 | exports['default'] = result; 1259 | },{"./ponyfill":15}],15:[function(_dereq_,module,exports){ 1260 | 'use strict'; 1261 | 1262 | Object.defineProperty(exports, "__esModule", { 1263 | value: true 1264 | }); 1265 | exports['default'] = symbolObservablePonyfill; 1266 | function symbolObservablePonyfill(root) { 1267 | var result; 1268 | var _Symbol = root.Symbol; 1269 | 1270 | if (typeof _Symbol === 'function') { 1271 | if (_Symbol.observable) { 1272 | result = _Symbol.observable; 1273 | } else { 1274 | result = _Symbol('observable'); 1275 | _Symbol.observable = result; 1276 | } 1277 | } else { 1278 | result = '@@observable'; 1279 | } 1280 | 1281 | return result; 1282 | }; 1283 | },{}],16:[function(_dereq_,module,exports){ 1284 | 'use strict'; 1285 | 1286 | Object.defineProperty(exports, "__esModule", { 1287 | value: true 1288 | }); 1289 | exports.subscribe = exports.constants = exports.actions = exports.getState = undefined; 1290 | 1291 | var _store = _dereq_('../src/store'); 1292 | 1293 | var _store2 = _interopRequireDefault(_store); 1294 | 1295 | var _pages = _dereq_('./site/constants/pages'); 1296 | 1297 | var PAGES = _interopRequireWildcard(_pages); 1298 | 1299 | var _statuses = _dereq_('./todos/constants/statuses'); 1300 | 1301 | var TODOS_STATUSES = _interopRequireWildcard(_statuses); 1302 | 1303 | var _updateUrl = _dereq_('./site/actions/update-url'); 1304 | 1305 | var _updateUrl2 = _interopRequireDefault(_updateUrl); 1306 | 1307 | var _updateSelectedPage = _dereq_('./site/actions/update-selected-page'); 1308 | 1309 | var _updateSelectedPage2 = _interopRequireDefault(_updateSelectedPage); 1310 | 1311 | var _addTodo = _dereq_('./todos/actions/add-todo'); 1312 | 1313 | var _addTodo2 = _interopRequireDefault(_addTodo); 1314 | 1315 | var _loadTodos = _dereq_('./todos/actions/load-todos'); 1316 | 1317 | var _loadTodos2 = _interopRequireDefault(_loadTodos); 1318 | 1319 | var _removeTodo = _dereq_('./todos/actions/remove-todo'); 1320 | 1321 | var _removeTodo2 = _interopRequireDefault(_removeTodo); 1322 | 1323 | var _completeTodo = _dereq_('./todos/actions/complete-todo'); 1324 | 1325 | var _completeTodo2 = _interopRequireDefault(_completeTodo); 1326 | 1327 | var _updateSelectedSummaryStatus = _dereq_('./todos/actions/update-selected-summary-status'); 1328 | 1329 | var _updateSelectedSummaryStatus2 = _interopRequireDefault(_updateSelectedSummaryStatus); 1330 | 1331 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } 1332 | 1333 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1334 | 1335 | var actionsSet = { 1336 | site: { 1337 | updateURL: _updateUrl2.default, 1338 | updateSelectedPage: _updateSelectedPage2.default 1339 | }, 1340 | todos: { 1341 | addTodo: _addTodo2.default, 1342 | loadTodos: _loadTodos2.default, 1343 | removeTodo: _removeTodo2.default, 1344 | completeTodo: _completeTodo2.default, 1345 | updateSelectedSummaryStatus: _updateSelectedSummaryStatus2.default 1346 | } 1347 | }; 1348 | 1349 | var actions = Object.keys(actionsSet).reduce(function (p1, key1) { 1350 | p1[key1] = Object.keys(actionsSet[key1]).reduce(function (p2, key2) { 1351 | p2[key2] = function () { 1352 | var action = actionsSet[key1][key2].apply(null, arguments); 1353 | _store2.default.dispatch(action); 1354 | return action; 1355 | }; 1356 | return p2; 1357 | }, {}); 1358 | return p1; 1359 | }, {}); 1360 | 1361 | var constants = { 1362 | PAGES: PAGES, 1363 | TODOS_STATUSES: TODOS_STATUSES 1364 | }; 1365 | 1366 | var subscribe = _store2.default.subscribe; 1367 | 1368 | var getState = _store2.default.getState; 1369 | 1370 | exports.default = { 1371 | getState: getState, 1372 | actions: actions, 1373 | constants: constants, 1374 | subscribe: subscribe 1375 | }; 1376 | exports.getState = getState; 1377 | exports.actions = actions; 1378 | exports.constants = constants; 1379 | exports.subscribe = subscribe; 1380 | 1381 | },{"../src/store":23,"./site/actions/update-selected-page":17,"./site/actions/update-url":18,"./site/constants/pages":19,"./todos/actions/add-todo":24,"./todos/actions/complete-todo":25,"./todos/actions/load-todos":26,"./todos/actions/remove-todo":27,"./todos/actions/update-selected-summary-status":28,"./todos/constants/statuses":30}],17:[function(_dereq_,module,exports){ 1382 | 'use strict'; 1383 | 1384 | Object.defineProperty(exports, "__esModule", { 1385 | value: true 1386 | }); 1387 | 1388 | exports.default = function (newSelectedPage) { 1389 | return function (dispatch, getState) { 1390 | var _getState = getState(); 1391 | 1392 | var selectedPage = _getState.selectedPage; 1393 | 1394 | if (selectedPage !== newSelectedPage) { 1395 | dispatch({ type: UPDATE_SELECTED_PAGE, selectedPage: newSelectedPage }); 1396 | } 1397 | }; 1398 | }; 1399 | 1400 | var UPDATE_SELECTED_PAGE = exports.UPDATE_SELECTED_PAGE = 'UPDATE_SELECTED_PAGE'; 1401 | 1402 | },{}],18:[function(_dereq_,module,exports){ 1403 | 'use strict'; 1404 | 1405 | Object.defineProperty(exports, "__esModule", { 1406 | value: true 1407 | }); 1408 | 1409 | exports.default = function (newURL) { 1410 | return function (dispatch, getState) { 1411 | var _getState = getState(); 1412 | 1413 | var url = _getState.url; 1414 | 1415 | if (newURL === url) { 1416 | return; 1417 | } 1418 | 1419 | var splitURL = newURL.split('?'); 1420 | var path = splitURL[0]; 1421 | var searchParams = {}; 1422 | 1423 | if (splitURL.length >= 2) { 1424 | searchParams = parseSearchParams(splitURL[1]); 1425 | } 1426 | 1427 | dispatch({ type: UPDATE_URL, parsedURL: { path: path, searchParams: searchParams, url: newURL } }); 1428 | }; 1429 | }; 1430 | 1431 | var UPDATE_URL = exports.UPDATE_URL = 'UPDATE_URL'; 1432 | 1433 | function parseSearchParams(searchString) { 1434 | var pairSplit = void 0; 1435 | return (searchString || '').replace(/^\?/, '').split('&').reduce(function (p, pair) { 1436 | pairSplit = pair.split('='); 1437 | if (pairSplit.length >= 1 && pairSplit[0].length >= 1) { 1438 | p[decodeURIComponent(pairSplit[0])] = decodeURIComponent(pairSplit[1]) || ''; 1439 | } 1440 | return p; 1441 | }, {}); 1442 | } 1443 | 1444 | },{}],19:[function(_dereq_,module,exports){ 1445 | 'use strict'; 1446 | 1447 | Object.defineProperty(exports, "__esModule", { 1448 | value: true 1449 | }); 1450 | var HOME = exports.HOME = 'HOME'; 1451 | var ABOUT = exports.ABOUT = 'ABOUT'; 1452 | 1453 | },{}],20:[function(_dereq_,module,exports){ 1454 | 'use strict'; 1455 | 1456 | Object.defineProperty(exports, "__esModule", { 1457 | value: true 1458 | }); 1459 | exports.DEFAULT_PATH = exports.PATHS = undefined; 1460 | 1461 | var _pages = _dereq_('../../site/constants/pages'); 1462 | 1463 | var PATHS = exports.PATHS = { 1464 | '/': _pages.HOME, 1465 | '/about': _pages.ABOUT 1466 | }; 1467 | 1468 | var DEFAULT_PATH = exports.DEFAULT_PATH = '/'; 1469 | 1470 | },{"../../site/constants/pages":19}],21:[function(_dereq_,module,exports){ 1471 | 'use strict'; 1472 | 1473 | Object.defineProperty(exports, "__esModule", { 1474 | value: true 1475 | }); 1476 | 1477 | exports.default = function () { 1478 | var selectedPage = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _pages.HOME; 1479 | var action = arguments[1]; 1480 | 1481 | switch (action.type) { 1482 | 1483 | case _updateSelectedPage.UPDATE_SELECTED_PAGE: 1484 | return action.selectedPage; 1485 | 1486 | case _updateUrl.UPDATE_URL: 1487 | return _paths.PATHS[action.parsedURL.path] || _pages.HOME; 1488 | 1489 | default: 1490 | return selectedPage; 1491 | } 1492 | }; 1493 | 1494 | var _updateSelectedPage = _dereq_('../../site/actions/update-selected-page'); 1495 | 1496 | var _updateUrl = _dereq_('../../site/actions/update-url'); 1497 | 1498 | var _pages = _dereq_('../../site/constants/pages'); 1499 | 1500 | var _paths = _dereq_('../../site/constants/paths'); 1501 | 1502 | },{"../../site/actions/update-selected-page":17,"../../site/actions/update-url":18,"../../site/constants/pages":19,"../../site/constants/paths":20}],22:[function(_dereq_,module,exports){ 1503 | 'use strict'; 1504 | 1505 | Object.defineProperty(exports, "__esModule", { 1506 | value: true 1507 | }); 1508 | 1509 | exports.default = function () { 1510 | var url = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _paths.DEFAULT_PATH; 1511 | var action = arguments[1]; 1512 | 1513 | switch (action.type) { 1514 | 1515 | case _updateUrl.UPDATE_URL: 1516 | return action.parsedURL.url; 1517 | 1518 | default: 1519 | return url; 1520 | } 1521 | }; 1522 | 1523 | var _updateUrl = _dereq_('../../site/actions/update-url'); 1524 | 1525 | var _paths = _dereq_('../../site/constants/paths'); 1526 | 1527 | },{"../../site/actions/update-url":18,"../../site/constants/paths":20}],23:[function(_dereq_,module,exports){ 1528 | 'use strict'; 1529 | 1530 | Object.defineProperty(exports, "__esModule", { 1531 | value: true 1532 | }); 1533 | 1534 | var _redux = _dereq_('redux'); 1535 | 1536 | var _reduxThunk = _dereq_('redux-thunk'); 1537 | 1538 | var _reduxThunk2 = _interopRequireDefault(_reduxThunk); 1539 | 1540 | var _url = _dereq_('./site/reducers/url'); 1541 | 1542 | var _url2 = _interopRequireDefault(_url); 1543 | 1544 | var _selectedPage = _dereq_('./site/reducers/selected-page'); 1545 | 1546 | var _selectedPage2 = _interopRequireDefault(_selectedPage); 1547 | 1548 | var _todos = _dereq_('./todos/reducers/todos'); 1549 | 1550 | var _todos2 = _interopRequireDefault(_todos); 1551 | 1552 | var _selectedSummaryStatus = _dereq_('./todos/reducers/selected-summary-status'); 1553 | 1554 | var _selectedSummaryStatus2 = _interopRequireDefault(_selectedSummaryStatus); 1555 | 1556 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1557 | 1558 | // reducers 1559 | var reducers = { 1560 | url: _url2.default, 1561 | selectedPage: _selectedPage2.default, 1562 | todos: _todos2.default, 1563 | selectedSummaryStatus: _selectedSummaryStatus2.default 1564 | }; 1565 | 1566 | // middleware that logs all actions to console 1567 | var consoleLog = function consoleLog(store) { 1568 | return function (next) { 1569 | return function (action) { 1570 | if (typeof action !== 'function') { 1571 | console.log(action); 1572 | } 1573 | return next(action); 1574 | }; 1575 | }; 1576 | }; 1577 | 1578 | // middleware 1579 | var middleWare = void 0; 1580 | if (process.env.NODE_ENV !== 'production') { 1581 | middleWare = (0, _redux.applyMiddleware)(consoleLog, _reduxThunk2.default); 1582 | } else { 1583 | middleWare = (0, _redux.applyMiddleware)(_reduxThunk2.default); 1584 | } 1585 | 1586 | // create store 1587 | exports.default = (0, _redux.createStore)((0, _redux.combineReducers)(reducers), middleWare); 1588 | 1589 | },{"./site/reducers/selected-page":21,"./site/reducers/url":22,"./todos/reducers/selected-summary-status":31,"./todos/reducers/todos":32,"redux":7,"redux-thunk":1}],24:[function(_dereq_,module,exports){ 1590 | 'use strict'; 1591 | 1592 | Object.defineProperty(exports, "__esModule", { 1593 | value: true 1594 | }); 1595 | 1596 | exports.default = function (description) { 1597 | return function (dispatch, getState) { 1598 | if (!description || !description.length) { 1599 | return Promise.resolve(null); 1600 | } 1601 | 1602 | return (0, _newTodo2.default)(description).then(function (todo) { 1603 | var id = todo.id; 1604 | delete todo.id; 1605 | dispatch((0, _updateTodos3.default)(_defineProperty({}, id, todo))); 1606 | }); 1607 | }; 1608 | }; 1609 | 1610 | var _newTodo = _dereq_('../../todos/services/fake-backend/new-todo'); 1611 | 1612 | var _newTodo2 = _interopRequireDefault(_newTodo); 1613 | 1614 | var _updateTodos2 = _dereq_('../../todos/actions/update-todos'); 1615 | 1616 | var _updateTodos3 = _interopRequireDefault(_updateTodos2); 1617 | 1618 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1619 | 1620 | function _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; } 1621 | 1622 | },{"../../todos/actions/update-todos":29,"../../todos/services/fake-backend/new-todo":35}],25:[function(_dereq_,module,exports){ 1623 | 'use strict'; 1624 | 1625 | Object.defineProperty(exports, "__esModule", { 1626 | value: true 1627 | }); 1628 | 1629 | exports.default = function (id, isComplete) { 1630 | return function (dispatch, getState) { 1631 | var _getState = getState(); 1632 | 1633 | var todos = _getState.todos; 1634 | 1635 | var todo = todos[id]; 1636 | 1637 | if (!todo) { 1638 | return; 1639 | } 1640 | 1641 | todo.isComplete = isComplete; 1642 | 1643 | return (0, _saveTodo2.default)(id, todo).then(function (res) { 1644 | dispatch((0, _updateTodos3.default)(_defineProperty({}, res.id, res.todo))); 1645 | }); 1646 | }; 1647 | }; 1648 | 1649 | var _saveTodo = _dereq_('../../todos/services/fake-backend/save-todo'); 1650 | 1651 | var _saveTodo2 = _interopRequireDefault(_saveTodo); 1652 | 1653 | var _updateTodos2 = _dereq_('../../todos/actions/update-todos'); 1654 | 1655 | var _updateTodos3 = _interopRequireDefault(_updateTodos2); 1656 | 1657 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1658 | 1659 | function _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; } 1660 | 1661 | },{"../../todos/actions/update-todos":29,"../../todos/services/fake-backend/save-todo":36}],26:[function(_dereq_,module,exports){ 1662 | 'use strict'; 1663 | 1664 | Object.defineProperty(exports, "__esModule", { 1665 | value: true 1666 | }); 1667 | exports.LOAD_TODOS = undefined; 1668 | 1669 | exports.default = function (todos) { 1670 | return function (dispatch, getState) { 1671 | return (0, _loadAllTodos2.default)().then(function (todos) { 1672 | if (!todos) { 1673 | return Promise.resolve(null); 1674 | } 1675 | dispatch((0, _updateTodos2.default)(todos)); 1676 | }); 1677 | }; 1678 | }; 1679 | 1680 | var _loadAllTodos = _dereq_('../../todos/services/fake-backend/load-all-todos'); 1681 | 1682 | var _loadAllTodos2 = _interopRequireDefault(_loadAllTodos); 1683 | 1684 | var _updateTodos = _dereq_('../../todos/actions/update-todos'); 1685 | 1686 | var _updateTodos2 = _interopRequireDefault(_updateTodos); 1687 | 1688 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1689 | 1690 | var LOAD_TODOS = exports.LOAD_TODOS = 'LOAD_TODOS'; 1691 | 1692 | },{"../../todos/actions/update-todos":29,"../../todos/services/fake-backend/load-all-todos":34}],27:[function(_dereq_,module,exports){ 1693 | 'use strict'; 1694 | 1695 | Object.defineProperty(exports, "__esModule", { 1696 | value: true 1697 | }); 1698 | 1699 | exports.default = function (id) { 1700 | return function (dispatch, getState) { 1701 | return (0, _deleteTodo2.default)(id).then(function (todo) { 1702 | dispatch((0, _updateTodos3.default)(_defineProperty({}, id, null))); 1703 | }); 1704 | }; 1705 | }; 1706 | 1707 | var _deleteTodo = _dereq_('../../todos/services/fake-backend/delete-todo'); 1708 | 1709 | var _deleteTodo2 = _interopRequireDefault(_deleteTodo); 1710 | 1711 | var _updateTodos2 = _dereq_('../../todos/actions/update-todos'); 1712 | 1713 | var _updateTodos3 = _interopRequireDefault(_updateTodos2); 1714 | 1715 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1716 | 1717 | function _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; } 1718 | 1719 | },{"../../todos/actions/update-todos":29,"../../todos/services/fake-backend/delete-todo":33}],28:[function(_dereq_,module,exports){ 1720 | 'use strict'; 1721 | 1722 | Object.defineProperty(exports, "__esModule", { 1723 | value: true 1724 | }); 1725 | 1726 | exports.default = function (selectedSummaryStatus) { 1727 | return { type: UPDATE_SELECTED_SUMMARY_STATUS, selectedSummaryStatus: selectedSummaryStatus }; 1728 | }; 1729 | 1730 | var UPDATE_SELECTED_SUMMARY_STATUS = exports.UPDATE_SELECTED_SUMMARY_STATUS = 'UPDATE_SELECTED_SUMMARY_STATUS'; 1731 | 1732 | },{}],29:[function(_dereq_,module,exports){ 1733 | 'use strict'; 1734 | 1735 | Object.defineProperty(exports, "__esModule", { 1736 | value: true 1737 | }); 1738 | 1739 | exports.default = function (todos) { 1740 | return { type: UPDATE_TODOS, todos: todos }; 1741 | }; 1742 | 1743 | var UPDATE_TODOS = exports.UPDATE_TODOS = 'UPDATE_TODOS'; 1744 | 1745 | },{}],30:[function(_dereq_,module,exports){ 1746 | 'use strict'; 1747 | 1748 | Object.defineProperty(exports, "__esModule", { 1749 | value: true 1750 | }); 1751 | var PENDING = exports.PENDING = 'PENDING'; 1752 | var COMPLETE = exports.COMPLETE = 'COMPLETE'; 1753 | var TOTAL = exports.TOTAL = 'TOTAL'; 1754 | 1755 | },{}],31:[function(_dereq_,module,exports){ 1756 | 'use strict'; 1757 | 1758 | Object.defineProperty(exports, "__esModule", { 1759 | value: true 1760 | }); 1761 | 1762 | exports.default = function () { 1763 | var selectedSummaryStatus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _statuses.TOTAL; 1764 | var action = arguments[1]; 1765 | 1766 | switch (action.type) { 1767 | case _updateSelectedSummaryStatus.UPDATE_SELECTED_SUMMARY_STATUS: 1768 | return action.selectedSummaryStatus; 1769 | 1770 | default: 1771 | return selectedSummaryStatus; 1772 | } 1773 | }; 1774 | 1775 | var _updateSelectedSummaryStatus = _dereq_('../../todos/actions/update-selected-summary-status'); 1776 | 1777 | var _statuses = _dereq_('../../todos/constants/statuses'); 1778 | 1779 | },{"../../todos/actions/update-selected-summary-status":28,"../../todos/constants/statuses":30}],32:[function(_dereq_,module,exports){ 1780 | 'use strict'; 1781 | 1782 | Object.defineProperty(exports, "__esModule", { 1783 | value: true 1784 | }); 1785 | 1786 | var _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; }; 1787 | 1788 | exports.default = function () { 1789 | var todos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 1790 | var action = arguments[1]; 1791 | 1792 | var newTodos = void 0; 1793 | 1794 | switch (action.type) { 1795 | case _updateTodos.UPDATE_TODOS: 1796 | newTodos = _extends({}, todos); 1797 | 1798 | Object.keys(action.todos).forEach(function (key) { 1799 | if (action.todos[key]) { 1800 | newTodos[key] = action.todos[key]; 1801 | } else { 1802 | delete newTodos[key]; 1803 | } 1804 | }); 1805 | 1806 | return newTodos; 1807 | 1808 | default: 1809 | return todos; 1810 | } 1811 | }; 1812 | 1813 | var _updateTodos = _dereq_('../../todos/actions/update-todos'); 1814 | 1815 | },{"../../todos/actions/update-todos":29}],33:[function(_dereq_,module,exports){ 1816 | "use strict"; 1817 | 1818 | Object.defineProperty(exports, "__esModule", { 1819 | value: true 1820 | }); 1821 | 1822 | exports.default = function (id) { 1823 | return new Promise(function (r, x) { 1824 | setTimeout(function () { 1825 | return r(true); 1826 | }, 50); 1827 | }); 1828 | }; 1829 | 1830 | },{}],34:[function(_dereq_,module,exports){ 1831 | 'use strict'; 1832 | 1833 | Object.defineProperty(exports, "__esModule", { 1834 | value: true 1835 | }); 1836 | 1837 | exports.default = function () { 1838 | var todos = { 1839 | '10': { 1840 | description: 'Buy tomatoes from grocery store', 1841 | dateCreated: '2016-09-19T18:44:15.635', 1842 | isComplete: false 1843 | }, 1844 | '3': { 1845 | description: 'Finish writing blog post', 1846 | dateCreated: '2016-09-20T18:44:18.635', 1847 | isComplete: false 1848 | } 1849 | }; 1850 | 1851 | return new Promise(function (r, x) { 1852 | setTimeout(function () { 1853 | return r(todos); 1854 | }, 50); 1855 | }); 1856 | }; 1857 | 1858 | },{}],35:[function(_dereq_,module,exports){ 1859 | "use strict"; 1860 | 1861 | Object.defineProperty(exports, "__esModule", { 1862 | value: true 1863 | }); 1864 | 1865 | exports.default = function (description) { 1866 | var id = Math.round(Math.random() * 10000).toFixed(); 1867 | var newTodo = { 1868 | id: id, 1869 | description: description, 1870 | dateCreated: new Date().toISOString(), 1871 | isComplete: false 1872 | }; 1873 | 1874 | return new Promise(function (r, x) { 1875 | setTimeout(function () { 1876 | return r(newTodo); 1877 | }, 50); 1878 | }); 1879 | }; 1880 | 1881 | },{}],36:[function(_dereq_,module,exports){ 1882 | "use strict"; 1883 | 1884 | Object.defineProperty(exports, "__esModule", { 1885 | value: true 1886 | }); 1887 | 1888 | exports.default = function (id, todo) { 1889 | return new Promise(function (r, x) { 1890 | setTimeout(function () { 1891 | return r({ id: id, todo: todo }); 1892 | }, 50); 1893 | }); 1894 | }; 1895 | 1896 | },{}]},{},[16])(16) 1897 | }); 1898 | }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1899 | 1900 | },{"_process":5}],8:[function(require,module,exports){ 1901 | 'use strict'; 1902 | 1903 | var _todoReduxState = require('todo-redux-state'); 1904 | 1905 | var _todoReactComponents = require('todo-react-components'); 1906 | 1907 | var _selectors = require('./selectors'); 1908 | 1909 | var _selectors2 = _interopRequireDefault(_selectors); 1910 | 1911 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1912 | 1913 | // debug stuff 1914 | Object.defineProperty(window, "state", { get: _todoReduxState.getState }); 1915 | window.selectors = _selectors2.default; 1916 | window.actions = _todoReduxState.actions; 1917 | console.log('********************************************* \n DEVELOPMENT MODE \n window.state available \n window.selectors available \n ********************************************* \n'); 1918 | 1919 | // read the url and navigate to the right page 1920 | _todoReduxState.actions.site.updateURL(window.location.pathname + window.location.search); 1921 | 1922 | // load todos 1923 | _todoReduxState.actions.todos.loadTodos(); 1924 | 1925 | // listen for back button, forward button, etc 1926 | window.onpopstate = function (e) { 1927 | _todoReduxState.actions.site.updateURL(window.location.pathname + window.location.search); 1928 | }; 1929 | 1930 | // subscribe to state changes and re-render view on every change 1931 | var htmlElement = document.getElementById('app'); 1932 | (0, _todoReduxState.subscribe)(function () { 1933 | return (0, _todoReactComponents.render)(_selectors2.default, htmlElement); 1934 | }); 1935 | 1936 | },{"./selectors":11,"todo-react-components":6,"todo-redux-state":7}],9:[function(require,module,exports){ 1937 | 'use strict'; 1938 | 1939 | Object.defineProperty(exports, "__esModule", { 1940 | value: true 1941 | }); 1942 | exports.selectAboutLink = undefined; 1943 | 1944 | exports.default = function (state) { 1945 | return selectAboutLink(); 1946 | }; 1947 | 1948 | var _memoizerific = require('memoizerific'); 1949 | 1950 | var _memoizerific2 = _interopRequireDefault(_memoizerific); 1951 | 1952 | var _todoReduxState = require('todo-redux-state'); 1953 | 1954 | var _paths = require('../site/constants/paths'); 1955 | 1956 | var PATHS = _interopRequireWildcard(_paths); 1957 | 1958 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } 1959 | 1960 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1961 | 1962 | var selectAboutLink = exports.selectAboutLink = (0, _memoizerific2.default)(1)(function () { 1963 | var url = PATHS[_todoReduxState.constants.PAGES.ABOUT]; 1964 | return { 1965 | label: 'About', 1966 | href: url, 1967 | onClick: function onClick() { 1968 | return _todoReduxState.actions.site.updateURL(url); 1969 | } 1970 | }; 1971 | }); 1972 | 1973 | },{"../site/constants/paths":12,"memoizerific":4,"todo-redux-state":7}],10:[function(require,module,exports){ 1974 | 'use strict'; 1975 | 1976 | Object.defineProperty(exports, "__esModule", { 1977 | value: true 1978 | }); 1979 | exports.selectHomeLink = undefined; 1980 | 1981 | exports.default = function (state) { 1982 | return selectHomeLink(); 1983 | }; 1984 | 1985 | var _memoizerific = require('memoizerific'); 1986 | 1987 | var _memoizerific2 = _interopRequireDefault(_memoizerific); 1988 | 1989 | var _todoReduxState = require('todo-redux-state'); 1990 | 1991 | var _paths = require('../site/constants/paths'); 1992 | 1993 | var PATHS = _interopRequireWildcard(_paths); 1994 | 1995 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } 1996 | 1997 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1998 | 1999 | var selectHomeLink = exports.selectHomeLink = (0, _memoizerific2.default)(1)(function () { 2000 | var url = PATHS[_todoReduxState.constants.PAGES.HOME]; 2001 | return { 2002 | label: 'Home', 2003 | href: url, 2004 | onClick: function onClick() { 2005 | return _todoReduxState.actions.site.updateURL(url); 2006 | } 2007 | }; 2008 | }); 2009 | 2010 | },{"../site/constants/paths":12,"memoizerific":4,"todo-redux-state":7}],11:[function(require,module,exports){ 2011 | 'use strict'; 2012 | 2013 | Object.defineProperty(exports, "__esModule", { 2014 | value: true 2015 | }); 2016 | 2017 | var _combineSelectors = require('combine-selectors'); 2018 | 2019 | var _combineSelectors2 = _interopRequireDefault(_combineSelectors); 2020 | 2021 | var _todoReduxState = require('todo-redux-state'); 2022 | 2023 | var _selectedPage = require('./site/selected-page'); 2024 | 2025 | var _selectedPage2 = _interopRequireDefault(_selectedPage); 2026 | 2027 | var _url = require('./site/url'); 2028 | 2029 | var _url2 = _interopRequireDefault(_url); 2030 | 2031 | var _siteHeader = require('./site/site-header'); 2032 | 2033 | var _siteHeader2 = _interopRequireDefault(_siteHeader); 2034 | 2035 | var _todos = require('./todos/todos'); 2036 | 2037 | var _todos2 = _interopRequireDefault(_todos); 2038 | 2039 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 2040 | 2041 | var selectors = { 2042 | selectedPage: _selectedPage2.default, 2043 | url: _url2.default, 2044 | siteHeader: _siteHeader2.default, 2045 | todos: _todos2.default 2046 | }; 2047 | 2048 | exports.default = (0, _combineSelectors2.default)(selectors, _todoReduxState.getState); 2049 | 2050 | },{"./site/selected-page":13,"./site/site-header":14,"./site/url":15,"./todos/todos":16,"combine-selectors":1,"todo-redux-state":7}],12:[function(require,module,exports){ 2051 | 'use strict'; 2052 | 2053 | Object.defineProperty(exports, "__esModule", { 2054 | value: true 2055 | }); 2056 | var HOME = exports.HOME = '/'; 2057 | var ABOUT = exports.ABOUT = '/about'; 2058 | 2059 | },{}],13:[function(require,module,exports){ 2060 | 'use strict'; 2061 | 2062 | Object.defineProperty(exports, "__esModule", { 2063 | value: true 2064 | }); 2065 | exports.selectSelectedPage = undefined; 2066 | 2067 | exports.default = function (state) { 2068 | var selectedPage = state.selectedPage; 2069 | 2070 | return selectSelectedPage(selectedPage); 2071 | }; 2072 | 2073 | var _memoizerific = require('memoizerific'); 2074 | 2075 | var _memoizerific2 = _interopRequireDefault(_memoizerific); 2076 | 2077 | var _todoReactComponents = require('todo-react-components'); 2078 | 2079 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 2080 | 2081 | var selectSelectedPage = exports.selectSelectedPage = (0, _memoizerific2.default)(1)(function (selectedPage) { 2082 | return _todoReactComponents.constants.PAGES[selectedPage]; 2083 | }); 2084 | 2085 | },{"memoizerific":4,"todo-react-components":6}],14:[function(require,module,exports){ 2086 | 'use strict'; 2087 | 2088 | Object.defineProperty(exports, "__esModule", { 2089 | value: true 2090 | }); 2091 | exports.selectSiteHeader = undefined; 2092 | 2093 | exports.default = function (state) { 2094 | var selectedPage = state.selectedPage; 2095 | 2096 | return selectSiteHeader(selectedPage); 2097 | }; 2098 | 2099 | var _memoizerific = require('memoizerific'); 2100 | 2101 | var _memoizerific2 = _interopRequireDefault(_memoizerific); 2102 | 2103 | var _paths = require('../site/constants/paths'); 2104 | 2105 | var PATHS = _interopRequireWildcard(_paths); 2106 | 2107 | var _home = require('../links/home'); 2108 | 2109 | var _about = require('../links/about'); 2110 | 2111 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } 2112 | 2113 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 2114 | 2115 | var selectSiteHeader = exports.selectSiteHeader = (0, _memoizerific2.default)(1)(function (selectedPage) { 2116 | return { 2117 | selectedPage: selectedPage, 2118 | homeLink: (0, _home.selectHomeLink)(), 2119 | aboutLink: (0, _about.selectAboutLink)() 2120 | }; 2121 | }); 2122 | 2123 | },{"../links/about":9,"../links/home":10,"../site/constants/paths":12,"memoizerific":4}],15:[function(require,module,exports){ 2124 | "use strict"; 2125 | 2126 | Object.defineProperty(exports, "__esModule", { 2127 | value: true 2128 | }); 2129 | 2130 | exports.default = function (state) { 2131 | var url = state.url; 2132 | 2133 | return url; 2134 | }; 2135 | 2136 | },{}],16:[function(require,module,exports){ 2137 | 'use strict'; 2138 | 2139 | Object.defineProperty(exports, "__esModule", { 2140 | value: true 2141 | }); 2142 | exports.selectTodos = undefined; 2143 | 2144 | var _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; }; 2145 | 2146 | exports.default = function (state) { 2147 | var todos = state.todos; 2148 | var selectedSummaryStatus = state.selectedSummaryStatus; 2149 | 2150 | 2151 | return selectTodos(todos, selectedSummaryStatus); 2152 | }; 2153 | 2154 | var _memoizerific = require('memoizerific'); 2155 | 2156 | var _memoizerific2 = _interopRequireDefault(_memoizerific); 2157 | 2158 | var _todoReduxState = require('todo-redux-state'); 2159 | 2160 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 2161 | 2162 | var _actions$todos = _todoReduxState.actions.todos; 2163 | var addTodo = _actions$todos.addTodo; 2164 | var removeTodo = _actions$todos.removeTodo; 2165 | var completeTodo = _actions$todos.completeTodo; 2166 | var updateSelectedSummaryStatus = _actions$todos.updateSelectedSummaryStatus; 2167 | var TODOS_STATUSES = _todoReduxState.constants.TODOS_STATUSES; 2168 | var selectTodos = exports.selectTodos = (0, _memoizerific2.default)(1)(function (todos, selectedSummaryStatus) { 2169 | 2170 | var newForm = { 2171 | placeholder: 'What do you need to do?', 2172 | onSubmit: function onSubmit(description) { 2173 | return addTodo(description); 2174 | } 2175 | }; 2176 | 2177 | var list = Object.keys(todos).map(function (key) { 2178 | return _extends({}, todos[key], { 2179 | id: key, 2180 | buttonLabel: 'delete', 2181 | onButtonClicked: function onButtonClicked() { 2182 | return removeTodo(key); 2183 | }, 2184 | onCheckboxToggled: function onCheckboxToggled() { 2185 | return completeTodo(key, !todos[key].isComplete); 2186 | } 2187 | }); 2188 | }); 2189 | 2190 | var summary = list.reduce(function (p, todo) { 2191 | !todo.isComplete && p.countIncomplete++; 2192 | todo.isComplete && p.countComplete++; 2193 | p.countTotal++; 2194 | return p; 2195 | }, { 2196 | countIncomplete: 0, 2197 | countComplete: 0, 2198 | countTotal: 0 2199 | }); 2200 | 2201 | list = list.filter(function (todo) { 2202 | return selectedSummaryStatus === TODOS_STATUSES.TOTAL || selectedSummaryStatus === TODOS_STATUSES.COMPLETE && todo.isComplete || selectedSummaryStatus === TODOS_STATUSES.PENDING && !todo.isComplete; 2203 | }).sort(function (a, b) { 2204 | if (a.dateCreated < b.dateCreated) { 2205 | return -1; 2206 | } 2207 | if (a.dateCreated > b.dateCreated) { 2208 | return 1; 2209 | } 2210 | if (a.id < b.id) { 2211 | return -1; 2212 | } 2213 | return 1; 2214 | }); 2215 | 2216 | summary.countIncomplete = summary.countIncomplete + ' pending'; 2217 | summary.countComplete = summary.countComplete + ' complete'; 2218 | summary.countTotal = summary.countTotal + ' total'; 2219 | 2220 | summary.selectedSummaryStatus = selectedSummaryStatus; 2221 | 2222 | summary.onClickPending = function () { 2223 | return updateSelectedSummaryStatus(TODOS_STATUSES.PENDING); 2224 | }; 2225 | summary.onClickComplete = function () { 2226 | return updateSelectedSummaryStatus(TODOS_STATUSES.COMPLETE); 2227 | }; 2228 | summary.onClickTotal = function () { 2229 | return updateSelectedSummaryStatus(TODOS_STATUSES.TOTAL); 2230 | }; 2231 | 2232 | return { 2233 | newForm: newForm, 2234 | list: list, 2235 | summary: summary 2236 | }; 2237 | }); 2238 | 2239 | },{"memoizerific":4,"todo-redux-state":7}]},{},[8]) 2240 | //# sourceMappingURL=build.js.map 2241 | -------------------------------------------------------------------------------- /build/1.0.0/build.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "sources": [ 4 | "node_modules/browser-pack/_prelude.js", 5 | "node_modules/combine-selectors/src/combine-selectors.js", 6 | "node_modules/map-or-similar/src/map-or-similar.js", 7 | "node_modules/map-or-similar/src/similar.js", 8 | "node_modules/memoizerific/src/memoizerific.js", 9 | "node_modules/process/browser.js", 10 | "node_modules/todo-react-components/build/todo-react-components.js", 11 | "node_modules/todo-redux-state/build/todo-redux-state.js", 12 | "src/index.js", 13 | "src/links/about.js", 14 | "src/links/home.js", 15 | "src/selectors.js", 16 | "src/site/constants/paths.js", 17 | "src/site/selected-page.js", 18 | "src/site/site-header.js", 19 | "src/site/url.js", 20 | "src/todos/todos.js" 21 | ], 22 | "names": [], 23 | "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACTA;AACA;AACA;AACA;AACA;AACA;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACpLA;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACl6CA;;AACA;;AAEA;;;;;;AAEA;AACA,OAAO,cAAP,CAAsB,MAAtB,EAA8B,OAA9B,EAAuC,EAAE,6BAAF,EAAvC;AACA,OAAO,SAAP;AACA,OAAO,OAAP;AACA,QAAQ,GAAR,CAAY,+KAAZ;;AAEA;AACA,wBAAQ,IAAR,CAAa,SAAb,CAAuB,OAAO,QAAP,CAAgB,QAAhB,GAA2B,OAAO,QAAP,CAAgB,MAAlE;;AAEA;AACA,wBAAQ,KAAR,CAAc,SAAd;;AAEA;AACA,OAAO,UAAP,GAAoB,UAAC,CAAD,EAAO;AACvB,4BAAQ,IAAR,CAAa,SAAb,CAAuB,OAAO,QAAP,CAAgB,QAAhB,GAA2B,OAAO,QAAP,CAAgB,MAAlE;AACH,CAFD;;AAIA;AACA,IAAM,cAAc,SAAS,cAAT,CAAwB,KAAxB,CAApB;AACA,+BAAU;AAAA,WAAM,sDAAkB,WAAlB,CAAN;AAAA,CAAV;;;;;;;;;;kBCnBe,UAAU,KAAV,EAAiB;AAC/B,QAAO,iBAAP;AACA,C;;AAPD;;;;AACA;;AAEA;;IAAY,K;;;;;;AAML,IAAM,4CAAkB,4BAAa,CAAb,EAAgB,YAAM;AACpD,KAAM,MAAM,MAAM,0BAAU,KAAV,CAAgB,KAAtB,CAAZ;AACA,QAAO;AACN,SAAO,OADD;AAEN,QAAM,GAFA;AAGN,WAAS;AAAA,UAAM,wBAAQ,IAAR,CAAa,SAAb,CAAuB,GAAvB,CAAN;AAAA;AAHH,EAAP;AAKA,CAP8B,CAAxB;;;;;;;;;;kBCJQ,UAAU,KAAV,EAAiB;AAC/B,QAAO,gBAAP;AACA,C;;AAPD;;;;AACA;;AAEA;;IAAY,K;;;;;;AAML,IAAM,0CAAiB,4BAAa,CAAb,EAAgB,YAAM;AACnD,KAAM,MAAM,MAAM,0BAAU,KAAV,CAAgB,IAAtB,CAAZ;AACA,QAAO;AACN,SAAO,MADD;AAEN,QAAM,GAFA;AAGN,WAAS;AAAA,UAAM,wBAAQ,IAAR,CAAa,SAAb,CAAuB,GAAvB,CAAN;AAAA;AAHH,EAAP;AAKA,CAP6B,CAAvB;;;;;;;;;ACTP;;;;AACA;;AAEA;;;;AACA;;;;AACA;;;;AACA;;;;;;AAEA,IAAM,YAAY;AACjB,qCADiB;AAEjB,mBAFiB;AAGjB,iCAHiB;AAIjB;AAJiB,CAAlB;;kBAOe,gCAAiB,SAAjB,2B;;;;;;;;ACfR,IAAM,sBAAO,GAAb;AACA,IAAM,wBAAQ,QAAd;;;;;;;;;;kBCEQ,UAAU,KAAV,EAAiB;AAAA,KACvB,YADuB,GACN,KADM,CACvB,YADuB;;AAE/B,QAAO,mBAAmB,YAAnB,CAAP;AACA,C;;AAND;;;;AACA;;;;AAOO,IAAM,kDAAqB,4BAAa,CAAb,EAAgB,UAAC,YAAD,EAAkB;AACnE,QAAO,+BAAU,KAAV,CAAgB,YAAhB,CAAP;AACA,CAFiC,CAA3B;;;;;;;;;;kBCAQ,UAAU,KAAV,EAAiB;AAAA,KACvB,YADuB,GACN,KADM,CACvB,YADuB;;AAE/B,QAAO,iBAAiB,YAAjB,CAAP;AACA,C;;AAXD;;;;AAEA;;IAAY,K;;AAEZ;;AACA;;;;;;AAQO,IAAM,8CAAmB,4BAAa,CAAb,EAAgB,UAAC,YAAD,EAAkB;AACjE,QAAO;AACN,gBAAc,YADR;AAEN,YAAU,2BAFJ;AAGN,aAAW;AAHL,EAAP;AAKA,CAN+B,CAAzB;;;;;;;;;kBCbQ,UAAU,KAAV,EAAiB;AAAA,KACvB,GADuB,GACf,KADe,CACvB,GADuB;;AAE/B,QAAO,GAAP;AACA,C;;;;;;;;;;;;kBCGc,UAAU,KAAV,EAAiB;AAAA,KACvB,KADuB,GACU,KADV,CACvB,KADuB;AAAA,KAChB,qBADgB,GACU,KADV,CAChB,qBADgB;;;AAG/B,QAAO,YAAY,KAAZ,EAAmB,qBAAnB,CAAP;AACA,C;;AAVD;;;;AACA;;;;qBAE2E,wBAAQ,K;IAA3E,O,kBAAA,O;IAAS,U,kBAAA,U;IAAY,Y,kBAAA,Y;IAAc,2B,kBAAA,2B;IACnC,c,6BAAA,c;AAQD,IAAM,oCAAc,4BAAa,CAAb,EAAgB,UAAC,KAAD,EAAQ,qBAAR,EAAkC;;AAE5E,KAAM,UAAU;AACf,eAAa,yBADE;AAEf,YAAU;AAAA,UAAe,QAAQ,WAAR,CAAf;AAAA;AAFK,EAAhB;;AAKA,KAAI,OAAO,OAAO,IAAP,CAAY,KAAZ,EAAmB,GAAnB,CAAuB,eAAO;AACxC,sBACI,MAAM,GAAN,CADJ;AAEC,OAAI,GAFL;AAGC,gBAAa,QAHd;AAIC,oBAAiB;AAAA,WAAM,WAAW,GAAX,CAAN;AAAA,IAJlB;AAKC,sBAAmB;AAAA,WAAM,aAAa,GAAb,EAAkB,CAAC,MAAM,GAAN,EAAW,UAA9B,CAAN;AAAA;AALpB;AAOA,EARU,CAAX;;AAUA,KAAM,UAAU,KAAK,MAAL,CAAY,UAAC,CAAD,EAAI,IAAJ,EAAa;AACvC,GAAC,KAAK,UAAN,IAAoB,EAAE,eAAF,EAApB;AACA,OAAK,UAAL,IAAmB,EAAE,aAAF,EAAnB;AACA,IAAE,UAAF;AACA,SAAO,CAAP;AACA,EALc,EAKZ;AACF,mBAAiB,CADf;AAEF,iBAAe,CAFb;AAGF,cAAY;AAHV,EALY,CAAhB;;AAWA,QAAO,KACL,MADK,CACE;AAAA,SACP,0BAA0B,eAAe,KAAzC,IACC,0BAA0B,eAAe,QAAzC,IAAqD,KAAK,UAD3D,IAEC,0BAA0B,eAAe,OAAzC,IAAoD,CAAC,KAAK,UAHpD;AAAA,EADF,EAML,IANK,CAMA,UAAC,CAAD,EAAI,CAAJ,EAAU;AACf,MAAI,EAAE,WAAF,GAAgB,EAAE,WAAtB,EAAmC;AAAE,UAAO,CAAC,CAAR;AAAY;AACjD,MAAI,EAAE,WAAF,GAAgB,EAAE,WAAtB,EAAmC;AAAE,UAAO,CAAP;AAAW;AAChD,MAAI,EAAE,EAAF,GAAO,EAAE,EAAb,EAAiB;AAAE,UAAO,CAAC,CAAR;AAAY;AAC/B,SAAO,CAAP;AACA,EAXK,CAAP;;AAaA,SAAQ,eAAR,GAA6B,QAAQ,eAArC;AACA,SAAQ,aAAR,GAA2B,QAAQ,aAAnC;AACA,SAAQ,UAAR,GAAwB,QAAQ,UAAhC;;AAEA,SAAQ,qBAAR,GAAgC,qBAAhC;;AAEA,SAAQ,cAAR,GAAyB;AAAA,SAAM,4BAA4B,eAAe,OAA3C,CAAN;AAAA,EAAzB;AACA,SAAQ,eAAR,GAA0B;AAAA,SAAM,4BAA4B,eAAe,QAA3C,CAAN;AAAA,EAA1B;AACA,SAAQ,YAAR,GAAuB;AAAA,SAAM,4BAA4B,eAAe,KAA3C,CAAN;AAAA,EAAvB;;AAEA,QAAO;AACN,kBADM;AAEN,YAFM;AAGN;AAHM,EAAP;AAKA,CAxD0B,CAApB", 24 | "file": "generated.js", 25 | "sourceRoot": "", 26 | "sourcesContent": [ 27 | "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o {\n\t\tObject.defineProperty(p, selectorKey, {\n\t\t\tget: function() { return selectors[selectorKey](getState(), ...args) },\n\t\t\tenumerable: true\n\t\t});\n\t\treturn p;\n\t}, {});\n};\n", 29 | "if (typeof Map !== 'function' || (process && process.env && process.env.TEST_MAPORSIMILAR === 'true')) {\n\tmodule.exports = require('./similar');\n}\nelse {\n\tmodule.exports = Map;\n}", 30 | "function Similar() {\n\tthis.list = [];\n\tthis.lastItem = undefined;\n\tthis.size = 0;\n\n\treturn this;\n}\n\nSimilar.prototype.get = function(key) {\n\tvar index;\n\n\tif (this.lastItem && this.isEqual(this.lastItem.key, key)) {\n\t\treturn this.lastItem.val;\n\t}\n\n\tindex = this.indexOf(key);\n\tif (index >= 0) {\n\t\tthis.lastItem = this.list[index];\n\t\treturn this.list[index].val;\n\t}\n\n\treturn undefined;\n};\n\nSimilar.prototype.set = function(key, val) {\n\tvar index;\n\n\tif (this.lastItem && this.isEqual(this.lastItem.key, key)) {\n\t\tthis.lastItem.val = val;\n\t\treturn this;\n\t}\n\n\tindex = this.indexOf(key);\n\tif (index >= 0) {\n\t\tthis.lastItem = this.list[index];\n\t\tthis.list[index].val = val;\n\t\treturn this;\n\t}\n\n\tthis.lastItem = { key: key, val: val };\n\tthis.list.push(this.lastItem);\n\tthis.size++;\n\n\treturn this;\n};\n\nSimilar.prototype.delete = function(key) {\n\tvar index;\n\n\tif (this.lastItem && this.isEqual(this.lastItem.key, key)) {\n\t\tthis.lastItem = undefined;\n\t}\n\n\tindex = this.indexOf(key);\n\tif (index >= 0) {\n\t\tthis.size--;\n\t\treturn this.list.splice(index, 1)[0];\n\t}\n\n\treturn undefined;\n};\n\n\n// important that has() doesn't use get() in case an existing key has a falsy value, in which case has() would return false\nSimilar.prototype.has = function(key) {\n\tvar index;\n\n\tif (this.lastItem && this.isEqual(this.lastItem.key, key)) {\n\t\treturn true;\n\t}\n\n\tindex = this.indexOf(key);\n\tif (index >= 0) {\n\t\tthis.lastItem = this.list[index];\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\nSimilar.prototype.forEach = function(callback, thisArg) {\n\tvar i;\n\tfor (i = 0; i < this.size; i++) {\n\t\tcallback.call(thisArg || this, this.list[i].val, this.list[i].key, this);\n\t}\n};\n\nSimilar.prototype.indexOf = function(key) {\n\tvar i;\n\tfor (i = 0; i < this.size; i++) {\n\t\tif (this.isEqual(this.list[i].key, key)) {\n\t\t\treturn i;\n\t\t}\n\t}\n\treturn -1;\n};\n\n// check if the numbers are equal, or whether they are both precisely NaN (isNaN returns true for all non-numbers)\nSimilar.prototype.isEqual = function(val1, val2) {\n\treturn val1 === val2 || (val1 !== val1 && val2 !== val2);\n};\n\nmodule.exports = Similar;", 31 | "var MapOrSimilar = require('map-or-similar');\n\nmodule.exports = function (limit) {\n\tvar cache = new MapOrSimilar(),\n\t\tlru = [];\n\n\treturn function (fn) {\n\t\tvar memoizerific = function () {\n\t\t\tvar currentCache = cache,\n\t\t\t\tnewMap,\n\t\t\t\tfnResult,\n\t\t\t\targsLengthMinusOne = arguments.length - 1,\n\t\t\t\tlruPath = Array(argsLengthMinusOne + 1),\n\t\t\t\tisMemoized = true,\n\t\t\t\ti;\n\n\t\t\tif ((memoizerific.numArgs || memoizerific.numArgs === 0) && memoizerific.numArgs !== argsLengthMinusOne + 1) {\n\t\t\t\tthrow new Error('Memoizerific functions should always be called with the same number of arguments');\n\t\t\t}\n\n\t\t\t// loop through each argument to traverse the map tree\n\t\t\tfor (i = 0; i < argsLengthMinusOne; i++) {\n\t\t\t\tlruPath[i] = {\n\t\t\t\t\tcacheItem: currentCache,\n\t\t\t\t\targ: arguments[i]\n\t\t\t\t};\n\n\t\t\t\t// climb through the hierarchical map tree until the second-last argument has been found, or an argument is missing.\n\t\t\t\t// if all arguments up to the second-last have been found, this will potentially be a cache hit (determined below)\n\t\t\t\tif (currentCache.has(arguments[i])) {\n\t\t\t\t\tcurrentCache = currentCache.get(arguments[i]);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tisMemoized = false;\n\n\t\t\t\t// make maps until last value\n\t\t\t\tnewMap = new MapOrSimilar();\n\t\t\t\tcurrentCache.set(arguments[i], newMap);\n\t\t\t\tcurrentCache = newMap;\n\t\t\t}\n\n\t\t\t// we are at the last arg, check if it is really memoized\n\t\t\tif (isMemoized) {\n\t\t\t\tif (currentCache.has(arguments[argsLengthMinusOne])) {\n\t\t\t\t\tfnResult = currentCache.get(arguments[argsLengthMinusOne]);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tisMemoized = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!isMemoized) {\n\t\t\t\tfnResult = fn.apply(null, arguments);\n\t\t\t\tcurrentCache.set(arguments[argsLengthMinusOne], fnResult);\n\t\t\t}\n\n\t\t\tif (limit > 0) {\n\t\t\t\tlruPath[argsLengthMinusOne] = {\n\t\t\t\t\tcacheItem: currentCache,\n\t\t\t\t\targ: arguments[argsLengthMinusOne]\n\t\t\t\t};\n\n\t\t\t\tif (isMemoized) {\n\t\t\t\t\tmoveToMostRecentLru(lru, lruPath);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tlru.push(lruPath);\n\t\t\t\t}\n\n\t\t\t\tif (lru.length > limit) {\n\t\t\t\t\tremoveCachedResult(lru.shift());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmemoizerific.wasMemoized = isMemoized;\n\t\t\tmemoizerific.numArgs = argsLengthMinusOne + 1;\n\n\t\t\treturn fnResult;\n\t\t};\n\n\t\tmemoizerific.limit = limit;\n\t\tmemoizerific.wasMemoized = false;\n\t\tmemoizerific.cache = cache;\n\t\tmemoizerific.lru = lru;\n\n\t\treturn memoizerific;\n\t};\n};\n\n// move current args to most recent position\nfunction moveToMostRecentLru(lru, lruPath) {\n\tvar lruLen = lru.length,\n\t\tlruPathLen = lruPath.length,\n\t\tisMatch,\n\t\ti, ii;\n\n\tfor (i = 0; i < lruLen; i++) {\n\t\tisMatch = true;\n\t\tfor (ii = 0; ii < lruPathLen; ii++) {\n\t\t\tif (!isEqual(lru[i][ii].arg, lruPath[ii].arg)) {\n\t\t\t\tisMatch = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (isMatch) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tlru.push(lru.splice(i, 1)[0]);\n}\n\n// remove least recently used cache item and all dead branches\nfunction removeCachedResult(removedLru) {\n\tvar removedLruLen = removedLru.length,\n\t\tcurrentLru = removedLru[removedLruLen - 1],\n\t\ttmp,\n\t\ti;\n\n\tcurrentLru.cacheItem.delete(currentLru.arg);\n\n\t// walk down the tree removing dead branches (size 0) along the way\n\tfor (i = removedLruLen - 2; i >= 0; i--) {\n\t\tcurrentLru = removedLru[i];\n\t\ttmp = currentLru.cacheItem.get(currentLru.arg);\n\n\t\tif (!tmp || !tmp.size) {\n\t\t\tcurrentLru.cacheItem.delete(currentLru.arg);\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n// check if the numbers are equal, or whether they are both precisely NaN (isNaN returns true for all non-numbers)\nfunction isEqual(val1, val2) {\n\treturn val1 === val2 || (val1 !== val1 && val2 !== val2);\n}", 32 | "// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n", 33 | "!function(e){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=e();else if(\"function\"==typeof define&&define.amd)define([],e);else{var t;t=\"undefined\"!=typeof window?window:\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:this,t.todoReactComponents=e()}}(function(){var e;return function e(t,a,n){function o(s,r){if(!a[s]){if(!t[s]){var u=\"function\"==typeof require&&require;if(!r&&u)return u(s,!0);if(l)return l(s,!0);var c=new Error(\"Cannot find module '\"+s+\"'\");throw c.code=\"MODULE_NOT_FOUND\",c}var d=a[s]={exports:{}};t[s][0].call(d.exports,function(e){var a=t[s][1][e];return o(a?a:e)},d,d.exports,e,t,a,n)}return a[s].exports}for(var l=\"function\"==typeof require&&require,s=0;s 0) {\n return 'Unexpected ' + (unexpectedKeys.length > 1 ? 'keys' : 'key') + ' ' + ('\"' + unexpectedKeys.join('\", \"') + '\" found in ' + argumentName + '. ') + 'Expected to find one of the known reducer keys instead: ' + ('\"' + reducerKeys.join('\", \"') + '\". Unexpected keys will be ignored.');\n }\n}\n\nfunction assertReducerSanity(reducers) {\n Object.keys(reducers).forEach(function (key) {\n var reducer = reducers[key];\n var initialState = reducer(undefined, { type: _createStore.ActionTypes.INIT });\n\n if (typeof initialState === 'undefined') {\n throw new Error('Reducer \"' + key + '\" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined.');\n }\n\n var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math.random().toString(36).substring(7).split('').join('.');\n if (typeof reducer(undefined, { type: type }) === 'undefined') {\n throw new Error('Reducer \"' + key + '\" returned undefined when probed with a random type. ' + ('Don\\'t try to handle ' + _createStore.ActionTypes.INIT + ' or other actions in \"redux/*\" ') + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined.');\n }\n });\n}\n\n/**\n * Turns an object whose values are different reducer functions, into a single\n * reducer function. It will call every child reducer, and gather their results\n * into a single state object, whose keys correspond to the keys of the passed\n * reducer functions.\n *\n * @param {Object} reducers An object whose values correspond to different\n * reducer functions that need to be combined into one. One handy way to obtain\n * it is to use ES6 `import * as reducers` syntax. The reducers may never return\n * undefined for any action. Instead, they should return their initial state\n * if the state passed to them was undefined, and the current state for any\n * unrecognized action.\n *\n * @returns {Function} A reducer function that invokes every reducer inside the\n * passed object, and builds a state object with the same shape.\n */\nfunction combineReducers(reducers) {\n var reducerKeys = Object.keys(reducers);\n var finalReducers = {};\n for (var i = 0; i < reducerKeys.length; i++) {\n var key = reducerKeys[i];\n\n if (\"development\" !== 'production') {\n if (typeof reducers[key] === 'undefined') {\n (0, _warning2['default'])('No reducer provided for key \"' + key + '\"');\n }\n }\n\n if (typeof reducers[key] === 'function') {\n finalReducers[key] = reducers[key];\n }\n }\n var finalReducerKeys = Object.keys(finalReducers);\n\n if (\"development\" !== 'production') {\n var unexpectedKeyCache = {};\n }\n\n var sanityError;\n try {\n assertReducerSanity(finalReducers);\n } catch (e) {\n sanityError = e;\n }\n\n return function combination() {\n var state = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n var action = arguments[1];\n\n if (sanityError) {\n throw sanityError;\n }\n\n if (\"development\" !== 'production') {\n var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache);\n if (warningMessage) {\n (0, _warning2['default'])(warningMessage);\n }\n }\n\n var hasChanged = false;\n var nextState = {};\n for (var i = 0; i < finalReducerKeys.length; i++) {\n var key = finalReducerKeys[i];\n var reducer = finalReducers[key];\n var previousStateForKey = state[key];\n var nextStateForKey = reducer(previousStateForKey, action);\n if (typeof nextStateForKey === 'undefined') {\n var errorMessage = getUndefinedStateErrorMessage(key, action);\n throw new Error(errorMessage);\n }\n nextState[key] = nextStateForKey;\n hasChanged = hasChanged || nextStateForKey !== previousStateForKey;\n }\n return hasChanged ? nextState : state;\n };\n}\n},{\"./createStore\":6,\"./utils/warning\":8,\"lodash/isPlainObject\":12}],5:[function(_dereq_,module,exports){\n\"use strict\";\n\nexports.__esModule = true;\nexports[\"default\"] = compose;\n/**\n * Composes single-argument functions from right to left. The rightmost\n * function can take multiple arguments as it provides the signature for\n * the resulting composite function.\n *\n * @param {...Function} funcs The functions to compose.\n * @returns {Function} A function obtained by composing the argument functions\n * from right to left. For example, compose(f, g, h) is identical to doing\n * (...args) => f(g(h(...args))).\n */\n\nfunction compose() {\n for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) {\n funcs[_key] = arguments[_key];\n }\n\n if (funcs.length === 0) {\n return function (arg) {\n return arg;\n };\n }\n\n if (funcs.length === 1) {\n return funcs[0];\n }\n\n var last = funcs[funcs.length - 1];\n var rest = funcs.slice(0, -1);\n return function () {\n return rest.reduceRight(function (composed, f) {\n return f(composed);\n }, last.apply(undefined, arguments));\n };\n}\n},{}],6:[function(_dereq_,module,exports){\n'use strict';\n\nexports.__esModule = true;\nexports.ActionTypes = undefined;\nexports['default'] = createStore;\n\nvar _isPlainObject = _dereq_('lodash/isPlainObject');\n\nvar _isPlainObject2 = _interopRequireDefault(_isPlainObject);\n\nvar _symbolObservable = _dereq_('symbol-observable');\n\nvar _symbolObservable2 = _interopRequireDefault(_symbolObservable);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/**\n * These are private action types reserved by Redux.\n * For any unknown actions, you must return the current state.\n * If the current state is undefined, you must return the initial state.\n * Do not reference these action types directly in your code.\n */\nvar ActionTypes = exports.ActionTypes = {\n INIT: '@@redux/INIT'\n};\n\n/**\n * Creates a Redux store that holds the state tree.\n * The only way to change the data in the store is to call `dispatch()` on it.\n *\n * There should only be a single store in your app. To specify how different\n * parts of the state tree respond to actions, you may combine several reducers\n * into a single reducer function by using `combineReducers`.\n *\n * @param {Function} reducer A function that returns the next state tree, given\n * the current state tree and the action to handle.\n *\n * @param {any} [preloadedState] The initial state. You may optionally specify it\n * to hydrate the state from the server in universal apps, or to restore a\n * previously serialized user session.\n * If you use `combineReducers` to produce the root reducer function, this must be\n * an object with the same shape as `combineReducers` keys.\n *\n * @param {Function} enhancer The store enhancer. You may optionally specify it\n * to enhance the store with third-party capabilities such as middleware,\n * time travel, persistence, etc. The only store enhancer that ships with Redux\n * is `applyMiddleware()`.\n *\n * @returns {Store} A Redux store that lets you read the state, dispatch actions\n * and subscribe to changes.\n */\nfunction createStore(reducer, preloadedState, enhancer) {\n var _ref2;\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {\n enhancer = preloadedState;\n preloadedState = undefined;\n }\n\n if (typeof enhancer !== 'undefined') {\n if (typeof enhancer !== 'function') {\n throw new Error('Expected the enhancer to be a function.');\n }\n\n return enhancer(createStore)(reducer, preloadedState);\n }\n\n if (typeof reducer !== 'function') {\n throw new Error('Expected the reducer to be a function.');\n }\n\n var currentReducer = reducer;\n var currentState = preloadedState;\n var currentListeners = [];\n var nextListeners = currentListeners;\n var isDispatching = false;\n\n function ensureCanMutateNextListeners() {\n if (nextListeners === currentListeners) {\n nextListeners = currentListeners.slice();\n }\n }\n\n /**\n * Reads the state tree managed by the store.\n *\n * @returns {any} The current state tree of your application.\n */\n function getState() {\n return currentState;\n }\n\n /**\n * Adds a change listener. It will be called any time an action is dispatched,\n * and some part of the state tree may potentially have changed. You may then\n * call `getState()` to read the current state tree inside the callback.\n *\n * You may call `dispatch()` from a change listener, with the following\n * caveats:\n *\n * 1. The subscriptions are snapshotted just before every `dispatch()` call.\n * If you subscribe or unsubscribe while the listeners are being invoked, this\n * will not have any effect on the `dispatch()` that is currently in progress.\n * However, the next `dispatch()` call, whether nested or not, will use a more\n * recent snapshot of the subscription list.\n *\n * 2. The listener should not expect to see all state changes, as the state\n * might have been updated multiple times during a nested `dispatch()` before\n * the listener is called. It is, however, guaranteed that all subscribers\n * registered before the `dispatch()` started will be called with the latest\n * state by the time it exits.\n *\n * @param {Function} listener A callback to be invoked on every dispatch.\n * @returns {Function} A function to remove this change listener.\n */\n function subscribe(listener) {\n if (typeof listener !== 'function') {\n throw new Error('Expected listener to be a function.');\n }\n\n var isSubscribed = true;\n\n ensureCanMutateNextListeners();\n nextListeners.push(listener);\n\n return function unsubscribe() {\n if (!isSubscribed) {\n return;\n }\n\n isSubscribed = false;\n\n ensureCanMutateNextListeners();\n var index = nextListeners.indexOf(listener);\n nextListeners.splice(index, 1);\n };\n }\n\n /**\n * Dispatches an action. It is the only way to trigger a state change.\n *\n * The `reducer` function, used to create the store, will be called with the\n * current state tree and the given `action`. Its return value will\n * be considered the **next** state of the tree, and the change listeners\n * will be notified.\n *\n * The base implementation only supports plain object actions. If you want to\n * dispatch a Promise, an Observable, a thunk, or something else, you need to\n * wrap your store creating function into the corresponding middleware. For\n * example, see the documentation for the `redux-thunk` package. Even the\n * middleware will eventually dispatch plain object actions using this method.\n *\n * @param {Object} action A plain object representing “what changed”. It is\n * a good idea to keep actions serializable so you can record and replay user\n * sessions, or use the time travelling `redux-devtools`. An action must have\n * a `type` property which may not be `undefined`. It is a good idea to use\n * string constants for action types.\n *\n * @returns {Object} For convenience, the same action object you dispatched.\n *\n * Note that, if you use a custom middleware, it may wrap `dispatch()` to\n * return something else (for example, a Promise you can await).\n */\n function dispatch(action) {\n if (!(0, _isPlainObject2['default'])(action)) {\n throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.');\n }\n\n if (typeof action.type === 'undefined') {\n throw new Error('Actions may not have an undefined \"type\" property. ' + 'Have you misspelled a constant?');\n }\n\n if (isDispatching) {\n throw new Error('Reducers may not dispatch actions.');\n }\n\n try {\n isDispatching = true;\n currentState = currentReducer(currentState, action);\n } finally {\n isDispatching = false;\n }\n\n var listeners = currentListeners = nextListeners;\n for (var i = 0; i < listeners.length; i++) {\n listeners[i]();\n }\n\n return action;\n }\n\n /**\n * Replaces the reducer currently used by the store to calculate the state.\n *\n * You might need this if your app implements code splitting and you want to\n * load some of the reducers dynamically. You might also need this if you\n * implement a hot reloading mechanism for Redux.\n *\n * @param {Function} nextReducer The reducer for the store to use instead.\n * @returns {void}\n */\n function replaceReducer(nextReducer) {\n if (typeof nextReducer !== 'function') {\n throw new Error('Expected the nextReducer to be a function.');\n }\n\n currentReducer = nextReducer;\n dispatch({ type: ActionTypes.INIT });\n }\n\n /**\n * Interoperability point for observable/reactive libraries.\n * @returns {observable} A minimal observable of state changes.\n * For more information, see the observable proposal:\n * https://github.com/zenparsing/es-observable\n */\n function observable() {\n var _ref;\n\n var outerSubscribe = subscribe;\n return _ref = {\n /**\n * The minimal observable subscription method.\n * @param {Object} observer Any object that can be used as an observer.\n * The observer object should have a `next` method.\n * @returns {subscription} An object with an `unsubscribe` method that can\n * be used to unsubscribe the observable from the store, and prevent further\n * emission of values from the observable.\n */\n subscribe: function subscribe(observer) {\n if (typeof observer !== 'object') {\n throw new TypeError('Expected the observer to be an object.');\n }\n\n function observeState() {\n if (observer.next) {\n observer.next(getState());\n }\n }\n\n observeState();\n var unsubscribe = outerSubscribe(observeState);\n return { unsubscribe: unsubscribe };\n }\n }, _ref[_symbolObservable2['default']] = function () {\n return this;\n }, _ref;\n }\n\n // When a store is created, an \"INIT\" action is dispatched so that every\n // reducer returns their initial state. This effectively populates\n // the initial state tree.\n dispatch({ type: ActionTypes.INIT });\n\n return _ref2 = {\n dispatch: dispatch,\n subscribe: subscribe,\n getState: getState,\n replaceReducer: replaceReducer\n }, _ref2[_symbolObservable2['default']] = observable, _ref2;\n}\n},{\"lodash/isPlainObject\":12,\"symbol-observable\":13}],7:[function(_dereq_,module,exports){\n'use strict';\n\nexports.__esModule = true;\nexports.compose = exports.applyMiddleware = exports.bindActionCreators = exports.combineReducers = exports.createStore = undefined;\n\nvar _createStore = _dereq_('./createStore');\n\nvar _createStore2 = _interopRequireDefault(_createStore);\n\nvar _combineReducers = _dereq_('./combineReducers');\n\nvar _combineReducers2 = _interopRequireDefault(_combineReducers);\n\nvar _bindActionCreators = _dereq_('./bindActionCreators');\n\nvar _bindActionCreators2 = _interopRequireDefault(_bindActionCreators);\n\nvar _applyMiddleware = _dereq_('./applyMiddleware');\n\nvar _applyMiddleware2 = _interopRequireDefault(_applyMiddleware);\n\nvar _compose = _dereq_('./compose');\n\nvar _compose2 = _interopRequireDefault(_compose);\n\nvar _warning = _dereq_('./utils/warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/*\n* This is a dummy function to check if the function name has been altered by minification.\n* If the function has been minified and NODE_ENV !== 'production', warn the user.\n*/\nfunction isCrushed() {}\n\nif (\"development\" !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') {\n (0, _warning2['default'])('You are currently using minified code outside of NODE_ENV === \\'production\\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.');\n}\n\nexports.createStore = _createStore2['default'];\nexports.combineReducers = _combineReducers2['default'];\nexports.bindActionCreators = _bindActionCreators2['default'];\nexports.applyMiddleware = _applyMiddleware2['default'];\nexports.compose = _compose2['default'];\n},{\"./applyMiddleware\":2,\"./bindActionCreators\":3,\"./combineReducers\":4,\"./compose\":5,\"./createStore\":6,\"./utils/warning\":8}],8:[function(_dereq_,module,exports){\n'use strict';\n\nexports.__esModule = true;\nexports['default'] = warning;\n/**\n * Prints a warning in the console if it exists.\n *\n * @param {String} message The warning message.\n * @returns {void}\n */\nfunction warning(message) {\n /* eslint-disable no-console */\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error(message);\n }\n /* eslint-enable no-console */\n try {\n // This error was thrown as a convenience so that if you enable\n // \"break on all exceptions\" in your console,\n // it would pause the execution at this line.\n throw new Error(message);\n /* eslint-disable no-empty */\n } catch (e) {}\n /* eslint-enable no-empty */\n}\n},{}],9:[function(_dereq_,module,exports){\nvar overArg = _dereq_('./_overArg');\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nmodule.exports = getPrototype;\n\n},{\"./_overArg\":10}],10:[function(_dereq_,module,exports){\n/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nmodule.exports = overArg;\n\n},{}],11:[function(_dereq_,module,exports){\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n\n},{}],12:[function(_dereq_,module,exports){\nvar getPrototype = _dereq_('./_getPrototype'),\n isObjectLike = _dereq_('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || objectToString.call(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return (typeof Ctor == 'function' &&\n Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);\n}\n\nmodule.exports = isPlainObject;\n\n},{\"./_getPrototype\":9,\"./isObjectLike\":11}],13:[function(_dereq_,module,exports){\nmodule.exports = _dereq_('./lib/index');\n\n},{\"./lib/index\":14}],14:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nvar _ponyfill = _dereq_('./ponyfill');\n\nvar _ponyfill2 = _interopRequireDefault(_ponyfill);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar root = undefined; /* global window */\n\nif (typeof global !== 'undefined') {\n\troot = global;\n} else if (typeof window !== 'undefined') {\n\troot = window;\n}\n\nvar result = (0, _ponyfill2['default'])(root);\nexports['default'] = result;\n},{\"./ponyfill\":15}],15:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\nexports['default'] = symbolObservablePonyfill;\nfunction symbolObservablePonyfill(root) {\n\tvar result;\n\tvar _Symbol = root.Symbol;\n\n\tif (typeof _Symbol === 'function') {\n\t\tif (_Symbol.observable) {\n\t\t\tresult = _Symbol.observable;\n\t\t} else {\n\t\t\tresult = _Symbol('observable');\n\t\t\t_Symbol.observable = result;\n\t\t}\n\t} else {\n\t\tresult = '@@observable';\n\t}\n\n\treturn result;\n};\n},{}],16:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\nexports.subscribe = exports.constants = exports.actions = exports.getState = undefined;\n\nvar _store = _dereq_('../src/store');\n\nvar _store2 = _interopRequireDefault(_store);\n\nvar _pages = _dereq_('./site/constants/pages');\n\nvar PAGES = _interopRequireWildcard(_pages);\n\nvar _statuses = _dereq_('./todos/constants/statuses');\n\nvar TODOS_STATUSES = _interopRequireWildcard(_statuses);\n\nvar _updateUrl = _dereq_('./site/actions/update-url');\n\nvar _updateUrl2 = _interopRequireDefault(_updateUrl);\n\nvar _updateSelectedPage = _dereq_('./site/actions/update-selected-page');\n\nvar _updateSelectedPage2 = _interopRequireDefault(_updateSelectedPage);\n\nvar _addTodo = _dereq_('./todos/actions/add-todo');\n\nvar _addTodo2 = _interopRequireDefault(_addTodo);\n\nvar _loadTodos = _dereq_('./todos/actions/load-todos');\n\nvar _loadTodos2 = _interopRequireDefault(_loadTodos);\n\nvar _removeTodo = _dereq_('./todos/actions/remove-todo');\n\nvar _removeTodo2 = _interopRequireDefault(_removeTodo);\n\nvar _completeTodo = _dereq_('./todos/actions/complete-todo');\n\nvar _completeTodo2 = _interopRequireDefault(_completeTodo);\n\nvar _updateSelectedSummaryStatus = _dereq_('./todos/actions/update-selected-summary-status');\n\nvar _updateSelectedSummaryStatus2 = _interopRequireDefault(_updateSelectedSummaryStatus);\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar actionsSet = {\n\tsite: {\n\t\tupdateURL: _updateUrl2.default,\n\t\tupdateSelectedPage: _updateSelectedPage2.default\n\t},\n\ttodos: {\n\t\taddTodo: _addTodo2.default,\n\t\tloadTodos: _loadTodos2.default,\n\t\tremoveTodo: _removeTodo2.default,\n\t\tcompleteTodo: _completeTodo2.default,\n\t\tupdateSelectedSummaryStatus: _updateSelectedSummaryStatus2.default\n\t}\n};\n\nvar actions = Object.keys(actionsSet).reduce(function (p1, key1) {\n\tp1[key1] = Object.keys(actionsSet[key1]).reduce(function (p2, key2) {\n\t\tp2[key2] = function () {\n\t\t\tvar action = actionsSet[key1][key2].apply(null, arguments);\n\t\t\t_store2.default.dispatch(action);\n\t\t\treturn action;\n\t\t};\n\t\treturn p2;\n\t}, {});\n\treturn p1;\n}, {});\n\nvar constants = {\n\tPAGES: PAGES,\n\tTODOS_STATUSES: TODOS_STATUSES\n};\n\nvar subscribe = _store2.default.subscribe;\n\nvar getState = _store2.default.getState;\n\nexports.default = {\n\tgetState: getState,\n\tactions: actions,\n\tconstants: constants,\n\tsubscribe: subscribe\n};\nexports.getState = getState;\nexports.actions = actions;\nexports.constants = constants;\nexports.subscribe = subscribe;\n\n},{\"../src/store\":23,\"./site/actions/update-selected-page\":17,\"./site/actions/update-url\":18,\"./site/constants/pages\":19,\"./todos/actions/add-todo\":24,\"./todos/actions/complete-todo\":25,\"./todos/actions/load-todos\":26,\"./todos/actions/remove-todo\":27,\"./todos/actions/update-selected-summary-status\":28,\"./todos/constants/statuses\":30}],17:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function (newSelectedPage) {\n\treturn function (dispatch, getState) {\n\t\tvar _getState = getState();\n\n\t\tvar selectedPage = _getState.selectedPage;\n\n\t\tif (selectedPage !== newSelectedPage) {\n\t\t\tdispatch({ type: UPDATE_SELECTED_PAGE, selectedPage: newSelectedPage });\n\t\t}\n\t};\n};\n\nvar UPDATE_SELECTED_PAGE = exports.UPDATE_SELECTED_PAGE = 'UPDATE_SELECTED_PAGE';\n\n},{}],18:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function (newURL) {\n\treturn function (dispatch, getState) {\n\t\tvar _getState = getState();\n\n\t\tvar url = _getState.url;\n\n\t\tif (newURL === url) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar splitURL = newURL.split('?');\n\t\tvar path = splitURL[0];\n\t\tvar searchParams = {};\n\n\t\tif (splitURL.length >= 2) {\n\t\t\tsearchParams = parseSearchParams(splitURL[1]);\n\t\t}\n\n\t\tdispatch({ type: UPDATE_URL, parsedURL: { path: path, searchParams: searchParams, url: newURL } });\n\t};\n};\n\nvar UPDATE_URL = exports.UPDATE_URL = 'UPDATE_URL';\n\nfunction parseSearchParams(searchString) {\n\tvar pairSplit = void 0;\n\treturn (searchString || '').replace(/^\\?/, '').split('&').reduce(function (p, pair) {\n\t\tpairSplit = pair.split('=');\n\t\tif (pairSplit.length >= 1 && pairSplit[0].length >= 1) {\n\t\t\tp[decodeURIComponent(pairSplit[0])] = decodeURIComponent(pairSplit[1]) || '';\n\t\t}\n\t\treturn p;\n\t}, {});\n}\n\n},{}],19:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar HOME = exports.HOME = 'HOME';\nvar ABOUT = exports.ABOUT = 'ABOUT';\n\n},{}],20:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\nexports.DEFAULT_PATH = exports.PATHS = undefined;\n\nvar _pages = _dereq_('../../site/constants/pages');\n\nvar PATHS = exports.PATHS = {\n\t'/': _pages.HOME,\n\t'/about': _pages.ABOUT\n};\n\nvar DEFAULT_PATH = exports.DEFAULT_PATH = '/';\n\n},{\"../../site/constants/pages\":19}],21:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function () {\n\tvar selectedPage = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _pages.HOME;\n\tvar action = arguments[1];\n\n\tswitch (action.type) {\n\n\t\tcase _updateSelectedPage.UPDATE_SELECTED_PAGE:\n\t\t\treturn action.selectedPage;\n\n\t\tcase _updateUrl.UPDATE_URL:\n\t\t\treturn _paths.PATHS[action.parsedURL.path] || _pages.HOME;\n\n\t\tdefault:\n\t\t\treturn selectedPage;\n\t}\n};\n\nvar _updateSelectedPage = _dereq_('../../site/actions/update-selected-page');\n\nvar _updateUrl = _dereq_('../../site/actions/update-url');\n\nvar _pages = _dereq_('../../site/constants/pages');\n\nvar _paths = _dereq_('../../site/constants/paths');\n\n},{\"../../site/actions/update-selected-page\":17,\"../../site/actions/update-url\":18,\"../../site/constants/pages\":19,\"../../site/constants/paths\":20}],22:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function () {\n\tvar url = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _paths.DEFAULT_PATH;\n\tvar action = arguments[1];\n\n\tswitch (action.type) {\n\n\t\tcase _updateUrl.UPDATE_URL:\n\t\t\treturn action.parsedURL.url;\n\n\t\tdefault:\n\t\t\treturn url;\n\t}\n};\n\nvar _updateUrl = _dereq_('../../site/actions/update-url');\n\nvar _paths = _dereq_('../../site/constants/paths');\n\n},{\"../../site/actions/update-url\":18,\"../../site/constants/paths\":20}],23:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nvar _redux = _dereq_('redux');\n\nvar _reduxThunk = _dereq_('redux-thunk');\n\nvar _reduxThunk2 = _interopRequireDefault(_reduxThunk);\n\nvar _url = _dereq_('./site/reducers/url');\n\nvar _url2 = _interopRequireDefault(_url);\n\nvar _selectedPage = _dereq_('./site/reducers/selected-page');\n\nvar _selectedPage2 = _interopRequireDefault(_selectedPage);\n\nvar _todos = _dereq_('./todos/reducers/todos');\n\nvar _todos2 = _interopRequireDefault(_todos);\n\nvar _selectedSummaryStatus = _dereq_('./todos/reducers/selected-summary-status');\n\nvar _selectedSummaryStatus2 = _interopRequireDefault(_selectedSummaryStatus);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// reducers\nvar reducers = {\n\turl: _url2.default,\n\tselectedPage: _selectedPage2.default,\n\ttodos: _todos2.default,\n\tselectedSummaryStatus: _selectedSummaryStatus2.default\n};\n\n// middleware that logs all actions to console\nvar consoleLog = function consoleLog(store) {\n\treturn function (next) {\n\t\treturn function (action) {\n\t\t\tif (typeof action !== 'function') {\n\t\t\t\tconsole.log(action);\n\t\t\t}\n\t\t\treturn next(action);\n\t\t};\n\t};\n};\n\n// middleware\nvar middleWare = void 0;\nif (process.env.NODE_ENV !== 'production') {\n\tmiddleWare = (0, _redux.applyMiddleware)(consoleLog, _reduxThunk2.default);\n} else {\n\tmiddleWare = (0, _redux.applyMiddleware)(_reduxThunk2.default);\n}\n\n// create store\nexports.default = (0, _redux.createStore)((0, _redux.combineReducers)(reducers), middleWare);\n\n},{\"./site/reducers/selected-page\":21,\"./site/reducers/url\":22,\"./todos/reducers/selected-summary-status\":31,\"./todos/reducers/todos\":32,\"redux\":7,\"redux-thunk\":1}],24:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function (description) {\n\treturn function (dispatch, getState) {\n\t\tif (!description || !description.length) {\n\t\t\treturn Promise.resolve(null);\n\t\t}\n\n\t\treturn (0, _newTodo2.default)(description).then(function (todo) {\n\t\t\tvar id = todo.id;\n\t\t\tdelete todo.id;\n\t\t\tdispatch((0, _updateTodos3.default)(_defineProperty({}, id, todo)));\n\t\t});\n\t};\n};\n\nvar _newTodo = _dereq_('../../todos/services/fake-backend/new-todo');\n\nvar _newTodo2 = _interopRequireDefault(_newTodo);\n\nvar _updateTodos2 = _dereq_('../../todos/actions/update-todos');\n\nvar _updateTodos3 = _interopRequireDefault(_updateTodos2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\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\n},{\"../../todos/actions/update-todos\":29,\"../../todos/services/fake-backend/new-todo\":35}],25:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function (id, isComplete) {\n\treturn function (dispatch, getState) {\n\t\tvar _getState = getState();\n\n\t\tvar todos = _getState.todos;\n\n\t\tvar todo = todos[id];\n\n\t\tif (!todo) {\n\t\t\treturn;\n\t\t}\n\n\t\ttodo.isComplete = isComplete;\n\n\t\treturn (0, _saveTodo2.default)(id, todo).then(function (res) {\n\t\t\tdispatch((0, _updateTodos3.default)(_defineProperty({}, res.id, res.todo)));\n\t\t});\n\t};\n};\n\nvar _saveTodo = _dereq_('../../todos/services/fake-backend/save-todo');\n\nvar _saveTodo2 = _interopRequireDefault(_saveTodo);\n\nvar _updateTodos2 = _dereq_('../../todos/actions/update-todos');\n\nvar _updateTodos3 = _interopRequireDefault(_updateTodos2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\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\n},{\"../../todos/actions/update-todos\":29,\"../../todos/services/fake-backend/save-todo\":36}],26:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\nexports.LOAD_TODOS = undefined;\n\nexports.default = function (todos) {\n\treturn function (dispatch, getState) {\n\t\treturn (0, _loadAllTodos2.default)().then(function (todos) {\n\t\t\tif (!todos) {\n\t\t\t\treturn Promise.resolve(null);\n\t\t\t}\n\t\t\tdispatch((0, _updateTodos2.default)(todos));\n\t\t});\n\t};\n};\n\nvar _loadAllTodos = _dereq_('../../todos/services/fake-backend/load-all-todos');\n\nvar _loadAllTodos2 = _interopRequireDefault(_loadAllTodos);\n\nvar _updateTodos = _dereq_('../../todos/actions/update-todos');\n\nvar _updateTodos2 = _interopRequireDefault(_updateTodos);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar LOAD_TODOS = exports.LOAD_TODOS = 'LOAD_TODOS';\n\n},{\"../../todos/actions/update-todos\":29,\"../../todos/services/fake-backend/load-all-todos\":34}],27:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function (id) {\n\treturn function (dispatch, getState) {\n\t\treturn (0, _deleteTodo2.default)(id).then(function (todo) {\n\t\t\tdispatch((0, _updateTodos3.default)(_defineProperty({}, id, null)));\n\t\t});\n\t};\n};\n\nvar _deleteTodo = _dereq_('../../todos/services/fake-backend/delete-todo');\n\nvar _deleteTodo2 = _interopRequireDefault(_deleteTodo);\n\nvar _updateTodos2 = _dereq_('../../todos/actions/update-todos');\n\nvar _updateTodos3 = _interopRequireDefault(_updateTodos2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\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\n},{\"../../todos/actions/update-todos\":29,\"../../todos/services/fake-backend/delete-todo\":33}],28:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function (selectedSummaryStatus) {\n\treturn { type: UPDATE_SELECTED_SUMMARY_STATUS, selectedSummaryStatus: selectedSummaryStatus };\n};\n\nvar UPDATE_SELECTED_SUMMARY_STATUS = exports.UPDATE_SELECTED_SUMMARY_STATUS = 'UPDATE_SELECTED_SUMMARY_STATUS';\n\n},{}],29:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function (todos) {\n\treturn { type: UPDATE_TODOS, todos: todos };\n};\n\nvar UPDATE_TODOS = exports.UPDATE_TODOS = 'UPDATE_TODOS';\n\n},{}],30:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar PENDING = exports.PENDING = 'PENDING';\nvar COMPLETE = exports.COMPLETE = 'COMPLETE';\nvar TOTAL = exports.TOTAL = 'TOTAL';\n\n},{}],31:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function () {\n\tvar selectedSummaryStatus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _statuses.TOTAL;\n\tvar action = arguments[1];\n\n\tswitch (action.type) {\n\t\tcase _updateSelectedSummaryStatus.UPDATE_SELECTED_SUMMARY_STATUS:\n\t\t\treturn action.selectedSummaryStatus;\n\n\t\tdefault:\n\t\t\treturn selectedSummaryStatus;\n\t}\n};\n\nvar _updateSelectedSummaryStatus = _dereq_('../../todos/actions/update-selected-summary-status');\n\nvar _statuses = _dereq_('../../todos/constants/statuses');\n\n},{\"../../todos/actions/update-selected-summary-status\":28,\"../../todos/constants/statuses\":30}],32:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nvar _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; };\n\nexports.default = function () {\n\tvar todos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\tvar action = arguments[1];\n\n\tvar newTodos = void 0;\n\n\tswitch (action.type) {\n\t\tcase _updateTodos.UPDATE_TODOS:\n\t\t\tnewTodos = _extends({}, todos);\n\n\t\t\tObject.keys(action.todos).forEach(function (key) {\n\t\t\t\tif (action.todos[key]) {\n\t\t\t\t\tnewTodos[key] = action.todos[key];\n\t\t\t\t} else {\n\t\t\t\t\tdelete newTodos[key];\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn newTodos;\n\n\t\tdefault:\n\t\t\treturn todos;\n\t}\n};\n\nvar _updateTodos = _dereq_('../../todos/actions/update-todos');\n\n},{\"../../todos/actions/update-todos\":29}],33:[function(_dereq_,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function (id) {\n\treturn new Promise(function (r, x) {\n\t\tsetTimeout(function () {\n\t\t\treturn r(true);\n\t\t}, 50);\n\t});\n};\n\n},{}],34:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function () {\n\tvar todos = {\n\t\t'10': {\n\t\t\tdescription: 'Buy tomatoes from grocery store',\n\t\t\tdateCreated: '2016-09-19T18:44:15.635',\n\t\t\tisComplete: false\n\t\t},\n\t\t'3': {\n\t\t\tdescription: 'Finish writing blog post',\n\t\t\tdateCreated: '2016-09-20T18:44:18.635',\n\t\t\tisComplete: false\n\t\t}\n\t};\n\n\treturn new Promise(function (r, x) {\n\t\tsetTimeout(function () {\n\t\t\treturn r(todos);\n\t\t}, 50);\n\t});\n};\n\n},{}],35:[function(_dereq_,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function (description) {\n\tvar id = Math.round(Math.random() * 10000).toFixed();\n\tvar newTodo = {\n\t\tid: id,\n\t\tdescription: description,\n\t\tdateCreated: new Date().toISOString(),\n\t\tisComplete: false\n\t};\n\n\treturn new Promise(function (r, x) {\n\t\tsetTimeout(function () {\n\t\t\treturn r(newTodo);\n\t\t}, 50);\n\t});\n};\n\n},{}],36:[function(_dereq_,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\n\nexports.default = function (id, todo) {\n\treturn new Promise(function (r, x) {\n\t\tsetTimeout(function () {\n\t\t\treturn r({ id: id, todo: todo });\n\t\t}, 50);\n\t});\n};\n\n},{}]},{},[16])(16)\n});", 35 | "import { getState, actions, subscribe } from 'todo-redux-state';\nimport { render } from 'todo-react-components';\n\nimport selectors from './selectors';\n\n// debug stuff\nObject.defineProperty(window, \"state\", { get: getState });\nwindow.selectors = selectors;\nwindow.actions = actions;\nconsole.log('********************************************* \\n DEVELOPMENT MODE \\n window.state available \\n window.selectors available \\n ********************************************* \\n');\n\n// read the url and navigate to the right page\nactions.site.updateURL(window.location.pathname + window.location.search);\n\n// load todos\nactions.todos.loadTodos();\n\n// listen for back button, forward button, etc\nwindow.onpopstate = (e) => {\n actions.site.updateURL(window.location.pathname + window.location.search);\n};\n\n// subscribe to state changes and re-render view on every change\nconst htmlElement = document.getElementById('app');\nsubscribe(() => render(selectors, htmlElement));\n", 36 | "import memoizerific from 'memoizerific';\nimport { actions, constants } from 'todo-redux-state';\n\nimport * as PATHS from '../site/constants/paths';\n\nexport default function (state) {\n\treturn selectAboutLink();\n}\n\nexport const selectAboutLink = memoizerific(1)(() => {\n\tconst url = PATHS[constants.PAGES.ABOUT];\n\treturn {\n\t\tlabel: 'About',\n\t\thref: url,\n\t\tonClick: () => actions.site.updateURL(url)\n\t};\n});\n", 37 | "import memoizerific from 'memoizerific';\nimport { actions, constants } from 'todo-redux-state';\n\nimport * as PATHS from '../site/constants/paths';\n\nexport default function (state) {\n\treturn selectHomeLink();\n}\n\nexport const selectHomeLink = memoizerific(1)(() => {\n\tconst url = PATHS[constants.PAGES.HOME];\n\treturn {\n\t\tlabel: 'Home',\n\t\thref: url,\n\t\tonClick: () => actions.site.updateURL(url)\n\t};\n});\n", 38 | "import combineSelectors from 'combine-selectors';\nimport { getState } from 'todo-redux-state';\n\nimport selectedPage from './site/selected-page';\nimport url from './site/url';\nimport siteHeader from './site/site-header';\nimport todos from './todos/todos';\n\nconst selectors = {\n\tselectedPage,\n\turl,\n\tsiteHeader,\n\ttodos\n};\n\nexport default combineSelectors(selectors, getState);\n", 39 | "export const HOME = '/';\nexport const ABOUT = '/about';", 40 | "import memoizerific from 'memoizerific';\nimport { constants } from 'todo-react-components';\n\nexport default function (state) {\n\tconst { selectedPage } = state;\n\treturn selectSelectedPage(selectedPage);\n}\n\nexport const selectSelectedPage = memoizerific(1)((selectedPage) => {\n\treturn constants.PAGES[selectedPage];\n});\n", 41 | "import memoizerific from 'memoizerific';\n\nimport * as PATHS from '../site/constants/paths';\n\nimport { selectHomeLink } from '../links/home';\nimport { selectAboutLink } from '../links/about';\n\n\nexport default function (state) {\n\tconst { selectedPage } = state;\n\treturn selectSiteHeader(selectedPage);\n}\n\nexport const selectSiteHeader = memoizerific(1)((selectedPage) => {\n\treturn {\n\t\tselectedPage: selectedPage,\n\t\thomeLink: selectHomeLink(),\n\t\taboutLink: selectAboutLink()\n\t};\n});\n", 42 | "export default function (state) {\n\tconst { url } = state;\n\treturn url;\n}\n", 43 | "import memoizerific from 'memoizerific';\nimport { actions, constants } from 'todo-redux-state';\n\nconst { addTodo, removeTodo, completeTodo, updateSelectedSummaryStatus } = actions.todos;\nconst { TODOS_STATUSES } = constants;\n\nexport default function (state) {\n\tconst { todos, selectedSummaryStatus } = state;\n\n\treturn selectTodos(todos, selectedSummaryStatus);\n}\n\nexport const selectTodos = memoizerific(1)((todos, selectedSummaryStatus) => {\n\n\tconst newForm = {\n\t\tplaceholder: 'What do you need to do?',\n\t\tonSubmit: description => addTodo(description)\n\t};\n\n\tlet list = Object.keys(todos).map(key => {\n\t\treturn {\n\t\t\t...todos[key],\n\t\t\tid: key,\n\t\t\tbuttonLabel: 'delete',\n\t\t\tonButtonClicked: () => removeTodo(key),\n\t\t\tonCheckboxToggled: () => completeTodo(key, !todos[key].isComplete)\n\t\t};\n\t});\n\n\tconst summary = list.reduce((p, todo) => {\n\t\t\t!todo.isComplete && p.countIncomplete++;\n\t\t\ttodo.isComplete && p.countComplete++;\n\t\t\tp.countTotal++;\n\t\t\treturn p;\n\t\t}, {\n\t\t\tcountIncomplete: 0,\n\t\t\tcountComplete: 0,\n\t\t\tcountTotal: 0\n\t\t});\n\n\tlist = list\n\t\t.filter(todo => (\n\t\t\tselectedSummaryStatus === TODOS_STATUSES.TOTAL ||\n\t\t\t(selectedSummaryStatus === TODOS_STATUSES.COMPLETE && todo.isComplete) ||\n\t\t\t(selectedSummaryStatus === TODOS_STATUSES.PENDING && !todo.isComplete)\n\t\t))\n\t\t.sort((a, b) => {\n\t\t\tif (a.dateCreated < b.dateCreated) { return -1; }\n\t\t\tif (a.dateCreated > b.dateCreated) { return 1; }\n\t\t\tif (a.id < b.id) { return -1; }\n\t\t\treturn 1;\n\t\t});\n\n\tsummary.countIncomplete = `${summary.countIncomplete} pending`;\n\tsummary.countComplete = `${summary.countComplete} complete`;\n\tsummary.countTotal = `${summary.countTotal} total`;\n\n\tsummary.selectedSummaryStatus = selectedSummaryStatus;\n\n\tsummary.onClickPending = () => updateSelectedSummaryStatus(TODOS_STATUSES.PENDING);\n\tsummary.onClickComplete = () => updateSelectedSummaryStatus(TODOS_STATUSES.COMPLETE);\n\tsummary.onClickTotal = () => updateSelectedSummaryStatus(TODOS_STATUSES.TOTAL);\n\n\treturn {\n\t\tnewForm,\n\t\tlist,\n\t\tsummary\n\t};\n});\n" 44 | ] 45 | } -------------------------------------------------------------------------------- /build/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Todo App 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 |
140 | 141 | 142 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "name": "todo-app", 4 | "description": "Example todo app of extreme decoupling of react, redux and selectors", 5 | "author": "Baz ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/thinkloop/todo-app.git" 10 | }, 11 | "homepage": "https://github.com/thinkloop/todo-app#readme", 12 | "bugs": { 13 | "url": "https://github.com/thinkloop/todo-app/issues" 14 | }, 15 | "keywords": [ 16 | "todo", 17 | "mvc", 18 | "todomvc", 19 | "redux" 20 | ], 21 | "main": "./build/index.html", 22 | "scripts": { 23 | "************": "", 24 | "start": "spa-webserver -d $npm_package_config_build_folder", 25 | "watch": "clear; echo '* NPM UPDATE *'; npm update; echo '* CLEAN * HTML * WATCHIFY *'; NODE_ENV=development npm run -s watch:all", 26 | "test": "clear; echo '* NPM UPDATE *'; npm update; echo '**** TESTS ****'; jest", 27 | "***********": "", 28 | "watch:all": "npm run -s clean && (npm run -s watch:js & npm run -s watch:html)", 29 | "watch:js": "watchify $npm_package_config_js_entry_file --extension=.js --extension=.jsx -t [ babelify ] --debug -o 'exorcist $npm_package_config_build_folder/$npm_package_version/build.js.map > $npm_package_config_build_folder/$npm_package_version/build.js && echo ---------WATCHIFY--------`date +%r`'", 30 | "watch:html": "onchange $npm_package_config_html_entry_file -i -- npm run -s watch:html:do", 31 | "watch:html:do": "cat $npm_package_config_html_entry_file | npm run -s partial:replaceBuildFolderString > $npm_package_config_build_folder/index.html && echo ---------HTML-----------`date +%r`", 32 | "*********": "", 33 | "clean": "rimraf $npm_package_config_build_folder/* && mkdir -p $npm_package_config_build_folder && mkdir -p $npm_package_config_build_folder/$npm_package_version && echo ---------CLEAN----------`date +%r`", 34 | "partial:uglify": "[ $NODE_ENV = production ] && uglifyjs --compress drop_console,unused=true --mangle --screw-ie8 || cat", 35 | "partial:replaceBuildFolderString": "sed 's~${build_folder}~'$npm_package_version'~g'" 36 | }, 37 | "dependencies": { 38 | "combine-selectors": "thinkloop/combine-selectors", 39 | "memoizerific": "^1.8.4", 40 | "todo-react-components": "thinkloop/todo-react-components", 41 | "todo-redux-state": "thinkloop/todo-redux-state" 42 | }, 43 | "devDependencies": { 44 | "babel-jest": "^16.0.0", 45 | "babel-preset-es2015": "^6.16.0", 46 | "babel-preset-stage-0": "6.16.0", 47 | "babelify": "^7.3.0", 48 | "browserify": "13.1.0", 49 | "exorcist": "^0.4.0", 50 | "jest": "^16.0.0", 51 | "npm-check-updates": "^2.8.2", 52 | "onchange": "^3.0.2", 53 | "rimraf": "^2.5.4", 54 | "spa-webserver": "^1.0.5", 55 | "uglifyjs": "^2.4.10", 56 | "watchify": "^3.7.0" 57 | }, 58 | "config": { 59 | "js_entry_file": "./src/index.js", 60 | "html_entry_file": "./src/index.html", 61 | "build_folder": "./build" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Todo App 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 |
140 | 141 | 142 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { getState, actions, subscribe } from 'todo-redux-state'; 2 | import { render } from 'todo-react-components'; 3 | 4 | import selectors from './selectors'; 5 | 6 | // debug stuff 7 | Object.defineProperty(window, "state", { get: getState }); 8 | window.selectors = selectors; 9 | window.actions = actions; 10 | console.log('********************************************* \n DEVELOPMENT MODE \n window.state available \n window.selectors available \n ********************************************* \n'); 11 | 12 | // read the url and navigate to the right page 13 | actions.site.updateURL(window.location.pathname + window.location.search); 14 | 15 | // load todos 16 | actions.todos.loadTodos(); 17 | 18 | // listen for back button, forward button, etc 19 | window.onpopstate = (e) => { 20 | actions.site.updateURL(window.location.pathname + window.location.search); 21 | }; 22 | 23 | // subscribe to state changes and re-render view on every change 24 | const htmlElement = document.getElementById('app'); 25 | subscribe(() => render(selectors, htmlElement)); 26 | -------------------------------------------------------------------------------- /src/links/about.js: -------------------------------------------------------------------------------- 1 | import memoizerific from 'memoizerific'; 2 | import { actions, constants } from 'todo-redux-state'; 3 | 4 | import * as PATHS from '../site/constants/paths'; 5 | 6 | export default function (state) { 7 | return selectAboutLink(); 8 | } 9 | 10 | export const selectAboutLink = memoizerific(1)(() => { 11 | const url = PATHS[constants.PAGES.ABOUT]; 12 | return { 13 | label: 'About', 14 | href: url, 15 | onClick: () => actions.site.updateURL(url) 16 | }; 17 | }); 18 | -------------------------------------------------------------------------------- /src/links/home.js: -------------------------------------------------------------------------------- 1 | import memoizerific from 'memoizerific'; 2 | import { actions, constants } from 'todo-redux-state'; 3 | 4 | import * as PATHS from '../site/constants/paths'; 5 | 6 | export default function (state) { 7 | return selectHomeLink(); 8 | } 9 | 10 | export const selectHomeLink = memoizerific(1)(() => { 11 | const url = PATHS[constants.PAGES.HOME]; 12 | return { 13 | label: 'Home', 14 | href: url, 15 | onClick: () => actions.site.updateURL(url) 16 | }; 17 | }); 18 | -------------------------------------------------------------------------------- /src/selectors.js: -------------------------------------------------------------------------------- 1 | import combineSelectors from 'combine-selectors'; 2 | import { getState } from 'todo-redux-state'; 3 | 4 | import selectedPage from './site/selected-page'; 5 | import url from './site/url'; 6 | import siteHeader from './site/site-header'; 7 | import todos from './todos/todos'; 8 | 9 | const selectors = { 10 | selectedPage, 11 | url, 12 | siteHeader, 13 | todos 14 | }; 15 | 16 | export default combineSelectors(selectors, getState); 17 | -------------------------------------------------------------------------------- /src/site/constants/paths.js: -------------------------------------------------------------------------------- 1 | export const HOME = '/'; 2 | export const ABOUT = '/about'; -------------------------------------------------------------------------------- /src/site/selected-page.js: -------------------------------------------------------------------------------- 1 | import memoizerific from 'memoizerific'; 2 | import { constants } from 'todo-react-components'; 3 | 4 | export default function (state) { 5 | const { selectedPage } = state; 6 | return selectSelectedPage(selectedPage); 7 | } 8 | 9 | export const selectSelectedPage = memoizerific(1)((selectedPage) => { 10 | return constants.PAGES[selectedPage]; 11 | }); 12 | -------------------------------------------------------------------------------- /src/site/site-header.js: -------------------------------------------------------------------------------- 1 | import memoizerific from 'memoizerific'; 2 | 3 | import * as PATHS from '../site/constants/paths'; 4 | 5 | import { selectHomeLink } from '../links/home'; 6 | import { selectAboutLink } from '../links/about'; 7 | 8 | 9 | export default function (state) { 10 | const { selectedPage } = state; 11 | return selectSiteHeader(selectedPage); 12 | } 13 | 14 | export const selectSiteHeader = memoizerific(1)((selectedPage) => { 15 | return { 16 | selectedPage: selectedPage, 17 | homeLink: selectHomeLink(), 18 | aboutLink: selectAboutLink() 19 | }; 20 | }); 21 | -------------------------------------------------------------------------------- /src/site/url.js: -------------------------------------------------------------------------------- 1 | export default function (state) { 2 | const { url } = state; 3 | return url; 4 | } 5 | -------------------------------------------------------------------------------- /src/todos/todos.js: -------------------------------------------------------------------------------- 1 | import memoizerific from 'memoizerific'; 2 | import { actions, constants } from 'todo-redux-state'; 3 | 4 | const { addTodo, removeTodo, completeTodo, updateSelectedSummaryStatus } = actions.todos; 5 | const { TODOS_STATUSES } = constants; 6 | 7 | export default function (state) { 8 | const { todos, selectedSummaryStatus } = state; 9 | 10 | return selectTodos(todos, selectedSummaryStatus); 11 | } 12 | 13 | export const selectTodos = memoizerific(1)((todos, selectedSummaryStatus) => { 14 | 15 | const newForm = { 16 | placeholder: 'What do you need to do?', 17 | onSubmit: description => addTodo(description) 18 | }; 19 | 20 | let list = Object.keys(todos).map(key => { 21 | return { 22 | ...todos[key], 23 | id: key, 24 | buttonLabel: 'delete', 25 | onButtonClicked: () => removeTodo(key), 26 | onCheckboxToggled: () => completeTodo(key, !todos[key].isComplete) 27 | }; 28 | }); 29 | 30 | const summary = list.reduce((p, todo) => { 31 | !todo.isComplete && p.countIncomplete++; 32 | todo.isComplete && p.countComplete++; 33 | p.countTotal++; 34 | return p; 35 | }, { 36 | countIncomplete: 0, 37 | countComplete: 0, 38 | countTotal: 0 39 | }); 40 | 41 | list = list 42 | .filter(todo => ( 43 | selectedSummaryStatus === TODOS_STATUSES.TOTAL || 44 | (selectedSummaryStatus === TODOS_STATUSES.COMPLETE && todo.isComplete) || 45 | (selectedSummaryStatus === TODOS_STATUSES.PENDING && !todo.isComplete) 46 | )) 47 | .sort((a, b) => { 48 | if (a.dateCreated < b.dateCreated) { return -1; } 49 | if (a.dateCreated > b.dateCreated) { return 1; } 50 | if (a.id < b.id) { return -1; } 51 | return 1; 52 | }); 53 | 54 | summary.countIncomplete = `${summary.countIncomplete} pending`; 55 | summary.countComplete = `${summary.countComplete} complete`; 56 | summary.countTotal = `${summary.countTotal} total`; 57 | 58 | summary.selectedSummaryStatus = selectedSummaryStatus; 59 | 60 | summary.onClickPending = () => updateSelectedSummaryStatus(TODOS_STATUSES.PENDING); 61 | summary.onClickComplete = () => updateSelectedSummaryStatus(TODOS_STATUSES.COMPLETE); 62 | summary.onClickTotal = () => updateSelectedSummaryStatus(TODOS_STATUSES.TOTAL); 63 | 64 | return { 65 | newForm, 66 | list, 67 | summary 68 | }; 69 | }); 70 | --------------------------------------------------------------------------------