diff --git a/docs/asset-manifest.json b/docs/asset-manifest.json index 0aaec67187..5c49ce7fa1 100644 --- a/docs/asset-manifest.json +++ b/docs/asset-manifest.json @@ -1,13 +1,13 @@ { "files": { "main.css": "/static/css/main.dbde8973.css", - "main.js": "/static/js/main.cd4adc17.js", + "main.js": "/static/js/main.3e3fbd79.js", "index.html": "/index.html", "main.dbde8973.css.map": "/static/css/main.dbde8973.css.map", - "main.cd4adc17.js.map": "/static/js/main.cd4adc17.js.map" + "main.3e3fbd79.js.map": "/static/js/main.3e3fbd79.js.map" }, "entrypoints": [ "static/css/main.dbde8973.css", - "static/js/main.cd4adc17.js" + "static/js/main.3e3fbd79.js" ] } \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index ff132af401..427fbc3d52 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1 +1 @@ -
a||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","export const SCORE = 'score'\nexport const DATE = 'date'\nexport const ASCE = 'ascending'\nexport const DESC = 'descending'\nexport const CURRENT_YEAR = (new Date()).getFullYear()\nexport const MIN_YEAR = 2018\n\nexport const ABSTRACT_URL = process.env.REACT_APP_ABSTRACT_URL\nexport const API_HOST = process.env.REACT_APP_API_HOST\n","import { ABSTRACT_URL, API_HOST } from \"./const\";\n\n/**\n * See api.cspapers.org/types/types.go\n * @typedef {{\n * query: string,\n * orderBy: string,\n * ascending: bool,\n * yearFrom: number,\n * yearTo: number,\n * skip: number,\n * }} SearchRequest\n * \n * @typedef {{\n * total: number,\n * skip: number,\n * duration: number, // msec, spent on searching\n * data: [SearchResponseUnit],\n * }} SearchResponse\n * \n * @typedef {{\n * title: string,\n * year: number,\n * venue: string,\n * index: string,\n * score: number,\n * }} SearchResponseUnit\n * \n */\n\n\n/**\n * \n * @param {SearchRequest} req \n * @returns {[SearchResponse, Error | null ]}\n */\nlet lastlyCalledAt = 0;\n/*\nApp() can invoke multiple fetch() in parallel, however,\nis interestd the latest search() result. \nSo, search() shares and update the timestamp of latest call.\nUsing this, search() returns only if the latest call timestamp\nmatches with the current context's call timestamp.\n*/\nconst search = async (req) => {\n const calledAt = Date.now()\n try {\n lastlyCalledAt = calledAt\n const res = await fetch(API_HOST + marshal(req))\n if (!res.ok) {\n throw new Error(`Response status: ${res.status}`);\n }\n const json = await res.json();\n if (json === null) {\n throw new Error(`response data is null`);\n }\n\n /* mimicking atomic compare-and-swap */\n const lastlyCalledAtAfterFetch = lastlyCalledAt\n lastlyCalledAt = calledAt === lastlyCalledAt ? 0 : lastlyCalledAt\n /* mimicking atomic compare-and-swap */\n\n if (lastlyCalledAtAfterFetch === calledAt) {\n // we are the latest call\n return [json, false]\n } else {\n return [{}, new Error(`Later call exists`)]\n }\n } catch (error) {\n console.error(error)\n /* mimicking atomic compare-and-swap */\n lastlyCalledAt = calledAt === lastlyCalledAt ? 0 : lastlyCalledAt\n /* mimicking atomic compare-and-swap */\n return [{}, error]\n }\n}\n\n/**\n * Convert SearchRequest to a query string\n * @param {SearchRequest} req \n * @returns {string} QueryString\n */\nconst marshal = (req) => {\n const q = new URLSearchParams(req)\n return `/?${q.toString()}`\n}\n\n/**\n * \n * @param {number} year\n * @param {string} venue \n * @param {string} title \n * @returns {[string, Error | null ]} abstract\n */\nconst getAbstract = async (year, venue, title) => {\n try {\n const res = await fetch(`${ABSTRACT_URL}/${year}/${venue.toLowerCase()}/${title}`)\n if (res.status === 404) {\n return [\"\", null]\n } else if (!res.ok) {\n return [\"\", new Error(`${res.status} ${res.statusText}`)]\n }\n const text = await res.text()\n return [text, null]\n } catch (err) {\n return [\"\", err]\n }\n}\n\nexport {\n getAbstract, search\n};\n","export const seq = (start, end, step = 1) => Array.from({ length: end - start }, (_, i) => start + i * step)\nexport const isEven = n => n % 2 === 0\n\nexport const fst = ([a, _]) => a\nexport const snd = ([_, a]) => a\n\n/**\n * Build tree from edges.\n * @typedef {{ name: string, children: [Tree] }} Tree\n * @typedef { [ parent: string, child: string ]} Edge\n * @param {[Edge]} edges\n * @param {string} root\n * @returns {Tree}\n */\nexport const buildTree = (edges, root) => {\n const [adjacent, notAdjacent] = edges.reduce(\n (acc, cur) => fst(cur) === root ?\n [[...fst(acc), cur], snd(acc)] :\n [fst(acc), [...snd(acc), cur]],\n [[], []])\n\n const t = buildTree1Depth(adjacent, root)\n if (t.children.length === 0) {\n return { name: root }\n }\n t.children = t.children.map(tre => buildTree(notAdjacent, tre.name))\n return t\n}\n\nconst buildTree1Depth = (edges = [], parent = \"\") => ({\n name: parent,\n children: edges.reduce((acc, cur) => fst(cur) === parent ? [...acc, { name: snd(cur) }] : acc, [])\n})","import { buildTree } from \"./functional\"\n\n/* add new conferences here */\nconst edges = [\n [\"All Areas\", \"AI\"],\n\n [\"AI\", \"Artificial intelligence\"],\n [\"Artificial intelligence\", \"AAAI\"],\n [\"Artificial intelligence\", \"IJCAI\"],\n\n [\"AI\", \"Computer vision\"],\n [\"Computer vision\", \"CVPR\"],\n\n [\"AI\", \"Machine learning\"],\n [\"Machine learning\", \"ICLR\"],\n [\"Machine learning\", \"ICML\"],\n [\"Machine learning\", \"NeurIPS\"],\n\n [\"AI\", \"Natural language processing\"],\n [\"Natural language processing\", \"ACL\"],\n [\"Natural language processing\", \"EMNLP\"],\n [\"Natural language processing\", \"NAACL\"],\n\n [\"AI\", \"The Web & information retrieval\"],\n [\"The Web & information retrieval\", \"SIGIR\"],\n [\"The Web & information retrieval\", \"WWW\"],\n\n [\"All Areas\", \"Systems\"],\n\n [\"Systems\", \"Computer architecture\"],\n [\"Computer architecture\", \"ASPLOS\"],\n\n [\"Systems\", \"Computer security\"],\n [\"Computer security\", \"NDSS\"],\n [\"Computer security\", \"Usenix\"],\n [\"Computer security\", \"SP\"],\n [\"Computer security\", \"CCS\"],\n\n [\"Systems\", \"Databases\"],\n [\"Databases\", \"SIGMOD\"],\n [\"Databases\", \"VLDB\"],\n\n [\"Systems\", \"Mobile computing\"],\n [\"Mobile computing\", \"MobiCom\"],\n [\"Mobile computing\", \"MobiSys\"],\n [\"Mobile computing\", \"SenSys\"],\n\n [\"Systems\", \"Operating systems\"],\n [\"Operating systems\", \"OSDI\"],\n [\"Operating systems\", \"SOSP\"],\n [\"Operating systems\", \"ATC\"],\n [\"Operating systems\", \"EuroSYS\"],\n\n [\"Systems\", \"Software engineering\"],\n [\"Software engineering\", \"FSE\"],\n [\"Software engineering\", \"ICSE\"],\n [\"Software engineering\", \"ASE\"],\n [\"Software engineering\", \"ISSTA\"],\n\n [\"Systems\", \"Programming languages\"],\n [\"Programming languages\", \"PACMPL\"],\n [\"Programming languages\", \"PLDI\"],\n\n [\"All Areas\", \"Theory\"],\n\n [\"Theory\", \"Algorithms & complexity\"],\n [\"Algorithms & complexity\", \"FOCS\"],\n [\"Algorithms & complexity\", \"SODA\"],\n [\"Algorithms & complexity\", \"STOC\"],\n\n [\"Theory\", \"Cryptography\"],\n [\"Cryptography\", \"CRYPTO\"],\n [\"Cryptography\", \"EuroCrypt\"],\n\n [\"Theory\", \"Logic & verification\"],\n [\"Logic & verification\", \"LICS\"],\n\n [\"All Areas\", \"Interdisciplinary Areas\"],\n\n [\"Interdisciplinary Areas\", \"Economics & computation\"],\n [\"Economics & computation\", \"EC\"],\n [\"Economics & computation\", \"WINE\"],\n \n [\"Interdisciplinary Areas\", \"Human-computer interaction\"],\n [\"Human-computer interaction\", \"CHI\"],\n [\"Human-computer interaction\", \"UbiComp\"],\n [\"Human-computer interaction\", \"UIST\"],\n\n [\"Interdisciplinary Areas\", \"Robotics\"],\n [\"Robotics\", \"ICRA\"],\n [\"Robotics\", \"IROS\"],\n [\"Robotics\", \"RSS\"],\n]\n\nconst comments = {\n \"ACL\": \"(long)\",\n \"PLDI\": \"(2018 - 2022)\",\n \"SOSP\": \"(2017 - 2023), biyearly\",\n}\n\n/**\n * Return leaves's names.\n * @typedef {{ name: string, children: [Tree] }} Tree\n * @param {Tree} tree\n * @returns {string}\n */\nconst flatten = (tree) =>\n tree.children.reduce((acc, cur) =>\n cur.children ? [...acc, ...flatten(cur)] : [...acc, cur.name]\n , [])\n\nconst conferences = {\n tree: buildTree(edges, \"All Areas\"),\n flatten,\n}\n\nexport {\n conferences,\n comments\n}","import { useEffect, useState } from 'react';\nimport { getAbstract } from '../api';\n\n/**\n * \n * @param {{ year: number, venue: string, title: string }} props\n * @returns \n */\nfunction Paper(props) {\n const [collapsed, setCollapsed] = useState(true)\n const [abstract, setAbstract] = useState('')\n const [isAbsLoaded, setIsAbsLoaded] = useState(false)\n const venueUpper = props.venue.toUpperCase()\n\n useEffect(() => {\n if (collapsed) {\n return\n }\n if (isAbsLoaded) {\n return\n }\n getAbstract(props.year, props.venue, props.title)\n .then(([abs, err]) => {\n if (err) {\n setAbstract(\"failed to retreive an abstract: \", err)\n } else {\n setAbstract(abs)\n }\n setIsAbsLoaded(true)\n })\n }, [collapsed])\n\n return (\n a||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","export const SCORE = 'score'\nexport const DATE = 'date'\nexport const ASCE = 'ascending'\nexport const DESC = 'descending'\nexport const CURRENT_YEAR = (new Date()).getFullYear()\nexport const MIN_YEAR = 2018\n\nexport const ABSTRACT_URL = process.env.REACT_APP_ABSTRACT_URL\nexport const API_HOST = process.env.REACT_APP_API_HOST\n","import { ABSTRACT_URL, API_HOST } from \"./const\";\n\n/**\n * See api.cspapers.org/types/types.go\n * @typedef {{\n * query: string,\n * orderBy: string,\n * ascending: bool,\n * yearFrom: number,\n * yearTo: number,\n * skip: number,\n * }} SearchRequest\n * \n * @typedef {{\n * total: number,\n * skip: number,\n * duration: number, // msec, spent on searching\n * data: [SearchResponseUnit],\n * }} SearchResponse\n * \n * @typedef {{\n * title: string,\n * year: number,\n * venue: string,\n * index: string,\n * score: number,\n * }} SearchResponseUnit\n * \n */\n\n\n/**\n * \n * @param {SearchRequest} req \n * @returns {[SearchResponse, Error | null ]}\n */\nlet lastlyCalledAt = 0;\n/*\nApp() can invoke multiple fetch() in parallel, however,\nis interestd the latest search() result. \nSo, search() shares and update the timestamp of latest call.\nUsing this, search() returns only if the latest call timestamp\nmatches with the current context's call timestamp.\n*/\nconst search = async (req) => {\n const calledAt = Date.now()\n try {\n lastlyCalledAt = calledAt\n const res = await fetch(API_HOST + marshal(req))\n if (!res.ok) {\n throw new Error(`Response status: ${res.status}`);\n }\n const json = await res.json();\n if (json === null) {\n throw new Error(`response data is null`);\n }\n\n /* mimicking atomic compare-and-swap */\n const lastlyCalledAtAfterFetch = lastlyCalledAt\n lastlyCalledAt = calledAt === lastlyCalledAt ? 0 : lastlyCalledAt\n /* mimicking atomic compare-and-swap */\n\n if (lastlyCalledAtAfterFetch === calledAt) {\n // we are the latest call\n return [json, false]\n } else {\n return [{}, new Error(`Later call exists`)]\n }\n } catch (error) {\n console.error(error)\n /* mimicking atomic compare-and-swap */\n lastlyCalledAt = calledAt === lastlyCalledAt ? 0 : lastlyCalledAt\n /* mimicking atomic compare-and-swap */\n return [{}, error]\n }\n}\n\n/**\n * Convert SearchRequest to a query string\n * @param {SearchRequest} req \n * @returns {string} QueryString\n */\nconst marshal = (req) => {\n const q = new URLSearchParams(req)\n return `/?${q.toString()}`\n}\n\n/**\n * \n * @param {number} year\n * @param {string} venue \n * @param {string} title \n * @returns {[string, Error | null ]} abstract\n */\nconst getAbstract = async (year, venue, title) => {\n try {\n const res = await fetch(`${ABSTRACT_URL}/${year}/${venue.toLowerCase()}/${title}`)\n if (res.status === 404) {\n return [\"\", null]\n } else if (!res.ok) {\n return [\"\", new Error(`${res.status} ${res.statusText}`)]\n }\n const text = await res.text()\n return [text, null]\n } catch (err) {\n return [\"\", err]\n }\n}\n\nexport {\n getAbstract, search\n};\n","export const seq = (start, end, step = 1) => Array.from({ length: end - start }, (_, i) => start + i * step)\nexport const isEven = n => n % 2 === 0\n\nexport const fst = ([a, _]) => a\nexport const snd = ([_, a]) => a\n\n/**\n * Build tree from edges.\n * @typedef {{ name: string, children: [Tree] }} Tree\n * @typedef { [ parent: string, child: string ]} Edge\n * @param {[Edge]} edges\n * @param {string} root\n * @returns {Tree}\n */\nexport const buildTree = (edges, root) => {\n const [adjacent, notAdjacent] = edges.reduce(\n (acc, cur) => fst(cur) === root ?\n [[...fst(acc), cur], snd(acc)] :\n [fst(acc), [...snd(acc), cur]],\n [[], []])\n\n const t = buildTree1Depth(adjacent, root)\n if (t.children.length === 0) {\n return { name: root }\n }\n t.children = t.children.map(tre => buildTree(notAdjacent, tre.name))\n return t\n}\n\nconst buildTree1Depth = (edges = [], parent = \"\") => ({\n name: parent,\n children: edges.reduce((acc, cur) => fst(cur) === parent ? [...acc, { name: snd(cur) }] : acc, [])\n})","import { buildTree } from \"./functional\"\n\n/* add new conferences here */\nconst edges = [\n [\"All Areas\", \"AI\"],\n\n [\"AI\", \"Artificial intelligence\"],\n [\"Artificial intelligence\", \"AAAI\"],\n [\"Artificial intelligence\", \"IJCAI\"],\n\n [\"AI\", \"Computer vision\"],\n [\"Computer vision\", \"CVPR\"],\n\n [\"AI\", \"Machine learning\"],\n [\"Machine learning\", \"ICLR\"],\n [\"Machine learning\", \"ICML\"],\n [\"Machine learning\", \"NeurIPS\"],\n\n [\"AI\", \"Natural language processing\"],\n [\"Natural language processing\", \"ACL\"],\n [\"Natural language processing\", \"EMNLP\"],\n [\"Natural language processing\", \"NAACL\"],\n\n [\"AI\", \"The Web & information retrieval\"],\n [\"The Web & information retrieval\", \"SIGIR\"],\n [\"The Web & information retrieval\", \"WWW\"],\n\n [\"All Areas\", \"Systems\"],\n\n [\"Systems\", \"Computer architecture\"],\n [\"Computer architecture\", \"ASPLOS\"],\n\n [\"Systems\", \"Computer security\"],\n [\"Computer security\", \"NDSS\"],\n [\"Computer security\", \"Usenix\"],\n [\"Computer security\", \"SP\"],\n [\"Computer security\", \"CCS\"],\n\n [\"Systems\", \"Databases\"],\n [\"Databases\", \"SIGMOD\"],\n [\"Databases\", \"VLDB\"],\n\n [\"Systems\", \"Mobile computing\"],\n [\"Mobile computing\", \"MobiCom\"],\n [\"Mobile computing\", \"MobiSys\"],\n [\"Mobile computing\", \"SenSys\"],\n\n [\"Systems\", \"Operating systems\"],\n [\"Operating systems\", \"OSDI\"],\n [\"Operating systems\", \"SOSP\"],\n [\"Operating systems\", \"ATC\"],\n [\"Operating systems\", \"EuroSYS\"],\n\n [\"Systems\", \"Software engineering\"],\n [\"Software engineering\", \"FSE\"],\n [\"Software engineering\", \"ICSE\"],\n [\"Software engineering\", \"ASE\"],\n [\"Software engineering\", \"ISSTA\"],\n\n [\"Systems\", \"Programming languages\"],\n [\"Programming languages\", \"PACMPL\"],\n [\"Programming languages\", \"PLDI\"],\n\n [\"All Areas\", \"Theory\"],\n\n [\"Theory\", \"Algorithms & complexity\"],\n [\"Algorithms & complexity\", \"FOCS\"],\n [\"Algorithms & complexity\", \"SODA\"],\n [\"Algorithms & complexity\", \"STOC\"],\n\n [\"Theory\", \"Cryptography\"],\n [\"Cryptography\", \"CRYPTO\"],\n [\"Cryptography\", \"EuroCrypt\"],\n\n [\"Theory\", \"Logic & verification\"],\n [\"Logic & verification\", \"LICS\"],\n\n [\"All Areas\", \"Interdisciplinary Areas\"],\n\n [\"Interdisciplinary Areas\", \"Economics & computation\"],\n [\"Economics & computation\", \"EC\"],\n [\"Economics & computation\", \"WINE\"],\n \n [\"Interdisciplinary Areas\", \"Human-computer interaction\"],\n [\"Human-computer interaction\", \"CHI\"],\n [\"Human-computer interaction\", \"UbiComp\"],\n [\"Human-computer interaction\", \"UIST\"],\n\n [\"Interdisciplinary Areas\", \"Robotics\"],\n [\"Robotics\", \"ICRA\"],\n [\"Robotics\", \"IROS\"],\n [\"Robotics\", \"RSS\"],\n]\n\nconst comments = {\n \"ACL\": \"(long)\",\n \"PLDI\": \"(2018 - 2022)\",\n \"SOSP\": \"(2017 - 2023), biyearly\",\n}\n\n/**\n * Return leaves's names.\n * @typedef {{ name: string, children: [Tree] }} Tree\n * @param {Tree} tree\n * @returns {string}\n */\nconst flatten = (tree) =>\n tree.children.reduce((acc, cur) =>\n cur.children ? [...acc, ...flatten(cur)] : [...acc, cur.name]\n , [])\n\nconst conferences = {\n tree: buildTree(edges, \"All Areas\"),\n flatten,\n}\n\nexport {\n conferences,\n comments\n}","import { useEffect, useState } from 'react';\nimport { getAbstract } from '../api';\n\n/**\n * \n * @param {{ year: number, venue: string, title: string }} props\n * @returns \n */\nfunction Paper(props) {\n const [collapsed, setCollapsed] = useState(true)\n const [abstract, setAbstract] = useState('')\n const [isAbsLoaded, setIsAbsLoaded] = useState(false)\n const venueUpper = props.venue.toUpperCase()\n\n useEffect(() => {\n if (collapsed) {\n return\n }\n if (isAbsLoaded) {\n return\n }\n getAbstract(props.year, props.venue, props.title)\n .then(([abs, err]) => {\n if (err) {\n setAbstract(\"failed to retreive an abstract: \", err)\n } else {\n setAbstract(abs)\n }\n setIsAbsLoaded(true)\n })\n }, [collapsed])\n\n return (\n \n {\n isAbsLoaded ?\n abstract ||\n <>No abstract indexed. See \n Google scholar\n > :\n \"...fetching\"\n }\n
\n
\n {d1.name} [ delVenueList(conferences.flatten(d1))} className='underline pointer'>off | addVenueList(conferences.flatten(d1))} className='underline pointer'>on ]\n {d1.children.map(d2 =>\n
\n
\n
\n \n {\n isAbsLoaded ?\n abstract ||\n <>No abstract indexed. See \n Google scholar\n > :\n \"...fetching\"\n }\n
\n
\n {d1.name} [ delVenueList(conferences.flatten(d1))} className='underline pointer'>off | addVenueList(conferences.flatten(d1))} className='underline pointer'>on ]\n {d1.children.map(d2 =>\n
\n
\n
\n