g(x,c))a[d]=x,a[n]=c,d=n;else break a}}return b}\nfunction g(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}if(\"object\"===typeof performance&&\"function\"===typeof performance.now){var l=performance;exports.unstable_now=function(){return l.now()}}else{var p=Date,q=p.now();exports.unstable_now=function(){return p.now()-q}}var r=[],t=[],u=1,v=null,y=3,z=!1,A=!1,B=!1,D=\"function\"===typeof setTimeout?setTimeout:null,E=\"function\"===typeof clearTimeout?clearTimeout:null,F=\"undefined\"!==typeof setImmediate?setImmediate:null;\n\"undefined\"!==typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function G(a){for(var b=h(t);null!==b;){if(null===b.callback)k(t);else if(b.startTime<=a)k(t),b.sortIndex=b.expirationTime,f(r,b);else break;b=h(t)}}function H(a){B=!1;G(a);if(!A)if(null!==h(r))A=!0,I(J);else{var b=h(t);null!==b&&K(H,b.startTime-a)}}\nfunction J(a,b){A=!1;B&&(B=!1,E(L),L=-1);z=!0;var c=y;try{G(b);for(v=h(r);null!==v&&(!(v.expirationTime>b)||a&&!M());){var d=v.callback;if(\"function\"===typeof d){v.callback=null;y=v.priorityLevel;var e=d(v.expirationTime<=b);b=exports.unstable_now();\"function\"===typeof e?v.callback=e:v===h(r)&&k(r);G(b)}else k(r);v=h(r)}if(null!==v)var w=!0;else{var m=h(t);null!==m&&K(H,m.startTime-b);w=!1}return w}finally{v=null,y=c,z=!1}}var N=!1,O=null,L=-1,P=5,Q=-1;\nfunction M(){return exports.unstable_now()-Qa||125d?(a.sortIndex=c,f(t,a),null===h(r)&&a===h(t)&&(B?(E(L),L=-1):B=!0,K(H,c-d))):(a.sortIndex=e,f(r,a),A||z||(A=!0,I(J)));return a};\nexports.unstable_shouldYield=M;exports.unstable_wrapCallback=function(a){var b=y;return function(){var c=y;y=b;try{return a.apply(this,arguments)}finally{y=c}}};\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/scheduler.production.min.js');\n} else {\n module.exports = require('./cjs/scheduler.development.js');\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = function(chunkId) {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce(function(promises, key) {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks\n__webpack_require__.u = function(chunkId) {\n\t// return url for filenames based on template\n\treturn \"static/js/\" + chunkId + \".\" + \"330910d3\" + \".chunk.js\";\n};","// This function allow to reference async chunks\n__webpack_require__.miniCssF = function(chunkId) {\n\t// return url for filenames based on template\n\treturn undefined;\n};","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","var inProgress = {};\nvar dataWebpackPrefix = \"pwa-autofocus-app:\";\n// loadScript function to load a script via script tag\n__webpack_require__.l = function(url, done, key, chunkId) {\n\tif(inProgress[url]) { inProgress[url].push(done); return; }\n\tvar script, needAttach;\n\tif(key !== undefined) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tfor(var i = 0; i < scripts.length; i++) {\n\t\t\tvar s = scripts[i];\n\t\t\tif(s.getAttribute(\"src\") == url || s.getAttribute(\"data-webpack\") == dataWebpackPrefix + key) { script = s; break; }\n\t\t}\n\t}\n\tif(!script) {\n\t\tneedAttach = true;\n\t\tscript = document.createElement('script');\n\n\t\tscript.charset = 'utf-8';\n\t\tscript.timeout = 120;\n\t\tif (__webpack_require__.nc) {\n\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n\t\t}\n\t\tscript.setAttribute(\"data-webpack\", dataWebpackPrefix + key);\n\n\t\tscript.src = url;\n\t}\n\tinProgress[url] = [done];\n\tvar onScriptComplete = function(prev, event) {\n\t\t// avoid mem leaks in IE.\n\t\tscript.onerror = script.onload = null;\n\t\tclearTimeout(timeout);\n\t\tvar doneFns = inProgress[url];\n\t\tdelete inProgress[url];\n\t\tscript.parentNode && script.parentNode.removeChild(script);\n\t\tdoneFns && doneFns.forEach(function(fn) { return fn(event); });\n\t\tif(prev) return prev(event);\n\t}\n\tvar timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);\n\tscript.onerror = onScriptComplete.bind(null, script.onerror);\n\tscript.onload = onScriptComplete.bind(null, script.onload);\n\tneedAttach && document.head.appendChild(script);\n};","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.p = \"/pwa-autofocus-app/\";","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t179: 0\n};\n\n__webpack_require__.f.j = function(chunkId, promises) {\n\t\t// JSONP chunk loading for javascript\n\t\tvar installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\n\t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n\t\t\t// a Promise means \"currently loading\".\n\t\t\tif(installedChunkData) {\n\t\t\t\tpromises.push(installedChunkData[2]);\n\t\t\t} else {\n\t\t\t\tif(true) { // all chunks have JS\n\t\t\t\t\t// setup Promise in chunk cache\n\t\t\t\t\tvar promise = new Promise(function(resolve, reject) { installedChunkData = installedChunks[chunkId] = [resolve, reject]; });\n\t\t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n\t\t\t\t\t// start chunk loading\n\t\t\t\t\tvar url = __webpack_require__.p + __webpack_require__.u(chunkId);\n\t\t\t\t\t// create error before stack unwound to get useful stacktrace later\n\t\t\t\t\tvar error = new Error();\n\t\t\t\t\tvar loadingEnded = function(event) {\n\t\t\t\t\t\tif(__webpack_require__.o(installedChunks, chunkId)) {\n\t\t\t\t\t\t\tinstalledChunkData = installedChunks[chunkId];\n\t\t\t\t\t\t\tif(installedChunkData !== 0) installedChunks[chunkId] = undefined;\n\t\t\t\t\t\t\tif(installedChunkData) {\n\t\t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n\t\t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n\t\t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n\t\t\t\t\t\t\t\terror.type = errorType;\n\t\t\t\t\t\t\t\terror.request = realSrc;\n\t\t\t\t\t\t\t\tinstalledChunkData[1](error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t__webpack_require__.l(url, loadingEnded, \"chunk-\" + chunkId, chunkId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n};\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n// no on chunks loaded\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkpwa_autofocus_app\"] = self[\"webpackChunkpwa_autofocus_app\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","export default function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n return arr2;\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}","import arrayWithHoles from \"./arrayWithHoles.js\";\nimport iterableToArrayLimit from \"./iterableToArrayLimit.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableRest from \"./nonIterableRest.js\";\nexport default function _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}","export default function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}","export default function _iterableToArrayLimit(r, l) {\n var t = null == r ? null : \"undefined\" != typeof Symbol && r[Symbol.iterator] || r[\"@@iterator\"];\n if (null != t) {\n var e,\n n,\n i,\n u,\n a = [],\n f = !0,\n o = !1;\n try {\n if (i = (t = t.call(r)).next, 0 === l) {\n if (Object(t) !== t) return;\n f = !1;\n } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);\n } catch (r) {\n o = !0, n = r;\n } finally {\n try {\n if (!f && null != t[\"return\"] && (u = t[\"return\"](), Object(u) !== u)) return;\n } finally {\n if (o) throw n;\n }\n }\n return a;\n }\n}","export default function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","export default function _typeof(o) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) {\n return typeof o;\n } : function (o) {\n return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o;\n }, _typeof(o);\n}","import _typeof from \"./typeof.js\";\nimport toPrimitive from \"./toPrimitive.js\";\nexport default function _toPropertyKey(arg) {\n var key = toPrimitive(arg, \"string\");\n return _typeof(key) === \"symbol\" ? key : String(key);\n}","import _typeof from \"./typeof.js\";\nexport default function _toPrimitive(input, hint) {\n if (_typeof(input) !== \"object\" || input === null) return input;\n var prim = input[Symbol.toPrimitive];\n if (prim !== undefined) {\n var res = prim.call(input, hint || \"default\");\n if (_typeof(res) !== \"object\") return res;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (hint === \"string\" ? String : Number)(input);\n}","import defineProperty from \"./defineProperty.js\";\nfunction ownKeys(e, r) {\n var t = Object.keys(e);\n if (Object.getOwnPropertySymbols) {\n var o = Object.getOwnPropertySymbols(e);\n r && (o = o.filter(function (r) {\n return Object.getOwnPropertyDescriptor(e, r).enumerable;\n })), t.push.apply(t, o);\n }\n return t;\n}\nexport default function _objectSpread2(e) {\n for (var r = 1; r < arguments.length; r++) {\n var t = null != arguments[r] ? arguments[r] : {};\n r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {\n defineProperty(e, r, t[r]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {\n Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));\n });\n }\n return e;\n}","import toPropertyKey from \"./toPropertyKey.js\";\nexport default function _defineProperty(obj, key, value) {\n key = toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}","import arrayWithoutHoles from \"./arrayWithoutHoles.js\";\nimport iterableToArray from \"./iterableToArray.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableSpread from \"./nonIterableSpread.js\";\nexport default function _toConsumableArray(arr) {\n return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return arrayLikeToArray(arr);\n}","export default function _iterableToArray(iter) {\n if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n}","export default function _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","export const hasNew = (tasks) => \n tasks.filter(x => x.status === \"new\").length > 0;\n\nexport const hasReady = (tasks) =>\n tasks.filter(x => x.status === \"ready\").length > 0;","import { hasReady, hasNew } from './taskUtils';\n\n// TODO: make consistent across project to use either \n// 'task' or 'item' term, but not both (domain language)\n\nexport const nextId = (tasks) => {\n return tasks.length === 0 ? \n 0 : \n Math.max(...tasks.map(x => x.id)) + 1;\n}\n\n// the benchmark item, also called the priority item, \n// is the last ready item in a list (domain language)\nexport const benchmarkItem = (tasks) => {\n if(!hasReady(tasks)) return null;\n\n return tasks.filter(x => x.status === \"ready\").at(-1);\n};\n\n// An automarkable list has new items and has no ready items. \nconst isAutoMarkableList = (tasks) => {\n return hasNew(tasks) && !hasReady(tasks);\n};\n\n// marks the first new item if the list is automarkable\nconst automark = (tasks) => {\n if(!isAutoMarkableList) {\n return tasks;\n }\n const firstNewItem = tasks.filter(x => x.status === \"new\").at(0);\n const updatedTasks = tasks.map(task =>\n task.id === firstNewItem.id ? { ...task, status: \"ready\" } : task);\n return updatedTasks;\n};\n\n// actionable lists have at least 1 ready status item\nexport const isActionableList = (tasks) => {\n return hasReady(tasks);\n};\n\nexport const completeBenchmarkTask = (tasks) => {\n if(!isActionableList(tasks)) {\n return tasks;\n }\n // get last ready item's id\n const benchmarkItem = tasks.filter(x => x.status === \"ready\").at(-1);\n // mark that item's status as done\n const updatedTasks = tasks.map(task =>\n task.id === benchmarkItem.id ? { ...task, status: \"done\" } : task);\n // if new list is automarkable, automark & then return, else return new list as-is \n return isAutoMarkableList(updatedTasks) ? automark(updatedTasks) : updatedTasks;\n};\n\n// newly added tasks have status of new unless no ready items exist, then they have a status of ready\nexport const addTask = (tasks, text) =>\n [...tasks, \n { id: nextId(tasks), text, status: hasReady(tasks) ? \"new\" : \"ready\" }];\n\nexport const emptyList = () => [];\n\nexport const addAll = (initialTasks, newTasks) => {\n const maxId = initialTasks.reduce((max, task) => Math.max(max, task.id), -1);\n const updatedNewTasks = newTasks.map((task, index) => ({\n id: maxId + index + 1, // Assign new IDs starting from maxId + 1\n text: task.text,\n status: task.status,\n }));\n\n return [...initialTasks, ...updatedNewTasks];\n};\n\n// TODO: test this function, confirm that it works as expected\nexport const cancelItem = (tasks, id) => {\n const updatedTasks = tasks.map(task => \n task.id === id ? { ...task, was: task.status, status: \"cancelled\" } : task\n );\n return isAutoMarkableList(updatedTasks) ? automark(updatedTasks) : updatedTasks;\n}\n\n// takes item of a given id and re-adds it to the list\nexport const cloneItem = (tasks, id) => {\n const itemText = tasks.filter(x => x.id === id).at(0).text;\n const updatedTasks = addTask(tasks, itemText);\n return updatedTasks;\n}","import { hasReady, hasNew } from './taskUtils';\n\nconst noValidCursorErrMsg = \"Review question cannot be generated because there is no valid cursor.\";\nconst noBenchmarkItemErrMsg = \"Review question cannot be generated because there is no benchmark item to compare against.\";\nconst listNotPrioritizableErrMsg = \"The list isn't prioritizable right now.\";\n\nconst questionString = (benchmarkItemText, cursorItemText) =>\n `In this moment, are you more ready to '${cursorItemText}' than '${benchmarkItemText}'?`;\n \nexport const genCurrentQuestion = (tasks, cursor) => {\n if(cursor === -1 || cursor >= tasks.length) {\n return noValidCursorErrMsg;\n }\n \n const cursorItem = tasks[cursor];\n const benchmarkItem = tasks.filter(x => x.status === \"ready\").at(-1);\n\n if (!benchmarkItem) {\n return noBenchmarkItemErrMsg;\n }\n\n return questionString(benchmarkItem.text, cursorItem.text);\n};\n\n// a prioritizable list has at least one ready item and \n// at least one new item after the last ready item\nexport const isPrioritizableList = (tasks) => {\n if (tasks.length <= 1) return false;\n if (!hasReady(tasks) || !hasNew(tasks)) return false;\n\n const lastReadyItem = tasks.filter(x => x.status === \"ready\").at(-1);\n const lastNewItem = tasks.filter(x => x.status === \"new\").at(-1);\n\n return lastNewItem.id > lastReadyItem.id;\n }\n\n// the initial prioritization session cursor starts at the first new item after the benchmark item\nexport const getInitialCursor = (tasks) => {\n const lastReadyItem = tasks.filter(x => x.status === \"ready\").at(-1);\n const lastReadyIndex = tasks.indexOf(lastReadyItem);\n const slicedList = tasks.slice(lastReadyIndex);\n const firstNewItem = slicedList.filter(x => x.status === \"new\").at(0);\n const firstNewAfterReadyIndex = tasks.indexOf(firstNewItem);\n return firstNewAfterReadyIndex;\n};\n\n// first new item after the cursor\nexport const nextCursor = (tasks, currentCursor) => {\n const slicedList = tasks.slice(currentCursor);\n const firstNewItem = slicedList.filter(x => x.status === \"new\").at(0);\n if(firstNewItem) {\n return tasks.indexOf(firstNewItem);\n } else {\n return -1; // indicates secondNewItem not found\n }\n};\n\nexport const markReadyAtIndex = (tasks, cursor) => {\n const updatedTasks = tasks.map((task, index) => \n index === cursor ? { ...task, status: \"ready\" } : task\n );\n return updatedTasks;\n };\n\nexport const startReview = (tasks) => {\n // check is task list prioritizable\n if (!isPrioritizableList(tasks)) {\n // TODO: add clear reason why list isn't prioritizable\n // for example, because there are no new items, or, because \n // the last non-done item is marked as ready already\n // TODO: create helper function that gives reason for \n // why a list isn't prioritizable (either the list is fully\n // prioritized, or, it has no new items)\n return { error: listNotPrioritizableErrMsg };\n }\n\n // get initial cursor position\n const initialCursor = getInitialCursor(tasks);\n return { cursor: initialCursor };\n};\n\nexport const handleReviewDecision = (tasks, cursor, decision) => {\n let updatedTasks = tasks;\n let newCursor = cursor;\n\n // handle user's decision\n if (decision === 'Yes') {\n updatedTasks = markReadyAtIndex(tasks, cursor);\n newCursor = nextCursor(tasks, cursor + 1);\n } else if (decision === 'No') {\n newCursor = nextCursor(tasks, cursor + 1);\n } else {\n // quit reviewing\n newCursor = -1;\n }\n\n // Check if review process should end\n if (newCursor === -1 || newCursor === tasks.length) {\n return { tasks: updatedTasks, cursor: newCursor, endReview: true };\n } else {\n return { tasks: updatedTasks, cursor: newCursor };\n }\n};\n","/**\n * Save data to local storage under the specified key.\n * @param {string} key - The key under which the data should be stored.\n * @param {any} data - The data to be stored.\n */\nexport const saveToLocalStorage = (key, data) => {\n try {\n const serializedData = JSON.stringify(data);\n localStorage.setItem(key, serializedData);\n } catch (error) {\n console.error(\"Failed to save data to local storage:\", error);\n }\n};\n\n/**\n * Retrieve data from local storage for the given key.\n * @param {string} key - The key for which data should be retrieved.\n * @param {any} defaultValue - The default value to return if the key doesn't exist.\n * @returns {any} - The retrieved data or the default value.\n */\nexport const getFromLocalStorage = (key, defaultValue = null) => {\n try {\n const serializedData = localStorage.getItem(key);\n if (serializedData === null) {\n return defaultValue;\n }\n return JSON.parse(serializedData);\n } catch (error) {\n console.error(\"Failed to retrieve data from local storage:\", error);\n return defaultValue;\n }\n};\n","// convert tasks list to JSON string\nexport const exportTasksToJSON = (tasks) => {\n try {\n return JSON.stringify(tasks);\n } catch (error) {\n console.error(\"Failed to convert tasks to JSON:\", error);\n return null;\n }\n};\n\n// parse JSON string and return tasks list\nexport const importTasksFromJSON = (jsonString) => {\n try {\n const tasks = JSON.parse(jsonString);\n \n if (!Array.isArray(tasks)) {\n throw new Error(\"The JSON content isn't an array.\");\n }\n \n for (let task of tasks) {\n if (typeof task !== 'object') {\n throw new Error(\"A task in the JSON isn't an object.\");\n }\n if (!task.hasOwnProperty('id')) {\n throw new Error(\"A task in the JSON doesn't have an 'id' property.\");\n }\n if (typeof task.id !== 'number') {\n throw new Error(\"The 'id' property in a task isn't a number.\");\n }\n if (!task.hasOwnProperty('text')) {\n throw new Error(\"A task in the JSON doesn't have a 'text' property.\");\n }\n if (typeof task.text !== 'string') {\n throw new Error(\"The 'text' property in a task isn't a string.\");\n }\n }\n \n return tasks;\n\n } catch (error) {\n console.error(\"Failed to parse JSON to tasks:\", error);\n return null;\n }\n};\n","import unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nexport default function _createForOfIteratorHelper(o, allowArrayLike) {\n var it = typeof Symbol !== \"undefined\" && o[Symbol.iterator] || o[\"@@iterator\"];\n if (!it) {\n if (Array.isArray(o) || (it = unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") {\n if (it) o = it;\n var i = 0;\n var F = function F() {};\n return {\n s: F,\n n: function n() {\n if (i >= o.length) return {\n done: true\n };\n return {\n done: false,\n value: o[i++]\n };\n },\n e: function e(_e) {\n throw _e;\n },\n f: F\n };\n }\n throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n }\n var normalCompletion = true,\n didErr = false,\n err;\n return {\n s: function s() {\n it = it.call(o);\n },\n n: function n() {\n var step = it.next();\n normalCompletion = step.done;\n return step;\n },\n e: function e(_e2) {\n didErr = true;\n err = _e2;\n },\n f: function f() {\n try {\n if (!normalCompletion && it[\"return\"] != null) it[\"return\"]();\n } finally {\n if (didErr) throw err;\n }\n }\n };\n}","export const objectsAreEqual = (obj1, obj2) => {\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n \n if (keys1.length !== keys2.length) {\n return false; // If the objects have different numbers of properties, they are not equal\n }\n \n for (const key of keys1) {\n if (obj1[key] !== obj2[key]) {\n return false; // If any property values are different, the objects are not equal\n }\n }\n \n return true; // If no differences were found, the objects are equal\n }\n\nexport const objectArraysAreEqual = (arr1, arr2) => {\n if (arr1.length !== arr2.length) {\n return false; // If the lengths are different, the arrays are not equal\n }\n \n // Sort the arrays by a unique property to ensure the order doesn't affect the comparison\n const sortedArr1 = arr1.slice().sort((a, b) => a.id - b.id);\n const sortedArr2 = arr2.slice().sort((a, b) => a.id - b.id);\n \n for (let i = 0; i < sortedArr1.length; i++) {\n if (!objectsAreEqual(sortedArr1[i], sortedArr2[i])) {\n return false; // If any objects are not equal, the arrays are not equal\n }\n }\n \n return true; // If no differences were found, the arrays are equal\n }","export const infoCircle = ;\n\nexport const saveDisk = ;\n\nexport const dotCircle = ;\n\nexport const emptyCircle = ;\n\nexport const filledCircle = ;\n\nexport const lightbulbSolid = ;\n\nexport const lightbulbRegular = ;\n\n// aliases in font awesome: fa-remove, fa-times, fa-close\nexport const cancelX = ;\n\n// aliases: fa-rotate-right, redo-alt\nexport const repeatArrow = ;","import React from 'react';\nimport {dotCircle, emptyCircle, filledCircle, \n cancelX, repeatArrow} from './core/icons'\n\n// converts the all possible statuses *except* for \n// 'cancelled' to a renderable symbol\nconst statusToSymbol = status => {\n if (status === \"done\") return filledCircle;\n if (status === \"ready\") return dotCircle;\n if (status === \"new\") return emptyCircle;\n return null;\n}\n\nfunction TodoItem({ task, isBenchmark, cancelFunc, cloneFunc, theme }) {\n return (\n \n \n {(statusToSymbol(task.status) !== null) ?\n statusToSymbol(task.status) :\n statusToSymbol(task.was)}\n {task.text}\n \n {cancelFunc && cloneFunc &&\n <>\n {task.status === \"new\" || task.status === \"ready\" ?\n : \n }>}\n
\n \n );\n}\n\nexport default TodoItem;\n","import {useState, useEffect, useRef} from 'react';\nimport { addTask, addAll, completeBenchmarkTask, benchmarkItem, \n emptyList, isActionableList, cancelItem, cloneItem } from './core/tasksManager';\nimport { startReview, handleReviewDecision, isPrioritizableList, \n genCurrentQuestion, getInitialCursor } from './core/reviewManager';\nimport { getFromLocalStorage, saveToLocalStorage } from './core/localStorageAdapter';\nimport { exportTasksToJSON, importTasksFromJSON } from './core/tasksIO';\nimport { objectArraysAreEqual } from './core/logicUtils';\nimport TodoItem from './TodoItem';\nimport {saveDisk, infoCircle, lightbulbSolid, lightbulbRegular } from './core/icons'\nimport './App.css';\n\n// TODO: refactor all buttons to change color on hover, focus, active rather than grow\n// TODO: implement an 'undo' button that undo's the last action taken, use fa-history icon\n// TODO: restrict 'next actionable item' text to 2 lines, end with ellipses if it exceeds that\n\nconst activeListOffset = 0;\nconst queryStringListOffset = 100;\nconst initialTasksListOffset = 200;\n\nconst appName = \"AutoFocus\";\nconst infoString2 = \"This web app was built by Avi Drucker using ReactJS, Font Awesome, and Tachyons CSS.\";\nconst infoString1 = \"The AutoFocus algorithm was designed by Mark Forster as a pen and paper method to help increase productivity. It does so by limiting list interaction and providing a simple (binary) decision-making framework.\";\nconst saveInfo1 = \"You can import and export JSON lists into and out of AutoFocus.\";\nconst saveInfo2 = \"You can also import a list by pasting in raw text below, and then clicking the 'Submit' button.\";\nconst emptyInputErrMsg1 = \"New items cannot be empty or only whitespace.\";\nconst cannotTakeActionErrMsg1 = \"There are no actionable tasks in your list.\";\nconst emptyTextAreaErrMsg1 = \"New items cannot be empty or whitespace only.\";\nconst badJSONimportErrMsg1 = \"Failed to import tasks. Ensure the JSON file has the correct format.\";\nconst nonJSONimportAttemptedErrMsg1 = \"Please select a valid JSON file.\";\nconst mismatchDetectedMsg1 = \"The link list and local storage list do not match. Which will you keep?\";\nconst confirmListDelete = \"Are you sure you want to delete your list? This action cannot be undone.\";\nconst clickDiskToClose = \"Click on the 'disk' icon above to close this window.\";\nconst clickIcircleToClose = \"Click on the 'i' icon above to close this window.\";\nconst invalidQueryParamsErrMsg1 = \"Invalid list query parameters detected. Reverting to local storage list data.\";\nconst nothingToDeleteErrMsg1 = \"There is nothing to delete.\";\nconst rebuildingQueryParamsConsoleMsg1 = \"rebuilding query params from local storage\";\nconst exportFailErrMsg1 = \"Failed to export tasks.\";\n\nfunction App() {\n const initialTasks = getFromLocalStorage('tasks', []);\n const [tasks, setTasks] = useState(initialTasks);\n const [inputValue, setInputValue] = useState('');\n const initialPrioritizing = getFromLocalStorage('isPrioritizing', false);\n const [isPrioritizing, setIsPrioritizing] = useState(initialPrioritizing);\n const initialCursor = getFromLocalStorage('cursor', -1);\n const [cursor, setCursor] = useState(initialCursor);\n const [errMsg, setErrMsg] = useState(\"\");\n const [showingDeleteModal, setShowingDeleteModal] = useState(false);\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n const [showingSaveModal, setShowingSaveModal] = useState(false);\n const [importErrMsg, setImportErrMsg] = useState(\"\");\n const inputRef = useRef(null);\n const [showingConflictModal, setShowingConflictModal] = useState(false);\n const [textAreaValue, setTextAreaValue] = useState('');\n const initialTheme = getFromLocalStorage('theme', 'dark');\n const [theme, setTheme] = useState(initialTheme);\n\n\n // sets focus to new item text input on initial load\n // Note: this effect runs only once after the initial render \n // because of the empty dependency array [].\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.focus();\n }\n }, []);\n\n // TODO: test setting main element bg color instead of body\n // now that html, body, and the #root div are all 100% height\n // sets the background color of the page based on the theme\n useEffect(() => {\n if (theme === 'light') {\n document.body.classList.add('bg-white');\n document.body.classList.remove('bg-black');\n } else {\n document.body.classList.add('bg-black');\n document.body.classList.remove('bg-white');\n }\n }, [theme]);\n\n // useEffect that loads list state on page load, attempts to get a list from\n // the URL and local storage, checks for any errors or potential conflicts\n useEffect(() => {\n // Attempt to load the list state from the URL\n const listStateWrapperFromURL = deserializeQueryStringToListStateWrapper(window.location.search);\n\n if(listStateWrapperFromURL.result) {\n if (listStateWrapperFromURL.result.length !== 0 && initialTasks.length === 0) {\n // If URL state is present and local storage is empty, use the URL state\n // console.info(\"using URL state\")\n handleListChange(listStateWrapperFromURL.result);\n } else if (listStateWrapperFromURL.result.length === 0 && initialTasks.length !== 0) {\n // If URL state is not present, default to using local storage state if it exists\n // console.info(\"URL state not found, defaulting to local storage\")\n handleListChange(initialTasks);\n }\n else if (listStateWrapperFromURL.result.length !== 0 && initialTasks.length !== 0) {\n if(objectArraysAreEqual(listStateWrapperFromURL.result, initialTasks)) {\n // we don't have to do anything if the query params and local storage list match\n // console.info(\"list from query params and list from local storage are the same\")\n } else {\n // however, if we have two different lists from query params and local storage,\n // we will prompt the user to choose which one to use\n // console.info(\"conflict found, activating conflict resolution modal\")\n setShowingConflictModal(true);\n }\n } else {\n // Neither state exists, so we will have an empty default list\n // console.info(\"No state found in address bar or local storage\")\n handleListChange(initialTasks);\n }\n } else {\n if(listStateWrapperFromURL.error) {\n setErrMsg(invalidQueryParamsErrMsg1);\n }\n // TODO: confirm there is no valid 'else' path here\n // invalid query string found or missing query string, so\n // let's rebuild it and save it back to the query params\n console.info(rebuildingQueryParamsConsoleMsg1);\n handleListChange(initialTasks);\n }\n // eslint-disable-next-line\n }, []); // The empty dependency array ensures this effect runs once on mount\n\n // useEffect that save cursor to local storage every time the cursor changes\n // it also sets the isPrioritizing state to false if the cursor is -1\n useEffect(()=>{\n saveToLocalStorage('cursor', cursor);\n if(cursor === -1) {\n setIsPrioritizing(false);\n }\n // eslint-disable-next-line\n }, [cursor]);\n\n // useEffect that saves isPrioritizing to local storage every time it changes\n // it also updates the cursor to either the first reviewable item or -1 \n // depending on whether or not isPrioritizing is true\n useEffect(() => {\n saveToLocalStorage('isPrioritizing', isPrioritizing);\n if(isPrioritizing) {\n setCursor(getInitialCursor(tasks));\n } else {\n setCursor(-1);\n }\n // eslint-disable-next-line\n }, [isPrioritizing])\n\n // focusing on the input after deleting the list\n useEffect(() => {\n if (!showingDeleteModal && tasks.length === 0) {\n inputRef.current.focus();\n }\n }, [showingDeleteModal, tasks.length]);\n\n const handlePrioritizeUI = () => {\n const result = startReview(tasks);\n if (result.error) {\n setErrMsg(result.error);\n } else {\n setIsPrioritizing(!isPrioritizing);\n setCursor(result.cursor);\n setErrMsg(\"\");\n }\n };\n\n const handleListChange = (newListState) => {\n // Serialize the new state to a query string\n const queryString = serializeListStateToQueryString(newListState);\n \n // Update the URL without reloading the page\n window.history.pushState({}, '', queryString);\n \n setTasks(newListState);\n saveToLocalStorage('tasks', newListState);\n };\n\n const handleAddTaskUI = (e) => {\n e.preventDefault();\n if (inputValue.trim()) {\n const updatedTasks = addTask(tasks, inputValue);\n handleListChange(updatedTasks);\n setInputValue('');\n } else {\n setErrMsg(emptyInputErrMsg1);\n }\n };\n\n const handleTakeActionUI = () => {\n if(!isActionableList(tasks)) {\n setErrMsg(cannotTakeActionErrMsg1);\n } else {\n const updatedTasks = completeBenchmarkTask(tasks);\n handleListChange(updatedTasks);\n setErrMsg(\"\");\n }\n }\n\n const handleDeleteUI = () => {\n const updatedTasks = emptyList();\n handleListChange(updatedTasks);\n setErrMsg(\"\");\n setShowingDeleteModal(false);\n };\n\n const handleNoUI = () => {\n const result = handleReviewDecision(tasks, cursor, \"No\");\n setCursor(result.cursor);\n }\n\n const handleYesUI = () => {\n const result = handleReviewDecision(tasks, cursor, \"Yes\");\n setCursor(result.cursor);\n handleListChange(result.tasks);\n }\n\n const handleQuitUI = () => {\n const result = handleReviewDecision(tasks, cursor, \"Quit\");\n setCursor(result.cursor);\n setIsPrioritizing(false);\n }\n\n const handleToggleDeleteModal = () => {\n if(tasks.length === 0) {\n setErrMsg(nothingToDeleteErrMsg1);\n } else {\n setShowingDeleteModal(!showingDeleteModal); \n }\n }\n\n const handleToggleInfoModal = () => {\n setShowingMoreInfo(!showingMoreInfo);\n setShowingSaveModal(false);\n setErrMsg(\"\");\n }\n\n const handleToggleSaveModal = () => {\n setShowingSaveModal(!showingSaveModal);\n setShowingMoreInfo(false);\n setImportErrMsg(\"\");\n setErrMsg(\"\");\n }\n\n const handleToggleTheme = () => {\n setTheme(theme === 'light' ? 'dark' : 'light');\n saveToLocalStorage('theme', theme === 'light' ? 'dark' : 'light');\n }\n\n // Function to handle exporting tasks to a JSON file\n const handleExportTasks = () => {\n setImportErrMsg(\"\");\n // TODO: extract out following logic into separate module as per hexagonal architecture\n const json = exportTasksToJSON(tasks);\n if (json) {\n const blob = new Blob([json], {type: \"application/json\"});\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'tasks.json';\n a.click();\n URL.revokeObjectURL(url);\n } else {\n setErrMsg(exportFailErrMsg1);\n }\n };\n\n // Function to handle importing tasks from raw text\n const handleTextImport = () => {\n if (textAreaValue.trim()) {\n const lines = textAreaValue.split(\"\\n\");\n let updatedTasks = tasks;\n for(let i = 0; i < lines.length; i++) {\n updatedTasks = addTask(updatedTasks, lines[i]);\n }\n handleListChange(updatedTasks);\n setTextAreaValue('');\n } else {\n setImportErrMsg(emptyTextAreaErrMsg1);\n }\n }\n\n // Function to handle importing tasks from a JSON file\n const handleImportTasks = (event) => {\n setImportErrMsg(\"\");\n const file = event.target.files[0];\n if (file && file.type === \"application/json\") {\n const reader = new FileReader();\n reader.onload = (e) => {\n const importedTasks = importTasksFromJSON(e.target.result);\n if (importedTasks) {\n // append imported tasks to current tasks,\n // addAll updates ids for 2nd list to \n // prevent id collisions\n const updatedTasks = addAll(tasks, importedTasks);\n handleListChange(updatedTasks);\n } else {\n setImportErrMsg(badJSONimportErrMsg1);\n }\n };\n reader.readAsText(file);\n } else {\n setErrMsg(nonJSONimportAttemptedErrMsg1);\n }\n };\n\n // TODO: rename function to better describe intent\n const handleLabelKeyPress = (event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n // Prevent the default action to avoid scrolling on Space press\n event.preventDefault();\n // Trigger click on file input\n document.getElementById('file-upload').click();\n }\n };\n\n const serializeListStateToQueryString = (listState) => {\n // TODO: refactor out btoa w/ Buffer.from(str, 'base64') and buf.toString('base64')\n // Serialize listState to a query-friendly string, such as base64\n const serializedState = btoa(encodeURIComponent(JSON.stringify(listState)));\n return `?list=${serializedState}`;\n };\n\n const deserializeQueryStringToListStateWrapper = (queryString) => {\n // Extract the 'list' parameter from the query string\n const params = new URLSearchParams(queryString);\n const serializedState = params.get('list');\n if (!serializedState) {\n console.info(\"No list data found in query parameters.\");\n return {result: []}; // TODO: test this as null and as {result: []}\n }\n // Deserialize the state from a query-friendly string\n try {\n // TODO: refactor out atob w/ Buffer.from(str, 'base64') and buf.toString('base64')\n const listState = JSON.parse(decodeURIComponent(atob(serializedState)));\n return {result: listState};\n } catch (error) {\n // TODO: move errors strings to top of file, decide whether \n // to use verbose or custom error messages\n console.error('Failed to deserialize query string:', error);\n return {error: 'Malformed query string'};\n }\n };\n\n // takes in the user's choice of new list, updates the list, \n // and closes the modal\n const handleListConflictChoice = (newListState) => {\n handleListChange(newListState);\n setShowingConflictModal(false);\n }\n\n // renders a list of tasks, with optional interactive buttons\n // Note: idOffset is here for the purposes of rendering multiple\n // lists at once, such as when evaluating conflicting\n // lists in localStorage and query params.\n // Note: the lists rendered in the conflict modal are not interactive\n const renderList = (inputList, idOffset, interactive) => \n
\n {interactive ?\n <> {inputList.map(task => (\n handleListChange(cancelItem(inputList, task.id))}\n cloneFunc={() => handleListChange(cloneItem(inputList, task.id))}\n isBenchmark={benchmarkItem(inputList) !== null && benchmarkItem(inputList).id === task.id}\n theme={theme}\n />))} > :\n <> {inputList.map(task => (\n \n ))}>}\n
\n
;\n \n return (\n \n \n\n \n \n \n \n {/* Note: the true on the next line turns ON cancel/clone buttons */}\n {tasks.length > 0 && renderList(tasks, activeListOffset, true)}\n \n\n \n
\n {`You have ${tasks.length} item${tasks.length !== 1 ? 's' : ''} in your list.`}\n
\n\n
\n {(benchmarkItem(tasks) !== null) && `The next actionable item is '${benchmarkItem(tasks).text}'.`}\n
\n
\n\n {/*prioritization review modal*/}\n {(isPrioritizing && cursor !== -1 && cursor < tasks.length) && \n \n \n {genCurrentQuestion(tasks, cursor)}
\n \n \n \n \n
\n \n }\n\n {/*'are you sure you want to delete your list?' modal*/}\n {showingDeleteModal &&\n \n \n {confirmListDelete}
\n \n \n \n
\n \n }\n\n {/*save modal*/}\n {showingSaveModal &&\n \n \n\n {saveInfo1}
\n \n \n \n \n
\n\n {importErrMsg && \n {importErrMsg}
}\n \n {saveInfo2}
\n\n \n
\n \n {clickDiskToClose}
\n \n \n }\n\n {/*app info modal*/}\n {showingMoreInfo &&\n \n \n\n {infoString1}
\n\n {infoString2}
\n\n {clickIcircleToClose}
\n \n \n }\n\n {/*local storage and query params conflict resolution modal*/}\n {showingConflictModal && \n \n {mismatchDetectedMsg1}
\n 1. List from the link address:
\n {renderList(deserializeQueryStringToListStateWrapper(window.location.search).result, queryStringListOffset)}\n 2. List from local storage:
\n {renderList(initialTasks, initialTasksListOffset)}\n \n \n \n \n
\n }\n\n \n \n );\n}\n\nexport default App;\n","const reportWebVitals = onPerfEntry => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry);\n getFID(onPerfEntry);\n getFCP(onPerfEntry);\n getLCP(onPerfEntry);\n getTTFB(onPerfEntry);\n });\n }\n};\n\nexport default reportWebVitals;\n","import React from 'react';\nimport ReactDOM from 'react-dom/client';\nimport './index.css';\nimport App from './App';\nimport reportWebVitals from './reportWebVitals';\n\nconst root = ReactDOM.createRoot(document.getElementById('root'));\nroot.render(\n \n \n \n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n\nfunction registerServiceWorker() {\n // Check for service worker support in the browser\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.register(`${process.env.PUBLIC_URL}/serviceWorker.js`)\n .then(registration => {\n console.log('Service Worker registered with scope:', registration.scope);\n }).catch(error => {\n console.log('Service Worker registration failed:', error);\n });\n }\n}\n\nregisterServiceWorker();"],"names":["aa","require","ca","p","a","b","c","arguments","length","encodeURIComponent","da","Set","ea","fa","ha","add","ia","window","document","createElement","ja","Object","prototype","hasOwnProperty","ka","la","ma","v","d","e","f","g","this","acceptsBooleans","attributeName","attributeNamespace","mustUseProperty","propertyName","type","sanitizeURL","removeEmptyString","z","split","forEach","toLowerCase","ra","sa","toUpperCase","ta","slice","pa","isNaN","qa","call","test","oa","removeAttribute","setAttribute","setAttributeNS","replace","xlinkHref","ua","__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","va","Symbol","for","wa","ya","za","Aa","Ba","Ca","Da","Ea","Fa","Ga","Ha","Ia","Ja","iterator","Ka","La","A","assign","Ma","Error","stack","trim","match","Na","Oa","prepareStackTrace","defineProperty","set","Reflect","construct","l","h","k","displayName","includes","name","Pa","tag","render","Qa","$$typeof","_context","_payload","_init","Ra","Sa","Ta","nodeName","Va","_valueTracker","getOwnPropertyDescriptor","constructor","get","configurable","enumerable","getValue","setValue","stopTracking","Ua","Wa","checked","value","Xa","activeElement","body","Ya","defaultChecked","defaultValue","_wrapperState","initialChecked","Za","initialValue","controlled","ab","bb","cb","db","ownerDocument","eb","Array","isArray","fb","options","selected","defaultSelected","disabled","gb","dangerouslySetInnerHTML","children","hb","ib","jb","textContent","kb","lb","mb","nb","namespaceURI","innerHTML","valueOf","toString","firstChild","removeChild","appendChild","MSApp","execUnsafeLocalFunction","ob","lastChild","nodeType","nodeValue","pb","animationIterationCount","aspectRatio","borderImageOutset","borderImageSlice","borderImageWidth","boxFlex","boxFlexGroup","boxOrdinalGroup","columnCount","columns","flex","flexGrow","flexPositive","flexShrink","flexNegative","flexOrder","gridArea","gridRow","gridRowEnd","gridRowSpan","gridRowStart","gridColumn","gridColumnEnd","gridColumnSpan","gridColumnStart","fontWeight","lineClamp","lineHeight","opacity","order","orphans","tabSize","widows","zIndex","zoom","fillOpacity","floodOpacity","stopOpacity","strokeDasharray","strokeDashoffset","strokeMiterlimit","strokeOpacity","strokeWidth","qb","rb","sb","style","indexOf","setProperty","keys","charAt","substring","tb","menuitem","area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr","ub","vb","is","wb","xb","target","srcElement","correspondingUseElement","parentNode","yb","zb","Ab","Bb","Cb","stateNode","Db","Eb","push","Fb","Gb","Hb","Ib","Jb","Kb","Lb","Mb","addEventListener","removeEventListener","Nb","apply","m","onError","Ob","Pb","Qb","Rb","Sb","Tb","Vb","alternate","return","flags","Wb","memoizedState","dehydrated","Xb","Zb","child","sibling","current","Yb","$b","ac","unstable_scheduleCallback","bc","unstable_cancelCallback","cc","unstable_shouldYield","dc","unstable_requestPaint","B","unstable_now","ec","unstable_getCurrentPriorityLevel","fc","unstable_ImmediatePriority","gc","unstable_UserBlockingPriority","hc","unstable_NormalPriority","ic","unstable_LowPriority","jc","unstable_IdlePriority","kc","lc","oc","Math","clz32","pc","qc","log","LN2","rc","sc","tc","uc","pendingLanes","suspendedLanes","pingedLanes","entangledLanes","entanglements","vc","xc","yc","zc","Ac","eventTimes","Cc","C","Dc","Ec","Fc","Gc","Hc","Ic","Jc","Kc","Lc","Mc","Nc","Oc","Map","Pc","Qc","Rc","Sc","delete","pointerId","Tc","nativeEvent","blockedOn","domEventName","eventSystemFlags","targetContainers","Vc","Wc","priority","isDehydrated","containerInfo","Xc","Yc","dispatchEvent","shift","Zc","$c","ad","bd","cd","ReactCurrentBatchConfig","dd","ed","transition","fd","gd","hd","id","Uc","stopPropagation","jd","kd","ld","md","nd","od","keyCode","charCode","pd","qd","rd","_reactName","_targetInst","currentTarget","isDefaultPrevented","defaultPrevented","returnValue","isPropagationStopped","preventDefault","cancelBubble","persist","isPersistent","wd","xd","yd","sd","eventPhase","bubbles","cancelable","timeStamp","Date","now","isTrusted","td","ud","view","detail","vd","Ad","screenX","screenY","clientX","clientY","pageX","pageY","ctrlKey","shiftKey","altKey","metaKey","getModifierState","zd","button","buttons","relatedTarget","fromElement","toElement","movementX","movementY","Bd","Dd","dataTransfer","Fd","Hd","animationName","elapsedTime","pseudoElement","Id","clipboardData","Jd","Ld","data","Md","Esc","Spacebar","Left","Up","Right","Down","Del","Win","Menu","Apps","Scroll","MozPrintableKey","Nd","Od","Alt","Control","Meta","Shift","Pd","Qd","key","String","fromCharCode","code","location","repeat","locale","which","Rd","Td","width","height","pressure","tangentialPressure","tiltX","tiltY","twist","pointerType","isPrimary","Vd","touches","targetTouches","changedTouches","Xd","Yd","deltaX","wheelDeltaX","deltaY","wheelDeltaY","wheelDelta","deltaZ","deltaMode","Zd","$d","ae","be","documentMode","ce","de","ee","fe","ge","he","ie","le","color","date","datetime","email","month","number","password","range","search","tel","text","time","url","week","me","ne","oe","event","listeners","pe","qe","re","se","te","ue","ve","we","xe","ye","ze","oninput","Ae","detachEvent","Be","Ce","attachEvent","De","Ee","Fe","He","Ie","Je","Ke","node","offset","nextSibling","Le","contains","compareDocumentPosition","Me","HTMLIFrameElement","contentWindow","href","Ne","contentEditable","Oe","focusedElem","selectionRange","documentElement","start","end","selectionStart","selectionEnd","min","defaultView","getSelection","extend","rangeCount","anchorNode","anchorOffset","focusNode","focusOffset","createRange","setStart","removeAllRanges","addRange","setEnd","element","left","scrollLeft","top","scrollTop","focus","Pe","Qe","Re","Se","Te","Ue","Ve","We","animationend","animationiteration","animationstart","transitionend","Xe","Ye","Ze","animation","$e","af","bf","cf","df","ef","ff","gf","hf","lf","mf","concat","nf","Ub","instance","listener","D","of","has","pf","qf","rf","random","sf","bind","capture","passive","n","t","J","x","u","w","F","tf","uf","parentWindow","vf","wf","na","xa","$a","ba","je","char","ke","unshift","xf","yf","zf","Af","Bf","Cf","Df","Ef","__html","Ff","setTimeout","Gf","clearTimeout","Hf","Promise","Jf","queueMicrotask","resolve","then","catch","If","Kf","Lf","Mf","previousSibling","Nf","Of","Pf","Qf","Rf","Sf","Tf","Uf","E","G","Vf","H","Wf","Xf","Yf","contextTypes","__reactInternalMemoizedUnmaskedChildContext","__reactInternalMemoizedMaskedChildContext","Zf","childContextTypes","$f","ag","bg","getChildContext","cg","__reactInternalMemoizedMergedChildContext","dg","eg","fg","gg","hg","jg","kg","lg","mg","ng","og","pg","qg","rg","sg","tg","ug","vg","wg","xg","yg","I","zg","Ag","Bg","elementType","deletions","Cg","pendingProps","overflow","treeContext","retryLane","Dg","mode","Eg","Fg","Gg","memoizedProps","Hg","Ig","Jg","Kg","Lg","defaultProps","Mg","Ng","Og","Pg","Qg","Rg","_currentValue","Sg","childLanes","Tg","dependencies","firstContext","lanes","Ug","Vg","context","memoizedValue","next","Wg","Xg","Yg","interleaved","Zg","$g","ah","updateQueue","baseState","firstBaseUpdate","lastBaseUpdate","shared","pending","effects","bh","ch","eventTime","lane","payload","callback","dh","K","eh","fh","gh","q","r","y","hh","ih","jh","Component","refs","kh","nh","isMounted","_reactInternals","enqueueSetState","L","lh","mh","enqueueReplaceState","enqueueForceUpdate","oh","shouldComponentUpdate","isPureReactComponent","ph","contextType","state","updater","qh","componentWillReceiveProps","UNSAFE_componentWillReceiveProps","rh","props","getDerivedStateFromProps","getSnapshotBeforeUpdate","UNSAFE_componentWillMount","componentWillMount","componentDidMount","sh","ref","_owner","_stringRef","th","join","uh","vh","index","wh","xh","yh","implementation","zh","Ah","done","Bh","Ch","Dh","Eh","Fh","Gh","Hh","Ih","tagName","Jh","Kh","Lh","M","Mh","revealOrder","Nh","Oh","_workInProgressVersionPrimary","Ph","ReactCurrentDispatcher","Qh","Rh","N","O","P","Sh","Th","Uh","Vh","Q","Wh","Xh","Yh","Zh","$h","ai","bi","ci","baseQueue","queue","di","ei","fi","lastRenderedReducer","action","hasEagerState","eagerState","lastRenderedState","dispatch","gi","hi","ii","ji","ki","getSnapshot","li","mi","R","ni","lastEffect","stores","oi","pi","qi","ri","create","destroy","deps","si","ti","ui","vi","wi","xi","yi","zi","Ai","Bi","Ci","Di","Ei","Fi","Gi","Hi","Ii","Ji","readContext","useCallback","useContext","useEffect","useImperativeHandle","useInsertionEffect","useLayoutEffect","useMemo","useReducer","useRef","useState","useDebugValue","useDeferredValue","useTransition","useMutableSource","useSyncExternalStore","useId","unstable_isNewReconciler","identifierPrefix","Ki","message","digest","Li","Mi","console","error","Ni","WeakMap","Oi","Pi","Qi","Ri","getDerivedStateFromError","componentDidCatch","Si","componentStack","Ti","pingCache","Ui","Vi","Wi","Xi","ReactCurrentOwner","Yi","Zi","$i","aj","bj","compare","cj","dj","ej","baseLanes","cachePool","transitions","fj","gj","hj","ij","jj","UNSAFE_componentWillUpdate","componentWillUpdate","componentDidUpdate","kj","lj","pendingContext","mj","Aj","Bj","Cj","Dj","nj","oj","pj","fallback","qj","rj","tj","dataset","dgst","uj","vj","_reactRetry","sj","subtreeFlags","wj","xj","isBackwards","rendering","renderingStartTime","last","tail","tailMode","yj","Ej","S","Fj","Gj","wasMultiple","multiple","suppressHydrationWarning","onClick","onclick","size","createElementNS","autoFocus","createTextNode","T","Hj","Ij","Jj","Kj","U","Lj","WeakSet","V","Mj","W","Nj","Oj","Qj","Rj","Sj","Tj","Uj","Vj","Wj","insertBefore","_reactRootContainer","Xj","X","Yj","Zj","ak","onCommitFiberUnmount","componentWillUnmount","bk","ck","dk","ek","fk","isHidden","gk","hk","display","ik","jk","kk","lk","__reactInternalSnapshotBeforeUpdate","src","Wk","mk","ceil","nk","ok","pk","Y","Z","qk","rk","sk","tk","uk","Infinity","vk","wk","xk","yk","zk","Ak","Bk","Ck","Dk","Ek","callbackNode","expirationTimes","expiredLanes","wc","callbackPriority","ig","Fk","Gk","Hk","Ik","Jk","Kk","Lk","Mk","Nk","Ok","Pk","finishedWork","finishedLanes","Qk","timeoutHandle","Rk","Sk","Tk","Uk","Vk","mutableReadLanes","Bc","Pj","onCommitFiberRoot","mc","onRecoverableError","Xk","onPostCommitFiberRoot","Yk","Zk","al","isReactComponent","pendingChildren","bl","mutableSourceEagerHydrationData","cl","cache","pendingSuspenseBoundaries","el","fl","gl","hl","il","jl","zj","$k","ll","reportError","ml","_internalRoot","nl","ol","pl","ql","sl","rl","unmount","unstable_scheduleHydration","splice","querySelectorAll","JSON","stringify","form","tl","usingClientEntryPoint","Events","ul","findFiberByHostInstance","bundleType","version","rendererPackageName","vl","rendererConfig","overrideHookState","overrideHookStateDeletePath","overrideHookStateRenamePath","overrideProps","overridePropsDeletePath","overridePropsRenamePath","setErrorHandler","setSuspenseHandler","scheduleUpdate","currentDispatcherRef","findHostInstanceByFiber","findHostInstancesForRefresh","scheduleRefresh","scheduleRoot","setRefreshHandler","getCurrentFiber","reconcilerVersion","__REACT_DEVTOOLS_GLOBAL_HOOK__","wl","isDisabled","supportsFiber","inject","exports","createPortal","dl","createRoot","unstable_strictMode","findDOMNode","flushSync","hydrate","hydrateRoot","hydratedSources","_getVersion","_source","unmountComponentAtNode","unstable_batchedUpdates","unstable_renderSubtreeIntoContainer","checkDCE","err","module","__self","__source","Fragment","jsx","jsxs","setState","forceUpdate","escape","_status","_result","default","Children","map","count","toArray","only","Profiler","PureComponent","StrictMode","Suspense","cloneElement","createContext","_currentValue2","_threadCount","Provider","Consumer","_defaultValue","_globalName","createFactory","createRef","forwardRef","isValidElement","lazy","memo","startTransition","unstable_act","pop","sortIndex","performance","setImmediate","startTime","expirationTime","priorityLevel","navigator","scheduling","isInputPending","MessageChannel","port2","port1","onmessage","postMessage","unstable_Profiling","unstable_continueExecution","unstable_forceFrameRate","floor","unstable_getFirstCallbackNode","unstable_next","unstable_pauseExecution","unstable_runWithPriority","delay","unstable_wrapCallback","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","definition","o","chunkId","all","reduce","promises","miniCssF","obj","prop","inProgress","dataWebpackPrefix","script","needAttach","scripts","getElementsByTagName","i","s","getAttribute","charset","timeout","nc","onScriptComplete","prev","onerror","onload","doneFns","fn","head","toStringTag","installedChunks","j","installedChunkData","promise","reject","errorType","realSrc","request","webpackJsonpCallback","parentChunkLoadingFunction","chunkIds","moreModules","runtime","some","chunkLoadingGlobal","self","_arrayLikeToArray","arr","len","arr2","_unsupportedIterableToArray","minLen","from","_slicedToArray","TypeError","_typeof","_toPropertyKey","arg","hint","prim","toPrimitive","res","Number","ownKeys","getOwnPropertySymbols","filter","_objectSpread2","writable","getOwnPropertyDescriptors","defineProperties","_toConsumableArray","iter","hasNew","tasks","status","hasReady","nextId","max","benchmarkItem","at","isAutoMarkableList","automark","firstNewItem","task","_objectSpread","isActionableList","addTask","genCurrentQuestion","cursor","benchmarkItemText","cursorItemText","cursorItem","isPrioritizableList","lastReadyItem","getInitialCursor","lastReadyIndex","nextCursor","currentCursor","handleReviewDecision","decision","updatedTasks","newCursor","markReadyAtIndex","endReview","saveToLocalStorage","serializedData","localStorage","setItem","getFromLocalStorage","getItem","parse","importTasksFromJSON","jsonString","_step","_iterator","allowArrayLike","it","_e","normalCompletion","didErr","step","_e2","_createForOfIteratorHelper","objectsAreEqual","obj1","obj2","keys1","keys2","_i","_keys","infoCircle","_jsx","fill","viewBox","xmlns","saveDisk","dotCircle","emptyCircle","filledCircle","lightbulbSolid","lightbulbRegular","cancelX","repeatArrow","statusToSymbol","_ref","isBenchmark","cancelFunc","cloneFunc","theme","_jsxs","className","title","was","_Fragment","initialTasks","_useState2","setTasks","_useState4","inputValue","setInputValue","initialPrioritizing","_useState6","isPrioritizing","setIsPrioritizing","initialCursor","_useState8","setCursor","_useState10","errMsg","setErrMsg","_useState12","showingDeleteModal","setShowingDeleteModal","_useState14","showingMoreInfo","setShowingMoreInfo","_useState16","showingSaveModal","setShowingSaveModal","_useState18","importErrMsg","setImportErrMsg","inputRef","_useState20","showingConflictModal","setShowingConflictModal","_useState22","textAreaValue","setTextAreaValue","initialTheme","_useState24","setTheme","classList","remove","listStateWrapperFromURL","deserializeQueryStringToListStateWrapper","result","handleListChange","arr1","sortedArr1","sort","sortedArr2","objectArraysAreEqual","info","newListState","queryString","serializeListStateToQueryString","history","pushState","handleToggleDeleteModal","handleToggleInfoModal","handleToggleSaveModal","listState","serializedState","btoa","URLSearchParams","decodeURIComponent","atob","handleListConflictChoice","renderList","inputList","idOffset","interactive","TodoItem","cancelItem","itemText","cloneItem","placeholder","onChange","startReview","completeBenchmarkTask","tabIndex","onKeyDown","getElementById","click","htmlFor","accept","file","files","reader","FileReader","importedTasks","newTasks","maxId","updatedNewTasks","addAll","readAsText","json","exportTasksToJSON","blob","Blob","URL","createObjectURL","download","revokeObjectURL","rows","lines","onPerfEntry","Function","getCLS","getFID","getFCP","getLCP","getTTFB","ReactDOM","React","App","reportWebVitals","serviceWorker","register","process","registration","scope"],"sourceRoot":""}
\ No newline at end of file