diff options
| author | Adam Mathes <adam@adammathes.com> | 2026-02-14 10:03:35 -0800 |
|---|---|---|
| committer | Adam Mathes <adam@adammathes.com> | 2026-02-14 10:03:35 -0800 |
| commit | a4997a5fbc65913b55f2215eb3b868693bd76c51 (patch) | |
| tree | fe303ee7c5e5aba89f1c13766b14556f6e3d2f79 /frontend | |
| parent | 4d058d9ddb34f0e8d384b20d4b9e30f74d349129 (diff) | |
| download | neko-a4997a5fbc65913b55f2215eb3b868693bd76c51.tar.gz neko-a4997a5fbc65913b55f2215eb3b868693bd76c51.tar.bz2 neko-a4997a5fbc65913b55f2215eb3b868693bd76c51.zip | |
test: increase frontend coverage for Settings and improve FeedItem css
Diffstat (limited to 'frontend')
24 files changed, 3905 insertions, 6178 deletions
diff --git a/frontend/coverage/base.css b/frontend/coverage/base.css index 8cd9700..f418035 100644 --- a/frontend/coverage/base.css +++ b/frontend/coverage/base.css @@ -1,129 +1,71 @@ -body, -html { - margin: 0; - padding: 0; +body, html { + margin:0; padding: 0; height: 100%; } body { - font-family: - Helvetica Neue, - Helvetica, - Arial; - font-size: 14px; - color: #333; -} -.small { - font-size: 12px; -} -*, -*:after, -*:before { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -h1 { - font-size: 20px; - margin: 0; -} -h2 { - font-size: 14px; -} + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } pre { - font: - 12px/1.4 Consolas, - 'Liberation Mono', - Menlo, - Courier, - monospace; - margin: 0; - padding: 0; - -moz-tab-size: 2; - -o-tab-size: 2; - tab-size: 2; -} -a { - color: #0074d9; - text-decoration: none; -} -a:hover { - text-decoration: underline; -} -.strong { - font-weight: bold; -} -.space-top1 { - padding: 10px 0 0 0; -} -.pad2y { - padding: 20px 0; -} -.pad1y { - padding: 10px 0; -} -.pad2x { - padding: 0 20px; -} -.pad2 { - padding: 20px; -} -.pad1 { - padding: 10px; -} -.space-left2 { - padding-left: 55px; -} -.space-right2 { - padding-right: 20px; -} -.center { - text-align: center; -} -.clearfix { - display: block; -} + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } .clearfix:after { - content: ''; - display: block; - height: 0; - clear: both; - visibility: hidden; -} -.fl { - float: left; -} -@media only screen and (max-width: 640px) { - .col3 { - width: 100%; - max-width: 100%; - } - .hide-mobile { - display: none !important; + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } } .quiet { color: #7f7f7f; - color: rgba(0, 0, 0, 0.5); -} -.quiet a { - opacity: 0.7; + color: rgba(0,0,0,0.5); } +.quiet a { opacity: 0.7; } .fraction { font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10px; color: #555; - background: #e8e8e8; + background: #E8E8E8; padding: 4px 5px; border-radius: 3px; vertical-align: middle; } -div.path a:link, -div.path a:visited { - color: #333; -} +div.path a:link, div.path a:visited { color: #333; } table.coverage { border-collapse: collapse; margin: 10px 0 0 0; @@ -136,219 +78,140 @@ table.coverage td { vertical-align: top; } table.coverage td.line-count { - text-align: right; - padding: 0 5px 0 20px; + text-align: right; + padding: 0 5px 0 20px; } table.coverage td.line-coverage { - text-align: right; - padding-right: 10px; - min-width: 20px; + text-align: right; + padding-right: 10px; + min-width:20px; } table.coverage td span.cline-any { - display: inline-block; - padding: 0 5px; - width: 100%; + display: inline-block; + padding: 0 5px; + width: 100%; } .missing-if-branch { - display: inline-block; - margin-right: 5px; - border-radius: 3px; - position: relative; - padding: 0 4px; - background: #333; - color: yellow; + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; } .skip-if-branch { - display: none; - margin-right: 10px; - position: relative; - padding: 0 4px; - background: #ccc; - color: white; + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; } -.missing-if-branch .typ, -.skip-if-branch .typ { - color: inherit !important; +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; } .coverage-summary { border-collapse: collapse; width: 100%; } -.coverage-summary tr { - border-bottom: 1px solid #bbb; -} -.keyline-all { - border: 1px solid #ddd; -} -.coverage-summary td, -.coverage-summary th { - padding: 10px; -} -.coverage-summary tbody { - border: 1px solid #bbb; -} -.coverage-summary td { - border-right: 1px solid #bbb; -} -.coverage-summary td:last-child { - border-right: none; -} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } .coverage-summary th { text-align: left; font-weight: normal; white-space: nowrap; } -.coverage-summary th.file { - border-right: none !important; -} -.coverage-summary th.pct { -} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } .coverage-summary th.pic, .coverage-summary th.abs, .coverage-summary td.pct, -.coverage-summary td.abs { - text-align: right; -} -.coverage-summary td.file { - white-space: nowrap; -} -.coverage-summary td.pic { - min-width: 120px !important; -} -.coverage-summary tfoot td { -} +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } .coverage-summary .sorter { - height: 10px; - width: 7px; - display: inline-block; - margin-left: 0.5em; - background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; } .coverage-summary .sorted .sorter { - background-position: 0 -20px; + background-position: 0 -20px; } .coverage-summary .sorted-desc .sorter { - background-position: 0 -10px; -} -.status-line { - height: 10px; + background-position: 0 -10px; } +.status-line { height: 10px; } /* yellow */ -.cbranch-no { - background: yellow !important; - color: #111; -} +.cbranch-no { background: yellow !important; color: #111; } /* dark red */ -.red.solid, -.status-line.low, -.low .cover-fill { - background: #c21f39; -} -.low .chart { - border: 1px solid #c21f39; -} +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } .highlighted, -.highlighted .cstat-no, -.highlighted .fstat-no, -.highlighted .cbranch-no { - background: #c21f39 !important; +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #C21F39 !important; } /* medium red */ -.cstat-no, -.fstat-no, -.cbranch-no, -.cbranch-no { - background: #f6c6ce; -} +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } /* light red */ -.low, -.cline-no { - background: #fce1e5; -} +.low, .cline-no { background:#FCE1E5 } /* light green */ -.high, -.cline-yes { - background: rgb(230, 245, 208); -} +.high, .cline-yes { background:rgb(230,245,208) } /* medium green */ -.cstat-yes { - background: rgb(161, 215, 106); -} +.cstat-yes { background:rgb(161,215,106) } /* dark green */ -.status-line.high, -.high .cover-fill { - background: rgb(77, 146, 33); -} -.high .chart { - border: 1px solid rgb(77, 146, 33); -} +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } /* dark yellow (gold) */ -.status-line.medium, -.medium .cover-fill { - background: #f9cd0b; -} -.medium .chart { - border: 1px solid #f9cd0b; -} +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } /* light yellow */ -.medium { - background: #fff4c2; -} +.medium { background: #fff4c2; } -.cstat-skip { - background: #ddd; - color: #111; -} -.fstat-skip { - background: #ddd; - color: #111 !important; -} -.cbranch-skip { - background: #ddd !important; - color: #111; -} +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } -span.cline-neutral { - background: #eaeaea; -} +span.cline-neutral { background: #eaeaea; } .coverage-summary td.empty { - opacity: 0.5; - padding-top: 4px; - padding-bottom: 4px; - line-height: 1; - color: #888; + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; } -.cover-fill, -.cover-empty { - display: inline-block; +.cover-fill, .cover-empty { + display:inline-block; height: 12px; } .chart { line-height: 0; } .cover-empty { - background: white; + background: white; } .cover-full { - border-right: none !important; + border-right: none !important; } pre.prettyprint { - border: none !important; - padding: 0 !important; - margin: 0 !important; -} -.com { - color: #999 !important; -} -.ignore-none { - color: #999; - font-weight: normal; + border: none !important; + padding: 0 !important; + margin: 0 !important; } +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } .wrapper { min-height: 100%; @@ -356,7 +219,6 @@ pre.prettyprint { height: 100%; margin: 0 auto -48px; } -.footer, -.push { +.footer, .push { height: 48px; } diff --git a/frontend/coverage/block-navigation.js b/frontend/coverage/block-navigation.js index 05f7569..530d1ed 100644 --- a/frontend/coverage/block-navigation.js +++ b/frontend/coverage/block-navigation.js @@ -1,82 +1,87 @@ - +/* eslint-disable */ var jumpToCode = (function init() { - // Classes of code we would like to highlight in the file view - var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; - // Elements to highlight in the file listing view - var fileListingElements = ['td.pct.low']; + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; - // We don't want to select elements that are direct descendants of another match - var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` - // Selector that finds elements on the page to which we can jump - var selector = - fileListingElements.join(', ') + - ', ' + - notSelector + - missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + // Selector that finds elements on the page to which we can jump + var selector = + fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` - // The NodeList of matching elements - var missingCoverageElements = document.querySelectorAll(selector); + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); - var currentIndex; + var currentIndex; - function toggleClass(index) { - missingCoverageElements.item(currentIndex).classList.remove('highlighted'); - missingCoverageElements.item(index).classList.add('highlighted'); - } - - function makeCurrent(index) { - toggleClass(index); - currentIndex = index; - missingCoverageElements.item(index).scrollIntoView({ - behavior: 'smooth', - block: 'center', - inline: 'center', - }); - } - - function goToPrevious() { - var nextIndex = 0; - if (typeof currentIndex !== 'number' || currentIndex === 0) { - nextIndex = missingCoverageElements.length - 1; - } else if (missingCoverageElements.length > 1) { - nextIndex = currentIndex - 1; + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); } - makeCurrent(nextIndex); - } + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } - function goToNext() { - var nextIndex = 0; + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } - if (typeof currentIndex === 'number' && currentIndex < missingCoverageElements.length - 1) { - nextIndex = currentIndex + 1; + makeCurrent(nextIndex); } - makeCurrent(nextIndex); - } + function goToNext() { + var nextIndex = 0; - return function jump(event) { - if ( - document.getElementById('fileSearch') === document.activeElement && - document.activeElement != null - ) { - // if we're currently focused on the search input, we don't want to navigate - return; - } + if ( + typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1 + ) { + nextIndex = currentIndex + 1; + } - switch (event.which) { - case 78: // n - case 74: // j - goToNext(); - break; - case 66: // b - case 75: // k - case 80: // p - goToPrevious(); - break; + makeCurrent(nextIndex); } - }; + + return function jump(event) { + if ( + document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null + ) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; })(); window.addEventListener('keydown', jumpToCode); diff --git a/frontend/coverage/clover.xml b/frontend/coverage/clover.xml index f05aeb1..4679d59 100644 --- a/frontend/coverage/clover.xml +++ b/frontend/coverage/clover.xml @@ -1,271 +1,341 @@ <?xml version="1.0" encoding="UTF-8"?> -<coverage generated="1771019398957" clover="3.2.0"> - <project timestamp="1771019398957" name="All files"> - <metrics statements="224" coveredstatements="198" conditionals="142" coveredconditionals="109" methods="73" coveredmethods="63" elements="439" coveredelements="370" complexity="0" loc="224" ncloc="224" packages="2" files="12" classes="12"/> +<coverage generated="1771092129074" clover="3.2.0"> + <project timestamp="1771092129074" name="All files"> + <metrics statements="291" coveredstatements="237" conditionals="197" coveredconditionals="138" methods="93" coveredmethods="70" elements="581" coveredelements="445" complexity="0" loc="291" ncloc="291" packages="2" files="13" classes="13"/> <package name="src"> - <metrics statements="19" coveredstatements="15" conditionals="6" coveredconditionals="4" methods="9" coveredmethods="7"/> + <metrics statements="33" coveredstatements="26" conditionals="26" coveredconditionals="18" methods="10" coveredmethods="7"/> <file name="App.css" path="/Users/adam/workspace/vibecode/neko/frontend/src/App.css"> <metrics statements="0" coveredstatements="0" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0"/> </file> <file name="App.tsx" path="/Users/adam/workspace/vibecode/neko/frontend/src/App.tsx"> - <metrics statements="19" coveredstatements="15" conditionals="6" coveredconditionals="4" methods="9" coveredmethods="7"/> - <line num="8" count="2" type="stmt"/> + <metrics statements="22" coveredstatements="16" conditionals="16" coveredconditionals="10" methods="8" coveredmethods="5"/> <line num="9" count="2" type="stmt"/> - <line num="11" count="2" type="stmt"/> - <line num="12" count="1" type="stmt"/> - <line num="14" count="1" type="cond" truecount="1" falsecount="1"/> - <line num="15" count="1" type="stmt"/> - <line num="17" count="0" type="stmt"/> - <line num="20" count="0" type="stmt"/> - <line num="23" count="2" type="cond" truecount="2" falsecount="0"/> - <line num="24" count="1" type="stmt"/> - <line num="27" count="1" type="cond" truecount="1" falsecount="1"/> - <line num="28" count="0" type="stmt"/> - <line num="31" count="1" type="stmt"/> - <line num="39" count="1" type="stmt"/> + <line num="10" count="2" type="stmt"/> + <line num="12" count="2" type="stmt"/> + <line num="13" count="1" type="stmt"/> + <line num="15" count="1" type="cond" truecount="1" falsecount="1"/> + <line num="16" count="1" type="stmt"/> + <line num="18" count="0" type="stmt"/> + <line num="21" count="0" type="stmt"/> + <line num="24" count="2" type="cond" truecount="2" falsecount="0"/> + <line num="25" count="1" type="stmt"/> + <line num="28" count="1" type="cond" truecount="1" falsecount="1"/> + <line num="29" count="0" type="stmt"/> + <line num="32" count="1" type="stmt"/> <line num="40" count="1" type="stmt"/> - <line num="45" count="0" type="stmt"/> - <line num="48" count="1" type="stmt"/> - <line num="49" count="1" type="stmt"/> - <line num="73" count="2" type="stmt"/> + <line num="42" count="1" type="stmt"/> + <line num="50" count="0" type="stmt"/> + <line num="73" count="2" type="cond" truecount="2" falsecount="0"/> + <line num="75" count="2" type="stmt"/> + <line num="76" count="0" type="stmt"/> + <line num="77" count="0" type="stmt"/> + <line num="80" count="2" type="cond" truecount="1" falsecount="1"/> + <line num="82" count="2" type="stmt"/> + </file> + <file name="utils.ts" path="/Users/adam/workspace/vibecode/neko/frontend/src/utils.ts"> + <metrics statements="11" coveredstatements="10" conditionals="10" coveredconditionals="8" methods="2" coveredmethods="2"/> + <line num="2" count="10" type="stmt"/> + <line num="3" count="10" type="stmt"/> + <line num="4" count="10" type="cond" truecount="1" falsecount="1"/> + <line num="12" count="36" type="cond" truecount="2" falsecount="0"/> + <line num="13" count="36" type="stmt"/> + <line num="15" count="36" type="cond" truecount="2" falsecount="0"/> + <line num="17" count="36" type="cond" truecount="2" falsecount="0"/> + <line num="18" count="10" type="stmt"/> + <line num="19" count="10" type="cond" truecount="1" falsecount="1"/> + <line num="20" count="0" type="stmt"/> + <line num="27" count="36" type="stmt"/> </file> </package> <package name="src.components"> - <metrics statements="205" coveredstatements="183" conditionals="136" coveredconditionals="105" methods="64" coveredmethods="56"/> + <metrics statements="258" coveredstatements="211" conditionals="171" coveredconditionals="120" methods="83" coveredmethods="63"/> <file name="FeedItem.css" path="/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItem.css"> <metrics statements="0" coveredstatements="0" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0"/> </file> <file name="FeedItem.tsx" path="/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItem.tsx"> - <metrics statements="19" coveredstatements="15" conditionals="18" coveredconditionals="16" methods="7" coveredmethods="6"/> - <line num="10" count="21" type="stmt"/> - <line num="11" count="21" type="stmt"/> - <line num="14" count="21" type="stmt"/> - <line num="15" count="1" type="stmt"/> - <line num="18" count="21" type="stmt"/> - <line num="19" count="1" type="stmt"/> - <line num="21" count="1" type="stmt"/> - <line num="22" count="1" type="stmt"/> + <metrics statements="31" coveredstatements="25" conditionals="23" coveredconditionals="20" methods="12" coveredmethods="10"/> + <line num="12" count="33" type="stmt"/> + <line num="13" count="33" type="stmt"/> + <line num="15" count="33" type="stmt"/> + <line num="16" count="16" type="stmt"/> + <line num="19" count="33" type="stmt"/> + <line num="20" count="1" type="stmt"/> + <line num="23" count="33" type="stmt"/> <line num="24" count="1" type="stmt"/> - <line num="36" count="1" type="cond" truecount="1" falsecount="1"/> - <line num="37" count="0" type="stmt"/> - <line num="39" count="1" type="stmt"/> + <line num="26" count="1" type="stmt"/> + <line num="27" count="1" type="stmt"/> + <line num="29" count="1" type="stmt"/> + <line num="41" count="1" type="cond" truecount="1" falsecount="1"/> + <line num="42" count="0" type="stmt"/> <line num="44" count="1" type="stmt"/> - <line num="47" count="0" type="stmt"/> - <line num="49" count="0" type="stmt"/> - <line num="50" count="0" type="stmt"/> - <line num="54" count="21" type="stmt"/> - <line num="59" count="1" type="stmt"/> + <line num="49" count="1" type="stmt"/> + <line num="52" count="0" type="stmt"/> + <line num="54" count="0" type="stmt"/> + <line num="55" count="0" type="stmt"/> + <line num="59" count="33" type="stmt"/> <line num="60" count="1" type="stmt"/> + <line num="61" count="1" type="stmt"/> + <line num="62" count="1" type="stmt"/> + <line num="64" count="1" type="cond" truecount="1" falsecount="1"/> + <line num="65" count="1" type="stmt"/> + <line num="68" count="1" type="stmt"/> + <line num="69" count="1" type="stmt"/> + <line num="72" count="0" type="stmt"/> + <line num="73" count="0" type="stmt"/> + <line num="77" count="33" type="stmt"/> + <line num="85" count="1" type="stmt"/> + <line num="86" count="1" type="stmt"/> </file> <file name="FeedItems.css" path="/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItems.css"> <metrics statements="0" coveredstatements="0" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0"/> </file> <file name="FeedItems.tsx" path="/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItems.tsx"> - <metrics statements="110" coveredstatements="98" conditionals="79" coveredconditionals="61" methods="29" coveredmethods="25"/> - <line num="8" count="27" type="stmt"/> + <metrics statements="115" coveredstatements="102" conditionals="81" coveredconditionals="61" methods="29" coveredmethods="25"/> <line num="9" count="27" type="stmt"/> - <line num="10" count="27" type="cond" truecount="2" falsecount="0"/> - <line num="12" count="27" type="stmt"/> + <line num="10" count="27" type="stmt"/> + <line num="11" count="27" type="cond" truecount="2" falsecount="0"/> <line num="13" count="27" type="stmt"/> <line num="14" count="27" type="stmt"/> <line num="15" count="27" type="stmt"/> <line num="16" count="27" type="stmt"/> + <line num="17" count="27" type="stmt"/> <line num="18" count="27" type="stmt"/> - <line num="19" count="8" type="cond" truecount="2" falsecount="0"/> - <line num="20" count="1" type="stmt"/> - <line num="22" count="7" type="stmt"/> - <line num="23" count="7" type="stmt"/> - <line num="25" count="8" type="stmt"/> + <line num="20" count="27" type="stmt"/> + <line num="21" count="8" type="cond" truecount="2" falsecount="0"/> + <line num="22" count="1" type="stmt"/> + <line num="24" count="7" type="stmt"/> + <line num="25" count="7" type="stmt"/> <line num="27" count="8" type="stmt"/> - <line num="28" count="8" type="stmt"/> - <line num="30" count="8" type="cond" truecount="2" falsecount="0"/> - <line num="31" count="2" type="stmt"/> - <line num="32" count="6" type="cond" truecount="2" falsecount="0"/> - <line num="33" count="1" type="stmt"/> - <line num="36" count="8" type="cond" truecount="2" falsecount="0"/> - <line num="37" count="1" type="stmt"/> - <line num="41" count="8" type="cond" truecount="1" falsecount="1"/> - <line num="42" count="0" type="stmt"/> - <line num="43" count="8" type="cond" truecount="1" falsecount="1"/> - <line num="44" count="0" type="stmt"/> + <line num="29" count="8" type="stmt"/> + <line num="30" count="8" type="stmt"/> + <line num="32" count="8" type="cond" truecount="2" falsecount="0"/> + <line num="33" count="2" type="stmt"/> + <line num="34" count="6" type="cond" truecount="2" falsecount="0"/> + <line num="35" count="1" type="stmt"/> + <line num="38" count="8" type="cond" truecount="2" falsecount="0"/> + <line num="39" count="1" type="stmt"/> + <line num="43" count="8" type="stmt"/> + <line num="44" count="8" type="cond" truecount="1" falsecount="1"/> <line num="45" count="0" type="stmt"/> - <line num="48" count="8" type="stmt"/> - <line num="51" count="8" type="stmt"/> - <line num="52" count="8" type="cond" truecount="1" falsecount="1"/> - <line num="53" count="8" type="stmt"/> + <line num="48" count="8" type="cond" truecount="1" falsecount="1"/> + <line num="49" count="0" type="stmt"/> + <line num="50" count="8" type="cond" truecount="1" falsecount="1"/> + <line num="51" count="0" type="stmt"/> + <line num="52" count="0" type="stmt"/> + <line num="55" count="8" type="cond" truecount="1" falsecount="1"/> <line num="56" count="8" type="stmt"/> - <line num="58" count="7" type="cond" truecount="1" falsecount="1"/> - <line num="59" count="0" type="stmt"/> - <line num="61" count="7" type="stmt"/> - <line num="64" count="6" type="cond" truecount="2" falsecount="0"/> - <line num="65" count="1" type="stmt"/> - <line num="67" count="5" type="stmt"/> - <line num="69" count="6" type="stmt"/> - <line num="70" count="6" type="stmt"/> - <line num="71" count="6" type="stmt"/> + <line num="60" count="8" type="stmt"/> + <line num="61" count="8" type="cond" truecount="1" falsecount="1"/> + <line num="62" count="8" type="stmt"/> + <line num="65" count="8" type="stmt"/> + <line num="67" count="7" type="cond" truecount="1" falsecount="1"/> + <line num="68" count="0" type="stmt"/> + <line num="70" count="7" type="stmt"/> + <line num="73" count="6" type="cond" truecount="2" falsecount="0"/> <line num="74" count="1" type="stmt"/> - <line num="75" count="1" type="stmt"/> - <line num="76" count="1" type="stmt"/> - <line num="80" count="27" type="stmt"/> - <line num="81" count="7" type="stmt"/> - <line num="84" count="27" type="stmt"/> - <line num="86" count="27" type="stmt"/> - <line num="87" count="23" type="stmt"/> - <line num="88" count="3" type="cond" truecount="1" falsecount="1"/> - <line num="90" count="3" type="cond" truecount="2" falsecount="0"/> - <line num="91" count="2" type="stmt"/> - <line num="92" count="2" type="stmt"/> - <line num="93" count="2" type="cond" truecount="1" falsecount="1"/> - <line num="94" count="2" type="stmt"/> - <line num="95" count="2" type="cond" truecount="2" falsecount="0"/> - <line num="96" count="1" type="stmt"/> + <line num="76" count="5" type="stmt"/> + <line num="78" count="6" type="stmt"/> + <line num="79" count="6" type="stmt"/> + <line num="80" count="6" type="stmt"/> + <line num="83" count="1" type="stmt"/> + <line num="84" count="1" type="stmt"/> + <line num="85" count="1" type="stmt"/> + <line num="89" count="27" type="stmt"/> + <line num="90" count="7" type="stmt"/> + <line num="91" count="7" type="stmt"/> + <line num="95" count="27" type="stmt"/> + <line num="96" count="2" type="stmt"/> + <line num="97" count="2" type="cond" truecount="1" falsecount="1"/> <line num="98" count="2" type="stmt"/> - <line num="100" count="2" type="stmt"/> - <line num="102" count="1" type="cond" truecount="1" falsecount="1"/> - <line num="103" count="0" type="stmt"/> - <line num="104" count="0" type="stmt"/> - <line num="105" count="0" type="cond" truecount="0" falsecount="2"/> - <line num="106" count="0" type="stmt"/> - <line num="108" count="0" type="stmt"/> - <line num="110" count="1" type="cond" truecount="1" falsecount="1"/> - <line num="111" count="1" type="stmt"/> - <line num="112" count="1" type="cond" truecount="3" falsecount="1"/> - <line num="113" count="1" type="stmt"/> + <line num="102" count="27" type="stmt"/> + <line num="103" count="2" type="stmt"/> + <line num="105" count="3" type="cond" truecount="2" falsecount="0"/> + <line num="107" count="2" type="stmt"/> + <line num="111" count="0" type="stmt"/> + <line num="114" count="27" type="stmt"/> <line num="115" count="1" type="stmt"/> - <line num="120" count="23" type="stmt"/> - <line num="121" count="23" type="stmt"/> - <line num="124" count="27" type="stmt"/> - <line num="125" count="2" type="stmt"/> - <line num="126" count="2" type="cond" truecount="1" falsecount="1"/> - <line num="127" count="2" type="stmt"/> - <line num="131" count="27" type="stmt"/> + <line num="117" count="2" type="cond" truecount="2" falsecount="0"/> + <line num="119" count="1" type="stmt"/> + <line num="123" count="0" type="stmt"/> + <line num="126" count="27" type="stmt"/> + <line num="127" count="23" type="stmt"/> + <line num="128" count="3" type="cond" truecount="1" falsecount="1"/> + <line num="130" count="3" type="cond" truecount="2" falsecount="0"/> + <line num="131" count="2" type="stmt"/> <line num="132" count="2" type="stmt"/> - <line num="134" count="3" type="cond" truecount="2" falsecount="0"/> - <line num="136" count="2" type="stmt"/> - <line num="140" count="0" type="stmt"/> - <line num="143" count="27" type="stmt"/> - <line num="144" count="1" type="stmt"/> - <line num="146" count="2" type="cond" truecount="2" falsecount="0"/> - <line num="148" count="1" type="stmt"/> - <line num="152" count="0" type="stmt"/> - <line num="155" count="27" type="stmt"/> - <line num="156" count="24" type="stmt"/> - <line num="158" count="2" type="stmt"/> - <line num="160" count="2" type="cond" truecount="2" falsecount="0"/> - <line num="161" count="1" type="cond" truecount="5" falsecount="1"/> - <line num="162" count="1" type="stmt"/> - <line num="164" count="1" type="stmt"/> - <line num="168" count="1" type="cond" truecount="3" falsecount="1"/> - <line num="169" count="1" type="stmt"/> - <line num="170" count="1" type="cond" truecount="4" falsecount="1"/> - <line num="171" count="1" type="stmt"/> - <line num="172" count="1" type="cond" truecount="1" falsecount="1"/> + <line num="133" count="2" type="cond" truecount="1" falsecount="1"/> + <line num="134" count="2" type="stmt"/> + <line num="135" count="2" type="cond" truecount="2" falsecount="0"/> + <line num="136" count="1" type="stmt"/> + <line num="138" count="2" type="stmt"/> + <line num="140" count="2" type="stmt"/> + <line num="142" count="1" type="cond" truecount="1" falsecount="1"/> + <line num="143" count="0" type="stmt"/> + <line num="144" count="0" type="stmt"/> + <line num="145" count="0" type="cond" truecount="0" falsecount="2"/> + <line num="146" count="0" type="stmt"/> + <line num="148" count="0" type="stmt"/> + <line num="150" count="1" type="cond" truecount="1" falsecount="1"/> + <line num="151" count="1" type="stmt"/> + <line num="152" count="1" type="cond" truecount="3" falsecount="1"/> + <line num="153" count="1" type="stmt"/> + <line num="155" count="1" type="stmt"/> + <line num="160" count="23" type="stmt"/> + <line num="161" count="23" type="stmt"/> + <line num="166" count="27" type="stmt"/> + <line num="167" count="24" type="stmt"/> + <line num="169" count="2" type="stmt"/> + <line num="171" count="2" type="cond" truecount="2" falsecount="0"/> + <line num="172" count="1" type="cond" truecount="5" falsecount="1"/> <line num="173" count="1" type="stmt"/> - <line num="182" count="24" type="stmt"/> - <line num="183" count="15" type="stmt"/> - <line num="184" count="15" type="cond" truecount="1" falsecount="1"/> - <line num="187" count="24" type="stmt"/> - <line num="188" count="24" type="cond" truecount="2" falsecount="0"/> - <line num="190" count="24" type="stmt"/> - <line num="193" count="27" type="cond" truecount="2" falsecount="0"/> - <line num="194" count="14" type="cond" truecount="2" falsecount="0"/> - <line num="197" count="13" type="stmt"/> - <line num="204" count="21" type="stmt"/> - <line num="209" count="0" type="stmt"/> + <line num="175" count="1" type="stmt"/> + <line num="179" count="1" type="cond" truecount="3" falsecount="1"/> + <line num="180" count="1" type="stmt"/> + <line num="181" count="1" type="cond" truecount="4" falsecount="1"/> + <line num="182" count="1" type="stmt"/> + <line num="183" count="1" type="cond" truecount="1" falsecount="1"/> + <line num="184" count="1" type="stmt"/> + <line num="193" count="24" type="stmt"/> + <line num="194" count="15" type="stmt"/> + <line num="195" count="15" type="cond" truecount="1" falsecount="1"/> + <line num="198" count="24" type="stmt"/> + <line num="199" count="24" type="cond" truecount="2" falsecount="0"/> + <line num="201" count="24" type="stmt"/> + <line num="204" count="27" type="cond" truecount="2" falsecount="0"/> + <line num="205" count="14" type="cond" truecount="2" falsecount="0"/> + <line num="207" count="13" type="stmt"/> + <line num="214" count="21" type="stmt"/> + <line num="219" count="0" type="stmt"/> </file> <file name="FeedList.css" path="/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedList.css"> <metrics statements="0" coveredstatements="0" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0"/> </file> <file name="FeedList.tsx" path="/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedList.tsx"> - <metrics statements="20" coveredstatements="20" conditionals="17" coveredconditionals="14" methods="8" coveredmethods="8"/> - <line num="7" count="11" type="stmt"/> - <line num="8" count="11" type="stmt"/> - <line num="9" count="11" type="stmt"/> - <line num="10" count="11" type="stmt"/> - <line num="12" count="11" type="stmt"/> - <line num="13" count="6" type="stmt"/> - <line num="15" count="4" type="cond" truecount="1" falsecount="1"/> - <line num="16" count="4" type="stmt"/> - <line num="19" count="4" type="cond" truecount="1" falsecount="1"/> - <line num="20" count="4" type="stmt"/> - <line num="24" count="4" type="stmt"/> - <line num="25" count="4" type="stmt"/> - <line num="26" count="4" type="stmt"/> - <line num="29" count="1" type="stmt"/> - <line num="30" count="1" type="stmt"/> - <line num="34" count="11" type="cond" truecount="2" falsecount="0"/> - <line num="35" count="5" type="cond" truecount="2" falsecount="0"/> - <line num="37" count="4" type="stmt"/> - <line num="53" count="3" type="stmt"/> - <line num="69" count="3" type="stmt"/> + <metrics statements="39" coveredstatements="32" conditionals="37" coveredconditionals="24" methods="17" coveredmethods="11"/> + <line num="16" count="13" type="stmt"/> + <line num="17" count="13" type="stmt"/> + <line num="18" count="13" type="stmt"/> + <line num="19" count="13" type="stmt"/> + <line num="20" count="13" type="stmt"/> + <line num="21" count="13" type="stmt"/> + <line num="22" count="13" type="stmt"/> + <line num="23" count="13" type="stmt"/> + <line num="24" count="13" type="stmt"/> + <line num="25" count="13" type="stmt"/> + <line num="28" count="13" type="cond" truecount="2" falsecount="0"/> + <line num="31" count="13" type="stmt"/> + <line num="32" count="0" type="stmt"/> + <line num="33" count="0" type="cond" truecount="0" falsecount="2"/> + <line num="34" count="0" type="stmt"/> + <line num="38" count="13" type="stmt"/> + <line num="39" count="2" type="stmt"/> + <line num="42" count="13" type="stmt"/> + <line num="43" count="6" type="stmt"/> + <line num="45" count="4" type="cond" truecount="1" falsecount="1"/> + <line num="46" count="4" type="stmt"/> + <line num="49" count="4" type="cond" truecount="1" falsecount="1"/> + <line num="50" count="4" type="stmt"/> + <line num="54" count="4" type="stmt"/> + <line num="55" count="4" type="stmt"/> + <line num="56" count="4" type="stmt"/> + <line num="59" count="1" type="stmt"/> + <line num="60" count="1" type="stmt"/> + <line num="64" count="13" type="cond" truecount="2" falsecount="0"/> + <line num="65" count="7" type="cond" truecount="2" falsecount="0"/> + <line num="67" count="6" type="stmt"/> + <line num="68" count="1" type="stmt"/> + <line num="71" count="6" type="stmt"/> + <line num="73" count="0" type="stmt"/> + <line num="83" count="0" type="stmt"/> + <line num="115" count="4" type="stmt"/> + <line num="137" count="2" type="stmt"/> + <line num="168" count="0" type="stmt"/> + <line num="175" count="0" type="stmt"/> </file> <file name="Login.css" path="/Users/adam/workspace/vibecode/neko/frontend/src/components/Login.css"> <metrics statements="0" coveredstatements="0" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0"/> </file> <file name="Login.tsx" path="/Users/adam/workspace/vibecode/neko/frontend/src/components/Login.tsx"> <metrics statements="17" coveredstatements="17" conditionals="6" coveredconditionals="5" methods="3" coveredmethods="3"/> - <line num="6" count="14" type="stmt"/> - <line num="7" count="14" type="stmt"/> <line num="8" count="14" type="stmt"/> + <line num="9" count="14" type="stmt"/> <line num="10" count="14" type="stmt"/> - <line num="11" count="3" type="stmt"/> - <line num="12" count="3" type="stmt"/> + <line num="12" count="14" type="stmt"/> + <line num="13" count="3" type="stmt"/> <line num="14" count="3" type="stmt"/> <line num="16" count="3" type="stmt"/> - <line num="17" count="3" type="stmt"/> + <line num="18" count="3" type="stmt"/> <line num="19" count="3" type="stmt"/> - <line num="24" count="2" type="cond" truecount="2" falsecount="0"/> - <line num="25" count="1" type="stmt"/> + <line num="21" count="3" type="stmt"/> + <line num="26" count="2" type="cond" truecount="2" falsecount="0"/> <line num="27" count="1" type="stmt"/> - <line num="28" count="1" type="cond" truecount="1" falsecount="1"/> - <line num="31" count="1" type="stmt"/> - <line num="35" count="14" type="stmt"/> - <line num="45" count="3" type="stmt"/> + <line num="29" count="1" type="stmt"/> + <line num="30" count="1" type="cond" truecount="1" falsecount="1"/> + <line num="33" count="1" type="stmt"/> + <line num="37" count="14" type="stmt"/> + <line num="47" count="3" type="stmt"/> </file> <file name="Settings.css" path="/Users/adam/workspace/vibecode/neko/frontend/src/components/Settings.css"> <metrics statements="0" coveredstatements="0" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0"/> </file> <file name="Settings.tsx" path="/Users/adam/workspace/vibecode/neko/frontend/src/components/Settings.tsx"> - <metrics statements="39" coveredstatements="33" conditionals="16" coveredconditionals="9" methods="17" coveredmethods="14"/> - <line num="6" count="14" type="stmt"/> + <metrics statements="56" coveredstatements="35" conditionals="24" coveredconditionals="10" methods="22" coveredmethods="14"/> <line num="7" count="14" type="stmt"/> <line num="8" count="14" type="stmt"/> <line num="9" count="14" type="stmt"/> - <line num="11" count="14" type="stmt"/> - <line num="12" count="3" type="stmt"/> - <line num="15" count="14" type="stmt"/> + <line num="10" count="14" type="stmt"/> + <line num="12" count="14" type="stmt"/> + <line num="14" count="14" type="stmt"/> + <line num="15" count="4" type="stmt"/> <line num="16" count="4" type="stmt"/> - <line num="17" count="4" type="stmt"/> - <line num="19" count="4" type="cond" truecount="1" falsecount="1"/> - <line num="20" count="4" type="stmt"/> + <line num="18" count="4" type="cond" truecount="1" falsecount="1"/> + <line num="19" count="4" type="stmt"/> + <line num="22" count="4" type="stmt"/> <line num="23" count="4" type="stmt"/> - <line num="24" count="4" type="stmt"/> + <line num="26" count="0" type="stmt"/> <line num="27" count="0" type="stmt"/> - <line num="28" count="0" type="stmt"/> - <line num="32" count="14" type="stmt"/> - <line num="33" count="1" type="stmt"/> - <line num="34" count="1" type="cond" truecount="1" falsecount="1"/> + <line num="31" count="14" type="stmt"/> + <line num="32" count="3" type="stmt"/> + <line num="35" count="14" type="stmt"/> <line num="36" count="1" type="stmt"/> - <line num="37" count="1" type="stmt"/> - <line num="43" count="1" type="cond" truecount="1" falsecount="1"/> - <line num="44" count="1" type="stmt"/> + <line num="37" count="1" type="cond" truecount="1" falsecount="1"/> + <line num="39" count="1" type="stmt"/> + <line num="40" count="1" type="stmt"/> + <line num="46" count="1" type="cond" truecount="1" falsecount="1"/> <line num="47" count="1" type="stmt"/> - <line num="48" count="1" type="stmt"/> - <line num="51" count="0" type="stmt"/> - <line num="52" count="0" type="stmt"/> - <line num="56" count="14" type="stmt"/> - <line num="57" count="1" type="cond" truecount="1" falsecount="1"/> - <line num="59" count="1" type="stmt"/> - <line num="60" count="1" type="stmt"/> - <line num="64" count="1" type="cond" truecount="1" falsecount="1"/> - <line num="65" count="1" type="stmt"/> - <line num="66" count="1" type="stmt"/> - <line num="69" count="0" type="stmt"/> - <line num="70" count="0" type="stmt"/> - <line num="74" count="14" type="stmt"/> - <line num="84" count="1" type="stmt"/> - <line num="102" count="5" type="stmt"/> - <line num="108" count="1" type="stmt"/> + <line num="50" count="1" type="stmt"/> + <line num="51" count="1" type="stmt"/> + <line num="54" count="0" type="stmt"/> + <line num="55" count="0" type="stmt"/> + <line num="59" count="14" type="stmt"/> + <line num="60" count="1" type="cond" truecount="1" falsecount="1"/> + <line num="62" count="1" type="stmt"/> + <line num="63" count="1" type="stmt"/> + <line num="67" count="1" type="cond" truecount="1" falsecount="1"/> + <line num="68" count="1" type="stmt"/> + <line num="69" count="1" type="stmt"/> + <line num="72" count="0" type="stmt"/> + <line num="73" count="0" type="stmt"/> + <line num="77" count="14" type="stmt"/> + <line num="78" count="0" type="stmt"/> + <line num="79" count="0" type="cond" truecount="0" falsecount="2"/> + <line num="81" count="0" type="stmt"/> + <line num="82" count="0" type="stmt"/> + <line num="83" count="0" type="stmt"/> + <line num="84" count="0" type="stmt"/> + <line num="86" count="0" type="stmt"/> + <line num="91" count="0" type="cond" truecount="0" falsecount="2"/> + <line num="92" count="0" type="stmt"/> + <line num="95" count="0" type="stmt"/> + <line num="96" count="0" type="stmt"/> + <line num="97" count="0" type="stmt"/> + <line num="100" count="0" type="stmt"/> + <line num="101" count="0" type="stmt"/> + <line num="105" count="14" type="stmt"/> + <line num="115" count="1" type="stmt"/> + <line num="134" count="0" type="cond" truecount="0" falsecount="2"/> + <line num="161" count="5" type="stmt"/> + <line num="167" count="1" type="stmt"/> </file> </package> </project> diff --git a/frontend/coverage/coverage-final.json b/frontend/coverage/coverage-final.json index e46821b..141aa13 100644 --- a/frontend/coverage/coverage-final.json +++ b/frontend/coverage/coverage-final.json @@ -1,2240 +1,14 @@ -{ - "/Users/adam/workspace/vibecode/neko/frontend/src/App.css": { - "path": "/Users/adam/workspace/vibecode/neko/frontend/src/App.css", - "statementMap": {}, - "fnMap": {}, - "branchMap": {}, - "s": {}, - "f": {}, - "b": {}, - "meta": { "lastBranch": 0, "lastFunction": 0, "lastStatement": 0, "seen": {} } - }, - "/Users/adam/workspace/vibecode/neko/frontend/src/App.tsx": { - "path": "/Users/adam/workspace/vibecode/neko/frontend/src/App.tsx", - "statementMap": { - "0": { "start": { "line": 8, "column": 22 }, "end": { "line": 8, "column": null } }, - "1": { "start": { "line": 9, "column": 8 }, "end": { "line": 9, "column": null } }, - "2": { "start": { "line": 11, "column": 2 }, "end": { "line": 21, "column": null } }, - "3": { "start": { "line": 12, "column": 4 }, "end": { "line": 20, "column": null } }, - "4": { "start": { "line": 14, "column": 8 }, "end": { "line": 18, "column": null } }, - "5": { "start": { "line": 15, "column": 10 }, "end": { "line": 15, "column": null } }, - "6": { "start": { "line": 17, "column": 10 }, "end": { "line": 17, "column": null } }, - "7": { "start": { "line": 20, "column": 19 }, "end": { "line": 20, "column": 33 } }, - "8": { "start": { "line": 23, "column": 2 }, "end": { "line": 25, "column": null } }, - "9": { "start": { "line": 24, "column": 4 }, "end": { "line": 24, "column": null } }, - "10": { "start": { "line": 27, "column": 2 }, "end": { "line": 29, "column": null } }, - "11": { "start": { "line": 28, "column": 4 }, "end": { "line": 28, "column": null } }, - "12": { "start": { "line": 31, "column": 2 }, "end": { "line": 31, "column": null } }, - "13": { "start": { "line": 39, "column": 8 }, "end": { "line": 39, "column": null } }, - "14": { "start": { "line": 40, "column": 2 }, "end": { "line": 68, "column": null } }, - "15": { "start": { "line": 45, "column": 33 }, "end": { "line": 45, "column": 56 } }, - "16": { "start": { "line": 48, "column": 12 }, "end": { "line": 49, "column": null } }, - "17": { "start": { "line": 49, "column": 26 }, "end": { "line": 49, "column": 60 } }, - "18": { "start": { "line": 73, "column": 2 }, "end": { "line": 86, "column": null } } - }, - "fnMap": { - "0": { - "name": "RequireAuth", - "decl": { "start": { "line": 7, "column": 9 }, "end": { "line": 7, "column": 21 } }, - "loc": { "start": { "line": 7, "column": 69 }, "end": { "line": 32, "column": null } }, - "line": 7 - }, - "1": { - "name": "(anonymous_1)", - "decl": { "start": { "line": 11, "column": 12 }, "end": { "line": 11, "column": 18 } }, - "loc": { "start": { "line": 11, "column": 18 }, "end": { "line": 21, "column": 5 } }, - "line": 11 - }, - "2": { - "name": "(anonymous_2)", - "decl": { "start": { "line": 13, "column": 12 }, "end": { "line": 13, "column": 13 } }, - "loc": { "start": { "line": 13, "column": 21 }, "end": { "line": 19, "column": 7 } }, - "line": 13 - }, - "3": { - "name": "(anonymous_3)", - "decl": { "start": { "line": 20, "column": 13 }, "end": { "line": 20, "column": 19 } }, - "loc": { "start": { "line": 20, "column": 19 }, "end": { "line": 20, "column": 33 } }, - "line": 20 - }, - "4": { - "name": "Dashboard", - "decl": { "start": { "line": 38, "column": 9 }, "end": { "line": 38, "column": 21 } }, - "loc": { "start": { "line": 38, "column": 21 }, "end": { "line": 70, "column": null } }, - "line": 38 - }, - "5": { - "name": "(anonymous_5)", - "decl": { "start": { "line": 45, "column": 27 }, "end": { "line": 45, "column": 33 } }, - "loc": { "start": { "line": 45, "column": 33 }, "end": { "line": 45, "column": 56 } }, - "line": 45 - }, - "6": { - "name": "(anonymous_6)", - "decl": { "start": { "line": 47, "column": 27 }, "end": { "line": 47, "column": 33 } }, - "loc": { "start": { "line": 47, "column": 33 }, "end": { "line": 50, "column": 13 } }, - "line": 47 - }, - "7": { - "name": "(anonymous_7)", - "decl": { "start": { "line": 49, "column": 20 }, "end": { "line": 49, "column": 26 } }, - "loc": { "start": { "line": 49, "column": 26 }, "end": { "line": 49, "column": 60 } }, - "line": 49 - }, - "8": { - "name": "App", - "decl": { "start": { "line": 72, "column": 9 }, "end": { "line": 72, "column": 15 } }, - "loc": { "start": { "line": 72, "column": 15 }, "end": { "line": 88, "column": null } }, - "line": 72 - } - }, - "branchMap": { - "0": { - "loc": { "start": { "line": 14, "column": 8 }, "end": { "line": 18, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 14, "column": 8 }, "end": { "line": 18, "column": null } }, - { "start": { "line": 16, "column": 15 }, "end": { "line": 18, "column": null } } - ], - "line": 14 - }, - "1": { - "loc": { "start": { "line": 23, "column": 2 }, "end": { "line": 25, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 23, "column": 2 }, "end": { "line": 25, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 23 - }, - "2": { - "loc": { "start": { "line": 27, "column": 2 }, "end": { "line": 29, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 27, "column": 2 }, "end": { "line": 29, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 27 - } - }, - "s": { - "0": 2, - "1": 2, - "2": 2, - "3": 1, - "4": 1, - "5": 1, - "6": 0, - "7": 0, - "8": 2, - "9": 1, - "10": 1, - "11": 0, - "12": 1, - "13": 1, - "14": 1, - "15": 0, - "16": 1, - "17": 1, - "18": 2 - }, - "f": { "0": 2, "1": 1, "2": 1, "3": 0, "4": 1, "5": 0, "6": 1, "7": 1, "8": 2 }, - "b": { "0": [1, 0], "1": [1, 1], "2": [0, 1] }, - "meta": { - "lastBranch": 3, - "lastFunction": 9, - "lastStatement": 19, - "seen": { - "f:7:9:7:21": 0, - "s:8:22:8:Infinity": 0, - "s:9:8:9:Infinity": 1, - "s:11:2:21:Infinity": 2, - "f:11:12:11:18": 1, - "s:12:4:20:Infinity": 3, - "f:13:12:13:13": 2, - "b:14:8:18:Infinity:16:15:18:Infinity": 0, - "s:14:8:18:Infinity": 4, - "s:15:10:15:Infinity": 5, - "s:17:10:17:Infinity": 6, - "f:20:13:20:19": 3, - "s:20:19:20:33": 7, - "b:23:2:25:Infinity:undefined:undefined:undefined:undefined": 1, - "s:23:2:25:Infinity": 8, - "s:24:4:24:Infinity": 9, - "b:27:2:29:Infinity:undefined:undefined:undefined:undefined": 2, - "s:27:2:29:Infinity": 10, - "s:28:4:28:Infinity": 11, - "s:31:2:31:Infinity": 12, - "f:38:9:38:21": 4, - "s:39:8:39:Infinity": 13, - "s:40:2:68:Infinity": 14, - "f:45:27:45:33": 5, - "s:45:33:45:56": 15, - "f:47:27:47:33": 6, - "s:48:12:49:Infinity": 16, - "f:49:20:49:26": 7, - "s:49:26:49:60": 17, - "f:72:9:72:15": 8, - "s:73:2:86:Infinity": 18 - } - } - }, - "/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItem.css": { - "path": "/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItem.css", - "statementMap": {}, - "fnMap": {}, - "branchMap": {}, - "s": {}, - "f": {}, - "b": {}, - "meta": { "lastBranch": 0, "lastFunction": 0, "lastStatement": 0, "seen": {} } - }, - "/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItem.tsx": { - "path": "/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItem.tsx", - "statementMap": { - "0": { "start": { "line": 10, "column": 24 }, "end": { "line": 10, "column": null } }, - "1": { "start": { "line": 11, "column": 30 }, "end": { "line": 11, "column": null } }, - "2": { "start": { "line": 14, "column": 23 }, "end": { "line": 16, "column": null } }, - "3": { "start": { "line": 15, "column": 8 }, "end": { "line": 15, "column": null } }, - "4": { "start": { "line": 18, "column": 23 }, "end": { "line": 52, "column": null } }, - "5": { "start": { "line": 19, "column": 8 }, "end": { "line": 19, "column": null } }, - "6": { "start": { "line": 21, "column": 29 }, "end": { "line": 21, "column": null } }, - "7": { "start": { "line": 22, "column": 8 }, "end": { "line": 22, "column": null } }, - "8": { "start": { "line": 24, "column": 8 }, "end": { "line": 51, "column": null } }, - "9": { "start": { "line": 36, "column": 16 }, "end": { "line": 38, "column": null } }, - "10": { "start": { "line": 37, "column": 20 }, "end": { "line": 37, "column": null } }, - "11": { "start": { "line": 39, "column": 16 }, "end": { "line": 39, "column": null } }, - "12": { "start": { "line": 44, "column": 16 }, "end": { "line": 44, "column": null } }, - "13": { "start": { "line": 47, "column": 16 }, "end": { "line": 47, "column": null } }, - "14": { "start": { "line": 49, "column": 16 }, "end": { "line": 49, "column": null } }, - "15": { "start": { "line": 50, "column": 16 }, "end": { "line": 50, "column": null } }, - "16": { "start": { "line": 54, "column": 4 }, "end": { "line": 82, "column": null } }, - "17": { "start": { "line": 59, "column": 24 }, "end": { "line": 59, "column": null } }, - "18": { "start": { "line": 60, "column": 24 }, "end": { "line": 60, "column": null } } - }, - "fnMap": { - "0": { - "name": "FeedItem", - "decl": { "start": { "line": 9, "column": 24 }, "end": { "line": 9, "column": 33 } }, - "loc": { "start": { "line": 9, "column": 71 }, "end": { "line": 84, "column": null } }, - "line": 9 - }, - "1": { - "name": "(anonymous_1)", - "decl": { "start": { "line": 14, "column": 23 }, "end": { "line": 14, "column": 29 } }, - "loc": { "start": { "line": 14, "column": 29 }, "end": { "line": 16, "column": null } }, - "line": 14 - }, - "2": { - "name": "(anonymous_2)", - "decl": { "start": { "line": 18, "column": 23 }, "end": { "line": 18, "column": 24 } }, - "loc": { "start": { "line": 18, "column": 42 }, "end": { "line": 52, "column": null } }, - "line": 18 - }, - "3": { - "name": "(anonymous_3)", - "decl": { "start": { "line": 35, "column": 18 }, "end": { "line": 35, "column": 19 } }, - "loc": { "start": { "line": 35, "column": 27 }, "end": { "line": 40, "column": 13 } }, - "line": 35 - }, - "4": { - "name": "(anonymous_4)", - "decl": { "start": { "line": 41, "column": 18 }, "end": { "line": 41, "column": 24 } }, - "loc": { "start": { "line": 41, "column": 24 }, "end": { "line": 45, "column": 13 } }, - "line": 41 - }, - "5": { - "name": "(anonymous_5)", - "decl": { "start": { "line": 46, "column": 19 }, "end": { "line": 46, "column": 20 } }, - "loc": { "start": { "line": 46, "column": 28 }, "end": { "line": 51, "column": 13 } }, - "line": 46 - }, - "6": { - "name": "(anonymous_6)", - "decl": { "start": { "line": 58, "column": 29 }, "end": { "line": 58, "column": 30 } }, - "loc": { "start": { "line": 58, "column": 36 }, "end": { "line": 61, "column": null } }, - "line": 58 - } - }, - "branchMap": { - "0": { - "loc": { "start": { "line": 36, "column": 16 }, "end": { "line": 38, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 36, "column": 16 }, "end": { "line": 38, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 36 - }, - "1": { - "loc": { "start": { "line": 55, "column": 36 }, "end": { "line": 55, "column": 65 } }, - "type": "cond-expr", - "locations": [ - { "start": { "line": 55, "column": 48 }, "end": { "line": 55, "column": 57 } }, - { "start": { "line": 55, "column": 57 }, "end": { "line": 55, "column": 65 } } - ], - "line": 55 - }, - "2": { - "loc": { "start": { "line": 55, "column": 69 }, "end": { "line": 55, "column": 93 } }, - "type": "cond-expr", - "locations": [ - { "start": { "line": 55, "column": 79 }, "end": { "line": 55, "column": 91 } }, - { "start": { "line": 55, "column": 91 }, "end": { "line": 55, "column": 93 } } - ], - "line": 55 - }, - "3": { - "loc": { "start": { "line": 62, "column": 43 }, "end": { "line": 62, "column": 87 } }, - "type": "cond-expr", - "locations": [ - { "start": { "line": 62, "column": 58 }, "end": { "line": 62, "column": 73 } }, - { "start": { "line": 62, "column": 73 }, "end": { "line": 62, "column": 87 } } - ], - "line": 62 - }, - "4": { - "loc": { "start": { "line": 63, "column": 27 }, "end": { "line": 63, "column": null } }, - "type": "cond-expr", - "locations": [ - { "start": { "line": 63, "column": 42 }, "end": { "line": 63, "column": 53 } }, - { "start": { "line": 63, "column": 53 }, "end": { "line": 63, "column": null } } - ], - "line": 63 - }, - "5": { - "loc": { "start": { "line": 65, "column": 21 }, "end": { "line": 65, "column": null } }, - "type": "cond-expr", - "locations": [ - { "start": { "line": 65, "column": 36 }, "end": { "line": 65, "column": 42 } }, - { "start": { "line": 65, "column": 42 }, "end": { "line": 65, "column": null } } - ], - "line": 65 - }, - "6": { - "loc": { "start": { "line": 68, "column": 21 }, "end": { "line": 68, "column": null } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 68, "column": 21 }, "end": { "line": 68, "column": 35 } }, - { "start": { "line": 68, "column": 35 }, "end": { "line": 68, "column": null } } - ], - "line": 68 - }, - "7": { - "loc": { "start": { "line": 74, "column": 21 }, "end": { "line": 74, "column": null } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 74, "column": 21 }, "end": { "line": 74, "column": 40 } }, - { "start": { "line": 74, "column": 40 }, "end": { "line": 74, "column": null } } - ], - "line": 74 - }, - "8": { - "loc": { "start": { "line": 79, "column": 13 }, "end": { "line": 80, "column": null } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 79, "column": 13 }, "end": { "line": 79, "column": null } }, - { "start": { "line": 80, "column": 16 }, "end": { "line": 80, "column": null } } - ], - "line": 79 - } - }, - "s": { - "0": 21, - "1": 21, - "2": 21, - "3": 1, - "4": 21, - "5": 1, - "6": 1, - "7": 1, - "8": 1, - "9": 1, - "10": 0, - "11": 1, - "12": 1, - "13": 0, - "14": 0, - "15": 0, - "16": 21, - "17": 1, - "18": 1 - }, - "f": { "0": 21, "1": 1, "2": 1, "3": 1, "4": 1, "5": 0, "6": 1 }, - "b": { - "0": [0, 1], - "1": [9, 12], - "2": [1, 20], - "3": [2, 19], - "4": [2, 19], - "5": [2, 19], - "6": [21, 0], - "7": [21, 5], - "8": [21, 4] - }, - "meta": { - "lastBranch": 9, - "lastFunction": 7, - "lastStatement": 19, - "seen": { - "f:9:24:9:33": 0, - "s:10:24:10:Infinity": 0, - "s:11:30:11:Infinity": 1, - "s:14:23:16:Infinity": 2, - "f:14:23:14:29": 1, - "s:15:8:15:Infinity": 3, - "s:18:23:52:Infinity": 4, - "f:18:23:18:24": 2, - "s:19:8:19:Infinity": 5, - "s:21:29:21:Infinity": 6, - "s:22:8:22:Infinity": 7, - "s:24:8:51:Infinity": 8, - "f:35:18:35:19": 3, - "b:36:16:38:Infinity:undefined:undefined:undefined:undefined": 0, - "s:36:16:38:Infinity": 9, - "s:37:20:37:Infinity": 10, - "s:39:16:39:Infinity": 11, - "f:41:18:41:24": 4, - "s:44:16:44:Infinity": 12, - "f:46:19:46:20": 5, - "s:47:16:47:Infinity": 13, - "s:49:16:49:Infinity": 14, - "s:50:16:50:Infinity": 15, - "s:54:4:82:Infinity": 16, - "b:55:48:55:57:55:57:55:65": 1, - "b:55:79:55:91:55:91:55:93": 2, - "f:58:29:58:30": 6, - "s:59:24:59:Infinity": 17, - "s:60:24:60:Infinity": 18, - "b:62:58:62:73:62:73:62:87": 3, - "b:63:42:63:53:63:53:63:Infinity": 4, - "b:65:36:65:42:65:42:65:Infinity": 5, - "b:68:21:68:35:68:35:68:Infinity": 6, - "b:74:21:74:40:74:40:74:Infinity": 7, - "b:79:13:79:Infinity:80:16:80:Infinity": 8 - } - } - }, - "/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItems.css": { - "path": "/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItems.css", - "statementMap": {}, - "fnMap": {}, - "branchMap": {}, - "s": {}, - "f": {}, - "b": {}, - "meta": { "lastBranch": 0, "lastFunction": 0, "lastStatement": 0, "seen": {} } - }, - "/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItems.tsx": { - "path": "/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItems.tsx", - "statementMap": { - "0": { "start": { "line": 8, "column": 28 }, "end": { "line": 8, "column": null } }, - "1": { "start": { "line": 9, "column": 23 }, "end": { "line": 9, "column": null } }, - "2": { "start": { "line": 10, "column": 21 }, "end": { "line": 10, "column": null } }, - "3": { "start": { "line": 12, "column": 26 }, "end": { "line": 12, "column": null } }, - "4": { "start": { "line": 13, "column": 30 }, "end": { "line": 13, "column": null } }, - "5": { "start": { "line": 14, "column": 38 }, "end": { "line": 14, "column": null } }, - "6": { "start": { "line": 15, "column": 30 }, "end": { "line": 15, "column": null } }, - "7": { "start": { "line": 16, "column": 26 }, "end": { "line": 16, "column": null } }, - "8": { "start": { "line": 18, "column": 23 }, "end": { "line": 78, "column": null } }, - "9": { "start": { "line": 19, "column": 8 }, "end": { "line": 24, "column": null } }, - "10": { "start": { "line": 20, "column": 12 }, "end": { "line": 20, "column": null } }, - "11": { "start": { "line": 22, "column": 12 }, "end": { "line": 22, "column": null } }, - "12": { "start": { "line": 23, "column": 12 }, "end": { "line": 23, "column": null } }, - "13": { "start": { "line": 25, "column": 8 }, "end": { "line": 25, "column": null } }, - "14": { "start": { "line": 27, "column": 18 }, "end": { "line": 27, "column": null } }, - "15": { "start": { "line": 28, "column": 23 }, "end": { "line": 28, "column": null } }, - "16": { "start": { "line": 30, "column": 8 }, "end": { "line": 34, "column": null } }, - "17": { "start": { "line": 31, "column": 12 }, "end": { "line": 31, "column": null } }, - "18": { "start": { "line": 32, "column": 8 }, "end": { "line": 34, "column": null } }, - "19": { "start": { "line": 33, "column": 12 }, "end": { "line": 33, "column": null } }, - "20": { "start": { "line": 36, "column": 8 }, "end": { "line": 38, "column": null } }, - "21": { "start": { "line": 37, "column": 12 }, "end": { "line": 37, "column": null } }, - "22": { "start": { "line": 41, "column": 8 }, "end": { "line": 49, "column": null } }, - "23": { "start": { "line": 42, "column": 12 }, "end": { "line": 42, "column": null } }, - "24": { "start": { "line": 43, "column": 8 }, "end": { "line": 49, "column": null } }, - "25": { "start": { "line": 44, "column": 12 }, "end": { "line": 44, "column": null } }, - "26": { "start": { "line": 45, "column": 12 }, "end": { "line": 45, "column": null } }, - "27": { "start": { "line": 48, "column": 12 }, "end": { "line": 48, "column": null } }, - "28": { "start": { "line": 51, "column": 28 }, "end": { "line": 51, "column": null } }, - "29": { "start": { "line": 52, "column": 8 }, "end": { "line": 54, "column": null } }, - "30": { "start": { "line": 53, "column": 12 }, "end": { "line": 53, "column": null } }, - "31": { "start": { "line": 56, "column": 8 }, "end": { "line": 77, "column": null } }, - "32": { "start": { "line": 58, "column": 16 }, "end": { "line": 60, "column": null } }, - "33": { "start": { "line": 59, "column": 20 }, "end": { "line": 59, "column": null } }, - "34": { "start": { "line": 61, "column": 16 }, "end": { "line": 61, "column": null } }, - "35": { "start": { "line": 64, "column": 16 }, "end": { "line": 68, "column": null } }, - "36": { "start": { "line": 65, "column": 20 }, "end": { "line": 65, "column": null } }, - "37": { "start": { "line": 65, "column": 39 }, "end": { "line": 65, "column": 57 } }, - "38": { "start": { "line": 67, "column": 20 }, "end": { "line": 67, "column": null } }, - "39": { "start": { "line": 69, "column": 16 }, "end": { "line": 69, "column": null } }, - "40": { "start": { "line": 70, "column": 16 }, "end": { "line": 70, "column": null } }, - "41": { "start": { "line": 71, "column": 16 }, "end": { "line": 71, "column": null } }, - "42": { "start": { "line": 74, "column": 16 }, "end": { "line": 74, "column": null } }, - "43": { "start": { "line": 75, "column": 16 }, "end": { "line": 75, "column": null } }, - "44": { "start": { "line": 76, "column": 16 }, "end": { "line": 76, "column": null } }, - "45": { "start": { "line": 80, "column": 4 }, "end": { "line": 82, "column": null } }, - "46": { "start": { "line": 81, "column": 8 }, "end": { "line": 81, "column": null } }, - "47": { "start": { "line": 84, "column": 42 }, "end": { "line": 84, "column": null } }, - "48": { "start": { "line": 86, "column": 4 }, "end": { "line": 122, "column": null } }, - "49": { "start": { "line": 87, "column": 30 }, "end": { "line": 118, "column": null } }, - "50": { "start": { "line": 88, "column": 12 }, "end": { "line": 88, "column": null } }, - "51": { "start": { "line": 88, "column": 36 }, "end": { "line": 88, "column": null } }, - "52": { "start": { "line": 90, "column": 12 }, "end": { "line": 117, "column": null } }, - "53": { "start": { "line": 91, "column": 16 }, "end": { "line": 101, "column": null } }, - "54": { "start": { "line": 92, "column": 38 }, "end": { "line": 92, "column": null } }, - "55": { "start": { "line": 93, "column": 20 }, "end": { "line": 99, "column": null } }, - "56": { "start": { "line": 94, "column": 37 }, "end": { "line": 94, "column": null } }, - "57": { "start": { "line": 95, "column": 24 }, "end": { "line": 97, "column": null } }, - "58": { "start": { "line": 96, "column": 28 }, "end": { "line": 96, "column": null } }, - "59": { "start": { "line": 98, "column": 24 }, "end": { "line": 98, "column": null } }, - "60": { "start": { "line": 100, "column": 20 }, "end": { "line": 100, "column": null } }, - "61": { "start": { "line": 102, "column": 12 }, "end": { "line": 117, "column": null } }, - "62": { "start": { "line": 103, "column": 16 }, "end": { "line": 109, "column": null } }, - "63": { "start": { "line": 104, "column": 38 }, "end": { "line": 104, "column": null } }, - "64": { "start": { "line": 105, "column": 20 }, "end": { "line": 107, "column": null } }, - "65": { "start": { "line": 106, "column": 24 }, "end": { "line": 106, "column": null } }, - "66": { "start": { "line": 108, "column": 20 }, "end": { "line": 108, "column": null } }, - "67": { "start": { "line": 110, "column": 12 }, "end": { "line": 117, "column": null } }, - "68": { "start": { "line": 111, "column": 16 }, "end": { "line": 116, "column": null } }, - "69": { "start": { "line": 112, "column": 20 }, "end": { "line": 114, "column": null } }, - "70": { "start": { "line": 113, "column": 24 }, "end": { "line": 113, "column": null } }, - "71": { "start": { "line": 115, "column": 20 }, "end": { "line": 115, "column": null } }, - "72": { "start": { "line": 120, "column": 8 }, "end": { "line": 120, "column": null } }, - "73": { "start": { "line": 121, "column": 8 }, "end": { "line": 121, "column": null } }, - "74": { "start": { "line": 121, "column": 21 }, "end": { "line": 121, "column": null } }, - "75": { "start": { "line": 124, "column": 25 }, "end": { "line": 129, "column": null } }, - "76": { "start": { "line": 125, "column": 24 }, "end": { "line": 125, "column": null } }, - "77": { "start": { "line": 126, "column": 8 }, "end": { "line": 128, "column": null } }, - "78": { "start": { "line": 127, "column": 12 }, "end": { "line": 127, "column": null } }, - "79": { "start": { "line": 131, "column": 23 }, "end": { "line": 141, "column": null } }, - "80": { "start": { "line": 132, "column": 28 }, "end": { "line": 132, "column": null } }, - "81": { "start": { "line": 134, "column": 8 }, "end": { "line": 134, "column": null } }, - "82": { "start": { "line": 134, "column": 32 }, "end": { "line": 134, "column": 92 } }, - "83": { "start": { "line": 134, "column": 54 }, "end": { "line": 134, "column": 91 } }, - "84": { "start": { "line": 136, "column": 8 }, "end": { "line": 140, "column": null } }, - "85": { "start": { "line": 140, "column": 26 }, "end": { "line": 140, "column": 67 } }, - "86": { "start": { "line": 143, "column": 23 }, "end": { "line": 153, "column": null } }, - "87": { "start": { "line": 144, "column": 28 }, "end": { "line": 144, "column": null } }, - "88": { "start": { "line": 146, "column": 8 }, "end": { "line": 146, "column": null } }, - "89": { "start": { "line": 146, "column": 32 }, "end": { "line": 146, "column": 92 } }, - "90": { "start": { "line": 146, "column": 54 }, "end": { "line": 146, "column": 91 } }, - "91": { "start": { "line": 148, "column": 8 }, "end": { "line": 152, "column": null } }, - "92": { "start": { "line": 152, "column": 26 }, "end": { "line": 152, "column": 69 } }, - "93": { "start": { "line": 155, "column": 4 }, "end": { "line": 191, "column": null } }, - "94": { "start": { "line": 156, "column": 25 }, "end": { "line": 180, "column": null } }, - "95": { "start": { "line": 158, "column": 16 }, "end": { "line": 177, "column": null } }, - "96": { "start": { "line": 160, "column": 20 }, "end": { "line": 165, "column": null } }, - "97": { "start": { "line": 161, "column": 24 }, "end": { "line": 163, "column": null } }, - "98": { "start": { "line": 162, "column": 28 }, "end": { "line": 162, "column": null } }, - "99": { "start": { "line": 164, "column": 24 }, "end": { "line": 164, "column": null } }, - "100": { "start": { "line": 168, "column": 20 }, "end": { "line": 176, "column": null } }, - "101": { "start": { "line": 169, "column": 38 }, "end": { "line": 169, "column": null } }, - "102": { "start": { "line": 170, "column": 24 }, "end": { "line": 175, "column": null } }, - "103": { "start": { "line": 171, "column": 41 }, "end": { "line": 171, "column": null } }, - "104": { "start": { "line": 172, "column": 28 }, "end": { "line": 174, "column": null } }, - "105": { "start": { "line": 173, "column": 32 }, "end": { "line": 173, "column": null } }, - "106": { "start": { "line": 182, "column": 8 }, "end": { "line": 185, "column": null } }, - "107": { "start": { "line": 183, "column": 23 }, "end": { "line": 183, "column": null } }, - "108": { "start": { "line": 184, "column": 12 }, "end": { "line": 184, "column": null } }, - "109": { "start": { "line": 184, "column": 20 }, "end": { "line": 184, "column": null } }, - "110": { "start": { "line": 187, "column": 25 }, "end": { "line": 187, "column": null } }, - "111": { "start": { "line": 188, "column": 8 }, "end": { "line": 188, "column": null } }, - "112": { "start": { "line": 188, "column": 22 }, "end": { "line": 188, "column": null } }, - "113": { "start": { "line": 190, "column": 8 }, "end": { "line": 190, "column": null } }, - "114": { "start": { "line": 190, "column": 21 }, "end": { "line": 190, "column": null } }, - "115": { "start": { "line": 193, "column": 4 }, "end": { "line": 193, "column": null } }, - "116": { "start": { "line": 193, "column": 17 }, "end": { "line": 193, "column": null } }, - "117": { "start": { "line": 194, "column": 4 }, "end": { "line": 194, "column": null } }, - "118": { "start": { "line": 194, "column": 15 }, "end": { "line": 194, "column": null } }, - "119": { "start": { "line": 197, "column": 4 }, "end": { "line": 221, "column": null } }, - "120": { "start": { "line": 204, "column": 24 }, "end": { "line": 212, "column": null } }, - "121": { "start": { "line": 209, "column": 43 }, "end": { "line": 209, "column": null } } - }, - "fnMap": { - "0": { - "name": "FeedItems", - "decl": { "start": { "line": 7, "column": 24 }, "end": { "line": 7, "column": 36 } }, - "loc": { "start": { "line": 7, "column": 36 }, "end": { "line": 223, "column": null } }, - "line": 7 - }, - "1": { - "name": "(anonymous_1)", - "decl": { "start": { "line": 18, "column": 23 }, "end": { "line": 18, "column": 24 } }, - "loc": { "start": { "line": 18, "column": 43 }, "end": { "line": 78, "column": null } }, - "line": 18 - }, - "2": { - "name": "(anonymous_2)", - "decl": { "start": { "line": 57, "column": 18 }, "end": { "line": 57, "column": 19 } }, - "loc": { "start": { "line": 57, "column": 27 }, "end": { "line": 62, "column": 13 } }, - "line": 57 - }, - "3": { - "name": "(anonymous_3)", - "decl": { "start": { "line": 63, "column": 18 }, "end": { "line": 63, "column": 19 } }, - "loc": { "start": { "line": 63, "column": 28 }, "end": { "line": 72, "column": 13 } }, - "line": 63 - }, - "4": { - "name": "(anonymous_4)", - "decl": { "start": { "line": 65, "column": 29 }, "end": { "line": 65, "column": 30 } }, - "loc": { "start": { "line": 65, "column": 39 }, "end": { "line": 65, "column": 57 } }, - "line": 65 - }, - "5": { - "name": "(anonymous_5)", - "decl": { "start": { "line": 73, "column": 19 }, "end": { "line": 73, "column": 20 } }, - "loc": { "start": { "line": 73, "column": 28 }, "end": { "line": 77, "column": 13 } }, - "line": 73 - }, - "6": { - "name": "(anonymous_6)", - "decl": { "start": { "line": 80, "column": 14 }, "end": { "line": 80, "column": 20 } }, - "loc": { "start": { "line": 80, "column": 20 }, "end": { "line": 82, "column": 7 } }, - "line": 80 - }, - "7": { - "name": "(anonymous_7)", - "decl": { "start": { "line": 86, "column": 14 }, "end": { "line": 86, "column": 20 } }, - "loc": { "start": { "line": 86, "column": 20 }, "end": { "line": 122, "column": 7 } }, - "line": 86 - }, - "8": { - "name": "(anonymous_8)", - "decl": { "start": { "line": 87, "column": 30 }, "end": { "line": 87, "column": 31 } }, - "loc": { "start": { "line": 87, "column": 52 }, "end": { "line": 118, "column": null } }, - "line": 87 - }, - "9": { - "name": "(anonymous_9)", - "decl": { "start": { "line": 91, "column": 33 }, "end": { "line": 91, "column": 34 } }, - "loc": { "start": { "line": 91, "column": 43 }, "end": { "line": 101, "column": 17 } }, - "line": 91 - }, - "10": { - "name": "(anonymous_10)", - "decl": { "start": { "line": 103, "column": 33 }, "end": { "line": 103, "column": 34 } }, - "loc": { "start": { "line": 103, "column": 43 }, "end": { "line": 109, "column": 17 } }, - "line": 103 - }, - "11": { - "name": "(anonymous_11)", - "decl": { "start": { "line": 111, "column": 33 }, "end": { "line": 111, "column": 34 } }, - "loc": { "start": { "line": 111, "column": 51 }, "end": { "line": 116, "column": 17 } }, - "line": 111 - }, - "12": { - "name": "(anonymous_12)", - "decl": { "start": { "line": 121, "column": 15 }, "end": { "line": 121, "column": 21 } }, - "loc": { "start": { "line": 121, "column": 21 }, "end": { "line": 121, "column": null } }, - "line": 121 - }, - "13": { - "name": "(anonymous_13)", - "decl": { "start": { "line": 124, "column": 25 }, "end": { "line": 124, "column": 26 } }, - "loc": { "start": { "line": 124, "column": 44 }, "end": { "line": 129, "column": null } }, - "line": 124 - }, - "14": { - "name": "(anonymous_14)", - "decl": { "start": { "line": 131, "column": 23 }, "end": { "line": 131, "column": 24 } }, - "loc": { "start": { "line": 131, "column": 39 }, "end": { "line": 141, "column": null } }, - "line": 131 - }, - "15": { - "name": "(anonymous_15)", - "decl": { "start": { "line": 134, "column": 17 }, "end": { "line": 134, "column": 18 } }, - "loc": { "start": { "line": 134, "column": 32 }, "end": { "line": 134, "column": 92 } }, - "line": 134 - }, - "16": { - "name": "(anonymous_16)", - "decl": { "start": { "line": 134, "column": 46 }, "end": { "line": 134, "column": 47 } }, - "loc": { "start": { "line": 134, "column": 54 }, "end": { "line": 134, "column": 91 } }, - "line": 134 - }, - "17": { - "name": "(anonymous_17)", - "decl": { "start": { "line": 140, "column": 17 }, "end": { "line": 140, "column": 18 } }, - "loc": { "start": { "line": 140, "column": 26 }, "end": { "line": 140, "column": 67 } }, - "line": 140 - }, - "18": { - "name": "(anonymous_18)", - "decl": { "start": { "line": 143, "column": 23 }, "end": { "line": 143, "column": 24 } }, - "loc": { "start": { "line": 143, "column": 39 }, "end": { "line": 153, "column": null } }, - "line": 143 - }, - "19": { - "name": "(anonymous_19)", - "decl": { "start": { "line": 146, "column": 17 }, "end": { "line": 146, "column": 18 } }, - "loc": { "start": { "line": 146, "column": 32 }, "end": { "line": 146, "column": 92 } }, - "line": 146 - }, - "20": { - "name": "(anonymous_20)", - "decl": { "start": { "line": 146, "column": 46 }, "end": { "line": 146, "column": 47 } }, - "loc": { "start": { "line": 146, "column": 54 }, "end": { "line": 146, "column": 91 } }, - "line": 146 - }, - "21": { - "name": "(anonymous_21)", - "decl": { "start": { "line": 152, "column": 17 }, "end": { "line": 152, "column": 18 } }, - "loc": { "start": { "line": 152, "column": 26 }, "end": { "line": 152, "column": 69 } }, - "line": 152 - }, - "22": { - "name": "(anonymous_22)", - "decl": { "start": { "line": 155, "column": 14 }, "end": { "line": 155, "column": 20 } }, - "loc": { "start": { "line": 155, "column": 20 }, "end": { "line": 191, "column": 7 } }, - "line": 155 - }, - "23": { - "name": "(anonymous_23)", - "decl": { "start": { "line": 157, "column": 12 }, "end": { "line": 157, "column": 13 } }, - "loc": { "start": { "line": 157, "column": 25 }, "end": { "line": 178, "column": null } }, - "line": 157 - }, - "24": { - "name": "(anonymous_24)", - "decl": { "start": { "line": 158, "column": 32 }, "end": { "line": 158, "column": 33 } }, - "loc": { "start": { "line": 158, "column": 43 }, "end": { "line": 177, "column": 17 } }, - "line": 158 - }, - "25": { - "name": "(anonymous_25)", - "decl": { "start": { "line": 182, "column": 22 }, "end": { "line": 182, "column": 23 } }, - "loc": { "start": { "line": 182, "column": 36 }, "end": { "line": 185, "column": 9 } }, - "line": 182 - }, - "26": { - "name": "(anonymous_26)", - "decl": { "start": { "line": 190, "column": 15 }, "end": { "line": 190, "column": 21 } }, - "loc": { "start": { "line": 190, "column": 21 }, "end": { "line": 190, "column": null } }, - "line": 190 - }, - "27": { - "name": "(anonymous_27)", - "decl": { "start": { "line": 203, "column": 31 }, "end": { "line": 203, "column": 32 } }, - "loc": { "start": { "line": 204, "column": 24 }, "end": { "line": 212, "column": null } }, - "line": 204 - }, - "28": { - "name": "(anonymous_28)", - "decl": { "start": { "line": 209, "column": 37 }, "end": { "line": 209, "column": 43 } }, - "loc": { "start": { "line": 209, "column": 43 }, "end": { "line": 209, "column": null } }, - "line": 209 - } - }, - "branchMap": { - "0": { - "loc": { "start": { "line": 10, "column": 21 }, "end": { "line": 10, "column": null } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 10, "column": 21 }, "end": { "line": 10, "column": 51 } }, - { "start": { "line": 10, "column": 51 }, "end": { "line": 10, "column": null } } - ], - "line": 10 - }, - "1": { - "loc": { "start": { "line": 19, "column": 8 }, "end": { "line": 24, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 19, "column": 8 }, "end": { "line": 24, "column": null } }, - { "start": { "line": 21, "column": 15 }, "end": { "line": 24, "column": null } } - ], - "line": 19 - }, - "2": { - "loc": { "start": { "line": 30, "column": 8 }, "end": { "line": 34, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 30, "column": 8 }, "end": { "line": 34, "column": null } }, - { "start": { "line": 32, "column": 8 }, "end": { "line": 34, "column": null } } - ], - "line": 30 - }, - "3": { - "loc": { "start": { "line": 32, "column": 8 }, "end": { "line": 34, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 32, "column": 8 }, "end": { "line": 34, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 32 - }, - "4": { - "loc": { "start": { "line": 36, "column": 8 }, "end": { "line": 38, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 36, "column": 8 }, "end": { "line": 38, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 36 - }, - "5": { - "loc": { "start": { "line": 41, "column": 8 }, "end": { "line": 49, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 41, "column": 8 }, "end": { "line": 49, "column": null } }, - { "start": { "line": 43, "column": 8 }, "end": { "line": 49, "column": null } } - ], - "line": 41 - }, - "6": { - "loc": { "start": { "line": 43, "column": 8 }, "end": { "line": 49, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 43, "column": 8 }, "end": { "line": 49, "column": null } }, - { "start": { "line": 46, "column": 15 }, "end": { "line": 49, "column": null } } - ], - "line": 43 - }, - "7": { - "loc": { "start": { "line": 52, "column": 8 }, "end": { "line": 54, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 52, "column": 8 }, "end": { "line": 54, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 52 - }, - "8": { - "loc": { "start": { "line": 58, "column": 16 }, "end": { "line": 60, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 58, "column": 16 }, "end": { "line": 60, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 58 - }, - "9": { - "loc": { "start": { "line": 64, "column": 16 }, "end": { "line": 68, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 64, "column": 16 }, "end": { "line": 68, "column": null } }, - { "start": { "line": 66, "column": 23 }, "end": { "line": 68, "column": null } } - ], - "line": 64 - }, - "10": { - "loc": { "start": { "line": 88, "column": 12 }, "end": { "line": 88, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 88, "column": 12 }, "end": { "line": 88, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 88 - }, - "11": { - "loc": { "start": { "line": 90, "column": 12 }, "end": { "line": 117, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 90, "column": 12 }, "end": { "line": 117, "column": null } }, - { "start": { "line": 102, "column": 12 }, "end": { "line": 117, "column": null } } - ], - "line": 90 - }, - "12": { - "loc": { "start": { "line": 93, "column": 20 }, "end": { "line": 99, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 93, "column": 20 }, "end": { "line": 99, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 93 - }, - "13": { - "loc": { "start": { "line": 95, "column": 24 }, "end": { "line": 97, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 95, "column": 24 }, "end": { "line": 97, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 95 - }, - "14": { - "loc": { "start": { "line": 102, "column": 12 }, "end": { "line": 117, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 102, "column": 12 }, "end": { "line": 117, "column": null } }, - { "start": { "line": 110, "column": 12 }, "end": { "line": 117, "column": null } } - ], - "line": 102 - }, - "15": { - "loc": { "start": { "line": 105, "column": 20 }, "end": { "line": 107, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 105, "column": 20 }, "end": { "line": 107, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 105 - }, - "16": { - "loc": { "start": { "line": 110, "column": 12 }, "end": { "line": 117, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 110, "column": 12 }, "end": { "line": 117, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 110 - }, - "17": { - "loc": { "start": { "line": 112, "column": 20 }, "end": { "line": 114, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 112, "column": 20 }, "end": { "line": 114, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 112 - }, - "18": { - "loc": { "start": { "line": 112, "column": 24 }, "end": { "line": 112, "column": 74 } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 112, "column": 24 }, "end": { "line": 112, "column": 45 } }, - { "start": { "line": 112, "column": 45 }, "end": { "line": 112, "column": 74 } } - ], - "line": 112 - }, - "19": { - "loc": { "start": { "line": 126, "column": 8 }, "end": { "line": 128, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 126, "column": 8 }, "end": { "line": 128, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 126 - }, - "20": { - "loc": { "start": { "line": 134, "column": 54 }, "end": { "line": 134, "column": 91 } }, - "type": "cond-expr", - "locations": [ - { "start": { "line": 134, "column": 75 }, "end": { "line": 134, "column": 89 } }, - { "start": { "line": 134, "column": 89 }, "end": { "line": 134, "column": 91 } } - ], - "line": 134 - }, - "21": { - "loc": { "start": { "line": 146, "column": 54 }, "end": { "line": 146, "column": 91 } }, - "type": "cond-expr", - "locations": [ - { "start": { "line": 146, "column": 75 }, "end": { "line": 146, "column": 89 } }, - { "start": { "line": 146, "column": 89 }, "end": { "line": 146, "column": 91 } } - ], - "line": 146 - }, - "22": { - "loc": { "start": { "line": 160, "column": 20 }, "end": { "line": 165, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 160, "column": 20 }, "end": { "line": 165, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 160 - }, - "23": { - "loc": { "start": { "line": 161, "column": 24 }, "end": { "line": 163, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 161, "column": 24 }, "end": { "line": 163, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 161 - }, - "24": { - "loc": { "start": { "line": 161, "column": 28 }, "end": { "line": 161, "column": 97 } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 161, "column": 28 }, "end": { "line": 161, "column": 52 } }, - { "start": { "line": 161, "column": 52 }, "end": { "line": 161, "column": 68 } }, - { "start": { "line": 161, "column": 68 }, "end": { "line": 161, "column": 79 } }, - { "start": { "line": 161, "column": 79 }, "end": { "line": 161, "column": 97 } } - ], - "line": 161 - }, - "25": { - "loc": { "start": { "line": 168, "column": 20 }, "end": { "line": 176, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 168, "column": 20 }, "end": { "line": 176, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 168 - }, - "26": { - "loc": { "start": { "line": 168, "column": 24 }, "end": { "line": 168, "column": 83 } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 168, "column": 24 }, "end": { "line": 168, "column": 49 } }, - { "start": { "line": 168, "column": 49 }, "end": { "line": 168, "column": 83 } } - ], - "line": 168 - }, - "27": { - "loc": { "start": { "line": 170, "column": 24 }, "end": { "line": 175, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 170, "column": 24 }, "end": { "line": 175, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 170 - }, - "28": { - "loc": { "start": { "line": 170, "column": 28 }, "end": { "line": 170, "column": 81 } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 170, "column": 28 }, "end": { "line": 170, "column": 45 } }, - { "start": { "line": 170, "column": 45 }, "end": { "line": 170, "column": 59 } }, - { "start": { "line": 170, "column": 59 }, "end": { "line": 170, "column": 81 } } - ], - "line": 170 - }, - "29": { - "loc": { "start": { "line": 172, "column": 28 }, "end": { "line": 174, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 172, "column": 28 }, "end": { "line": 174, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 172 - }, - "30": { - "loc": { "start": { "line": 184, "column": 12 }, "end": { "line": 184, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 184, "column": 12 }, "end": { "line": 184, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 184 - }, - "31": { - "loc": { "start": { "line": 188, "column": 8 }, "end": { "line": 188, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 188, "column": 8 }, "end": { "line": 188, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 188 - }, - "32": { - "loc": { "start": { "line": 193, "column": 4 }, "end": { "line": 193, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 193, "column": 4 }, "end": { "line": 193, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 193 - }, - "33": { - "loc": { "start": { "line": 194, "column": 4 }, "end": { "line": 194, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 194, "column": 4 }, "end": { "line": 194, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 194 - }, - "34": { - "loc": { "start": { "line": 199, "column": 13 }, "end": { "line": 219, "column": null } }, - "type": "cond-expr", - "locations": [ - { "start": { "line": 200, "column": 16 }, "end": { "line": 200, "column": null } }, - { "start": { "line": 202, "column": 16 }, "end": { "line": 219, "column": null } } - ], - "line": 199 - }, - "35": { - "loc": { "start": { "line": 208, "column": 39 }, "end": { "line": 208, "column": null } }, - "type": "cond-expr", - "locations": [ - { "start": { "line": 208, "column": 65 }, "end": { "line": 208, "column": 93 } }, - { "start": { "line": 208, "column": 93 }, "end": { "line": 208, "column": null } } - ], - "line": 208 - }, - "36": { - "loc": { "start": { "line": 214, "column": 21 }, "end": { "line": 217, "column": null } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 214, "column": 21 }, "end": { "line": 214, "column": null } }, - { "start": { "line": 215, "column": 24 }, "end": { "line": 217, "column": null } } - ], - "line": 214 - }, - "37": { - "loc": { "start": { "line": 216, "column": 29 }, "end": { "line": 216, "column": null } }, - "type": "cond-expr", - "locations": [ - { "start": { "line": 216, "column": 43 }, "end": { "line": 216, "column": 63 } }, - { "start": { "line": 216, "column": 63 }, "end": { "line": 216, "column": null } } - ], - "line": 216 - } - }, - "s": { - "0": 27, - "1": 27, - "2": 27, - "3": 27, - "4": 27, - "5": 27, - "6": 27, - "7": 27, - "8": 27, - "9": 8, - "10": 1, - "11": 7, - "12": 7, - "13": 8, - "14": 8, - "15": 8, - "16": 8, - "17": 2, - "18": 6, - "19": 1, - "20": 8, - "21": 1, - "22": 8, - "23": 0, - "24": 8, - "25": 0, - "26": 0, - "27": 8, - "28": 8, - "29": 8, - "30": 8, - "31": 8, - "32": 7, - "33": 0, - "34": 7, - "35": 6, - "36": 1, - "37": 1, - "38": 5, - "39": 6, - "40": 6, - "41": 6, - "42": 1, - "43": 1, - "44": 1, - "45": 27, - "46": 7, - "47": 27, - "48": 27, - "49": 23, - "50": 3, - "51": 0, - "52": 3, - "53": 2, - "54": 2, - "55": 2, - "56": 2, - "57": 2, - "58": 1, - "59": 2, - "60": 2, - "61": 1, - "62": 0, - "63": 0, - "64": 0, - "65": 0, - "66": 0, - "67": 1, - "68": 1, - "69": 1, - "70": 1, - "71": 1, - "72": 23, - "73": 23, - "74": 23, - "75": 27, - "76": 2, - "77": 2, - "78": 2, - "79": 27, - "80": 2, - "81": 2, - "82": 2, - "83": 3, - "84": 2, - "85": 0, - "86": 27, - "87": 1, - "88": 1, - "89": 1, - "90": 2, - "91": 1, - "92": 0, - "93": 27, - "94": 24, - "95": 2, - "96": 2, - "97": 1, - "98": 1, - "99": 1, - "100": 1, - "101": 1, - "102": 1, - "103": 1, - "104": 1, - "105": 1, - "106": 24, - "107": 15, - "108": 15, - "109": 15, - "110": 24, - "111": 24, - "112": 10, - "113": 24, - "114": 24, - "115": 27, - "116": 13, - "117": 14, - "118": 14, - "119": 13, - "120": 21, - "121": 0 - }, - "f": { - "0": 27, - "1": 8, - "2": 7, - "3": 6, - "4": 1, - "5": 1, - "6": 7, - "7": 23, - "8": 3, - "9": 2, - "10": 0, - "11": 1, - "12": 23, - "13": 2, - "14": 2, - "15": 2, - "16": 3, - "17": 0, - "18": 1, - "19": 1, - "20": 2, - "21": 0, - "22": 24, - "23": 2, - "24": 2, - "25": 15, - "26": 24, - "27": 21, - "28": 0 - }, - "b": { - "0": [27, 27], - "1": [1, 7], - "2": [2, 6], - "3": [1, 5], - "4": [1, 7], - "5": [0, 8], - "6": [0, 8], - "7": [8, 0], - "8": [0, 7], - "9": [1, 5], - "10": [0, 3], - "11": [2, 1], - "12": [2, 0], - "13": [1, 1], - "14": [0, 1], - "15": [0, 0], - "16": [1, 0], - "17": [1, 0], - "18": [1, 1], - "19": [2, 0], - "20": [2, 1], - "21": [1, 1], - "22": [1, 1], - "23": [1, 0], - "24": [1, 1, 1, 1], - "25": [1, 0], - "26": [1, 1], - "27": [1, 0], - "28": [1, 1, 1], - "29": [1, 0], - "30": [15, 0], - "31": [10, 14], - "32": [13, 14], - "33": [1, 13], - "34": [0, 13], - "35": [5, 16], - "36": [13, 13], - "37": [1, 12] - }, - "meta": { - "lastBranch": 38, - "lastFunction": 29, - "lastStatement": 122, - "seen": { - "f:7:24:7:36": 0, - "s:8:28:8:Infinity": 0, - "s:9:23:9:Infinity": 1, - "s:10:21:10:Infinity": 2, - "b:10:21:10:51:10:51:10:Infinity": 0, - "s:12:26:12:Infinity": 3, - "s:13:30:13:Infinity": 4, - "s:14:38:14:Infinity": 5, - "s:15:30:15:Infinity": 6, - "s:16:26:16:Infinity": 7, - "s:18:23:78:Infinity": 8, - "f:18:23:18:24": 1, - "b:19:8:24:Infinity:21:15:24:Infinity": 1, - "s:19:8:24:Infinity": 9, - "s:20:12:20:Infinity": 10, - "s:22:12:22:Infinity": 11, - "s:23:12:23:Infinity": 12, - "s:25:8:25:Infinity": 13, - "s:27:18:27:Infinity": 14, - "s:28:23:28:Infinity": 15, - "b:30:8:34:Infinity:32:8:34:Infinity": 2, - "s:30:8:34:Infinity": 16, - "s:31:12:31:Infinity": 17, - "b:32:8:34:Infinity:undefined:undefined:undefined:undefined": 3, - "s:32:8:34:Infinity": 18, - "s:33:12:33:Infinity": 19, - "b:36:8:38:Infinity:undefined:undefined:undefined:undefined": 4, - "s:36:8:38:Infinity": 20, - "s:37:12:37:Infinity": 21, - "b:41:8:49:Infinity:43:8:49:Infinity": 5, - "s:41:8:49:Infinity": 22, - "s:42:12:42:Infinity": 23, - "b:43:8:49:Infinity:46:15:49:Infinity": 6, - "s:43:8:49:Infinity": 24, - "s:44:12:44:Infinity": 25, - "s:45:12:45:Infinity": 26, - "s:48:12:48:Infinity": 27, - "s:51:28:51:Infinity": 28, - "b:52:8:54:Infinity:undefined:undefined:undefined:undefined": 7, - "s:52:8:54:Infinity": 29, - "s:53:12:53:Infinity": 30, - "s:56:8:77:Infinity": 31, - "f:57:18:57:19": 2, - "b:58:16:60:Infinity:undefined:undefined:undefined:undefined": 8, - "s:58:16:60:Infinity": 32, - "s:59:20:59:Infinity": 33, - "s:61:16:61:Infinity": 34, - "f:63:18:63:19": 3, - "b:64:16:68:Infinity:66:23:68:Infinity": 9, - "s:64:16:68:Infinity": 35, - "s:65:20:65:Infinity": 36, - "f:65:29:65:30": 4, - "s:65:39:65:57": 37, - "s:67:20:67:Infinity": 38, - "s:69:16:69:Infinity": 39, - "s:70:16:70:Infinity": 40, - "s:71:16:71:Infinity": 41, - "f:73:19:73:20": 5, - "s:74:16:74:Infinity": 42, - "s:75:16:75:Infinity": 43, - "s:76:16:76:Infinity": 44, - "s:80:4:82:Infinity": 45, - "f:80:14:80:20": 6, - "s:81:8:81:Infinity": 46, - "s:84:42:84:Infinity": 47, - "s:86:4:122:Infinity": 48, - "f:86:14:86:20": 7, - "s:87:30:118:Infinity": 49, - "f:87:30:87:31": 8, - "b:88:12:88:Infinity:undefined:undefined:undefined:undefined": 10, - "s:88:12:88:Infinity": 50, - "s:88:36:88:Infinity": 51, - "b:90:12:117:Infinity:102:12:117:Infinity": 11, - "s:90:12:117:Infinity": 52, - "s:91:16:101:Infinity": 53, - "f:91:33:91:34": 9, - "s:92:38:92:Infinity": 54, - "b:93:20:99:Infinity:undefined:undefined:undefined:undefined": 12, - "s:93:20:99:Infinity": 55, - "s:94:37:94:Infinity": 56, - "b:95:24:97:Infinity:undefined:undefined:undefined:undefined": 13, - "s:95:24:97:Infinity": 57, - "s:96:28:96:Infinity": 58, - "s:98:24:98:Infinity": 59, - "s:100:20:100:Infinity": 60, - "b:102:12:117:Infinity:110:12:117:Infinity": 14, - "s:102:12:117:Infinity": 61, - "s:103:16:109:Infinity": 62, - "f:103:33:103:34": 10, - "s:104:38:104:Infinity": 63, - "b:105:20:107:Infinity:undefined:undefined:undefined:undefined": 15, - "s:105:20:107:Infinity": 64, - "s:106:24:106:Infinity": 65, - "s:108:20:108:Infinity": 66, - "b:110:12:117:Infinity:undefined:undefined:undefined:undefined": 16, - "s:110:12:117:Infinity": 67, - "s:111:16:116:Infinity": 68, - "f:111:33:111:34": 11, - "b:112:20:114:Infinity:undefined:undefined:undefined:undefined": 17, - "s:112:20:114:Infinity": 69, - "b:112:24:112:45:112:45:112:74": 18, - "s:113:24:113:Infinity": 70, - "s:115:20:115:Infinity": 71, - "s:120:8:120:Infinity": 72, - "s:121:8:121:Infinity": 73, - "f:121:15:121:21": 12, - "s:121:21:121:Infinity": 74, - "s:124:25:129:Infinity": 75, - "f:124:25:124:26": 13, - "s:125:24:125:Infinity": 76, - "b:126:8:128:Infinity:undefined:undefined:undefined:undefined": 19, - "s:126:8:128:Infinity": 77, - "s:127:12:127:Infinity": 78, - "s:131:23:141:Infinity": 79, - "f:131:23:131:24": 14, - "s:132:28:132:Infinity": 80, - "s:134:8:134:Infinity": 81, - "f:134:17:134:18": 15, - "s:134:32:134:92": 82, - "f:134:46:134:47": 16, - "s:134:54:134:91": 83, - "b:134:75:134:89:134:89:134:91": 20, - "s:136:8:140:Infinity": 84, - "f:140:17:140:18": 17, - "s:140:26:140:67": 85, - "s:143:23:153:Infinity": 86, - "f:143:23:143:24": 18, - "s:144:28:144:Infinity": 87, - "s:146:8:146:Infinity": 88, - "f:146:17:146:18": 19, - "s:146:32:146:92": 89, - "f:146:46:146:47": 20, - "s:146:54:146:91": 90, - "b:146:75:146:89:146:89:146:91": 21, - "s:148:8:152:Infinity": 91, - "f:152:17:152:18": 21, - "s:152:26:152:69": 92, - "s:155:4:191:Infinity": 93, - "f:155:14:155:20": 22, - "s:156:25:180:Infinity": 94, - "f:157:12:157:13": 23, - "s:158:16:177:Infinity": 95, - "f:158:32:158:33": 24, - "b:160:20:165:Infinity:undefined:undefined:undefined:undefined": 22, - "s:160:20:165:Infinity": 96, - "b:161:24:163:Infinity:undefined:undefined:undefined:undefined": 23, - "s:161:24:163:Infinity": 97, - "b:161:28:161:52:161:52:161:68:161:68:161:79:161:79:161:97": 24, - "s:162:28:162:Infinity": 98, - "s:164:24:164:Infinity": 99, - "b:168:20:176:Infinity:undefined:undefined:undefined:undefined": 25, - "s:168:20:176:Infinity": 100, - "b:168:24:168:49:168:49:168:83": 26, - "s:169:38:169:Infinity": 101, - "b:170:24:175:Infinity:undefined:undefined:undefined:undefined": 27, - "s:170:24:175:Infinity": 102, - "b:170:28:170:45:170:45:170:59:170:59:170:81": 28, - "s:171:41:171:Infinity": 103, - "b:172:28:174:Infinity:undefined:undefined:undefined:undefined": 29, - "s:172:28:174:Infinity": 104, - "s:173:32:173:Infinity": 105, - "s:182:8:185:Infinity": 106, - "f:182:22:182:23": 25, - "s:183:23:183:Infinity": 107, - "b:184:12:184:Infinity:undefined:undefined:undefined:undefined": 30, - "s:184:12:184:Infinity": 108, - "s:184:20:184:Infinity": 109, - "s:187:25:187:Infinity": 110, - "b:188:8:188:Infinity:undefined:undefined:undefined:undefined": 31, - "s:188:8:188:Infinity": 111, - "s:188:22:188:Infinity": 112, - "s:190:8:190:Infinity": 113, - "f:190:15:190:21": 26, - "s:190:21:190:Infinity": 114, - "b:193:4:193:Infinity:undefined:undefined:undefined:undefined": 32, - "s:193:4:193:Infinity": 115, - "s:193:17:193:Infinity": 116, - "b:194:4:194:Infinity:undefined:undefined:undefined:undefined": 33, - "s:194:4:194:Infinity": 117, - "s:194:15:194:Infinity": 118, - "s:197:4:221:Infinity": 119, - "b:200:16:200:Infinity:202:16:219:Infinity": 34, - "f:203:31:203:32": 27, - "s:204:24:212:Infinity": 120, - "b:208:65:208:93:208:93:208:Infinity": 35, - "f:209:37:209:43": 28, - "s:209:43:209:Infinity": 121, - "b:214:21:214:Infinity:215:24:217:Infinity": 36, - "b:216:43:216:63:216:63:216:Infinity": 37 - } - } - }, - "/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedList.css": { - "path": "/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedList.css", - "statementMap": {}, - "fnMap": {}, - "branchMap": {}, - "s": {}, - "f": {}, - "b": {}, - "meta": { "lastBranch": 0, "lastFunction": 0, "lastStatement": 0, "seen": {} } - }, - "/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedList.tsx": { - "path": "/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedList.tsx", - "statementMap": { - "0": { "start": { "line": 7, "column": 26 }, "end": { "line": 7, "column": null } }, - "1": { "start": { "line": 8, "column": 24 }, "end": { "line": 8, "column": null } }, - "2": { "start": { "line": 9, "column": 30 }, "end": { "line": 9, "column": null } }, - "3": { "start": { "line": 10, "column": 26 }, "end": { "line": 10, "column": null } }, - "4": { "start": { "line": 12, "column": 4 }, "end": { "line": 32, "column": null } }, - "5": { "start": { "line": 13, "column": 8 }, "end": { "line": 31, "column": null } }, - "6": { "start": { "line": 15, "column": 16 }, "end": { "line": 15, "column": null } }, - "7": { "start": { "line": 15, "column": 29 }, "end": { "line": 15, "column": null } }, - "8": { "start": { "line": 16, "column": 16 }, "end": { "line": 16, "column": null } }, - "9": { "start": { "line": 19, "column": 16 }, "end": { "line": 19, "column": null } }, - "10": { "start": { "line": 19, "column": 29 }, "end": { "line": 19, "column": null } }, - "11": { "start": { "line": 20, "column": 16 }, "end": { "line": 20, "column": null } }, - "12": { "start": { "line": 24, "column": 16 }, "end": { "line": 24, "column": null } }, - "13": { "start": { "line": 25, "column": 16 }, "end": { "line": 25, "column": null } }, - "14": { "start": { "line": 26, "column": 16 }, "end": { "line": 26, "column": null } }, - "15": { "start": { "line": 29, "column": 16 }, "end": { "line": 29, "column": null } }, - "16": { "start": { "line": 30, "column": 16 }, "end": { "line": 30, "column": null } }, - "17": { "start": { "line": 34, "column": 4 }, "end": { "line": 34, "column": null } }, - "18": { "start": { "line": 34, "column": 17 }, "end": { "line": 34, "column": null } }, - "19": { "start": { "line": 35, "column": 4 }, "end": { "line": 35, "column": null } }, - "20": { "start": { "line": 35, "column": 15 }, "end": { "line": 35, "column": null } }, - "21": { "start": { "line": 37, "column": 4 }, "end": { "line": 78, "column": null } }, - "22": { "start": { "line": 53, "column": 28 }, "end": { "line": 58, "column": null } }, - "23": { "start": { "line": 69, "column": 28 }, "end": { "line": 73, "column": null } } - }, - "fnMap": { - "0": { - "name": "FeedList", - "decl": { "start": { "line": 6, "column": 24 }, "end": { "line": 6, "column": 35 } }, - "loc": { "start": { "line": 6, "column": 35 }, "end": { "line": 80, "column": null } }, - "line": 6 - }, - "1": { - "name": "(anonymous_1)", - "decl": { "start": { "line": 12, "column": 14 }, "end": { "line": 12, "column": 20 } }, - "loc": { "start": { "line": 12, "column": 20 }, "end": { "line": 32, "column": 7 } }, - "line": 12 - }, - "2": { - "name": "(anonymous_2)", - "decl": { "start": { "line": 14, "column": 37 }, "end": { "line": 14, "column": 44 } }, - "loc": { "start": { "line": 14, "column": 44 }, "end": { "line": 17, "column": 13 } }, - "line": 14 - }, - "3": { - "name": "(anonymous_3)", - "decl": { "start": { "line": 18, "column": 35 }, "end": { "line": 18, "column": 42 } }, - "loc": { "start": { "line": 18, "column": 42 }, "end": { "line": 21, "column": 13 } }, - "line": 18 - }, - "4": { - "name": "(anonymous_4)", - "decl": { "start": { "line": 23, "column": 18 }, "end": { "line": 23, "column": 19 } }, - "loc": { "start": { "line": 23, "column": 45 }, "end": { "line": 27, "column": 13 } }, - "line": 23 - }, - "5": { - "name": "(anonymous_5)", - "decl": { "start": { "line": 28, "column": 19 }, "end": { "line": 28, "column": 20 } }, - "loc": { "start": { "line": 28, "column": 28 }, "end": { "line": 31, "column": 13 } }, - "line": 28 - }, - "6": { - "name": "(anonymous_6)", - "decl": { "start": { "line": 52, "column": 35 }, "end": { "line": 52, "column": 36 } }, - "loc": { "start": { "line": 53, "column": 28 }, "end": { "line": 58, "column": null } }, - "line": 53 - }, - "7": { - "name": "(anonymous_7)", - "decl": { "start": { "line": 68, "column": 34 }, "end": { "line": 68, "column": 35 } }, - "loc": { "start": { "line": 69, "column": 28 }, "end": { "line": 73, "column": null } }, - "line": 69 - } - }, - "branchMap": { - "0": { - "loc": { "start": { "line": 15, "column": 16 }, "end": { "line": 15, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 15, "column": 16 }, "end": { "line": 15, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 15 - }, - "1": { - "loc": { "start": { "line": 19, "column": 16 }, "end": { "line": 19, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 19, "column": 16 }, "end": { "line": 19, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 19 - }, - "2": { - "loc": { "start": { "line": 34, "column": 4 }, "end": { "line": 34, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 34, "column": 4 }, "end": { "line": 34, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 34 - }, - "3": { - "loc": { "start": { "line": 35, "column": 4 }, "end": { "line": 35, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 35, "column": 4 }, "end": { "line": 35, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 35 - }, - "4": { - "loc": { "start": { "line": 48, "column": 17 }, "end": { "line": 60, "column": null } }, - "type": "cond-expr", - "locations": [ - { "start": { "line": 49, "column": 20 }, "end": { "line": 49, "column": null } }, - { "start": { "line": 51, "column": 20 }, "end": { "line": 60, "column": null } } - ], - "line": 48 - }, - "5": { - "loc": { "start": { "line": 55, "column": 37 }, "end": { "line": 55, "column": null } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 55, "column": 37 }, "end": { "line": 55, "column": 51 } }, - { "start": { "line": 55, "column": 51 }, "end": { "line": 55, "column": null } } - ], - "line": 55 - }, - "6": { - "loc": { "start": { "line": 57, "column": 33 }, "end": { "line": 57, "column": null } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 57, "column": 33 }, "end": { "line": 57, "column": 50 } }, - { "start": { "line": 57, "column": 50 }, "end": { "line": 57, "column": null } } - ], - "line": 57 - }, - "7": { - "loc": { "start": { "line": 64, "column": 13 }, "end": { "line": 76, "column": null } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 64, "column": 13 }, "end": { "line": 64, "column": 21 } }, - { "start": { "line": 64, "column": 21 }, "end": { "line": 64, "column": null } }, - { "start": { "line": 65, "column": 16 }, "end": { "line": 76, "column": null } } - ], - "line": 64 - } - }, - "s": { - "0": 11, - "1": 11, - "2": 11, - "3": 11, - "4": 11, - "5": 6, - "6": 4, - "7": 0, - "8": 4, - "9": 4, - "10": 0, - "11": 4, - "12": 4, - "13": 4, - "14": 4, - "15": 1, - "16": 1, - "17": 11, - "18": 6, - "19": 5, - "20": 5, - "21": 4, - "22": 3, - "23": 3 - }, - "f": { "0": 11, "1": 6, "2": 4, "3": 4, "4": 4, "5": 1, "6": 3, "7": 3 }, - "b": { - "0": [0, 4], - "1": [0, 4], - "2": [6, 5], - "3": [1, 4], - "4": [2, 2], - "5": [3, 0], - "6": [3, 3], - "7": [11, 4, 2] - }, - "meta": { - "lastBranch": 8, - "lastFunction": 8, - "lastStatement": 24, - "seen": { - "f:6:24:6:35": 0, - "s:7:26:7:Infinity": 0, - "s:8:24:8:Infinity": 1, - "s:9:30:9:Infinity": 2, - "s:10:26:10:Infinity": 3, - "s:12:4:32:Infinity": 4, - "f:12:14:12:20": 1, - "s:13:8:31:Infinity": 5, - "f:14:37:14:44": 2, - "b:15:16:15:Infinity:undefined:undefined:undefined:undefined": 0, - "s:15:16:15:Infinity": 6, - "s:15:29:15:Infinity": 7, - "s:16:16:16:Infinity": 8, - "f:18:35:18:42": 3, - "b:19:16:19:Infinity:undefined:undefined:undefined:undefined": 1, - "s:19:16:19:Infinity": 9, - "s:19:29:19:Infinity": 10, - "s:20:16:20:Infinity": 11, - "f:23:18:23:19": 4, - "s:24:16:24:Infinity": 12, - "s:25:16:25:Infinity": 13, - "s:26:16:26:Infinity": 14, - "f:28:19:28:20": 5, - "s:29:16:29:Infinity": 15, - "s:30:16:30:Infinity": 16, - "b:34:4:34:Infinity:undefined:undefined:undefined:undefined": 2, - "s:34:4:34:Infinity": 17, - "s:34:17:34:Infinity": 18, - "b:35:4:35:Infinity:undefined:undefined:undefined:undefined": 3, - "s:35:4:35:Infinity": 19, - "s:35:15:35:Infinity": 20, - "s:37:4:78:Infinity": 21, - "b:49:20:49:Infinity:51:20:60:Infinity": 4, - "f:52:35:52:36": 6, - "s:53:28:58:Infinity": 22, - "b:55:37:55:51:55:51:55:Infinity": 5, - "b:57:33:57:50:57:50:57:Infinity": 6, - "b:64:13:64:21:64:21:64:Infinity:65:16:76:Infinity": 7, - "f:68:34:68:35": 7, - "s:69:28:73:Infinity": 23 - } - } - }, - "/Users/adam/workspace/vibecode/neko/frontend/src/components/Login.css": { - "path": "/Users/adam/workspace/vibecode/neko/frontend/src/components/Login.css", - "statementMap": {}, - "fnMap": {}, - "branchMap": {}, - "s": {}, - "f": {}, - "b": {}, - "meta": { "lastBranch": 0, "lastFunction": 0, "lastStatement": 0, "seen": {} } - }, - "/Users/adam/workspace/vibecode/neko/frontend/src/components/Login.tsx": { - "path": "/Users/adam/workspace/vibecode/neko/frontend/src/components/Login.tsx", - "statementMap": { - "0": { "start": { "line": 6, "column": 32 }, "end": { "line": 6, "column": null } }, - "1": { "start": { "line": 7, "column": 26 }, "end": { "line": 7, "column": null } }, - "2": { "start": { "line": 8, "column": 10 }, "end": { "line": 8, "column": null } }, - "3": { "start": { "line": 10, "column": 25 }, "end": { "line": 33, "column": null } }, - "4": { "start": { "line": 11, "column": 8 }, "end": { "line": 11, "column": null } }, - "5": { "start": { "line": 12, "column": 8 }, "end": { "line": 12, "column": null } }, - "6": { "start": { "line": 14, "column": 8 }, "end": { "line": 32, "column": null } }, - "7": { "start": { "line": 16, "column": 27 }, "end": { "line": 16, "column": null } }, - "8": { "start": { "line": 17, "column": 12 }, "end": { "line": 17, "column": null } }, - "9": { "start": { "line": 19, "column": 24 }, "end": { "line": 22, "column": null } }, - "10": { "start": { "line": 24, "column": 12 }, "end": { "line": 29, "column": null } }, - "11": { "start": { "line": 25, "column": 16 }, "end": { "line": 25, "column": null } }, - "12": { "start": { "line": 27, "column": 29 }, "end": { "line": 27, "column": null } }, - "13": { "start": { "line": 28, "column": 16 }, "end": { "line": 28, "column": null } }, - "14": { "start": { "line": 31, "column": 12 }, "end": { "line": 31, "column": null } }, - "15": { "start": { "line": 35, "column": 4 }, "end": { "line": 52, "column": null } }, - "16": { "start": { "line": 45, "column": 41 }, "end": { "line": 45, "column": null } } - }, - "fnMap": { - "0": { - "name": "Login", - "decl": { "start": { "line": 5, "column": 24 }, "end": { "line": 5, "column": 32 } }, - "loc": { "start": { "line": 5, "column": 32 }, "end": { "line": 54, "column": null } }, - "line": 5 - }, - "1": { - "name": "(anonymous_1)", - "decl": { "start": { "line": 10, "column": 25 }, "end": { "line": 10, "column": 32 } }, - "loc": { "start": { "line": 10, "column": 49 }, "end": { "line": 33, "column": null } }, - "line": 10 - }, - "2": { - "name": "(anonymous_2)", - "decl": { "start": { "line": 45, "column": 34 }, "end": { "line": 45, "column": 35 } }, - "loc": { "start": { "line": 45, "column": 41 }, "end": { "line": 45, "column": null } }, - "line": 45 - } - }, - "branchMap": { - "0": { - "loc": { "start": { "line": 24, "column": 12 }, "end": { "line": 29, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 24, "column": 12 }, "end": { "line": 29, "column": null } }, - { "start": { "line": 26, "column": 19 }, "end": { "line": 29, "column": null } } - ], - "line": 24 - }, - "1": { - "loc": { "start": { "line": 28, "column": 25 }, "end": { "line": 28, "column": 55 } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 28, "column": 25 }, "end": { "line": 28, "column": 41 } }, - { "start": { "line": 28, "column": 41 }, "end": { "line": 28, "column": 55 } } - ], - "line": 28 - }, - "2": { - "loc": { "start": { "line": 49, "column": 17 }, "end": { "line": 49, "column": null } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 49, "column": 17 }, "end": { "line": 49, "column": 26 } }, - { "start": { "line": 49, "column": 26 }, "end": { "line": 49, "column": null } } - ], - "line": 49 - } - }, - "s": { - "0": 14, - "1": 14, - "2": 14, - "3": 14, - "4": 3, - "5": 3, - "6": 3, - "7": 3, - "8": 3, - "9": 3, - "10": 2, - "11": 1, - "12": 1, - "13": 1, - "14": 1, - "15": 14, - "16": 3 - }, - "f": { "0": 14, "1": 3, "2": 3 }, - "b": { "0": [1, 1], "1": [1, 0], "2": [14, 2] }, - "meta": { - "lastBranch": 3, - "lastFunction": 3, - "lastStatement": 17, - "seen": { - "f:5:24:5:32": 0, - "s:6:32:6:Infinity": 0, - "s:7:26:7:Infinity": 1, - "s:8:10:8:Infinity": 2, - "s:10:25:33:Infinity": 3, - "f:10:25:10:32": 1, - "s:11:8:11:Infinity": 4, - "s:12:8:12:Infinity": 5, - "s:14:8:32:Infinity": 6, - "s:16:27:16:Infinity": 7, - "s:17:12:17:Infinity": 8, - "s:19:24:22:Infinity": 9, - "b:24:12:29:Infinity:26:19:29:Infinity": 0, - "s:24:12:29:Infinity": 10, - "s:25:16:25:Infinity": 11, - "s:27:29:27:Infinity": 12, - "s:28:16:28:Infinity": 13, - "b:28:25:28:41:28:41:28:55": 1, - "s:31:12:31:Infinity": 14, - "s:35:4:52:Infinity": 15, - "f:45:34:45:35": 2, - "s:45:41:45:Infinity": 16, - "b:49:17:49:26:49:26:49:Infinity": 2 - } - } - }, - "/Users/adam/workspace/vibecode/neko/frontend/src/components/Settings.css": { - "path": "/Users/adam/workspace/vibecode/neko/frontend/src/components/Settings.css", - "statementMap": {}, - "fnMap": {}, - "branchMap": {}, - "s": {}, - "f": {}, - "b": {}, - "meta": { "lastBranch": 0, "lastFunction": 0, "lastStatement": 0, "seen": {} } - }, - "/Users/adam/workspace/vibecode/neko/frontend/src/components/Settings.tsx": { - "path": "/Users/adam/workspace/vibecode/neko/frontend/src/components/Settings.tsx", - "statementMap": { - "0": { "start": { "line": 6, "column": 26 }, "end": { "line": 6, "column": null } }, - "1": { "start": { "line": 7, "column": 36 }, "end": { "line": 7, "column": null } }, - "2": { "start": { "line": 8, "column": 30 }, "end": { "line": 8, "column": null } }, - "3": { "start": { "line": 9, "column": 26 }, "end": { "line": 9, "column": null } }, - "4": { "start": { "line": 11, "column": 4 }, "end": { "line": 13, "column": null } }, - "5": { "start": { "line": 12, "column": 8 }, "end": { "line": 12, "column": null } }, - "6": { "start": { "line": 15, "column": 23 }, "end": { "line": 30, "column": null } }, - "7": { "start": { "line": 16, "column": 8 }, "end": { "line": 16, "column": null } }, - "8": { "start": { "line": 17, "column": 8 }, "end": { "line": 29, "column": null } }, - "9": { "start": { "line": 19, "column": 16 }, "end": { "line": 19, "column": null } }, - "10": { "start": { "line": 19, "column": 29 }, "end": { "line": 19, "column": null } }, - "11": { "start": { "line": 20, "column": 16 }, "end": { "line": 20, "column": null } }, - "12": { "start": { "line": 23, "column": 16 }, "end": { "line": 23, "column": null } }, - "13": { "start": { "line": 24, "column": 16 }, "end": { "line": 24, "column": null } }, - "14": { "start": { "line": 27, "column": 16 }, "end": { "line": 27, "column": null } }, - "15": { "start": { "line": 28, "column": 16 }, "end": { "line": 28, "column": null } }, - "16": { "start": { "line": 32, "column": 26 }, "end": { "line": 54, "column": null } }, - "17": { "start": { "line": 33, "column": 8 }, "end": { "line": 33, "column": null } }, - "18": { "start": { "line": 34, "column": 8 }, "end": { "line": 34, "column": null } }, - "19": { "start": { "line": 34, "column": 25 }, "end": { "line": 34, "column": null } }, - "20": { "start": { "line": 36, "column": 8 }, "end": { "line": 36, "column": null } }, - "21": { "start": { "line": 37, "column": 8 }, "end": { "line": 53, "column": null } }, - "22": { "start": { "line": 43, "column": 16 }, "end": { "line": 43, "column": null } }, - "23": { "start": { "line": 43, "column": 29 }, "end": { "line": 43, "column": null } }, - "24": { "start": { "line": 44, "column": 16 }, "end": { "line": 44, "column": null } }, - "25": { "start": { "line": 47, "column": 16 }, "end": { "line": 47, "column": null } }, - "26": { "start": { "line": 48, "column": 16 }, "end": { "line": 48, "column": null } }, - "27": { "start": { "line": 51, "column": 16 }, "end": { "line": 51, "column": null } }, - "28": { "start": { "line": 52, "column": 16 }, "end": { "line": 52, "column": null } }, - "29": { "start": { "line": 56, "column": 29 }, "end": { "line": 72, "column": null } }, - "30": { "start": { "line": 57, "column": 8 }, "end": { "line": 57, "column": null } }, - "31": { "start": { "line": 57, "column": 79 }, "end": { "line": 57, "column": null } }, - "32": { "start": { "line": 59, "column": 8 }, "end": { "line": 59, "column": null } }, - "33": { "start": { "line": 60, "column": 8 }, "end": { "line": 71, "column": null } }, - "34": { "start": { "line": 64, "column": 16 }, "end": { "line": 64, "column": null } }, - "35": { "start": { "line": 64, "column": 29 }, "end": { "line": 64, "column": null } }, - "36": { "start": { "line": 65, "column": 16 }, "end": { "line": 65, "column": null } }, - "37": { "start": { "line": 65, "column": 45 }, "end": { "line": 65, "column": 57 } }, - "38": { "start": { "line": 66, "column": 16 }, "end": { "line": 66, "column": null } }, - "39": { "start": { "line": 69, "column": 16 }, "end": { "line": 69, "column": null } }, - "40": { "start": { "line": 70, "column": 16 }, "end": { "line": 70, "column": null } }, - "41": { "start": { "line": 74, "column": 4 }, "end": { "line": 119, "column": null } }, - "42": { "start": { "line": 84, "column": 41 }, "end": { "line": 84, "column": null } }, - "43": { "start": { "line": 102, "column": 24 }, "end": { "line": 115, "column": null } }, - "44": { "start": { "line": 108, "column": 47 }, "end": { "line": 108, "column": null } } - }, - "fnMap": { - "0": { - "name": "Settings", - "decl": { "start": { "line": 5, "column": 24 }, "end": { "line": 5, "column": 35 } }, - "loc": { "start": { "line": 5, "column": 35 }, "end": { "line": 121, "column": null } }, - "line": 5 - }, - "1": { - "name": "(anonymous_1)", - "decl": { "start": { "line": 11, "column": 14 }, "end": { "line": 11, "column": 20 } }, - "loc": { "start": { "line": 11, "column": 20 }, "end": { "line": 13, "column": 7 } }, - "line": 11 - }, - "2": { - "name": "(anonymous_2)", - "decl": { "start": { "line": 15, "column": 23 }, "end": { "line": 15, "column": 29 } }, - "loc": { "start": { "line": 15, "column": 29 }, "end": { "line": 30, "column": null } }, - "line": 15 - }, - "3": { - "name": "(anonymous_3)", - "decl": { "start": { "line": 18, "column": 18 }, "end": { "line": 18, "column": 19 } }, - "loc": { "start": { "line": 18, "column": 27 }, "end": { "line": 21, "column": 13 } }, - "line": 18 - }, - "4": { - "name": "(anonymous_4)", - "decl": { "start": { "line": 22, "column": 18 }, "end": { "line": 22, "column": 19 } }, - "loc": { "start": { "line": 22, "column": 28 }, "end": { "line": 25, "column": 13 } }, - "line": 22 - }, - "5": { - "name": "(anonymous_5)", - "decl": { "start": { "line": 26, "column": 19 }, "end": { "line": 26, "column": 20 } }, - "loc": { "start": { "line": 26, "column": 28 }, "end": { "line": 29, "column": 13 } }, - "line": 26 - }, - "6": { - "name": "(anonymous_6)", - "decl": { "start": { "line": 32, "column": 26 }, "end": { "line": 32, "column": 27 } }, - "loc": { "start": { "line": 32, "column": 50 }, "end": { "line": 54, "column": null } }, - "line": 32 - }, - "7": { - "name": "(anonymous_7)", - "decl": { "start": { "line": 42, "column": 18 }, "end": { "line": 42, "column": 19 } }, - "loc": { "start": { "line": 42, "column": 27 }, "end": { "line": 45, "column": 13 } }, - "line": 42 - }, - "8": { - "name": "(anonymous_8)", - "decl": { "start": { "line": 46, "column": 18 }, "end": { "line": 46, "column": 24 } }, - "loc": { "start": { "line": 46, "column": 24 }, "end": { "line": 49, "column": 13 } }, - "line": 46 - }, - "9": { - "name": "(anonymous_9)", - "decl": { "start": { "line": 50, "column": 19 }, "end": { "line": 50, "column": 20 } }, - "loc": { "start": { "line": 50, "column": 28 }, "end": { "line": 53, "column": 13 } }, - "line": 50 - }, - "10": { - "name": "(anonymous_10)", - "decl": { "start": { "line": 56, "column": 29 }, "end": { "line": 56, "column": 30 } }, - "loc": { "start": { "line": 56, "column": 45 }, "end": { "line": 72, "column": null } }, - "line": 56 - }, - "11": { - "name": "(anonymous_11)", - "decl": { "start": { "line": 63, "column": 18 }, "end": { "line": 63, "column": 19 } }, - "loc": { "start": { "line": 63, "column": 27 }, "end": { "line": 67, "column": 13 } }, - "line": 63 - }, - "12": { - "name": "(anonymous_12)", - "decl": { "start": { "line": 65, "column": 38 }, "end": { "line": 65, "column": 39 } }, - "loc": { "start": { "line": 65, "column": 45 }, "end": { "line": 65, "column": 57 } }, - "line": 65 - }, - "13": { - "name": "(anonymous_13)", - "decl": { "start": { "line": 68, "column": 19 }, "end": { "line": 68, "column": 20 } }, - "loc": { "start": { "line": 68, "column": 28 }, "end": { "line": 71, "column": 13 } }, - "line": 68 - }, - "14": { - "name": "(anonymous_14)", - "decl": { "start": { "line": 84, "column": 34 }, "end": { "line": 84, "column": 35 } }, - "loc": { "start": { "line": 84, "column": 41 }, "end": { "line": 84, "column": null } }, - "line": 84 - }, - "15": { - "name": "(anonymous_15)", - "decl": { "start": { "line": 101, "column": 31 }, "end": { "line": 101, "column": 32 } }, - "loc": { "start": { "line": 102, "column": 24 }, "end": { "line": 115, "column": null } }, - "line": 102 - }, - "16": { - "name": "(anonymous_16)", - "decl": { "start": { "line": 108, "column": 41 }, "end": { "line": 108, "column": 47 } }, - "loc": { "start": { "line": 108, "column": 47 }, "end": { "line": 108, "column": null } }, - "line": 108 - } - }, - "branchMap": { - "0": { - "loc": { "start": { "line": 19, "column": 16 }, "end": { "line": 19, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 19, "column": 16 }, "end": { "line": 19, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 19 - }, - "1": { - "loc": { "start": { "line": 34, "column": 8 }, "end": { "line": 34, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 34, "column": 8 }, "end": { "line": 34, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 34 - }, - "2": { - "loc": { "start": { "line": 43, "column": 16 }, "end": { "line": 43, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 43, "column": 16 }, "end": { "line": 43, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 43 - }, - "3": { - "loc": { "start": { "line": 57, "column": 8 }, "end": { "line": 57, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 57, "column": 8 }, "end": { "line": 57, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 57 - }, - "4": { - "loc": { "start": { "line": 64, "column": 16 }, "end": { "line": 64, "column": null } }, - "type": "if", - "locations": [ - { "start": { "line": 64, "column": 16 }, "end": { "line": 64, "column": null } }, - { "start": {}, "end": {} } - ], - "line": 64 - }, - "5": { - "loc": { "start": { "line": 94, "column": 17 }, "end": { "line": 94, "column": null } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 94, "column": 17 }, "end": { "line": 94, "column": 26 } }, - { "start": { "line": 94, "column": 26 }, "end": { "line": 94, "column": null } } - ], - "line": 94 - }, - "6": { - "loc": { "start": { "line": 99, "column": 17 }, "end": { "line": 99, "column": null } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 99, "column": 17 }, "end": { "line": 99, "column": 28 } }, - { "start": { "line": 99, "column": 28 }, "end": { "line": 99, "column": null } } - ], - "line": 99 - }, - "7": { - "loc": { "start": { "line": 104, "column": 62 }, "end": { "line": 104, "column": 89 } }, - "type": "binary-expr", - "locations": [ - { "start": { "line": 104, "column": 62 }, "end": { "line": 104, "column": 76 } }, - { "start": { "line": 104, "column": 76 }, "end": { "line": 104, "column": 89 } } - ], - "line": 104 - } - }, - "s": { - "0": 14, - "1": 14, - "2": 14, - "3": 14, - "4": 14, - "5": 3, - "6": 14, - "7": 4, - "8": 4, - "9": 4, - "10": 0, - "11": 4, - "12": 4, - "13": 4, - "14": 0, - "15": 0, - "16": 14, - "17": 1, - "18": 1, - "19": 0, - "20": 1, - "21": 1, - "22": 1, - "23": 0, - "24": 1, - "25": 1, - "26": 1, - "27": 0, - "28": 0, - "29": 14, - "30": 1, - "31": 0, - "32": 1, - "33": 1, - "34": 1, - "35": 0, - "36": 1, - "37": 1, - "38": 1, - "39": 0, - "40": 0, - "41": 14, - "42": 1, - "43": 5, - "44": 1 - }, - "f": { - "0": 14, - "1": 3, - "2": 4, - "3": 4, - "4": 4, - "5": 0, - "6": 1, - "7": 1, - "8": 1, - "9": 0, - "10": 1, - "11": 1, - "12": 1, - "13": 0, - "14": 1, - "15": 5, - "16": 1 - }, - "b": { - "0": [0, 4], - "1": [0, 1], - "2": [0, 1], - "3": [0, 1], - "4": [0, 1], - "5": [14, 0], - "6": [14, 5], - "7": [5, 0] - }, - "meta": { - "lastBranch": 8, - "lastFunction": 17, - "lastStatement": 45, - "seen": { - "f:5:24:5:35": 0, - "s:6:26:6:Infinity": 0, - "s:7:36:7:Infinity": 1, - "s:8:30:8:Infinity": 2, - "s:9:26:9:Infinity": 3, - "s:11:4:13:Infinity": 4, - "f:11:14:11:20": 1, - "s:12:8:12:Infinity": 5, - "s:15:23:30:Infinity": 6, - "f:15:23:15:29": 2, - "s:16:8:16:Infinity": 7, - "s:17:8:29:Infinity": 8, - "f:18:18:18:19": 3, - "b:19:16:19:Infinity:undefined:undefined:undefined:undefined": 0, - "s:19:16:19:Infinity": 9, - "s:19:29:19:Infinity": 10, - "s:20:16:20:Infinity": 11, - "f:22:18:22:19": 4, - "s:23:16:23:Infinity": 12, - "s:24:16:24:Infinity": 13, - "f:26:19:26:20": 5, - "s:27:16:27:Infinity": 14, - "s:28:16:28:Infinity": 15, - "s:32:26:54:Infinity": 16, - "f:32:26:32:27": 6, - "s:33:8:33:Infinity": 17, - "b:34:8:34:Infinity:undefined:undefined:undefined:undefined": 1, - "s:34:8:34:Infinity": 18, - "s:34:25:34:Infinity": 19, - "s:36:8:36:Infinity": 20, - "s:37:8:53:Infinity": 21, - "f:42:18:42:19": 7, - "b:43:16:43:Infinity:undefined:undefined:undefined:undefined": 2, - "s:43:16:43:Infinity": 22, - "s:43:29:43:Infinity": 23, - "s:44:16:44:Infinity": 24, - "f:46:18:46:24": 8, - "s:47:16:47:Infinity": 25, - "s:48:16:48:Infinity": 26, - "f:50:19:50:20": 9, - "s:51:16:51:Infinity": 27, - "s:52:16:52:Infinity": 28, - "s:56:29:72:Infinity": 29, - "f:56:29:56:30": 10, - "b:57:8:57:Infinity:undefined:undefined:undefined:undefined": 3, - "s:57:8:57:Infinity": 30, - "s:57:79:57:Infinity": 31, - "s:59:8:59:Infinity": 32, - "s:60:8:71:Infinity": 33, - "f:63:18:63:19": 11, - "b:64:16:64:Infinity:undefined:undefined:undefined:undefined": 4, - "s:64:16:64:Infinity": 34, - "s:64:29:64:Infinity": 35, - "s:65:16:65:Infinity": 36, - "f:65:38:65:39": 12, - "s:65:45:65:57": 37, - "s:66:16:66:Infinity": 38, - "f:68:19:68:20": 13, - "s:69:16:69:Infinity": 39, - "s:70:16:70:Infinity": 40, - "s:74:4:119:Infinity": 41, - "f:84:34:84:35": 14, - "s:84:41:84:Infinity": 42, - "b:94:17:94:26:94:26:94:Infinity": 5, - "b:99:17:99:28:99:28:99:Infinity": 6, - "f:101:31:101:32": 15, - "s:102:24:115:Infinity": 43, - "b:104:62:104:76:104:76:104:89": 7, - "f:108:41:108:47": 16, - "s:108:47:108:Infinity": 44 - } - } - } +{"/Users/adam/workspace/vibecode/neko/frontend/src/App.css": {"path":"/Users/adam/workspace/vibecode/neko/frontend/src/App.css","statementMap":{},"fnMap":{},"branchMap":{},"s":{},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":0,"seen":{}}} +,"/Users/adam/workspace/vibecode/neko/frontend/src/App.tsx": {"path":"/Users/adam/workspace/vibecode/neko/frontend/src/App.tsx","statementMap":{"0":{"start":{"line":9,"column":22},"end":{"line":9,"column":null}},"1":{"start":{"line":10,"column":8},"end":{"line":10,"column":null}},"2":{"start":{"line":12,"column":2},"end":{"line":22,"column":null}},"3":{"start":{"line":13,"column":4},"end":{"line":21,"column":null}},"4":{"start":{"line":15,"column":8},"end":{"line":19,"column":null}},"5":{"start":{"line":16,"column":10},"end":{"line":16,"column":null}},"6":{"start":{"line":18,"column":10},"end":{"line":18,"column":null}},"7":{"start":{"line":21,"column":19},"end":{"line":21,"column":33}},"8":{"start":{"line":24,"column":2},"end":{"line":26,"column":null}},"9":{"start":{"line":25,"column":4},"end":{"line":25,"column":null}},"10":{"start":{"line":28,"column":2},"end":{"line":30,"column":null}},"11":{"start":{"line":29,"column":4},"end":{"line":29,"column":null}},"12":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"13":{"start":{"line":40,"column":42},"end":{"line":40,"column":null}},"14":{"start":{"line":42,"column":2},"end":{"line":68,"column":null}},"15":{"start":{"line":50,"column":27},"end":{"line":50,"column":null}},"16":{"start":{"line":73,"column":24},"end":{"line":73,"column":null}},"17":{"start":{"line":75,"column":25},"end":{"line":78,"column":null}},"18":{"start":{"line":76,"column":4},"end":{"line":76,"column":null}},"19":{"start":{"line":77,"column":4},"end":{"line":77,"column":null}},"20":{"start":{"line":80,"column":19},"end":{"line":80,"column":null}},"21":{"start":{"line":82,"column":2},"end":{"line":95,"column":null}}},"fnMap":{"0":{"name":"RequireAuth","decl":{"start":{"line":8,"column":9},"end":{"line":8,"column":21}},"loc":{"start":{"line":8,"column":69},"end":{"line":33,"column":null}},"line":8},"1":{"name":"(anonymous_1)","decl":{"start":{"line":12,"column":12},"end":{"line":12,"column":18}},"loc":{"start":{"line":12,"column":18},"end":{"line":22,"column":5}},"line":12},"2":{"name":"(anonymous_2)","decl":{"start":{"line":14,"column":12},"end":{"line":14,"column":13}},"loc":{"start":{"line":14,"column":21},"end":{"line":20,"column":7}},"line":14},"3":{"name":"(anonymous_3)","decl":{"start":{"line":21,"column":13},"end":{"line":21,"column":19}},"loc":{"start":{"line":21,"column":19},"end":{"line":21,"column":33}},"line":21},"4":{"name":"Dashboard","decl":{"start":{"line":39,"column":9},"end":{"line":39,"column":19}},"loc":{"start":{"line":39,"column":90},"end":{"line":70,"column":null}},"line":39},"5":{"name":"(anonymous_5)","decl":{"start":{"line":50,"column":21},"end":{"line":50,"column":27}},"loc":{"start":{"line":50,"column":27},"end":{"line":50,"column":null}},"line":50},"6":{"name":"App","decl":{"start":{"line":72,"column":9},"end":{"line":72,"column":15}},"loc":{"start":{"line":72,"column":15},"end":{"line":97,"column":null}},"line":72},"7":{"name":"(anonymous_7)","decl":{"start":{"line":75,"column":25},"end":{"line":75,"column":26}},"loc":{"start":{"line":75,"column":47},"end":{"line":78,"column":null}},"line":75}},"branchMap":{"0":{"loc":{"start":{"line":15,"column":8},"end":{"line":19,"column":null}},"type":"if","locations":[{"start":{"line":15,"column":8},"end":{"line":19,"column":null}},{"start":{"line":17,"column":15},"end":{"line":19,"column":null}}],"line":15},"1":{"loc":{"start":{"line":24,"column":2},"end":{"line":26,"column":null}},"type":"if","locations":[{"start":{"line":24,"column":2},"end":{"line":26,"column":null}},{"start":{},"end":{}}],"line":24},"2":{"loc":{"start":{"line":28,"column":2},"end":{"line":30,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":2},"end":{"line":30,"column":null}},{"start":{},"end":{}}],"line":28},"3":{"loc":{"start":{"line":44,"column":30},"end":{"line":44,"column":83}},"type":"cond-expr","locations":[{"start":{"line":44,"column":47},"end":{"line":44,"column":67}},{"start":{"line":44,"column":67},"end":{"line":44,"column":83}}],"line":44},"4":{"loc":{"start":{"line":47,"column":9},"end":{"line":54,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":9},"end":{"line":47,"column":null}},{"start":{"line":48,"column":10},"end":{"line":54,"column":null}}],"line":47},"5":{"loc":{"start":{"line":56,"column":47},"end":{"line":56,"column":77}},"type":"cond-expr","locations":[{"start":{"line":56,"column":64},"end":{"line":56,"column":69}},{"start":{"line":56,"column":69},"end":{"line":56,"column":77}}],"line":56},"6":{"loc":{"start":{"line":73,"column":37},"end":{"line":73,"column":82}},"type":"binary-expr","locations":[{"start":{"line":73,"column":37},"end":{"line":73,"column":75}},{"start":{"line":73,"column":75},"end":{"line":73,"column":82}}],"line":73},"7":{"loc":{"start":{"line":80,"column":19},"end":{"line":80,"column":null}},"type":"cond-expr","locations":[{"start":{"line":80,"column":64},"end":{"line":80,"column":72}},{"start":{"line":80,"column":72},"end":{"line":80,"column":null}}],"line":80}},"s":{"0":2,"1":2,"2":2,"3":1,"4":1,"5":1,"6":0,"7":0,"8":2,"9":1,"10":1,"11":0,"12":1,"13":1,"14":1,"15":0,"16":2,"17":2,"18":0,"19":0,"20":2,"21":2},"f":{"0":2,"1":1,"2":1,"3":0,"4":1,"5":0,"6":2,"7":0},"b":{"0":[1,0],"1":[1,1],"2":[0,1],"3":[1,0],"4":[1,0],"5":[1,0],"6":[2,2],"7":[2,0]},"meta":{"lastBranch":8,"lastFunction":8,"lastStatement":22,"seen":{"f:8:9:8:21":0,"s:9:22:9:Infinity":0,"s:10:8:10:Infinity":1,"s:12:2:22:Infinity":2,"f:12:12:12:18":1,"s:13:4:21:Infinity":3,"f:14:12:14:13":2,"b:15:8:19:Infinity:17:15:19:Infinity":0,"s:15:8:19:Infinity":4,"s:16:10:16:Infinity":5,"s:18:10:18:Infinity":6,"f:21:13:21:19":3,"s:21:19:21:33":7,"b:24:2:26:Infinity:undefined:undefined:undefined:undefined":1,"s:24:2:26:Infinity":8,"s:25:4:25:Infinity":9,"b:28:2:30:Infinity:undefined:undefined:undefined:undefined":2,"s:28:2:30:Infinity":10,"s:29:4:29:Infinity":11,"s:32:2:32:Infinity":12,"f:39:9:39:19":4,"s:40:42:40:Infinity":13,"s:42:2:68:Infinity":14,"b:44:47:44:67:44:67:44:83":3,"b:47:9:47:Infinity:48:10:54:Infinity":4,"f:50:21:50:27":5,"s:50:27:50:Infinity":15,"b:56:64:56:69:56:69:56:77":5,"f:72:9:72:15":6,"s:73:24:73:Infinity":16,"b:73:37:73:75:73:75:73:82":6,"s:75:25:78:Infinity":17,"f:75:25:75:26":7,"s:76:4:76:Infinity":18,"s:77:4:77:Infinity":19,"s:80:19:80:Infinity":20,"b:80:64:80:72:80:72:80:Infinity":7,"s:82:2:95:Infinity":21}}} +,"/Users/adam/workspace/vibecode/neko/frontend/src/utils.ts": {"path":"/Users/adam/workspace/vibecode/neko/frontend/src/utils.ts","statementMap":{"0":{"start":{"line":2,"column":18},"end":{"line":2,"column":null}},"1":{"start":{"line":3,"column":18},"end":{"line":3,"column":null}},"2":{"start":{"line":4,"column":4},"end":{"line":4,"column":null}},"3":{"start":{"line":4,"column":28},"end":{"line":4,"column":null}},"4":{"start":{"line":12,"column":19},"end":{"line":12,"column":null}},"5":{"start":{"line":13,"column":28},"end":{"line":13,"column":null}},"6":{"start":{"line":15,"column":20},"end":{"line":15,"column":null}},"7":{"start":{"line":17,"column":4},"end":{"line":22,"column":null}},"8":{"start":{"line":18,"column":22},"end":{"line":18,"column":null}},"9":{"start":{"line":19,"column":8},"end":{"line":21,"column":null}},"10":{"start":{"line":20,"column":12},"end":{"line":20,"column":null}},"11":{"start":{"line":27,"column":4},"end":{"line":30,"column":null}}},"fnMap":{"0":{"name":"getCookie","decl":{"start":{"line":1,"column":16},"end":{"line":1,"column":26}},"loc":{"start":{"line":1,"column":60},"end":{"line":5,"column":null}},"line":1},"1":{"name":"apiFetch","decl":{"start":{"line":11,"column":22},"end":{"line":11,"column":31}},"loc":{"start":{"line":11,"column":96},"end":{"line":31,"column":null}},"line":11}},"branchMap":{"0":{"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":null}},"type":"if","locations":[{"start":{"line":4,"column":4},"end":{"line":4,"column":null}},{"start":{},"end":{}}],"line":4},"1":{"loc":{"start":{"line":12,"column":19},"end":{"line":12,"column":null}},"type":"binary-expr","locations":[{"start":{"line":12,"column":19},"end":{"line":12,"column":50}},{"start":{"line":12,"column":50},"end":{"line":12,"column":null}}],"line":12},"2":{"loc":{"start":{"line":15,"column":32},"end":{"line":15,"column":51}},"type":"binary-expr","locations":[{"start":{"line":15,"column":32},"end":{"line":15,"column":49}},{"start":{"line":15,"column":49},"end":{"line":15,"column":51}}],"line":15},"3":{"loc":{"start":{"line":17,"column":4},"end":{"line":22,"column":null}},"type":"if","locations":[{"start":{"line":17,"column":4},"end":{"line":22,"column":null}},{"start":{},"end":{}}],"line":17},"4":{"loc":{"start":{"line":19,"column":8},"end":{"line":21,"column":null}},"type":"if","locations":[{"start":{"line":19,"column":8},"end":{"line":21,"column":null}},{"start":{},"end":{}}],"line":19}},"s":{"0":10,"1":10,"2":10,"3":0,"4":36,"5":36,"6":36,"7":36,"8":10,"9":10,"10":0,"11":36},"f":{"0":10,"1":36},"b":{"0":[0,10],"1":[36,26],"2":[36,31],"3":[10,26],"4":[0,10]},"meta":{"lastBranch":5,"lastFunction":2,"lastStatement":12,"seen":{"f:1:16:1:26":0,"s:2:18:2:Infinity":0,"s:3:18:3:Infinity":1,"b:4:4:4:Infinity:undefined:undefined:undefined:undefined":0,"s:4:4:4:Infinity":2,"s:4:28:4:Infinity":3,"f:11:22:11:31":1,"s:12:19:12:Infinity":4,"b:12:19:12:50:12:50:12:Infinity":1,"s:13:28:13:Infinity":5,"s:15:20:15:Infinity":6,"b:15:32:15:49:15:49:15:51":2,"b:17:4:22:Infinity:undefined:undefined:undefined:undefined":3,"s:17:4:22:Infinity":7,"s:18:22:18:Infinity":8,"b:19:8:21:Infinity:undefined:undefined:undefined:undefined":4,"s:19:8:21:Infinity":9,"s:20:12:20:Infinity":10,"s:27:4:30:Infinity":11}}} +,"/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItem.css": {"path":"/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItem.css","statementMap":{},"fnMap":{},"branchMap":{},"s":{},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":0,"seen":{}}} +,"/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItem.tsx": {"path":"/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItem.tsx","statementMap":{"0":{"start":{"line":12,"column":22},"end":{"line":12,"column":null}},"1":{"start":{"line":13,"column":28},"end":{"line":13,"column":null}},"2":{"start":{"line":15,"column":2},"end":{"line":17,"column":null}},"3":{"start":{"line":16,"column":4},"end":{"line":16,"column":null}},"4":{"start":{"line":19,"column":21},"end":{"line":21,"column":null}},"5":{"start":{"line":20,"column":4},"end":{"line":20,"column":null}},"6":{"start":{"line":23,"column":21},"end":{"line":57,"column":null}},"7":{"start":{"line":24,"column":4},"end":{"line":24,"column":null}},"8":{"start":{"line":26,"column":25},"end":{"line":26,"column":null}},"9":{"start":{"line":27,"column":4},"end":{"line":27,"column":null}},"10":{"start":{"line":29,"column":4},"end":{"line":56,"column":null}},"11":{"start":{"line":41,"column":8},"end":{"line":43,"column":null}},"12":{"start":{"line":42,"column":10},"end":{"line":42,"column":null}},"13":{"start":{"line":44,"column":8},"end":{"line":44,"column":null}},"14":{"start":{"line":49,"column":8},"end":{"line":49,"column":null}},"15":{"start":{"line":52,"column":8},"end":{"line":52,"column":null}},"16":{"start":{"line":54,"column":8},"end":{"line":54,"column":null}},"17":{"start":{"line":55,"column":8},"end":{"line":55,"column":null}},"18":{"start":{"line":59,"column":26},"end":{"line":75,"column":null}},"19":{"start":{"line":60,"column":4},"end":{"line":60,"column":null}},"20":{"start":{"line":61,"column":4},"end":{"line":61,"column":null}},"21":{"start":{"line":62,"column":4},"end":{"line":74,"column":null}},"22":{"start":{"line":64,"column":8},"end":{"line":64,"column":null}},"23":{"start":{"line":64,"column":21},"end":{"line":64,"column":null}},"24":{"start":{"line":65,"column":8},"end":{"line":65,"column":null}},"25":{"start":{"line":68,"column":8},"end":{"line":68,"column":null}},"26":{"start":{"line":69,"column":8},"end":{"line":69,"column":null}},"27":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"28":{"start":{"line":73,"column":8},"end":{"line":73,"column":null}},"29":{"start":{"line":77,"column":2},"end":{"line":113,"column":null}},"30":{"start":{"line":85,"column":12},"end":{"line":85,"column":null}},"31":{"start":{"line":86,"column":12},"end":{"line":86,"column":null}}},"fnMap":{"0":{"name":"FeedItem","decl":{"start":{"line":11,"column":24},"end":{"line":11,"column":33}},"loc":{"start":{"line":11,"column":71},"end":{"line":115,"column":null}},"line":11},"1":{"name":"(anonymous_1)","decl":{"start":{"line":15,"column":12},"end":{"line":15,"column":18}},"loc":{"start":{"line":15,"column":18},"end":{"line":17,"column":5}},"line":15},"2":{"name":"(anonymous_2)","decl":{"start":{"line":19,"column":21},"end":{"line":19,"column":27}},"loc":{"start":{"line":19,"column":27},"end":{"line":21,"column":null}},"line":19},"3":{"name":"(anonymous_3)","decl":{"start":{"line":23,"column":21},"end":{"line":23,"column":22}},"loc":{"start":{"line":23,"column":40},"end":{"line":57,"column":null}},"line":23},"4":{"name":"(anonymous_4)","decl":{"start":{"line":40,"column":12},"end":{"line":40,"column":13}},"loc":{"start":{"line":40,"column":21},"end":{"line":45,"column":7}},"line":40},"5":{"name":"(anonymous_5)","decl":{"start":{"line":46,"column":12},"end":{"line":46,"column":18}},"loc":{"start":{"line":46,"column":18},"end":{"line":50,"column":7}},"line":46},"6":{"name":"(anonymous_6)","decl":{"start":{"line":51,"column":13},"end":{"line":51,"column":14}},"loc":{"start":{"line":51,"column":22},"end":{"line":56,"column":7}},"line":51},"7":{"name":"(anonymous_7)","decl":{"start":{"line":59,"column":26},"end":{"line":59,"column":27}},"loc":{"start":{"line":59,"column":51},"end":{"line":75,"column":null}},"line":59},"8":{"name":"(anonymous_8)","decl":{"start":{"line":63,"column":12},"end":{"line":63,"column":13}},"loc":{"start":{"line":63,"column":21},"end":{"line":66,"column":7}},"line":63},"9":{"name":"(anonymous_9)","decl":{"start":{"line":67,"column":12},"end":{"line":67,"column":13}},"loc":{"start":{"line":67,"column":22},"end":{"line":70,"column":7}},"line":67},"10":{"name":"(anonymous_10)","decl":{"start":{"line":71,"column":13},"end":{"line":71,"column":14}},"loc":{"start":{"line":71,"column":22},"end":{"line":74,"column":7}},"line":71},"11":{"name":"(anonymous_11)","decl":{"start":{"line":84,"column":19},"end":{"line":84,"column":20}},"loc":{"start":{"line":84,"column":26},"end":{"line":87,"column":null}},"line":84}},"branchMap":{"0":{"loc":{"start":{"line":41,"column":8},"end":{"line":43,"column":null}},"type":"if","locations":[{"start":{"line":41,"column":8},"end":{"line":43,"column":null}},{"start":{},"end":{}}],"line":41},"1":{"loc":{"start":{"line":64,"column":8},"end":{"line":64,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":8},"end":{"line":64,"column":null}},{"start":{},"end":{}}],"line":64},"2":{"loc":{"start":{"line":78,"column":32},"end":{"line":78,"column":61}},"type":"cond-expr","locations":[{"start":{"line":78,"column":44},"end":{"line":78,"column":53}},{"start":{"line":78,"column":53},"end":{"line":78,"column":61}}],"line":78},"3":{"loc":{"start":{"line":78,"column":65},"end":{"line":78,"column":89}},"type":"cond-expr","locations":[{"start":{"line":78,"column":75},"end":{"line":78,"column":87}},{"start":{"line":78,"column":87},"end":{"line":78,"column":89}}],"line":78},"4":{"loc":{"start":{"line":81,"column":11},"end":{"line":81,"column":null}},"type":"binary-expr","locations":[{"start":{"line":81,"column":11},"end":{"line":81,"column":25}},{"start":{"line":81,"column":25},"end":{"line":81,"column":null}}],"line":81},"5":{"loc":{"start":{"line":88,"column":33},"end":{"line":88,"column":77}},"type":"cond-expr","locations":[{"start":{"line":88,"column":48},"end":{"line":88,"column":63}},{"start":{"line":88,"column":63},"end":{"line":88,"column":77}}],"line":88},"6":{"loc":{"start":{"line":89,"column":17},"end":{"line":89,"column":null}},"type":"cond-expr","locations":[{"start":{"line":89,"column":32},"end":{"line":89,"column":43}},{"start":{"line":89,"column":43},"end":{"line":89,"column":null}}],"line":89},"7":{"loc":{"start":{"line":97,"column":11},"end":{"line":97,"column":null}},"type":"binary-expr","locations":[{"start":{"line":97,"column":11},"end":{"line":97,"column":30}},{"start":{"line":97,"column":30},"end":{"line":97,"column":null}}],"line":97},"8":{"loc":{"start":{"line":100,"column":11},"end":{"line":103,"column":null}},"type":"binary-expr","locations":[{"start":{"line":100,"column":11},"end":{"line":100,"column":null}},{"start":{"line":101,"column":12},"end":{"line":103,"column":null}}],"line":100},"9":{"loc":{"start":{"line":106,"column":6},"end":{"line":111,"column":null}},"type":"binary-expr","locations":[{"start":{"line":107,"column":8},"end":{"line":107,"column":29}},{"start":{"line":107,"column":29},"end":{"line":107,"column":null}},{"start":{"line":108,"column":8},"end":{"line":111,"column":null}}],"line":106},"10":{"loc":{"start":{"line":110,"column":45},"end":{"line":110,"column":83}},"type":"binary-expr","locations":[{"start":{"line":110,"column":45},"end":{"line":110,"column":66}},{"start":{"line":110,"column":66},"end":{"line":110,"column":83}}],"line":110}},"s":{"0":33,"1":33,"2":33,"3":16,"4":33,"5":1,"6":33,"7":1,"8":1,"9":1,"10":1,"11":1,"12":0,"13":1,"14":1,"15":0,"16":0,"17":0,"18":33,"19":1,"20":1,"21":1,"22":1,"23":0,"24":1,"25":1,"26":1,"27":0,"28":0,"29":33,"30":1,"31":1},"f":{"0":33,"1":16,"2":1,"3":1,"4":1,"5":1,"6":0,"7":1,"8":1,"9":1,"10":0,"11":1},"b":{"0":[0,1],"1":[0,1],"2":[16,17],"3":[4,29],"4":[33,0],"5":[4,29],"6":[4,29],"7":[33,13],"8":[33,32],"9":[33,32,12],"10":[12,11]},"meta":{"lastBranch":11,"lastFunction":12,"lastStatement":32,"seen":{"f:11:24:11:33":0,"s:12:22:12:Infinity":0,"s:13:28:13:Infinity":1,"s:15:2:17:Infinity":2,"f:15:12:15:18":1,"s:16:4:16:Infinity":3,"s:19:21:21:Infinity":4,"f:19:21:19:27":2,"s:20:4:20:Infinity":5,"s:23:21:57:Infinity":6,"f:23:21:23:22":3,"s:24:4:24:Infinity":7,"s:26:25:26:Infinity":8,"s:27:4:27:Infinity":9,"s:29:4:56:Infinity":10,"f:40:12:40:13":4,"b:41:8:43:Infinity:undefined:undefined:undefined:undefined":0,"s:41:8:43:Infinity":11,"s:42:10:42:Infinity":12,"s:44:8:44:Infinity":13,"f:46:12:46:18":5,"s:49:8:49:Infinity":14,"f:51:13:51:14":6,"s:52:8:52:Infinity":15,"s:54:8:54:Infinity":16,"s:55:8:55:Infinity":17,"s:59:26:75:Infinity":18,"f:59:26:59:27":7,"s:60:4:60:Infinity":19,"s:61:4:61:Infinity":20,"s:62:4:74:Infinity":21,"f:63:12:63:13":8,"b:64:8:64:Infinity:undefined:undefined:undefined:undefined":1,"s:64:8:64:Infinity":22,"s:64:21:64:Infinity":23,"s:65:8:65:Infinity":24,"f:67:12:67:13":9,"s:68:8:68:Infinity":25,"s:69:8:69:Infinity":26,"f:71:13:71:14":10,"s:72:8:72:Infinity":27,"s:73:8:73:Infinity":28,"s:77:2:113:Infinity":29,"b:78:44:78:53:78:53:78:61":2,"b:78:75:78:87:78:87:78:89":3,"b:81:11:81:25:81:25:81:Infinity":4,"f:84:19:84:20":11,"s:85:12:85:Infinity":30,"s:86:12:86:Infinity":31,"b:88:48:88:63:88:63:88:77":5,"b:89:32:89:43:89:43:89:Infinity":6,"b:97:11:97:30:97:30:97:Infinity":7,"b:100:11:100:Infinity:101:12:103:Infinity":8,"b:107:8:107:29:107:29:107:Infinity:108:8:111:Infinity":9,"b:110:45:110:66:110:66:110:83":10}}} +,"/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItems.css": {"path":"/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItems.css","statementMap":{},"fnMap":{},"branchMap":{},"s":{},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":0,"seen":{}}} +,"/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItems.tsx": {"path":"/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedItems.tsx","statementMap":{"0":{"start":{"line":9,"column":26},"end":{"line":9,"column":null}},"1":{"start":{"line":10,"column":21},"end":{"line":10,"column":null}},"2":{"start":{"line":11,"column":19},"end":{"line":11,"column":null}},"3":{"start":{"line":13,"column":24},"end":{"line":13,"column":null}},"4":{"start":{"line":14,"column":28},"end":{"line":14,"column":null}},"5":{"start":{"line":15,"column":36},"end":{"line":15,"column":null}},"6":{"start":{"line":16,"column":28},"end":{"line":16,"column":null}},"7":{"start":{"line":17,"column":24},"end":{"line":17,"column":null}},"8":{"start":{"line":18,"column":40},"end":{"line":18,"column":null}},"9":{"start":{"line":20,"column":21},"end":{"line":87,"column":null}},"10":{"start":{"line":21,"column":4},"end":{"line":26,"column":null}},"11":{"start":{"line":22,"column":6},"end":{"line":22,"column":null}},"12":{"start":{"line":24,"column":6},"end":{"line":24,"column":null}},"13":{"start":{"line":25,"column":6},"end":{"line":25,"column":null}},"14":{"start":{"line":27,"column":4},"end":{"line":27,"column":null}},"15":{"start":{"line":29,"column":14},"end":{"line":29,"column":null}},"16":{"start":{"line":30,"column":19},"end":{"line":30,"column":null}},"17":{"start":{"line":32,"column":4},"end":{"line":36,"column":null}},"18":{"start":{"line":33,"column":6},"end":{"line":33,"column":null}},"19":{"start":{"line":34,"column":4},"end":{"line":36,"column":null}},"20":{"start":{"line":35,"column":6},"end":{"line":35,"column":null}},"21":{"start":{"line":38,"column":4},"end":{"line":40,"column":null}},"22":{"start":{"line":39,"column":6},"end":{"line":39,"column":null}},"23":{"start":{"line":43,"column":24},"end":{"line":43,"column":null}},"24":{"start":{"line":44,"column":4},"end":{"line":46,"column":null}},"25":{"start":{"line":45,"column":6},"end":{"line":45,"column":null}},"26":{"start":{"line":48,"column":4},"end":{"line":58,"column":null}},"27":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"28":{"start":{"line":50,"column":4},"end":{"line":58,"column":null}},"29":{"start":{"line":51,"column":6},"end":{"line":51,"column":null}},"30":{"start":{"line":52,"column":6},"end":{"line":52,"column":null}},"31":{"start":{"line":55,"column":6},"end":{"line":57,"column":null}},"32":{"start":{"line":56,"column":8},"end":{"line":56,"column":null}},"33":{"start":{"line":60,"column":24},"end":{"line":60,"column":null}},"34":{"start":{"line":61,"column":4},"end":{"line":63,"column":null}},"35":{"start":{"line":62,"column":6},"end":{"line":62,"column":null}},"36":{"start":{"line":65,"column":4},"end":{"line":86,"column":null}},"37":{"start":{"line":67,"column":8},"end":{"line":69,"column":null}},"38":{"start":{"line":68,"column":10},"end":{"line":68,"column":null}},"39":{"start":{"line":70,"column":8},"end":{"line":70,"column":null}},"40":{"start":{"line":73,"column":8},"end":{"line":77,"column":null}},"41":{"start":{"line":74,"column":10},"end":{"line":74,"column":null}},"42":{"start":{"line":74,"column":29},"end":{"line":74,"column":47}},"43":{"start":{"line":76,"column":10},"end":{"line":76,"column":null}},"44":{"start":{"line":78,"column":8},"end":{"line":78,"column":null}},"45":{"start":{"line":79,"column":8},"end":{"line":79,"column":null}},"46":{"start":{"line":80,"column":8},"end":{"line":80,"column":null}},"47":{"start":{"line":83,"column":8},"end":{"line":83,"column":null}},"48":{"start":{"line":84,"column":8},"end":{"line":84,"column":null}},"49":{"start":{"line":85,"column":8},"end":{"line":85,"column":null}},"50":{"start":{"line":89,"column":2},"end":{"line":92,"column":null}},"51":{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},"52":{"start":{"line":91,"column":4},"end":{"line":91,"column":null}},"53":{"start":{"line":95,"column":23},"end":{"line":100,"column":null}},"54":{"start":{"line":96,"column":20},"end":{"line":96,"column":null}},"55":{"start":{"line":97,"column":4},"end":{"line":99,"column":null}},"56":{"start":{"line":98,"column":6},"end":{"line":98,"column":null}},"57":{"start":{"line":102,"column":21},"end":{"line":112,"column":null}},"58":{"start":{"line":103,"column":24},"end":{"line":103,"column":null}},"59":{"start":{"line":105,"column":4},"end":{"line":105,"column":null}},"60":{"start":{"line":105,"column":28},"end":{"line":105,"column":88}},"61":{"start":{"line":105,"column":50},"end":{"line":105,"column":87}},"62":{"start":{"line":107,"column":4},"end":{"line":111,"column":null}},"63":{"start":{"line":111,"column":22},"end":{"line":111,"column":63}},"64":{"start":{"line":114,"column":21},"end":{"line":124,"column":null}},"65":{"start":{"line":115,"column":24},"end":{"line":115,"column":null}},"66":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"67":{"start":{"line":117,"column":28},"end":{"line":117,"column":88}},"68":{"start":{"line":117,"column":50},"end":{"line":117,"column":87}},"69":{"start":{"line":119,"column":4},"end":{"line":123,"column":null}},"70":{"start":{"line":123,"column":22},"end":{"line":123,"column":65}},"71":{"start":{"line":126,"column":2},"end":{"line":162,"column":null}},"72":{"start":{"line":127,"column":26},"end":{"line":158,"column":null}},"73":{"start":{"line":128,"column":6},"end":{"line":128,"column":null}},"74":{"start":{"line":128,"column":30},"end":{"line":128,"column":null}},"75":{"start":{"line":130,"column":6},"end":{"line":157,"column":null}},"76":{"start":{"line":131,"column":8},"end":{"line":141,"column":null}},"77":{"start":{"line":132,"column":28},"end":{"line":132,"column":null}},"78":{"start":{"line":133,"column":10},"end":{"line":139,"column":null}},"79":{"start":{"line":134,"column":25},"end":{"line":134,"column":null}},"80":{"start":{"line":135,"column":12},"end":{"line":137,"column":null}},"81":{"start":{"line":136,"column":14},"end":{"line":136,"column":null}},"82":{"start":{"line":138,"column":12},"end":{"line":138,"column":null}},"83":{"start":{"line":140,"column":10},"end":{"line":140,"column":null}},"84":{"start":{"line":142,"column":6},"end":{"line":157,"column":null}},"85":{"start":{"line":143,"column":8},"end":{"line":149,"column":null}},"86":{"start":{"line":144,"column":28},"end":{"line":144,"column":null}},"87":{"start":{"line":145,"column":10},"end":{"line":147,"column":null}},"88":{"start":{"line":146,"column":12},"end":{"line":146,"column":null}},"89":{"start":{"line":148,"column":10},"end":{"line":148,"column":null}},"90":{"start":{"line":150,"column":6},"end":{"line":157,"column":null}},"91":{"start":{"line":151,"column":8},"end":{"line":156,"column":null}},"92":{"start":{"line":152,"column":10},"end":{"line":154,"column":null}},"93":{"start":{"line":153,"column":12},"end":{"line":153,"column":null}},"94":{"start":{"line":155,"column":10},"end":{"line":155,"column":null}},"95":{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},"96":{"start":{"line":161,"column":4},"end":{"line":161,"column":null}},"97":{"start":{"line":161,"column":17},"end":{"line":161,"column":null}},"98":{"start":{"line":166,"column":2},"end":{"line":202,"column":null}},"99":{"start":{"line":167,"column":21},"end":{"line":191,"column":null}},"100":{"start":{"line":169,"column":8},"end":{"line":188,"column":null}},"101":{"start":{"line":171,"column":10},"end":{"line":176,"column":null}},"102":{"start":{"line":172,"column":12},"end":{"line":174,"column":null}},"103":{"start":{"line":173,"column":14},"end":{"line":173,"column":null}},"104":{"start":{"line":175,"column":12},"end":{"line":175,"column":null}},"105":{"start":{"line":179,"column":10},"end":{"line":187,"column":null}},"106":{"start":{"line":180,"column":26},"end":{"line":180,"column":null}},"107":{"start":{"line":181,"column":12},"end":{"line":186,"column":null}},"108":{"start":{"line":182,"column":27},"end":{"line":182,"column":null}},"109":{"start":{"line":183,"column":14},"end":{"line":185,"column":null}},"110":{"start":{"line":184,"column":16},"end":{"line":184,"column":null}},"111":{"start":{"line":193,"column":4},"end":{"line":196,"column":null}},"112":{"start":{"line":194,"column":17},"end":{"line":194,"column":null}},"113":{"start":{"line":195,"column":6},"end":{"line":195,"column":null}},"114":{"start":{"line":195,"column":14},"end":{"line":195,"column":null}},"115":{"start":{"line":198,"column":21},"end":{"line":198,"column":null}},"116":{"start":{"line":199,"column":4},"end":{"line":199,"column":null}},"117":{"start":{"line":199,"column":18},"end":{"line":199,"column":null}},"118":{"start":{"line":201,"column":4},"end":{"line":201,"column":null}},"119":{"start":{"line":201,"column":17},"end":{"line":201,"column":null}},"120":{"start":{"line":204,"column":2},"end":{"line":204,"column":null}},"121":{"start":{"line":204,"column":15},"end":{"line":204,"column":null}},"122":{"start":{"line":205,"column":2},"end":{"line":205,"column":null}},"123":{"start":{"line":205,"column":13},"end":{"line":205,"column":null}},"124":{"start":{"line":207,"column":2},"end":{"line":231,"column":null}},"125":{"start":{"line":214,"column":12},"end":{"line":222,"column":null}},"126":{"start":{"line":219,"column":29},"end":{"line":219,"column":null}}},"fnMap":{"0":{"name":"FeedItems","decl":{"start":{"line":8,"column":24},"end":{"line":8,"column":36}},"loc":{"start":{"line":8,"column":36},"end":{"line":233,"column":null}},"line":8},"1":{"name":"(anonymous_1)","decl":{"start":{"line":20,"column":21},"end":{"line":20,"column":22}},"loc":{"start":{"line":20,"column":41},"end":{"line":87,"column":null}},"line":20},"2":{"name":"(anonymous_2)","decl":{"start":{"line":66,"column":12},"end":{"line":66,"column":13}},"loc":{"start":{"line":66,"column":21},"end":{"line":71,"column":7}},"line":66},"3":{"name":"(anonymous_3)","decl":{"start":{"line":72,"column":12},"end":{"line":72,"column":13}},"loc":{"start":{"line":72,"column":22},"end":{"line":81,"column":7}},"line":72},"4":{"name":"(anonymous_4)","decl":{"start":{"line":74,"column":19},"end":{"line":74,"column":20}},"loc":{"start":{"line":74,"column":29},"end":{"line":74,"column":47}},"line":74},"5":{"name":"(anonymous_5)","decl":{"start":{"line":82,"column":13},"end":{"line":82,"column":14}},"loc":{"start":{"line":82,"column":22},"end":{"line":86,"column":7}},"line":82},"6":{"name":"(anonymous_6)","decl":{"start":{"line":89,"column":12},"end":{"line":89,"column":18}},"loc":{"start":{"line":89,"column":18},"end":{"line":92,"column":5}},"line":89},"7":{"name":"(anonymous_7)","decl":{"start":{"line":95,"column":23},"end":{"line":95,"column":24}},"loc":{"start":{"line":95,"column":42},"end":{"line":100,"column":null}},"line":95},"8":{"name":"(anonymous_8)","decl":{"start":{"line":102,"column":21},"end":{"line":102,"column":22}},"loc":{"start":{"line":102,"column":37},"end":{"line":112,"column":null}},"line":102},"9":{"name":"(anonymous_9)","decl":{"start":{"line":105,"column":13},"end":{"line":105,"column":14}},"loc":{"start":{"line":105,"column":28},"end":{"line":105,"column":88}},"line":105},"10":{"name":"(anonymous_10)","decl":{"start":{"line":105,"column":42},"end":{"line":105,"column":43}},"loc":{"start":{"line":105,"column":50},"end":{"line":105,"column":87}},"line":105},"11":{"name":"(anonymous_11)","decl":{"start":{"line":111,"column":13},"end":{"line":111,"column":14}},"loc":{"start":{"line":111,"column":22},"end":{"line":111,"column":63}},"line":111},"12":{"name":"(anonymous_12)","decl":{"start":{"line":114,"column":21},"end":{"line":114,"column":22}},"loc":{"start":{"line":114,"column":37},"end":{"line":124,"column":null}},"line":114},"13":{"name":"(anonymous_13)","decl":{"start":{"line":117,"column":13},"end":{"line":117,"column":14}},"loc":{"start":{"line":117,"column":28},"end":{"line":117,"column":88}},"line":117},"14":{"name":"(anonymous_14)","decl":{"start":{"line":117,"column":42},"end":{"line":117,"column":43}},"loc":{"start":{"line":117,"column":50},"end":{"line":117,"column":87}},"line":117},"15":{"name":"(anonymous_15)","decl":{"start":{"line":123,"column":13},"end":{"line":123,"column":14}},"loc":{"start":{"line":123,"column":22},"end":{"line":123,"column":65}},"line":123},"16":{"name":"(anonymous_16)","decl":{"start":{"line":126,"column":12},"end":{"line":126,"column":18}},"loc":{"start":{"line":126,"column":18},"end":{"line":162,"column":5}},"line":126},"17":{"name":"(anonymous_17)","decl":{"start":{"line":127,"column":26},"end":{"line":127,"column":27}},"loc":{"start":{"line":127,"column":48},"end":{"line":158,"column":null}},"line":127},"18":{"name":"(anonymous_18)","decl":{"start":{"line":131,"column":25},"end":{"line":131,"column":26}},"loc":{"start":{"line":131,"column":35},"end":{"line":141,"column":9}},"line":131},"19":{"name":"(anonymous_19)","decl":{"start":{"line":143,"column":25},"end":{"line":143,"column":26}},"loc":{"start":{"line":143,"column":35},"end":{"line":149,"column":9}},"line":143},"20":{"name":"(anonymous_20)","decl":{"start":{"line":151,"column":25},"end":{"line":151,"column":26}},"loc":{"start":{"line":151,"column":43},"end":{"line":156,"column":9}},"line":151},"21":{"name":"(anonymous_21)","decl":{"start":{"line":161,"column":11},"end":{"line":161,"column":17}},"loc":{"start":{"line":161,"column":17},"end":{"line":161,"column":null}},"line":161},"22":{"name":"(anonymous_22)","decl":{"start":{"line":166,"column":12},"end":{"line":166,"column":18}},"loc":{"start":{"line":166,"column":18},"end":{"line":202,"column":5}},"line":166},"23":{"name":"(anonymous_23)","decl":{"start":{"line":168,"column":6},"end":{"line":168,"column":7}},"loc":{"start":{"line":168,"column":19},"end":{"line":189,"column":null}},"line":168},"24":{"name":"(anonymous_24)","decl":{"start":{"line":169,"column":24},"end":{"line":169,"column":25}},"loc":{"start":{"line":169,"column":35},"end":{"line":188,"column":9}},"line":169},"25":{"name":"(anonymous_25)","decl":{"start":{"line":193,"column":18},"end":{"line":193,"column":19}},"loc":{"start":{"line":193,"column":32},"end":{"line":196,"column":5}},"line":193},"26":{"name":"(anonymous_26)","decl":{"start":{"line":201,"column":11},"end":{"line":201,"column":17}},"loc":{"start":{"line":201,"column":17},"end":{"line":201,"column":null}},"line":201},"27":{"name":"(anonymous_27)","decl":{"start":{"line":213,"column":21},"end":{"line":213,"column":22}},"loc":{"start":{"line":214,"column":12},"end":{"line":222,"column":null}},"line":214},"28":{"name":"(anonymous_28)","decl":{"start":{"line":219,"column":23},"end":{"line":219,"column":29}},"loc":{"start":{"line":219,"column":29},"end":{"line":219,"column":null}},"line":219}},"branchMap":{"0":{"loc":{"start":{"line":11,"column":19},"end":{"line":11,"column":null}},"type":"binary-expr","locations":[{"start":{"line":11,"column":19},"end":{"line":11,"column":49}},{"start":{"line":11,"column":49},"end":{"line":11,"column":null}}],"line":11},"1":{"loc":{"start":{"line":21,"column":4},"end":{"line":26,"column":null}},"type":"if","locations":[{"start":{"line":21,"column":4},"end":{"line":26,"column":null}},{"start":{"line":23,"column":11},"end":{"line":26,"column":null}}],"line":21},"2":{"loc":{"start":{"line":32,"column":4},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":4},"end":{"line":36,"column":null}},{"start":{"line":34,"column":4},"end":{"line":36,"column":null}}],"line":32},"3":{"loc":{"start":{"line":34,"column":4},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":4},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":34},"4":{"loc":{"start":{"line":38,"column":4},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":38,"column":4},"end":{"line":40,"column":null}},{"start":{},"end":{}}],"line":38},"5":{"loc":{"start":{"line":44,"column":4},"end":{"line":46,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":46,"column":null}},{"start":{},"end":{}}],"line":44},"6":{"loc":{"start":{"line":48,"column":4},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":4},"end":{"line":58,"column":null}},{"start":{"line":50,"column":4},"end":{"line":58,"column":null}}],"line":48},"7":{"loc":{"start":{"line":50,"column":4},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":4},"end":{"line":58,"column":null}},{"start":{"line":53,"column":11},"end":{"line":58,"column":null}}],"line":50},"8":{"loc":{"start":{"line":55,"column":6},"end":{"line":57,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":6},"end":{"line":57,"column":null}},{"start":{},"end":{}}],"line":55},"9":{"loc":{"start":{"line":61,"column":4},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":61,"column":4},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":61},"10":{"loc":{"start":{"line":67,"column":8},"end":{"line":69,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":8},"end":{"line":69,"column":null}},{"start":{},"end":{}}],"line":67},"11":{"loc":{"start":{"line":73,"column":8},"end":{"line":77,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":8},"end":{"line":77,"column":null}},{"start":{"line":75,"column":15},"end":{"line":77,"column":null}}],"line":73},"12":{"loc":{"start":{"line":97,"column":4},"end":{"line":99,"column":null}},"type":"if","locations":[{"start":{"line":97,"column":4},"end":{"line":99,"column":null}},{"start":{},"end":{}}],"line":97},"13":{"loc":{"start":{"line":105,"column":50},"end":{"line":105,"column":87}},"type":"cond-expr","locations":[{"start":{"line":105,"column":71},"end":{"line":105,"column":85}},{"start":{"line":105,"column":85},"end":{"line":105,"column":87}}],"line":105},"14":{"loc":{"start":{"line":117,"column":50},"end":{"line":117,"column":87}},"type":"cond-expr","locations":[{"start":{"line":117,"column":71},"end":{"line":117,"column":85}},{"start":{"line":117,"column":85},"end":{"line":117,"column":87}}],"line":117},"15":{"loc":{"start":{"line":128,"column":6},"end":{"line":128,"column":null}},"type":"if","locations":[{"start":{"line":128,"column":6},"end":{"line":128,"column":null}},{"start":{},"end":{}}],"line":128},"16":{"loc":{"start":{"line":130,"column":6},"end":{"line":157,"column":null}},"type":"if","locations":[{"start":{"line":130,"column":6},"end":{"line":157,"column":null}},{"start":{"line":142,"column":6},"end":{"line":157,"column":null}}],"line":130},"17":{"loc":{"start":{"line":133,"column":10},"end":{"line":139,"column":null}},"type":"if","locations":[{"start":{"line":133,"column":10},"end":{"line":139,"column":null}},{"start":{},"end":{}}],"line":133},"18":{"loc":{"start":{"line":135,"column":12},"end":{"line":137,"column":null}},"type":"if","locations":[{"start":{"line":135,"column":12},"end":{"line":137,"column":null}},{"start":{},"end":{}}],"line":135},"19":{"loc":{"start":{"line":142,"column":6},"end":{"line":157,"column":null}},"type":"if","locations":[{"start":{"line":142,"column":6},"end":{"line":157,"column":null}},{"start":{"line":150,"column":6},"end":{"line":157,"column":null}}],"line":142},"20":{"loc":{"start":{"line":145,"column":10},"end":{"line":147,"column":null}},"type":"if","locations":[{"start":{"line":145,"column":10},"end":{"line":147,"column":null}},{"start":{},"end":{}}],"line":145},"21":{"loc":{"start":{"line":150,"column":6},"end":{"line":157,"column":null}},"type":"if","locations":[{"start":{"line":150,"column":6},"end":{"line":157,"column":null}},{"start":{},"end":{}}],"line":150},"22":{"loc":{"start":{"line":152,"column":10},"end":{"line":154,"column":null}},"type":"if","locations":[{"start":{"line":152,"column":10},"end":{"line":154,"column":null}},{"start":{},"end":{}}],"line":152},"23":{"loc":{"start":{"line":152,"column":14},"end":{"line":152,"column":64}},"type":"binary-expr","locations":[{"start":{"line":152,"column":14},"end":{"line":152,"column":35}},{"start":{"line":152,"column":35},"end":{"line":152,"column":64}}],"line":152},"24":{"loc":{"start":{"line":171,"column":10},"end":{"line":176,"column":null}},"type":"if","locations":[{"start":{"line":171,"column":10},"end":{"line":176,"column":null}},{"start":{},"end":{}}],"line":171},"25":{"loc":{"start":{"line":172,"column":12},"end":{"line":174,"column":null}},"type":"if","locations":[{"start":{"line":172,"column":12},"end":{"line":174,"column":null}},{"start":{},"end":{}}],"line":172},"26":{"loc":{"start":{"line":172,"column":16},"end":{"line":172,"column":85}},"type":"binary-expr","locations":[{"start":{"line":172,"column":16},"end":{"line":172,"column":40}},{"start":{"line":172,"column":40},"end":{"line":172,"column":56}},{"start":{"line":172,"column":56},"end":{"line":172,"column":67}},{"start":{"line":172,"column":67},"end":{"line":172,"column":85}}],"line":172},"27":{"loc":{"start":{"line":179,"column":10},"end":{"line":187,"column":null}},"type":"if","locations":[{"start":{"line":179,"column":10},"end":{"line":187,"column":null}},{"start":{},"end":{}}],"line":179},"28":{"loc":{"start":{"line":179,"column":14},"end":{"line":179,"column":73}},"type":"binary-expr","locations":[{"start":{"line":179,"column":14},"end":{"line":179,"column":39}},{"start":{"line":179,"column":39},"end":{"line":179,"column":73}}],"line":179},"29":{"loc":{"start":{"line":181,"column":12},"end":{"line":186,"column":null}},"type":"if","locations":[{"start":{"line":181,"column":12},"end":{"line":186,"column":null}},{"start":{},"end":{}}],"line":181},"30":{"loc":{"start":{"line":181,"column":16},"end":{"line":181,"column":69}},"type":"binary-expr","locations":[{"start":{"line":181,"column":16},"end":{"line":181,"column":33}},{"start":{"line":181,"column":33},"end":{"line":181,"column":47}},{"start":{"line":181,"column":47},"end":{"line":181,"column":69}}],"line":181},"31":{"loc":{"start":{"line":183,"column":14},"end":{"line":185,"column":null}},"type":"if","locations":[{"start":{"line":183,"column":14},"end":{"line":185,"column":null}},{"start":{},"end":{}}],"line":183},"32":{"loc":{"start":{"line":195,"column":6},"end":{"line":195,"column":null}},"type":"if","locations":[{"start":{"line":195,"column":6},"end":{"line":195,"column":null}},{"start":{},"end":{}}],"line":195},"33":{"loc":{"start":{"line":199,"column":4},"end":{"line":199,"column":null}},"type":"if","locations":[{"start":{"line":199,"column":4},"end":{"line":199,"column":null}},{"start":{},"end":{}}],"line":199},"34":{"loc":{"start":{"line":204,"column":2},"end":{"line":204,"column":null}},"type":"if","locations":[{"start":{"line":204,"column":2},"end":{"line":204,"column":null}},{"start":{},"end":{}}],"line":204},"35":{"loc":{"start":{"line":205,"column":2},"end":{"line":205,"column":null}},"type":"if","locations":[{"start":{"line":205,"column":2},"end":{"line":205,"column":null}},{"start":{},"end":{}}],"line":205},"36":{"loc":{"start":{"line":209,"column":7},"end":{"line":229,"column":null}},"type":"cond-expr","locations":[{"start":{"line":210,"column":8},"end":{"line":210,"column":null}},{"start":{"line":212,"column":8},"end":{"line":229,"column":null}}],"line":209},"37":{"loc":{"start":{"line":224,"column":11},"end":{"line":227,"column":null}},"type":"binary-expr","locations":[{"start":{"line":224,"column":11},"end":{"line":224,"column":null}},{"start":{"line":225,"column":12},"end":{"line":227,"column":null}}],"line":224},"38":{"loc":{"start":{"line":226,"column":15},"end":{"line":226,"column":null}},"type":"cond-expr","locations":[{"start":{"line":226,"column":29},"end":{"line":226,"column":49}},{"start":{"line":226,"column":49},"end":{"line":226,"column":null}}],"line":226}},"s":{"0":27,"1":27,"2":27,"3":27,"4":27,"5":27,"6":27,"7":27,"8":27,"9":27,"10":8,"11":1,"12":7,"13":7,"14":8,"15":8,"16":8,"17":8,"18":2,"19":6,"20":1,"21":8,"22":1,"23":8,"24":8,"25":0,"26":8,"27":0,"28":8,"29":0,"30":0,"31":8,"32":8,"33":8,"34":8,"35":8,"36":8,"37":7,"38":0,"39":7,"40":6,"41":1,"42":1,"43":5,"44":6,"45":6,"46":6,"47":1,"48":1,"49":1,"50":27,"51":7,"52":7,"53":27,"54":2,"55":2,"56":2,"57":27,"58":2,"59":2,"60":2,"61":3,"62":2,"63":0,"64":27,"65":1,"66":1,"67":1,"68":2,"69":1,"70":0,"71":27,"72":23,"73":3,"74":0,"75":3,"76":2,"77":2,"78":2,"79":2,"80":2,"81":1,"82":2,"83":2,"84":1,"85":0,"86":0,"87":0,"88":0,"89":0,"90":1,"91":1,"92":1,"93":1,"94":1,"95":23,"96":23,"97":23,"98":27,"99":24,"100":2,"101":2,"102":1,"103":1,"104":1,"105":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":24,"112":15,"113":15,"114":15,"115":24,"116":24,"117":10,"118":24,"119":24,"120":27,"121":13,"122":14,"123":14,"124":13,"125":21,"126":0},"f":{"0":27,"1":8,"2":7,"3":6,"4":1,"5":1,"6":7,"7":2,"8":2,"9":2,"10":3,"11":0,"12":1,"13":1,"14":2,"15":0,"16":23,"17":3,"18":2,"19":0,"20":1,"21":23,"22":24,"23":2,"24":2,"25":15,"26":24,"27":21,"28":0},"b":{"0":[27,27],"1":[1,7],"2":[2,6],"3":[1,5],"4":[1,7],"5":[0,8],"6":[0,8],"7":[0,8],"8":[8,0],"9":[8,0],"10":[0,7],"11":[1,5],"12":[2,0],"13":[2,1],"14":[1,1],"15":[0,3],"16":[2,1],"17":[2,0],"18":[1,1],"19":[0,1],"20":[0,0],"21":[1,0],"22":[1,0],"23":[1,1],"24":[1,1],"25":[1,0],"26":[1,1,1,1],"27":[1,0],"28":[1,1],"29":[1,0],"30":[1,1,1],"31":[1,0],"32":[15,0],"33":[10,14],"34":[13,14],"35":[1,13],"36":[0,13],"37":[13,13],"38":[1,12]},"meta":{"lastBranch":39,"lastFunction":29,"lastStatement":127,"seen":{"f:8:24:8:36":0,"s:9:26:9:Infinity":0,"s:10:21:10:Infinity":1,"s:11:19:11:Infinity":2,"b:11:19:11:49:11:49:11:Infinity":0,"s:13:24:13:Infinity":3,"s:14:28:14:Infinity":4,"s:15:36:15:Infinity":5,"s:16:28:16:Infinity":6,"s:17:24:17:Infinity":7,"s:18:40:18:Infinity":8,"s:20:21:87:Infinity":9,"f:20:21:20:22":1,"b:21:4:26:Infinity:23:11:26:Infinity":1,"s:21:4:26:Infinity":10,"s:22:6:22:Infinity":11,"s:24:6:24:Infinity":12,"s:25:6:25:Infinity":13,"s:27:4:27:Infinity":14,"s:29:14:29:Infinity":15,"s:30:19:30:Infinity":16,"b:32:4:36:Infinity:34:4:36:Infinity":2,"s:32:4:36:Infinity":17,"s:33:6:33:Infinity":18,"b:34:4:36:Infinity:undefined:undefined:undefined:undefined":3,"s:34:4:36:Infinity":19,"s:35:6:35:Infinity":20,"b:38:4:40:Infinity:undefined:undefined:undefined:undefined":4,"s:38:4:40:Infinity":21,"s:39:6:39:Infinity":22,"s:43:24:43:Infinity":23,"b:44:4:46:Infinity:undefined:undefined:undefined:undefined":5,"s:44:4:46:Infinity":24,"s:45:6:45:Infinity":25,"b:48:4:58:Infinity:50:4:58:Infinity":6,"s:48:4:58:Infinity":26,"s:49:6:49:Infinity":27,"b:50:4:58:Infinity:53:11:58:Infinity":7,"s:50:4:58:Infinity":28,"s:51:6:51:Infinity":29,"s:52:6:52:Infinity":30,"b:55:6:57:Infinity:undefined:undefined:undefined:undefined":8,"s:55:6:57:Infinity":31,"s:56:8:56:Infinity":32,"s:60:24:60:Infinity":33,"b:61:4:63:Infinity:undefined:undefined:undefined:undefined":9,"s:61:4:63:Infinity":34,"s:62:6:62:Infinity":35,"s:65:4:86:Infinity":36,"f:66:12:66:13":2,"b:67:8:69:Infinity:undefined:undefined:undefined:undefined":10,"s:67:8:69:Infinity":37,"s:68:10:68:Infinity":38,"s:70:8:70:Infinity":39,"f:72:12:72:13":3,"b:73:8:77:Infinity:75:15:77:Infinity":11,"s:73:8:77:Infinity":40,"s:74:10:74:Infinity":41,"f:74:19:74:20":4,"s:74:29:74:47":42,"s:76:10:76:Infinity":43,"s:78:8:78:Infinity":44,"s:79:8:79:Infinity":45,"s:80:8:80:Infinity":46,"f:82:13:82:14":5,"s:83:8:83:Infinity":47,"s:84:8:84:Infinity":48,"s:85:8:85:Infinity":49,"s:89:2:92:Infinity":50,"f:89:12:89:18":6,"s:90:4:90:Infinity":51,"s:91:4:91:Infinity":52,"s:95:23:100:Infinity":53,"f:95:23:95:24":7,"s:96:20:96:Infinity":54,"b:97:4:99:Infinity:undefined:undefined:undefined:undefined":12,"s:97:4:99:Infinity":55,"s:98:6:98:Infinity":56,"s:102:21:112:Infinity":57,"f:102:21:102:22":8,"s:103:24:103:Infinity":58,"s:105:4:105:Infinity":59,"f:105:13:105:14":9,"s:105:28:105:88":60,"f:105:42:105:43":10,"s:105:50:105:87":61,"b:105:71:105:85:105:85:105:87":13,"s:107:4:111:Infinity":62,"f:111:13:111:14":11,"s:111:22:111:63":63,"s:114:21:124:Infinity":64,"f:114:21:114:22":12,"s:115:24:115:Infinity":65,"s:117:4:117:Infinity":66,"f:117:13:117:14":13,"s:117:28:117:88":67,"f:117:42:117:43":14,"s:117:50:117:87":68,"b:117:71:117:85:117:85:117:87":14,"s:119:4:123:Infinity":69,"f:123:13:123:14":15,"s:123:22:123:65":70,"s:126:2:162:Infinity":71,"f:126:12:126:18":16,"s:127:26:158:Infinity":72,"f:127:26:127:27":17,"b:128:6:128:Infinity:undefined:undefined:undefined:undefined":15,"s:128:6:128:Infinity":73,"s:128:30:128:Infinity":74,"b:130:6:157:Infinity:142:6:157:Infinity":16,"s:130:6:157:Infinity":75,"s:131:8:141:Infinity":76,"f:131:25:131:26":18,"s:132:28:132:Infinity":77,"b:133:10:139:Infinity:undefined:undefined:undefined:undefined":17,"s:133:10:139:Infinity":78,"s:134:25:134:Infinity":79,"b:135:12:137:Infinity:undefined:undefined:undefined:undefined":18,"s:135:12:137:Infinity":80,"s:136:14:136:Infinity":81,"s:138:12:138:Infinity":82,"s:140:10:140:Infinity":83,"b:142:6:157:Infinity:150:6:157:Infinity":19,"s:142:6:157:Infinity":84,"s:143:8:149:Infinity":85,"f:143:25:143:26":19,"s:144:28:144:Infinity":86,"b:145:10:147:Infinity:undefined:undefined:undefined:undefined":20,"s:145:10:147:Infinity":87,"s:146:12:146:Infinity":88,"s:148:10:148:Infinity":89,"b:150:6:157:Infinity:undefined:undefined:undefined:undefined":21,"s:150:6:157:Infinity":90,"s:151:8:156:Infinity":91,"f:151:25:151:26":20,"b:152:10:154:Infinity:undefined:undefined:undefined:undefined":22,"s:152:10:154:Infinity":92,"b:152:14:152:35:152:35:152:64":23,"s:153:12:153:Infinity":93,"s:155:10:155:Infinity":94,"s:160:4:160:Infinity":95,"s:161:4:161:Infinity":96,"f:161:11:161:17":21,"s:161:17:161:Infinity":97,"s:166:2:202:Infinity":98,"f:166:12:166:18":22,"s:167:21:191:Infinity":99,"f:168:6:168:7":23,"s:169:8:188:Infinity":100,"f:169:24:169:25":24,"b:171:10:176:Infinity:undefined:undefined:undefined:undefined":24,"s:171:10:176:Infinity":101,"b:172:12:174:Infinity:undefined:undefined:undefined:undefined":25,"s:172:12:174:Infinity":102,"b:172:16:172:40:172:40:172:56:172:56:172:67:172:67:172:85":26,"s:173:14:173:Infinity":103,"s:175:12:175:Infinity":104,"b:179:10:187:Infinity:undefined:undefined:undefined:undefined":27,"s:179:10:187:Infinity":105,"b:179:14:179:39:179:39:179:73":28,"s:180:26:180:Infinity":106,"b:181:12:186:Infinity:undefined:undefined:undefined:undefined":29,"s:181:12:186:Infinity":107,"b:181:16:181:33:181:33:181:47:181:47:181:69":30,"s:182:27:182:Infinity":108,"b:183:14:185:Infinity:undefined:undefined:undefined:undefined":31,"s:183:14:185:Infinity":109,"s:184:16:184:Infinity":110,"s:193:4:196:Infinity":111,"f:193:18:193:19":25,"s:194:17:194:Infinity":112,"b:195:6:195:Infinity:undefined:undefined:undefined:undefined":32,"s:195:6:195:Infinity":113,"s:195:14:195:Infinity":114,"s:198:21:198:Infinity":115,"b:199:4:199:Infinity:undefined:undefined:undefined:undefined":33,"s:199:4:199:Infinity":116,"s:199:18:199:Infinity":117,"s:201:4:201:Infinity":118,"f:201:11:201:17":26,"s:201:17:201:Infinity":119,"b:204:2:204:Infinity:undefined:undefined:undefined:undefined":34,"s:204:2:204:Infinity":120,"s:204:15:204:Infinity":121,"b:205:2:205:Infinity:undefined:undefined:undefined:undefined":35,"s:205:2:205:Infinity":122,"s:205:13:205:Infinity":123,"s:207:2:231:Infinity":124,"b:210:8:210:Infinity:212:8:229:Infinity":36,"f:213:21:213:22":27,"s:214:12:222:Infinity":125,"f:219:23:219:29":28,"s:219:29:219:Infinity":126,"b:224:11:224:Infinity:225:12:227:Infinity":37,"b:226:29:226:49:226:49:226:Infinity":38}}} +,"/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedList.css": {"path":"/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedList.css","statementMap":{},"fnMap":{},"branchMap":{},"s":{},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":0,"seen":{}}} +,"/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedList.tsx": {"path":"/Users/adam/workspace/vibecode/neko/frontend/src/components/FeedList.tsx","statementMap":{"0":{"start":{"line":16,"column":24},"end":{"line":16,"column":null}},"1":{"start":{"line":17,"column":22},"end":{"line":17,"column":null}},"2":{"start":{"line":18,"column":28},"end":{"line":18,"column":null}},"3":{"start":{"line":19,"column":24},"end":{"line":19,"column":null}},"4":{"start":{"line":20,"column":40},"end":{"line":20,"column":null}},"5":{"start":{"line":21,"column":36},"end":{"line":21,"column":null}},"6":{"start":{"line":22,"column":8},"end":{"line":22,"column":null}},"7":{"start":{"line":23,"column":21},"end":{"line":23,"column":null}},"8":{"start":{"line":24,"column":8},"end":{"line":24,"column":null}},"9":{"start":{"line":25,"column":26},"end":{"line":25,"column":null}},"10":{"start":{"line":28,"column":4},"end":{"line":29,"column":null}},"11":{"start":{"line":31,"column":23},"end":{"line":36,"column":null}},"12":{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},"13":{"start":{"line":33,"column":4},"end":{"line":35,"column":null}},"14":{"start":{"line":34,"column":6},"end":{"line":34,"column":null}},"15":{"start":{"line":38,"column":22},"end":{"line":40,"column":null}},"16":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"17":{"start":{"line":42,"column":2},"end":{"line":62,"column":null}},"18":{"start":{"line":43,"column":4},"end":{"line":61,"column":null}},"19":{"start":{"line":45,"column":8},"end":{"line":45,"column":null}},"20":{"start":{"line":45,"column":21},"end":{"line":45,"column":null}},"21":{"start":{"line":46,"column":8},"end":{"line":46,"column":null}},"22":{"start":{"line":49,"column":8},"end":{"line":49,"column":null}},"23":{"start":{"line":49,"column":21},"end":{"line":49,"column":null}},"24":{"start":{"line":50,"column":8},"end":{"line":50,"column":null}},"25":{"start":{"line":54,"column":8},"end":{"line":54,"column":null}},"26":{"start":{"line":55,"column":8},"end":{"line":55,"column":null}},"27":{"start":{"line":56,"column":8},"end":{"line":56,"column":null}},"28":{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},"29":{"start":{"line":60,"column":8},"end":{"line":60,"column":null}},"30":{"start":{"line":64,"column":2},"end":{"line":64,"column":null}},"31":{"start":{"line":64,"column":15},"end":{"line":64,"column":null}},"32":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"33":{"start":{"line":65,"column":13},"end":{"line":65,"column":null}},"34":{"start":{"line":67,"column":23},"end":{"line":69,"column":null}},"35":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"36":{"start":{"line":68,"column":60},"end":{"line":68,"column":95}},"37":{"start":{"line":71,"column":2},"end":{"line":183,"column":null}},"38":{"start":{"line":73,"column":42},"end":{"line":73,"column":68}},"39":{"start":{"line":83,"column":29},"end":{"line":83,"column":null}},"40":{"start":{"line":115,"column":12},"end":{"line":122,"column":null}},"41":{"start":{"line":137,"column":16},"end":{"line":144,"column":null}},"42":{"start":{"line":168,"column":27},"end":{"line":168,"column":null}},"43":{"start":{"line":175,"column":27},"end":{"line":175,"column":null}}},"fnMap":{"0":{"name":"FeedList","decl":{"start":{"line":7,"column":24},"end":{"line":7,"column":33}},"loc":{"start":{"line":15,"column":3},"end":{"line":185,"column":null}},"line":15},"1":{"name":"(anonymous_1)","decl":{"start":{"line":31,"column":23},"end":{"line":31,"column":24}},"loc":{"start":{"line":31,"column":47},"end":{"line":36,"column":null}},"line":31},"2":{"name":"(anonymous_2)","decl":{"start":{"line":38,"column":22},"end":{"line":38,"column":28}},"loc":{"start":{"line":38,"column":28},"end":{"line":40,"column":null}},"line":38},"3":{"name":"(anonymous_3)","decl":{"start":{"line":42,"column":12},"end":{"line":42,"column":18}},"loc":{"start":{"line":42,"column":18},"end":{"line":62,"column":5}},"line":42},"4":{"name":"(anonymous_4)","decl":{"start":{"line":44,"column":34},"end":{"line":44,"column":35}},"loc":{"start":{"line":44,"column":43},"end":{"line":47,"column":7}},"line":44},"5":{"name":"(anonymous_5)","decl":{"start":{"line":48,"column":32},"end":{"line":48,"column":33}},"loc":{"start":{"line":48,"column":41},"end":{"line":51,"column":7}},"line":48},"6":{"name":"(anonymous_6)","decl":{"start":{"line":53,"column":12},"end":{"line":53,"column":13}},"loc":{"start":{"line":53,"column":39},"end":{"line":57,"column":7}},"line":53},"7":{"name":"(anonymous_7)","decl":{"start":{"line":58,"column":13},"end":{"line":58,"column":14}},"loc":{"start":{"line":58,"column":22},"end":{"line":61,"column":7}},"line":58},"8":{"name":"(anonymous_8)","decl":{"start":{"line":67,"column":23},"end":{"line":67,"column":29}},"loc":{"start":{"line":67,"column":29},"end":{"line":69,"column":null}},"line":67},"9":{"name":"(anonymous_9)","decl":{"start":{"line":68,"column":53},"end":{"line":68,"column":60}},"loc":{"start":{"line":68,"column":60},"end":{"line":68,"column":95}},"line":68},"10":{"name":"(anonymous_10)","decl":{"start":{"line":73,"column":36},"end":{"line":73,"column":42}},"loc":{"start":{"line":73,"column":42},"end":{"line":73,"column":68}},"line":73},"11":{"name":"(anonymous_11)","decl":{"start":{"line":83,"column":22},"end":{"line":83,"column":23}},"loc":{"start":{"line":83,"column":29},"end":{"line":83,"column":null}},"line":83},"12":{"name":"(anonymous_12)","decl":{"start":{"line":110,"column":21},"end":{"line":110,"column":27}},"loc":{"start":{"line":110,"column":27},"end":{"line":110,"column":32}},"line":110},"13":{"name":"(anonymous_13)","decl":{"start":{"line":114,"column":20},"end":{"line":114,"column":21}},"loc":{"start":{"line":115,"column":12},"end":{"line":122,"column":null}},"line":115},"14":{"name":"(anonymous_14)","decl":{"start":{"line":136,"column":25},"end":{"line":136,"column":26}},"loc":{"start":{"line":137,"column":16},"end":{"line":144,"column":null}},"line":137},"15":{"name":"(anonymous_15)","decl":{"start":{"line":168,"column":21},"end":{"line":168,"column":27}},"loc":{"start":{"line":168,"column":27},"end":{"line":168,"column":null}},"line":168},"16":{"name":"(anonymous_16)","decl":{"start":{"line":175,"column":21},"end":{"line":175,"column":27}},"loc":{"start":{"line":175,"column":27},"end":{"line":175,"column":null}},"line":175}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":4},"end":{"line":29,"column":null}},"type":"binary-expr","locations":[{"start":{"line":28,"column":4},"end":{"line":28,"column":null}},{"start":{"line":29,"column":5},"end":{"line":29,"column":null}}],"line":28},"1":{"loc":{"start":{"line":29,"column":5},"end":{"line":29,"column":null}},"type":"cond-expr","locations":[{"start":{"line":29,"column":56},"end":{"line":29,"column":67}},{"start":{"line":29,"column":67},"end":{"line":29,"column":null}}],"line":29},"2":{"loc":{"start":{"line":29,"column":5},"end":{"line":29,"column":56}},"type":"binary-expr","locations":[{"start":{"line":29,"column":5},"end":{"line":29,"column":34}},{"start":{"line":29,"column":34},"end":{"line":29,"column":45}},{"start":{"line":29,"column":45},"end":{"line":29,"column":56}}],"line":29},"3":{"loc":{"start":{"line":33,"column":4},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":35,"column":null}},{"start":{},"end":{}}],"line":33},"4":{"loc":{"start":{"line":45,"column":8},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":8},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":45},"5":{"loc":{"start":{"line":49,"column":8},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":8},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":49},"6":{"loc":{"start":{"line":64,"column":2},"end":{"line":64,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":2},"end":{"line":64,"column":null}},{"start":{},"end":{}}],"line":64},"7":{"loc":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":65},"8":{"loc":{"start":{"line":92,"column":50},"end":{"line":92,"column":94}},"type":"cond-expr","locations":[{"start":{"line":92,"column":79},"end":{"line":92,"column":90}},{"start":{"line":92,"column":90},"end":{"line":92,"column":94}}],"line":92},"9":{"loc":{"start":{"line":97,"column":47},"end":{"line":97,"column":88}},"type":"cond-expr","locations":[{"start":{"line":97,"column":73},"end":{"line":97,"column":84}},{"start":{"line":97,"column":84},"end":{"line":97,"column":88}}],"line":97},"10":{"loc":{"start":{"line":102,"column":51},"end":{"line":102,"column":96}},"type":"cond-expr","locations":[{"start":{"line":102,"column":81},"end":{"line":102,"column":92}},{"start":{"line":102,"column":92},"end":{"line":102,"column":96}}],"line":102},"11":{"loc":{"start":{"line":118,"column":39},"end":{"line":118,"column":76}},"type":"cond-expr","locations":[{"start":{"line":118,"column":63},"end":{"line":118,"column":74}},{"start":{"line":118,"column":74},"end":{"line":118,"column":76}}],"line":118},"12":{"loc":{"start":{"line":131,"column":9},"end":{"line":146,"column":null}},"type":"binary-expr","locations":[{"start":{"line":131,"column":9},"end":{"line":131,"column":null}},{"start":{"line":132,"column":11},"end":{"line":146,"column":null}}],"line":131},"13":{"loc":{"start":{"line":132,"column":11},"end":{"line":146,"column":null}},"type":"cond-expr","locations":[{"start":{"line":133,"column":12},"end":{"line":133,"column":null}},{"start":{"line":135,"column":12},"end":{"line":146,"column":null}}],"line":132},"14":{"loc":{"start":{"line":140,"column":45},"end":{"line":140,"column":88}},"type":"cond-expr","locations":[{"start":{"line":140,"column":75},"end":{"line":140,"column":86}},{"start":{"line":140,"column":86},"end":{"line":140,"column":88}}],"line":140},"15":{"loc":{"start":{"line":142,"column":21},"end":{"line":142,"column":null}},"type":"binary-expr","locations":[{"start":{"line":142,"column":21},"end":{"line":142,"column":35}},{"start":{"line":142,"column":35},"end":{"line":142,"column":null}}],"line":142},"16":{"loc":{"start":{"line":169,"column":23},"end":{"line":169,"column":null}},"type":"cond-expr","locations":[{"start":{"line":169,"column":43},"end":{"line":169,"column":54}},{"start":{"line":169,"column":54},"end":{"line":169,"column":null}}],"line":169},"17":{"loc":{"start":{"line":176,"column":23},"end":{"line":176,"column":null}},"type":"cond-expr","locations":[{"start":{"line":176,"column":42},"end":{"line":176,"column":53}},{"start":{"line":176,"column":53},"end":{"line":176,"column":null}}],"line":176}},"s":{"0":13,"1":13,"2":13,"3":13,"4":13,"5":13,"6":13,"7":13,"8":13,"9":13,"10":13,"11":13,"12":0,"13":0,"14":0,"15":13,"16":2,"17":13,"18":6,"19":4,"20":0,"21":4,"22":4,"23":0,"24":4,"25":4,"26":4,"27":4,"28":1,"29":1,"30":13,"31":6,"32":7,"33":7,"34":6,"35":1,"36":1,"37":6,"38":0,"39":0,"40":4,"41":2,"42":0,"43":0},"f":{"0":13,"1":0,"2":2,"3":6,"4":4,"5":4,"6":4,"7":1,"8":1,"9":1,"10":0,"11":0,"12":0,"13":4,"14":2,"15":0,"16":0},"b":{"0":[13,13],"1":[13,0],"2":[13,13,13],"3":[0,0],"4":[0,4],"5":[0,4],"6":[6,7],"7":[1,6],"8":[6,0],"9":[0,6],"10":[0,6],"11":[0,4],"12":[13,2],"13":[1,1],"14":[0,2],"15":[2,0],"16":[6,0],"17":[0,6]},"meta":{"lastBranch":18,"lastFunction":17,"lastStatement":44,"seen":{"f:7:24:7:33":0,"s:16:24:16:Infinity":0,"s:17:22:17:Infinity":1,"s:18:28:18:Infinity":2,"s:19:24:19:Infinity":3,"s:20:40:20:Infinity":4,"s:21:36:21:Infinity":5,"s:22:8:22:Infinity":6,"s:23:21:23:Infinity":7,"s:24:8:24:Infinity":8,"s:25:26:25:Infinity":9,"s:28:4:29:Infinity":10,"b:28:4:28:Infinity:29:5:29:Infinity":0,"b:29:56:29:67:29:67:29:Infinity":1,"b:29:5:29:34:29:34:29:45:29:45:29:56":2,"s:31:23:36:Infinity":11,"f:31:23:31:24":1,"s:32:4:32:Infinity":12,"b:33:4:35:Infinity:undefined:undefined:undefined:undefined":3,"s:33:4:35:Infinity":13,"s:34:6:34:Infinity":14,"s:38:22:40:Infinity":15,"f:38:22:38:28":2,"s:39:4:39:Infinity":16,"s:42:2:62:Infinity":17,"f:42:12:42:18":3,"s:43:4:61:Infinity":18,"f:44:34:44:35":4,"b:45:8:45:Infinity:undefined:undefined:undefined:undefined":4,"s:45:8:45:Infinity":19,"s:45:21:45:Infinity":20,"s:46:8:46:Infinity":21,"f:48:32:48:33":5,"b:49:8:49:Infinity:undefined:undefined:undefined:undefined":5,"s:49:8:49:Infinity":22,"s:49:21:49:Infinity":23,"s:50:8:50:Infinity":24,"f:53:12:53:13":6,"s:54:8:54:Infinity":25,"s:55:8:55:Infinity":26,"s:56:8:56:Infinity":27,"f:58:13:58:14":7,"s:59:8:59:Infinity":28,"s:60:8:60:Infinity":29,"b:64:2:64:Infinity:undefined:undefined:undefined:undefined":6,"s:64:2:64:Infinity":30,"s:64:15:64:Infinity":31,"b:65:2:65:Infinity:undefined:undefined:undefined:undefined":7,"s:65:2:65:Infinity":32,"s:65:13:65:Infinity":33,"s:67:23:69:Infinity":34,"f:67:23:67:29":8,"s:68:4:68:Infinity":35,"f:68:53:68:60":9,"s:68:60:68:95":36,"s:71:2:183:Infinity":37,"f:73:36:73:42":10,"s:73:42:73:68":38,"f:83:22:83:23":11,"s:83:29:83:Infinity":39,"b:92:79:92:90:92:90:92:94":8,"b:97:73:97:84:97:84:97:88":9,"b:102:81:102:92:102:92:102:96":10,"f:110:21:110:27":12,"f:114:20:114:21":13,"s:115:12:122:Infinity":40,"b:118:63:118:74:118:74:118:76":11,"b:131:9:131:Infinity:132:11:146:Infinity":12,"b:133:12:133:Infinity:135:12:146:Infinity":13,"f:136:25:136:26":14,"s:137:16:144:Infinity":41,"b:140:75:140:86:140:86:140:88":14,"b:142:21:142:35:142:35:142:Infinity":15,"f:168:21:168:27":15,"s:168:27:168:Infinity":42,"b:169:43:169:54:169:54:169:Infinity":16,"f:175:21:175:27":16,"s:175:27:175:Infinity":43,"b:176:42:176:53:176:53:176:Infinity":17}}} +,"/Users/adam/workspace/vibecode/neko/frontend/src/components/Login.css": {"path":"/Users/adam/workspace/vibecode/neko/frontend/src/components/Login.css","statementMap":{},"fnMap":{},"branchMap":{},"s":{},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":0,"seen":{}}} +,"/Users/adam/workspace/vibecode/neko/frontend/src/components/Login.tsx": {"path":"/Users/adam/workspace/vibecode/neko/frontend/src/components/Login.tsx","statementMap":{"0":{"start":{"line":8,"column":30},"end":{"line":8,"column":null}},"1":{"start":{"line":9,"column":24},"end":{"line":9,"column":null}},"2":{"start":{"line":10,"column":8},"end":{"line":10,"column":null}},"3":{"start":{"line":12,"column":23},"end":{"line":35,"column":null}},"4":{"start":{"line":13,"column":4},"end":{"line":13,"column":null}},"5":{"start":{"line":14,"column":4},"end":{"line":14,"column":null}},"6":{"start":{"line":16,"column":4},"end":{"line":34,"column":null}},"7":{"start":{"line":18,"column":21},"end":{"line":18,"column":null}},"8":{"start":{"line":19,"column":6},"end":{"line":19,"column":null}},"9":{"start":{"line":21,"column":18},"end":{"line":24,"column":null}},"10":{"start":{"line":26,"column":6},"end":{"line":31,"column":null}},"11":{"start":{"line":27,"column":8},"end":{"line":27,"column":null}},"12":{"start":{"line":29,"column":21},"end":{"line":29,"column":null}},"13":{"start":{"line":30,"column":8},"end":{"line":30,"column":null}},"14":{"start":{"line":33,"column":6},"end":{"line":33,"column":null}},"15":{"start":{"line":37,"column":2},"end":{"line":54,"column":null}},"16":{"start":{"line":47,"column":29},"end":{"line":47,"column":null}}},"fnMap":{"0":{"name":"Login","decl":{"start":{"line":7,"column":24},"end":{"line":7,"column":32}},"loc":{"start":{"line":7,"column":32},"end":{"line":56,"column":null}},"line":7},"1":{"name":"(anonymous_1)","decl":{"start":{"line":12,"column":23},"end":{"line":12,"column":30}},"loc":{"start":{"line":12,"column":47},"end":{"line":35,"column":null}},"line":12},"2":{"name":"(anonymous_2)","decl":{"start":{"line":47,"column":22},"end":{"line":47,"column":23}},"loc":{"start":{"line":47,"column":29},"end":{"line":47,"column":null}},"line":47}},"branchMap":{"0":{"loc":{"start":{"line":26,"column":6},"end":{"line":31,"column":null}},"type":"if","locations":[{"start":{"line":26,"column":6},"end":{"line":31,"column":null}},{"start":{"line":28,"column":13},"end":{"line":31,"column":null}}],"line":26},"1":{"loc":{"start":{"line":30,"column":17},"end":{"line":30,"column":47}},"type":"binary-expr","locations":[{"start":{"line":30,"column":17},"end":{"line":30,"column":33}},{"start":{"line":30,"column":33},"end":{"line":30,"column":47}}],"line":30},"2":{"loc":{"start":{"line":51,"column":9},"end":{"line":51,"column":null}},"type":"binary-expr","locations":[{"start":{"line":51,"column":9},"end":{"line":51,"column":18}},{"start":{"line":51,"column":18},"end":{"line":51,"column":null}}],"line":51}},"s":{"0":14,"1":14,"2":14,"3":14,"4":3,"5":3,"6":3,"7":3,"8":3,"9":3,"10":2,"11":1,"12":1,"13":1,"14":1,"15":14,"16":3},"f":{"0":14,"1":3,"2":3},"b":{"0":[1,1],"1":[1,0],"2":[14,2]},"meta":{"lastBranch":3,"lastFunction":3,"lastStatement":17,"seen":{"f:7:24:7:32":0,"s:8:30:8:Infinity":0,"s:9:24:9:Infinity":1,"s:10:8:10:Infinity":2,"s:12:23:35:Infinity":3,"f:12:23:12:30":1,"s:13:4:13:Infinity":4,"s:14:4:14:Infinity":5,"s:16:4:34:Infinity":6,"s:18:21:18:Infinity":7,"s:19:6:19:Infinity":8,"s:21:18:24:Infinity":9,"b:26:6:31:Infinity:28:13:31:Infinity":0,"s:26:6:31:Infinity":10,"s:27:8:27:Infinity":11,"s:29:21:29:Infinity":12,"s:30:8:30:Infinity":13,"b:30:17:30:33:30:33:30:47":1,"s:33:6:33:Infinity":14,"s:37:2:54:Infinity":15,"f:47:22:47:23":2,"s:47:29:47:Infinity":16,"b:51:9:51:18:51:18:51:Infinity":2}}} +,"/Users/adam/workspace/vibecode/neko/frontend/src/components/Settings.css": {"path":"/Users/adam/workspace/vibecode/neko/frontend/src/components/Settings.css","statementMap":{},"fnMap":{},"branchMap":{},"s":{},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":0,"seen":{}}} +,"/Users/adam/workspace/vibecode/neko/frontend/src/components/Settings.tsx": {"path":"/Users/adam/workspace/vibecode/neko/frontend/src/components/Settings.tsx","statementMap":{"0":{"start":{"line":7,"column":24},"end":{"line":7,"column":null}},"1":{"start":{"line":8,"column":34},"end":{"line":8,"column":null}},"2":{"start":{"line":9,"column":28},"end":{"line":9,"column":null}},"3":{"start":{"line":10,"column":24},"end":{"line":10,"column":null}},"4":{"start":{"line":12,"column":34},"end":{"line":12,"column":null}},"5":{"start":{"line":14,"column":21},"end":{"line":29,"column":null}},"6":{"start":{"line":15,"column":4},"end":{"line":15,"column":null}},"7":{"start":{"line":16,"column":4},"end":{"line":28,"column":null}},"8":{"start":{"line":18,"column":8},"end":{"line":18,"column":null}},"9":{"start":{"line":18,"column":21},"end":{"line":18,"column":null}},"10":{"start":{"line":19,"column":8},"end":{"line":19,"column":null}},"11":{"start":{"line":22,"column":8},"end":{"line":22,"column":null}},"12":{"start":{"line":23,"column":8},"end":{"line":23,"column":null}},"13":{"start":{"line":26,"column":8},"end":{"line":26,"column":null}},"14":{"start":{"line":27,"column":8},"end":{"line":27,"column":null}},"15":{"start":{"line":31,"column":2},"end":{"line":33,"column":null}},"16":{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},"17":{"start":{"line":35,"column":24},"end":{"line":57,"column":null}},"18":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"19":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"20":{"start":{"line":37,"column":21},"end":{"line":37,"column":null}},"21":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"22":{"start":{"line":40,"column":4},"end":{"line":56,"column":null}},"23":{"start":{"line":46,"column":8},"end":{"line":46,"column":null}},"24":{"start":{"line":46,"column":21},"end":{"line":46,"column":null}},"25":{"start":{"line":47,"column":8},"end":{"line":47,"column":null}},"26":{"start":{"line":50,"column":8},"end":{"line":50,"column":null}},"27":{"start":{"line":51,"column":8},"end":{"line":51,"column":null}},"28":{"start":{"line":54,"column":8},"end":{"line":54,"column":null}},"29":{"start":{"line":55,"column":8},"end":{"line":55,"column":null}},"30":{"start":{"line":59,"column":27},"end":{"line":75,"column":null}},"31":{"start":{"line":60,"column":4},"end":{"line":60,"column":null}},"32":{"start":{"line":60,"column":75},"end":{"line":60,"column":null}},"33":{"start":{"line":62,"column":4},"end":{"line":62,"column":null}},"34":{"start":{"line":63,"column":4},"end":{"line":74,"column":null}},"35":{"start":{"line":67,"column":8},"end":{"line":67,"column":null}},"36":{"start":{"line":67,"column":21},"end":{"line":67,"column":null}},"37":{"start":{"line":68,"column":8},"end":{"line":68,"column":null}},"38":{"start":{"line":68,"column":37},"end":{"line":68,"column":49}},"39":{"start":{"line":69,"column":8},"end":{"line":69,"column":null}},"40":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"41":{"start":{"line":73,"column":8},"end":{"line":73,"column":null}},"42":{"start":{"line":77,"column":23},"end":{"line":103,"column":null}},"43":{"start":{"line":78,"column":4},"end":{"line":78,"column":null}},"44":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"45":{"start":{"line":79,"column":21},"end":{"line":79,"column":null}},"46":{"start":{"line":81,"column":4},"end":{"line":81,"column":null}},"47":{"start":{"line":82,"column":21},"end":{"line":82,"column":null}},"48":{"start":{"line":83,"column":4},"end":{"line":83,"column":null}},"49":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"50":{"start":{"line":86,"column":4},"end":{"line":102,"column":null}},"51":{"start":{"line":91,"column":8},"end":{"line":91,"column":null}},"52":{"start":{"line":91,"column":21},"end":{"line":91,"column":null}},"53":{"start":{"line":92,"column":8},"end":{"line":92,"column":null}},"54":{"start":{"line":95,"column":8},"end":{"line":95,"column":null}},"55":{"start":{"line":96,"column":8},"end":{"line":96,"column":null}},"56":{"start":{"line":97,"column":8},"end":{"line":97,"column":null}},"57":{"start":{"line":100,"column":8},"end":{"line":100,"column":null}},"58":{"start":{"line":101,"column":8},"end":{"line":101,"column":null}},"59":{"start":{"line":105,"column":2},"end":{"line":178,"column":null}},"60":{"start":{"line":115,"column":29},"end":{"line":115,"column":null}},"61":{"start":{"line":134,"column":31},"end":{"line":134,"column":null}},"62":{"start":{"line":161,"column":12},"end":{"line":174,"column":null}},"63":{"start":{"line":167,"column":31},"end":{"line":167,"column":null}}},"fnMap":{"0":{"name":"Settings","decl":{"start":{"line":6,"column":24},"end":{"line":6,"column":35}},"loc":{"start":{"line":6,"column":35},"end":{"line":180,"column":null}},"line":6},"1":{"name":"(anonymous_1)","decl":{"start":{"line":14,"column":21},"end":{"line":14,"column":27}},"loc":{"start":{"line":14,"column":27},"end":{"line":29,"column":null}},"line":14},"2":{"name":"(anonymous_2)","decl":{"start":{"line":17,"column":12},"end":{"line":17,"column":13}},"loc":{"start":{"line":17,"column":21},"end":{"line":20,"column":7}},"line":17},"3":{"name":"(anonymous_3)","decl":{"start":{"line":21,"column":12},"end":{"line":21,"column":13}},"loc":{"start":{"line":21,"column":22},"end":{"line":24,"column":7}},"line":21},"4":{"name":"(anonymous_4)","decl":{"start":{"line":25,"column":13},"end":{"line":25,"column":14}},"loc":{"start":{"line":25,"column":22},"end":{"line":28,"column":7}},"line":25},"5":{"name":"(anonymous_5)","decl":{"start":{"line":31,"column":12},"end":{"line":31,"column":18}},"loc":{"start":{"line":31,"column":18},"end":{"line":33,"column":5}},"line":31},"6":{"name":"(anonymous_6)","decl":{"start":{"line":35,"column":24},"end":{"line":35,"column":25}},"loc":{"start":{"line":35,"column":48},"end":{"line":57,"column":null}},"line":35},"7":{"name":"(anonymous_7)","decl":{"start":{"line":45,"column":12},"end":{"line":45,"column":13}},"loc":{"start":{"line":45,"column":21},"end":{"line":48,"column":7}},"line":45},"8":{"name":"(anonymous_8)","decl":{"start":{"line":49,"column":12},"end":{"line":49,"column":18}},"loc":{"start":{"line":49,"column":18},"end":{"line":52,"column":7}},"line":49},"9":{"name":"(anonymous_9)","decl":{"start":{"line":53,"column":13},"end":{"line":53,"column":14}},"loc":{"start":{"line":53,"column":22},"end":{"line":56,"column":7}},"line":53},"10":{"name":"(anonymous_10)","decl":{"start":{"line":59,"column":27},"end":{"line":59,"column":28}},"loc":{"start":{"line":59,"column":43},"end":{"line":75,"column":null}},"line":59},"11":{"name":"(anonymous_11)","decl":{"start":{"line":66,"column":12},"end":{"line":66,"column":13}},"loc":{"start":{"line":66,"column":21},"end":{"line":70,"column":7}},"line":66},"12":{"name":"(anonymous_12)","decl":{"start":{"line":68,"column":30},"end":{"line":68,"column":31}},"loc":{"start":{"line":68,"column":37},"end":{"line":68,"column":49}},"line":68},"13":{"name":"(anonymous_13)","decl":{"start":{"line":71,"column":13},"end":{"line":71,"column":14}},"loc":{"start":{"line":71,"column":22},"end":{"line":74,"column":7}},"line":71},"14":{"name":"(anonymous_14)","decl":{"start":{"line":77,"column":23},"end":{"line":77,"column":24}},"loc":{"start":{"line":77,"column":47},"end":{"line":103,"column":null}},"line":77},"15":{"name":"(anonymous_15)","decl":{"start":{"line":90,"column":12},"end":{"line":90,"column":13}},"loc":{"start":{"line":90,"column":21},"end":{"line":93,"column":7}},"line":90},"16":{"name":"(anonymous_16)","decl":{"start":{"line":94,"column":12},"end":{"line":94,"column":18}},"loc":{"start":{"line":94,"column":18},"end":{"line":98,"column":7}},"line":94},"17":{"name":"(anonymous_17)","decl":{"start":{"line":99,"column":13},"end":{"line":99,"column":14}},"loc":{"start":{"line":99,"column":22},"end":{"line":102,"column":7}},"line":99},"18":{"name":"(anonymous_18)","decl":{"start":{"line":115,"column":22},"end":{"line":115,"column":23}},"loc":{"start":{"line":115,"column":29},"end":{"line":115,"column":null}},"line":115},"19":{"name":"(anonymous_19)","decl":{"start":{"line":134,"column":24},"end":{"line":134,"column":25}},"loc":{"start":{"line":134,"column":31},"end":{"line":134,"column":null}},"line":134},"20":{"name":"(anonymous_20)","decl":{"start":{"line":160,"column":21},"end":{"line":160,"column":22}},"loc":{"start":{"line":161,"column":12},"end":{"line":174,"column":null}},"line":161},"21":{"name":"(anonymous_21)","decl":{"start":{"line":167,"column":25},"end":{"line":167,"column":31}},"loc":{"start":{"line":167,"column":31},"end":{"line":167,"column":null}},"line":167}},"branchMap":{"0":{"loc":{"start":{"line":18,"column":8},"end":{"line":18,"column":null}},"type":"if","locations":[{"start":{"line":18,"column":8},"end":{"line":18,"column":null}},{"start":{},"end":{}}],"line":18},"1":{"loc":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":37},"2":{"loc":{"start":{"line":46,"column":8},"end":{"line":46,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":8},"end":{"line":46,"column":null}},{"start":{},"end":{}}],"line":46},"3":{"loc":{"start":{"line":60,"column":4},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":60,"column":4},"end":{"line":60,"column":null}},{"start":{},"end":{}}],"line":60},"4":{"loc":{"start":{"line":67,"column":8},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":8},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":67},"5":{"loc":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},{"start":{},"end":{}}],"line":79},"6":{"loc":{"start":{"line":91,"column":8},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":91,"column":8},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":91},"7":{"loc":{"start":{"line":134,"column":45},"end":{"line":134,"column":72}},"type":"binary-expr","locations":[{"start":{"line":134,"column":45},"end":{"line":134,"column":68}},{"start":{"line":134,"column":68},"end":{"line":134,"column":72}}],"line":134},"8":{"loc":{"start":{"line":138,"column":44},"end":{"line":138,"column":68}},"type":"binary-expr","locations":[{"start":{"line":138,"column":44},"end":{"line":138,"column":59}},{"start":{"line":138,"column":59},"end":{"line":138,"column":68}}],"line":138},"9":{"loc":{"start":{"line":154,"column":7},"end":{"line":154,"column":null}},"type":"binary-expr","locations":[{"start":{"line":154,"column":7},"end":{"line":154,"column":16}},{"start":{"line":154,"column":16},"end":{"line":154,"column":null}}],"line":154},"10":{"loc":{"start":{"line":158,"column":9},"end":{"line":158,"column":null}},"type":"binary-expr","locations":[{"start":{"line":158,"column":9},"end":{"line":158,"column":20}},{"start":{"line":158,"column":20},"end":{"line":158,"column":null}}],"line":158},"11":{"loc":{"start":{"line":163,"column":46},"end":{"line":163,"column":73}},"type":"binary-expr","locations":[{"start":{"line":163,"column":46},"end":{"line":163,"column":60}},{"start":{"line":163,"column":60},"end":{"line":163,"column":73}}],"line":163}},"s":{"0":14,"1":14,"2":14,"3":14,"4":14,"5":14,"6":4,"7":4,"8":4,"9":0,"10":4,"11":4,"12":4,"13":0,"14":0,"15":14,"16":3,"17":14,"18":1,"19":1,"20":0,"21":1,"22":1,"23":1,"24":0,"25":1,"26":1,"27":1,"28":0,"29":0,"30":14,"31":1,"32":0,"33":1,"34":1,"35":1,"36":0,"37":1,"38":1,"39":1,"40":0,"41":0,"42":14,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":14,"60":1,"61":0,"62":5,"63":1},"f":{"0":14,"1":4,"2":4,"3":4,"4":0,"5":3,"6":1,"7":1,"8":1,"9":0,"10":1,"11":1,"12":1,"13":0,"14":0,"15":0,"16":0,"17":0,"18":1,"19":0,"20":5,"21":1},"b":{"0":[0,4],"1":[0,1],"2":[0,1],"3":[0,1],"4":[0,1],"5":[0,0],"6":[0,0],"7":[0,0],"8":[14,0],"9":[14,0],"10":[14,5],"11":[5,0]},"meta":{"lastBranch":12,"lastFunction":22,"lastStatement":64,"seen":{"f:6:24:6:35":0,"s:7:24:7:Infinity":0,"s:8:34:8:Infinity":1,"s:9:28:9:Infinity":2,"s:10:24:10:Infinity":3,"s:12:34:12:Infinity":4,"s:14:21:29:Infinity":5,"f:14:21:14:27":1,"s:15:4:15:Infinity":6,"s:16:4:28:Infinity":7,"f:17:12:17:13":2,"b:18:8:18:Infinity:undefined:undefined:undefined:undefined":0,"s:18:8:18:Infinity":8,"s:18:21:18:Infinity":9,"s:19:8:19:Infinity":10,"f:21:12:21:13":3,"s:22:8:22:Infinity":11,"s:23:8:23:Infinity":12,"f:25:13:25:14":4,"s:26:8:26:Infinity":13,"s:27:8:27:Infinity":14,"s:31:2:33:Infinity":15,"f:31:12:31:18":5,"s:32:4:32:Infinity":16,"s:35:24:57:Infinity":17,"f:35:24:35:25":6,"s:36:4:36:Infinity":18,"b:37:4:37:Infinity:undefined:undefined:undefined:undefined":1,"s:37:4:37:Infinity":19,"s:37:21:37:Infinity":20,"s:39:4:39:Infinity":21,"s:40:4:56:Infinity":22,"f:45:12:45:13":7,"b:46:8:46:Infinity:undefined:undefined:undefined:undefined":2,"s:46:8:46:Infinity":23,"s:46:21:46:Infinity":24,"s:47:8:47:Infinity":25,"f:49:12:49:18":8,"s:50:8:50:Infinity":26,"s:51:8:51:Infinity":27,"f:53:13:53:14":9,"s:54:8:54:Infinity":28,"s:55:8:55:Infinity":29,"s:59:27:75:Infinity":30,"f:59:27:59:28":10,"b:60:4:60:Infinity:undefined:undefined:undefined:undefined":3,"s:60:4:60:Infinity":31,"s:60:75:60:Infinity":32,"s:62:4:62:Infinity":33,"s:63:4:74:Infinity":34,"f:66:12:66:13":11,"b:67:8:67:Infinity:undefined:undefined:undefined:undefined":4,"s:67:8:67:Infinity":35,"s:67:21:67:Infinity":36,"s:68:8:68:Infinity":37,"f:68:30:68:31":12,"s:68:37:68:49":38,"s:69:8:69:Infinity":39,"f:71:13:71:14":13,"s:72:8:72:Infinity":40,"s:73:8:73:Infinity":41,"s:77:23:103:Infinity":42,"f:77:23:77:24":14,"s:78:4:78:Infinity":43,"b:79:4:79:Infinity:undefined:undefined:undefined:undefined":5,"s:79:4:79:Infinity":44,"s:79:21:79:Infinity":45,"s:81:4:81:Infinity":46,"s:82:21:82:Infinity":47,"s:83:4:83:Infinity":48,"s:84:4:84:Infinity":49,"s:86:4:102:Infinity":50,"f:90:12:90:13":15,"b:91:8:91:Infinity:undefined:undefined:undefined:undefined":6,"s:91:8:91:Infinity":51,"s:91:21:91:Infinity":52,"s:92:8:92:Infinity":53,"f:94:12:94:18":16,"s:95:8:95:Infinity":54,"s:96:8:96:Infinity":55,"s:97:8:97:Infinity":56,"f:99:13:99:14":17,"s:100:8:100:Infinity":57,"s:101:8:101:Infinity":58,"s:105:2:178:Infinity":59,"f:115:22:115:23":18,"s:115:29:115:Infinity":60,"f:134:24:134:25":19,"s:134:31:134:Infinity":61,"b:134:45:134:68:134:68:134:72":7,"b:138:44:138:59:138:59:138:68":8,"b:154:7:154:16:154:16:154:Infinity":9,"b:158:9:158:20:158:20:158:Infinity":10,"f:160:21:160:22":20,"s:161:12:174:Infinity":62,"b:163:46:163:60:163:60:163:73":11,"f:167:25:167:31":21,"s:167:31:167:Infinity":63}}} } diff --git a/frontend/coverage/index.html b/frontend/coverage/index.html index bd1150d..ad1f79d 100644 --- a/frontend/coverage/index.html +++ b/frontend/coverage/index.html @@ -1,141 +1,131 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for All files</title> <meta charset="utf-8" /> <link rel="stylesheet" href="prettify.css" /> <link rel="stylesheet" href="base.css" /> <link rel="shortcut icon" type="image/x-icon" href="favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> <h1>All files</h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">86.17% </span> - <span class="quiet">Statements</span> - <span class="fraction">212/246</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">76.76% </span> - <span class="quiet">Branches</span> - <span class="fraction">109/142</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">86.3% </span> - <span class="quiet">Functions</span> - <span class="fraction">63/73</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">88.39% </span> - <span class="quiet">Lines</span> - <span class="fraction">198/224</span> - </div> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">79.24% </span> + <span class="quiet">Statements</span> + <span class='fraction'>252/318</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">70.05% </span> + <span class="quiet">Branches</span> + <span class='fraction'>138/197</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">75.26% </span> + <span class="quiet">Functions</span> + <span class='fraction'>70/93</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">81.44% </span> + <span class="quiet">Lines</span> + <span class='fraction'>237/291</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line high"></div> - <div class="pad1"> - <table class="coverage-summary"> - <thead> - <tr> - <th data-col="file" data-fmt="html" data-html="true" class="file">File</th> - <th - data-col="pic" - data-type="number" - data-fmt="html" - data-html="true" - class="pic" - ></th> - <th data-col="statements" data-type="number" data-fmt="pct" class="pct"> - Statements - </th> - <th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th> - <th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th> - <th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th> - <th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th> - <th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th> - <th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th> - <th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th> - </tr> - </thead> - <tbody> - <tr> - <td class="file medium" data-value="src"><a href="src/index.html">src</a></td> - <td data-value="78.94" class="pic medium"> - <div class="chart"> - <div class="cover-fill" style="width: 78%"></div> - <div class="cover-empty" style="width: 22%"></div> - </div> - </td> - <td data-value="78.94" class="pct medium">78.94%</td> - <td data-value="19" class="abs medium">15/19</td> - <td data-value="66.66" class="pct medium">66.66%</td> - <td data-value="6" class="abs medium">4/6</td> - <td data-value="77.77" class="pct medium">77.77%</td> - <td data-value="9" class="abs medium">7/9</td> - <td data-value="78.94" class="pct medium">78.94%</td> - <td data-value="19" class="abs medium">15/19</td> - </tr> - - <tr> - <td class="file high" data-value="src/components"> - <a href="src/components/index.html">src/components</a> - </td> - <td data-value="86.78" class="pic high"> - <div class="chart"> - <div class="cover-fill" style="width: 86%"></div> - <div class="cover-empty" style="width: 14%"></div> - </div> - </td> - <td data-value="86.78" class="pct high">86.78%</td> - <td data-value="227" class="abs high">197/227</td> - <td data-value="77.2" class="pct medium">77.2%</td> - <td data-value="136" class="abs medium">105/136</td> - <td data-value="87.5" class="pct high">87.5%</td> - <td data-value="64" class="abs high">56/64</td> - <td data-value="89.26" class="pct high">89.26%</td> - <td data-value="205" class="abs high">183/205</td> - </tr> - </tbody> - </table> - </div> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z </div> - <script src="prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="sorter.js"></script> - <script src="block-navigation.js"></script> - </body> + <div class='status-line medium'></div> + <div class="pad1"> +<table class="coverage-summary"> +<thead> +<tr> + <th data-col="file" data-fmt="html" data-html="true" class="file">File</th> + <th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th> + <th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th> + <th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th> + <th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th> + <th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th> + <th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th> + <th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th> + <th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th> + <th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th> +</tr> +</thead> +<tbody><tr> + <td class="file medium" data-value="src"><a href="src/index.html">src</a></td> + <td data-value="76.47" class="pic medium"> + <div class="chart"><div class="cover-fill" style="width: 76%"></div><div class="cover-empty" style="width: 24%"></div></div> + </td> + <td data-value="76.47" class="pct medium">76.47%</td> + <td data-value="34" class="abs medium">26/34</td> + <td data-value="69.23" class="pct medium">69.23%</td> + <td data-value="26" class="abs medium">18/26</td> + <td data-value="70" class="pct medium">70%</td> + <td data-value="10" class="abs medium">7/10</td> + <td data-value="78.78" class="pct medium">78.78%</td> + <td data-value="33" class="abs medium">26/33</td> + </tr> + +<tr> + <td class="file medium" data-value="src/components"><a href="src/components/index.html">src/components</a></td> + <td data-value="79.57" class="pic medium"> + <div class="chart"><div class="cover-fill" style="width: 79%"></div><div class="cover-empty" style="width: 21%"></div></div> + </td> + <td data-value="79.57" class="pct medium">79.57%</td> + <td data-value="284" class="abs medium">226/284</td> + <td data-value="70.17" class="pct medium">70.17%</td> + <td data-value="171" class="abs medium">120/171</td> + <td data-value="75.9" class="pct medium">75.9%</td> + <td data-value="83" class="abs medium">63/83</td> + <td data-value="81.78" class="pct high">81.78%</td> + <td data-value="258" class="abs high">211/258</td> + </tr> + +</tbody> +</table> +</div> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="sorter.js"></script> + <script src="block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/prettify.css b/frontend/coverage/prettify.css index 006492c..b317a7c 100644 --- a/frontend/coverage/prettify.css +++ b/frontend/coverage/prettify.css @@ -1,101 +1 @@ -.pln { - color: #000; -} -@media screen { - .str { - color: #080; - } - .kwd { - color: #008; - } - .com { - color: #800; - } - .typ { - color: #606; - } - .lit { - color: #066; - } - .pun, - .opn, - .clo { - color: #660; - } - .tag { - color: #008; - } - .atn { - color: #606; - } - .atv { - color: #080; - } - .dec, - .var { - color: #606; - } - .fun { - color: red; - } -} -@media print, projection { - .str { - color: #060; - } - .kwd { - color: #006; - font-weight: bold; - } - .com { - color: #600; - font-style: italic; - } - .typ { - color: #404; - font-weight: bold; - } - .lit { - color: #044; - } - .pun, - .opn, - .clo { - color: #440; - } - .tag { - color: #006; - font-weight: bold; - } - .atn { - color: #404; - } - .atv { - color: #060; - } -} -pre.prettyprint { - padding: 2px; - border: 1px solid #888; -} -ol.linenums { - margin-top: 0; - margin-bottom: 0; -} -li.L0, -li.L1, -li.L2, -li.L3, -li.L5, -li.L6, -li.L7, -li.L8 { - list-style-type: none; -} -li.L1, -li.L3, -li.L5, -li.L7, -li.L9 { - background: #eee; -} +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/frontend/coverage/prettify.js b/frontend/coverage/prettify.js index a318211..b322523 100644 --- a/frontend/coverage/prettify.js +++ b/frontend/coverage/prettify.js @@ -1,937 +1,2 @@ - -window.PR_SHOULD_USE_CONTINUATION = true; -(function () { - var h = ['break,continue,do,else,for,if,return,while']; - var u = [ - h, - 'auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile', - ]; - var p = [ - u, - 'catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof', - ]; - var l = [ - p, - 'alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where', - ]; - var x = [ - p, - 'abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient', - ]; - var R = [ - x, - 'as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var', - ]; - var r = - 'all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes'; - var w = [p, 'debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN']; - var s = - 'caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END'; - var I = [ - h, - 'and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None', - ]; - var f = [ - h, - 'alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END', - ]; - var H = [h, 'case,done,elif,esac,eval,fi,function,in,local,set,then,until']; - var A = [l, R, w, s + I, f, H]; - var e = - /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/; - var C = 'str'; - var z = 'kwd'; - var j = 'com'; - var O = 'typ'; - var G = 'lit'; - var L = 'pun'; - var F = 'pln'; - var m = 'tag'; - var E = 'dec'; - var J = 'src'; - var P = 'atn'; - var n = 'atv'; - var N = 'nocode'; - var M = - '(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*'; - function k(Z) { - var ad = 0; - var S = false; - var ac = false; - for (var V = 0, U = Z.length; V < U; ++V) { - var ae = Z[V]; - if (ae.ignoreCase) { - ac = true; - } else { - if (/[a-z]/i.test(ae.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) { - S = true; - ac = false; - break; - } - } - } - var Y = { b: 8, t: 9, n: 10, v: 11, f: 12, r: 13 }; - function ab(ah) { - var ag = ah.charCodeAt(0); - if (ag !== 92) { - return ag; - } - var af = ah.charAt(1); - ag = Y[af]; - if (ag) { - return ag; - } else { - if ('0' <= af && af <= '7') { - return parseInt(ah.substring(1), 8); - } else { - if (af === 'u' || af === 'x') { - return parseInt(ah.substring(2), 16); - } else { - return ah.charCodeAt(1); - } - } - } - } - function T(af) { - if (af < 32) { - return (af < 16 ? '\\x0' : '\\x') + af.toString(16); - } - var ag = String.fromCharCode(af); - if (ag === '\\' || ag === '-' || ag === '[' || ag === ']') { - ag = '\\' + ag; - } - return ag; - } - function X(am) { - var aq = am - .substring(1, am.length - 1) - .match( - new RegExp( - '\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]', - 'g' - ) - ); - var ak = []; - var af = []; - var ao = aq[0] === '^'; - for (var ar = ao ? 1 : 0, aj = aq.length; ar < aj; ++ar) { - var ah = aq[ar]; - if (/\\[bdsw]/i.test(ah)) { - ak.push(ah); - } else { - var ag = ab(ah); - var al; - if (ar + 2 < aj && '-' === aq[ar + 1]) { - al = ab(aq[ar + 2]); - ar += 2; - } else { - al = ag; - } - af.push([ag, al]); - if (!(al < 65 || ag > 122)) { - if (!(al < 65 || ag > 90)) { - af.push([Math.max(65, ag) | 32, Math.min(al, 90) | 32]); - } - if (!(al < 97 || ag > 122)) { - af.push([Math.max(97, ag) & ~32, Math.min(al, 122) & ~32]); - } - } - } - } - af.sort(function (av, au) { - return av[0] - au[0] || au[1] - av[1]; - }); - var ai = []; - var ap = [NaN, NaN]; - for (var ar = 0; ar < af.length; ++ar) { - var at = af[ar]; - if (at[0] <= ap[1] + 1) { - ap[1] = Math.max(ap[1], at[1]); - } else { - ai.push((ap = at)); - } - } - var an = ['[']; - if (ao) { - an.push('^'); - } - an.push.apply(an, ak); - for (var ar = 0; ar < ai.length; ++ar) { - var at = ai[ar]; - an.push(T(at[0])); - if (at[1] > at[0]) { - if (at[1] + 1 > at[0]) { - an.push('-'); - } - an.push(T(at[1])); - } - } - an.push(']'); - return an.join(''); - } - function W(al) { - var aj = al.source.match( - new RegExp( - '(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)', - 'g' - ) - ); - var ah = aj.length; - var an = []; - for (var ak = 0, am = 0; ak < ah; ++ak) { - var ag = aj[ak]; - if (ag === '(') { - ++am; - } else { - if ('\\' === ag.charAt(0)) { - var af = +ag.substring(1); - if (af && af <= am) { - an[af] = -1; - } - } - } - } - for (var ak = 1; ak < an.length; ++ak) { - if (-1 === an[ak]) { - an[ak] = ++ad; - } - } - for (var ak = 0, am = 0; ak < ah; ++ak) { - var ag = aj[ak]; - if (ag === '(') { - ++am; - if (an[am] === undefined) { - aj[ak] = '(?:'; - } - } else { - if ('\\' === ag.charAt(0)) { - var af = +ag.substring(1); - if (af && af <= am) { - aj[ak] = '\\' + an[am]; - } - } - } - } - for (var ak = 0, am = 0; ak < ah; ++ak) { - if ('^' === aj[ak] && '^' !== aj[ak + 1]) { - aj[ak] = ''; - } - } - if (al.ignoreCase && S) { - for (var ak = 0; ak < ah; ++ak) { - var ag = aj[ak]; - var ai = ag.charAt(0); - if (ag.length >= 2 && ai === '[') { - aj[ak] = X(ag); - } else { - if (ai !== '\\') { - aj[ak] = ag.replace(/[a-zA-Z]/g, function (ao) { - var ap = ao.charCodeAt(0); - return '[' + String.fromCharCode(ap & ~32, ap | 32) + ']'; - }); - } - } - } - } - return aj.join(''); - } - var aa = []; - for (var V = 0, U = Z.length; V < U; ++V) { - var ae = Z[V]; - if (ae.global || ae.multiline) { - throw new Error('' + ae); - } - aa.push('(?:' + W(ae) + ')'); - } - return new RegExp(aa.join('|'), ac ? 'gi' : 'g'); - } - function a(V) { - var U = /(?:^|\s)nocode(?:\s|$)/; - var X = []; - var T = 0; - var Z = []; - var W = 0; - var S; - if (V.currentStyle) { - S = V.currentStyle.whiteSpace; - } else { - if (window.getComputedStyle) { - S = document.defaultView.getComputedStyle(V, null).getPropertyValue('white-space'); - } - } - var Y = S && 'pre' === S.substring(0, 3); - function aa(ab) { - switch (ab.nodeType) { - case 1: - if (U.test(ab.className)) { - return; - } - for (var ae = ab.firstChild; ae; ae = ae.nextSibling) { - aa(ae); - } - var ad = ab.nodeName; - if ('BR' === ad || 'LI' === ad) { - X[W] = '\n'; - Z[W << 1] = T++; - Z[(W++ << 1) | 1] = ab; - } - break; - case 3: - case 4: - var ac = ab.nodeValue; - if (ac.length) { - if (!Y) { - ac = ac.replace(/[ \t\r\n]+/g, ' '); - } else { - ac = ac.replace(/\r\n?/g, '\n'); - } - X[W] = ac; - Z[W << 1] = T; - T += ac.length; - Z[(W++ << 1) | 1] = ab; - } - break; - } - } - aa(V); - return { sourceCode: X.join('').replace(/\n$/, ''), spans: Z }; - } - function B(S, U, W, T) { - if (!U) { - return; - } - var V = { sourceCode: U, basePos: S }; - W(V); - T.push.apply(T, V.decorations); - } - var v = /\S/; - function o(S) { - var V = undefined; - for (var U = S.firstChild; U; U = U.nextSibling) { - var T = U.nodeType; - V = T === 1 ? (V ? S : U) : T === 3 ? (v.test(U.nodeValue) ? S : V) : V; - } - return V === S ? undefined : V; - } - function g(U, T) { - var S = {}; - var V; - (function () { - var ad = U.concat(T); - var ah = []; - var ag = {}; - for (var ab = 0, Z = ad.length; ab < Z; ++ab) { - var Y = ad[ab]; - var ac = Y[3]; - if (ac) { - for (var ae = ac.length; --ae >= 0; ) { - S[ac.charAt(ae)] = Y; - } - } - var af = Y[1]; - var aa = '' + af; - if (!ag.hasOwnProperty(aa)) { - ah.push(af); - ag[aa] = null; - } - } - ah.push(/[\0-\uffff]/); - V = k(ah); - })(); - var X = T.length; - var W = function (ah) { - var Z = ah.sourceCode, - Y = ah.basePos; - var ad = [Y, F]; - var af = 0; - var an = Z.match(V) || []; - var aj = {}; - for (var ae = 0, aq = an.length; ae < aq; ++ae) { - var ag = an[ae]; - var ap = aj[ag]; - var ai = void 0; - var am; - if (typeof ap === 'string') { - am = false; - } else { - var aa = S[ag.charAt(0)]; - if (aa) { - ai = ag.match(aa[1]); - ap = aa[0]; - } else { - for (var ao = 0; ao < X; ++ao) { - aa = T[ao]; - ai = ag.match(aa[1]); - if (ai) { - ap = aa[0]; - break; - } - } - if (!ai) { - ap = F; - } - } - am = ap.length >= 5 && 'lang-' === ap.substring(0, 5); - if (am && !(ai && typeof ai[1] === 'string')) { - am = false; - ap = J; - } - if (!am) { - aj[ag] = ap; - } - } - var ab = af; - af += ag.length; - if (!am) { - ad.push(Y + ab, ap); - } else { - var al = ai[1]; - var ak = ag.indexOf(al); - var ac = ak + al.length; - if (ai[2]) { - ac = ag.length - ai[2].length; - ak = ac - al.length; - } - var ar = ap.substring(5); - B(Y + ab, ag.substring(0, ak), W, ad); - B(Y + ab + ak, al, q(ar, al), ad); - B(Y + ab + ac, ag.substring(ac), W, ad); - } - } - ah.decorations = ad; - }; - return W; - } - function i(T) { - var W = [], - S = []; - if (T.tripleQuotedStrings) { - W.push([ - C, - /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/, - null, - '\'"', - ]); - } else { - if (T.multiLineStrings) { - W.push([ - C, - /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/, - null, - '\'"`', - ]); - } else { - W.push([ - C, - /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/, - null, - '"\'', - ]); - } - } - if (T.verbatimStrings) { - S.push([C, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]); - } - var Y = T.hashComments; - if (Y) { - if (T.cStyleComments) { - if (Y > 1) { - W.push([j, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']); - } else { - W.push([ - j, - /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/, - null, - '#', - ]); - } - S.push([C, /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/, null]); - } else { - W.push([j, /^#[^\r\n]*/, null, '#']); - } - } - if (T.cStyleComments) { - S.push([j, /^\/\/[^\r\n]*/, null]); - S.push([j, /^\/\*[\s\S]*?(?:\*\/|$)/, null]); - } - if (T.regexLiterals) { - var X = - '/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/'; - S.push(['lang-regex', new RegExp('^' + M + '(' + X + ')')]); - } - var V = T.types; - if (V) { - S.push([O, V]); - } - var U = ('' + T.keywords).replace(/^ | $/g, ''); - if (U.length) { - S.push([z, new RegExp('^(?:' + U.replace(/[\s,]+/g, '|') + ')\\b'), null]); - } - W.push([F, /^\s+/, null, ' \r\n\t\xA0']); - S.push( - [G, /^@[a-z_$][a-z_$@0-9]*/i, null], - [O, /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null], - [F, /^[a-z_$][a-z_$@0-9]*/i, null], - [ - G, - new RegExp( - '^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*', - 'i' - ), - null, - '0123456789', - ], - [F, /^\\[\s\S]?/, null], - [L, /^.[^\s\w\.$@\'\"\`\/\#\\]*/, null] - ); - return g(W, S); - } - var K = i({ - keywords: A, - hashComments: true, - cStyleComments: true, - multiLineStrings: true, - regexLiterals: true, - }); - function Q(V, ag) { - var U = /(?:^|\s)nocode(?:\s|$)/; - var ab = /\r\n?|\n/; - var ac = V.ownerDocument; - var S; - if (V.currentStyle) { - S = V.currentStyle.whiteSpace; - } else { - if (window.getComputedStyle) { - S = ac.defaultView.getComputedStyle(V, null).getPropertyValue('white-space'); - } - } - var Z = S && 'pre' === S.substring(0, 3); - var af = ac.createElement('LI'); - while (V.firstChild) { - af.appendChild(V.firstChild); - } - var W = [af]; - function ae(al) { - switch (al.nodeType) { - case 1: - if (U.test(al.className)) { - break; - } - if ('BR' === al.nodeName) { - ad(al); - if (al.parentNode) { - al.parentNode.removeChild(al); - } - } else { - for (var an = al.firstChild; an; an = an.nextSibling) { - ae(an); - } - } - break; - case 3: - case 4: - if (Z) { - var am = al.nodeValue; - var aj = am.match(ab); - if (aj) { - var ai = am.substring(0, aj.index); - al.nodeValue = ai; - var ah = am.substring(aj.index + aj[0].length); - if (ah) { - var ak = al.parentNode; - ak.insertBefore(ac.createTextNode(ah), al.nextSibling); - } - ad(al); - if (!ai) { - al.parentNode.removeChild(al); - } - } - } - break; - } - } - function ad(ak) { - while (!ak.nextSibling) { - ak = ak.parentNode; - if (!ak) { - return; - } - } - function ai(al, ar) { - var aq = ar ? al.cloneNode(false) : al; - var ao = al.parentNode; - if (ao) { - var ap = ai(ao, 1); - var an = al.nextSibling; - ap.appendChild(aq); - for (var am = an; am; am = an) { - an = am.nextSibling; - ap.appendChild(am); - } - } - return aq; - } - var ah = ai(ak.nextSibling, 0); - for (var aj; (aj = ah.parentNode) && aj.nodeType === 1; ) { - ah = aj; - } - W.push(ah); - } - for (var Y = 0; Y < W.length; ++Y) { - ae(W[Y]); - } - if (ag === (ag | 0)) { - W[0].setAttribute('value', ag); - } - var aa = ac.createElement('OL'); - aa.className = 'linenums'; - var X = Math.max(0, (ag - 1) | 0) || 0; - for (var Y = 0, T = W.length; Y < T; ++Y) { - af = W[Y]; - af.className = 'L' + ((Y + X) % 10); - if (!af.firstChild) { - af.appendChild(ac.createTextNode('\xA0')); - } - aa.appendChild(af); - } - V.appendChild(aa); - } - function D(ac) { - var aj = /\bMSIE\b/.test(navigator.userAgent); - var am = /\n/g; - var al = ac.sourceCode; - var an = al.length; - var V = 0; - var aa = ac.spans; - var T = aa.length; - var ah = 0; - var X = ac.decorations; - var Y = X.length; - var Z = 0; - X[Y] = an; - var ar, aq; - for (aq = ar = 0; aq < Y; ) { - if (X[aq] !== X[aq + 2]) { - X[ar++] = X[aq++]; - X[ar++] = X[aq++]; - } else { - aq += 2; - } - } - Y = ar; - for (aq = ar = 0; aq < Y; ) { - var at = X[aq]; - var ab = X[aq + 1]; - var W = aq + 2; - while (W + 2 <= Y && X[W + 1] === ab) { - W += 2; - } - X[ar++] = at; - X[ar++] = ab; - aq = W; - } - Y = X.length = ar; - var ae = null; - while (ah < T) { - var af = aa[ah]; - var S = aa[ah + 2] || an; - var ag = X[Z]; - var ap = X[Z + 2] || an; - var W = Math.min(S, ap); - var ak = aa[ah + 1]; - var U; - if (ak.nodeType !== 1 && (U = al.substring(V, W))) { - if (aj) { - U = U.replace(am, '\r'); - } - ak.nodeValue = U; - var ai = ak.ownerDocument; - var ao = ai.createElement('SPAN'); - ao.className = X[Z + 1]; - var ad = ak.parentNode; - ad.replaceChild(ao, ak); - ao.appendChild(ak); - if (V < S) { - aa[ah + 1] = ak = ai.createTextNode(al.substring(W, S)); - ad.insertBefore(ak, ao.nextSibling); - } - } - V = W; - if (V >= S) { - ah += 2; - } - if (V >= ap) { - Z += 2; - } - } - } - var t = {}; - function c(U, V) { - for (var S = V.length; --S >= 0; ) { - var T = V[S]; - if (!t.hasOwnProperty(T)) { - t[T] = U; - } else { - if (window.console) { - console.warn('cannot override language handler %s', T); - } - } - } - } - function q(T, S) { - if (!(T && t.hasOwnProperty(T))) { - T = /^\s*</.test(S) ? 'default-markup' : 'default-code'; - } - return t[T]; - } - c(K, ['default-code']); - c( - g( - [], - [ - [F, /^[^<?]+/], - [E, /^<!\w[^>]*(?:>|$)/], - [j, /^<\!--[\s\S]*?(?:-\->|$)/], - ['lang-', /^<\?([\s\S]+?)(?:\?>|$)/], - ['lang-', /^<%([\s\S]+?)(?:%>|$)/], - [L, /^(?:<[%?]|[%?]>)/], - ['lang-', /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i], - ['lang-js', /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i], - ['lang-css', /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i], - ['lang-in.tag', /^(<\/?[a-z][^<>]*>)/i], - ] - ), - ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl'] - ); - c( - g( - [ - [F, /^[\s]+/, null, ' \t\r\n'], - [n, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '"\''], - ], - [ - [m, /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i], - [P, /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i], - ['lang-uq.val', /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/], - [L, /^[=<>\/]+/], - ['lang-js', /^on\w+\s*=\s*\"([^\"]+)\"/i], - ['lang-js', /^on\w+\s*=\s*\'([^\']+)\'/i], - ['lang-js', /^on\w+\s*=\s*([^\"\'>\s]+)/i], - ['lang-css', /^style\s*=\s*\"([^\"]+)\"/i], - ['lang-css', /^style\s*=\s*\'([^\']+)\'/i], - ['lang-css', /^style\s*=\s*([^\"\'>\s]+)/i], - ] - ), - ['in.tag'] - ); - c(g([], [[n, /^[\s\S]+/]]), ['uq.val']); - c(i({ keywords: l, hashComments: true, cStyleComments: true, types: e }), [ - 'c', - 'cc', - 'cpp', - 'cxx', - 'cyc', - 'm', - ]); - c(i({ keywords: 'null,true,false' }), ['json']); - c(i({ keywords: R, hashComments: true, cStyleComments: true, verbatimStrings: true, types: e }), [ - 'cs', - ]); - c(i({ keywords: x, cStyleComments: true }), ['java']); - c(i({ keywords: H, hashComments: true, multiLineStrings: true }), ['bsh', 'csh', 'sh']); - c(i({ keywords: I, hashComments: true, multiLineStrings: true, tripleQuotedStrings: true }), [ - 'cv', - 'py', - ]); - c(i({ keywords: s, hashComments: true, multiLineStrings: true, regexLiterals: true }), [ - 'perl', - 'pl', - 'pm', - ]); - c(i({ keywords: f, hashComments: true, multiLineStrings: true, regexLiterals: true }), ['rb']); - c(i({ keywords: w, cStyleComments: true, regexLiterals: true }), ['js']); - c( - i({ - keywords: r, - hashComments: 3, - cStyleComments: true, - multilineStrings: true, - tripleQuotedStrings: true, - regexLiterals: true, - }), - ['coffee'] - ); - c(g([], [[C, /^[\s\S]+/]]), ['regex']); - function d(V) { - var U = V.langExtension; - try { - var S = a(V.sourceNode); - var T = S.sourceCode; - V.sourceCode = T; - V.spans = S.spans; - V.basePos = 0; - q(U, T)(V); - D(V); - } catch (W) { - if ('console' in window) { - console.log(W && W.stack ? W.stack : W); - } - } - } - function y(W, V, U) { - var S = document.createElement('PRE'); - S.innerHTML = W; - if (U) { - Q(S, U); - } - var T = { langExtension: V, numberLines: U, sourceNode: S }; - d(T); - return S.innerHTML; - } - function b(ad) { - function Y(af) { - return document.getElementsByTagName(af); - } - var ac = [Y('pre'), Y('code'), Y('xmp')]; - var T = []; - for (var aa = 0; aa < ac.length; ++aa) { - for (var Z = 0, V = ac[aa].length; Z < V; ++Z) { - T.push(ac[aa][Z]); - } - } - ac = null; - var W = Date; - if (!W.now) { - W = { - now: function () { - return +new Date(); - }, - }; - } - var X = 0; - var S; - var ab = /\blang(?:uage)?-([\w.]+)(?!\S)/; - var ae = /\bprettyprint\b/; - function U() { - var ag = window.PR_SHOULD_USE_CONTINUATION ? W.now() + 250 : Infinity; - for (; X < T.length && W.now() < ag; X++) { - var aj = T[X]; - var ai = aj.className; - if (ai.indexOf('prettyprint') >= 0) { - var ah = ai.match(ab); - var am; - if (!ah && (am = o(aj)) && 'CODE' === am.tagName) { - ah = am.className.match(ab); - } - if (ah) { - ah = ah[1]; - } - var al = false; - for (var ak = aj.parentNode; ak; ak = ak.parentNode) { - if ( - (ak.tagName === 'pre' || ak.tagName === 'code' || ak.tagName === 'xmp') && - ak.className && - ak.className.indexOf('prettyprint') >= 0 - ) { - al = true; - break; - } - } - if (!al) { - var af = aj.className.match(/\blinenums\b(?::(\d+))?/); - af = af ? (af[1] && af[1].length ? +af[1] : true) : false; - if (af) { - Q(aj, af); - } - S = { langExtension: ah, sourceNode: aj, numberLines: af }; - d(S); - } - } - } - if (X < T.length) { - setTimeout(U, 250); - } else { - if (ad) { - ad(); - } - } - } - U(); - } - window.prettyPrintOne = y; - window.prettyPrint = b; - window.PR = { - createSimpleLexer: g, - registerLangHandler: c, - sourceDecorator: i, - PR_ATTRIB_NAME: P, - PR_ATTRIB_VALUE: n, - PR_COMMENT: j, - PR_DECLARATION: E, - PR_KEYWORD: z, - PR_LITERAL: G, - PR_NOCODE: N, - PR_PLAIN: F, - PR_PUNCTUATION: L, - PR_SOURCE: J, - PR_STRING: C, - PR_TAG: m, - PR_TYPE: O, - }; -})(); -PR.registerLangHandler( - PR.createSimpleLexer( - [], - [ - [PR.PR_DECLARATION, /^<!\w[^>]*(?:>|$)/], - [PR.PR_COMMENT, /^<\!--[\s\S]*?(?:-\->|$)/], - [PR.PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/], - ['lang-', /^<\?([\s\S]+?)(?:\?>|$)/], - ['lang-', /^<%([\s\S]+?)(?:%>|$)/], - ['lang-', /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i], - [ - 'lang-handlebars', - /^<script\b[^>]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i, - ], - ['lang-js', /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i], - ['lang-css', /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i], - ['lang-in.tag', /^(<\/?[a-z][^<>]*>)/i], - [PR.PR_DECLARATION, /^{{[#^>/]?\s*[\w.][^}]*}}/], - [PR.PR_DECLARATION, /^{{&?\s*[\w.][^}]*}}/], - [PR.PR_DECLARATION, /^{{{>?\s*[\w.][^}]*}}}/], - [PR.PR_COMMENT, /^{{![^}]*}}/], - ] - ), - ['handlebars', 'hbs'] -); -PR.registerLangHandler( - PR.createSimpleLexer( - [[PR.PR_PLAIN, /^[ \t\r\n\f]+/, null, ' \t\r\n\f']], - [ - [PR.PR_STRING, /^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/, null], - [PR.PR_STRING, /^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/, null], - ['lang-css-str', /^url\(([^\)\"\']*)\)/i], - [ - PR.PR_KEYWORD, - /^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i, - null, - ], - ['lang-css-kw', /^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i], - [PR.PR_COMMENT, /^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//], - [PR.PR_COMMENT, /^(?:<!--|-->)/], - [PR.PR_LITERAL, /^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i], - [PR.PR_LITERAL, /^#(?:[0-9a-f]{3}){1,2}/i], - [PR.PR_PLAIN, /^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i], - [PR.PR_PUNCTUATION, /^[^\s\w\'\"]+/], - ] - ), - ['css'] -); -PR.registerLangHandler( - PR.createSimpleLexer( - [], - [[PR.PR_KEYWORD, /^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]] - ), - ['css-kw'] -); -PR.registerLangHandler(PR.createSimpleLexer([], [[PR.PR_STRING, /^[^\)\"\']+/]]), ['css-str']); +/* eslint-disable */ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V<U;++V){var ae=Z[V];if(ae.ignoreCase){ac=true}else{if(/[a-z]/i.test(ae.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,""))){S=true;ac=false;break}}}var Y={b:8,t:9,n:10,v:11,f:12,r:13};function ab(ah){var ag=ah.charCodeAt(0);if(ag!==92){return ag}var af=ah.charAt(1);ag=Y[af];if(ag){return ag}else{if("0"<=af&&af<="7"){return parseInt(ah.substring(1),8)}else{if(af==="u"||af==="x"){return parseInt(ah.substring(2),16)}else{return ah.charCodeAt(1)}}}}function T(af){if(af<32){return(af<16?"\\x0":"\\x")+af.toString(16)}var ag=String.fromCharCode(af);if(ag==="\\"||ag==="-"||ag==="["||ag==="]"){ag="\\"+ag}return ag}function X(am){var aq=am.substring(1,am.length-1).match(new RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));var ak=[];var af=[];var ao=aq[0]==="^";for(var ar=ao?1:0,aj=aq.length;ar<aj;++ar){var ah=aq[ar];if(/\\[bdsw]/i.test(ah)){ak.push(ah)}else{var ag=ab(ah);var al;if(ar+2<aj&&"-"===aq[ar+1]){al=ab(aq[ar+2]);ar+=2}else{al=ag}af.push([ag,al]);if(!(al<65||ag>122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;ar<af.length;++ar){var at=af[ar];if(at[0]<=ap[1]+1){ap[1]=Math.max(ap[1],at[1])}else{ai.push(ap=at)}}var an=["["];if(ao){an.push("^")}an.push.apply(an,ak);for(var ar=0;ar<ai.length;++ar){var at=ai[ar];an.push(T(at[0]));if(at[1]>at[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak<ah;++ak){var ag=aj[ak];if(ag==="("){++am}else{if("\\"===ag.charAt(0)){var af=+ag.substring(1);if(af&&af<=am){an[af]=-1}}}}for(var ak=1;ak<an.length;++ak){if(-1===an[ak]){an[ak]=++ad}}for(var ak=0,am=0;ak<ah;++ak){var ag=aj[ak];if(ag==="("){++am;if(an[am]===undefined){aj[ak]="(?:"}}else{if("\\"===ag.charAt(0)){var af=+ag.substring(1);if(af&&af<=am){aj[ak]="\\"+an[am]}}}}for(var ak=0,am=0;ak<ah;++ak){if("^"===aj[ak]&&"^"!==aj[ak+1]){aj[ak]=""}}if(al.ignoreCase&&S){for(var ak=0;ak<ah;++ak){var ag=aj[ak];var ai=ag.charAt(0);if(ag.length>=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V<U;++V){var ae=Z[V];if(ae.global||ae.multiline){throw new Error(""+ae)}aa.push("(?:"+W(ae)+")")}return new RegExp(aa.join("|"),ac?"gi":"g")}function a(V){var U=/(?:^|\s)nocode(?:\s|$)/;var X=[];var T=0;var Z=[];var W=0;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=document.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Y=S&&"pre"===S.substring(0,3);function aa(ab){switch(ab.nodeType){case 1:if(U.test(ab.className)){return}for(var ae=ab.firstChild;ae;ae=ae.nextSibling){aa(ae)}var ad=ab.nodeName;if("BR"===ad||"LI"===ad){X[W]="\n";Z[W<<1]=T++;Z[(W++<<1)|1]=ab}break;case 3:case 4:var ac=ab.nodeValue;if(ac.length){if(!Y){ac=ac.replace(/[ \t\r\n]+/g," ")}else{ac=ac.replace(/\r\n?/g,"\n")}X[W]=ac;Z[W<<1]=T;T+=ac.length;Z[(W++<<1)|1]=ab}break}}aa(V);return{sourceCode:X.join("").replace(/\n$/,""),spans:Z}}function B(S,U,W,T){if(!U){return}var V={sourceCode:U,basePos:S};W(V);T.push.apply(T,V.decorations)}var v=/\S/;function o(S){var V=undefined;for(var U=S.firstChild;U;U=U.nextSibling){var T=U.nodeType;V=(T===1)?(V?S:U):(T===3)?(v.test(U.nodeValue)?S:V):V}return V===S?undefined:V}function g(U,T){var S={};var V;(function(){var ad=U.concat(T);var ah=[];var ag={};for(var ab=0,Z=ad.length;ab<Z;++ab){var Y=ad[ab];var ac=Y[3];if(ac){for(var ae=ac.length;--ae>=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae<aq;++ae){var ag=an[ae];var ap=aj[ag];var ai=void 0;var am;if(typeof ap==="string"){am=false}else{var aa=S[ag.charAt(0)];if(aa){ai=ag.match(aa[1]);ap=aa[0]}else{for(var ao=0;ao<X;++ao){aa=T[ao];ai=ag.match(aa[1]);if(ai){ap=aa[0];break}}if(!ai){ap=F}}am=ap.length>=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y<W.length;++Y){ae(W[Y])}if(ag===(ag|0)){W[0].setAttribute("value",ag)}var aa=ac.createElement("OL");aa.className="linenums";var X=Math.max(0,((ag-1))|0)||0;for(var Y=0,T=W.length;Y<T;++Y){af=W[Y];af.className="L"+((Y+X)%10);if(!af.firstChild){af.appendChild(ac.createTextNode("\xA0"))}aa.appendChild(af)}V.appendChild(aa)}function D(ac){var aj=/\bMSIE\b/.test(navigator.userAgent);var am=/\n/g;var al=ac.sourceCode;var an=al.length;var V=0;var aa=ac.spans;var T=aa.length;var ah=0;var X=ac.decorations;var Y=X.length;var Z=0;X[Y]=an;var ar,aq;for(aq=ar=0;aq<Y;){if(X[aq]!==X[aq+2]){X[ar++]=X[aq++];X[ar++]=X[aq++]}else{aq+=2}}Y=ar;for(aq=ar=0;aq<Y;){var at=X[aq];var ab=X[aq+1];var W=aq+2;while(W+2<=Y&&X[W+1]===ab){W+=2}X[ar++]=at;X[ar++]=ab;aq=W}Y=X.length=ar;var ae=null;while(ah<T){var af=aa[ah];var S=aa[ah+2]||an;var ag=X[Z];var ap=X[Z+2]||an;var W=Math.min(S,ap);var ak=aa[ah+1];var U;if(ak.nodeType!==1&&(U=al.substring(V,W))){if(aj){U=U.replace(am,"\r")}ak.nodeValue=U;var ai=ak.ownerDocument;var ao=ai.createElement("SPAN");ao.className=X[Z+1];var ad=ak.parentNode;ad.replaceChild(ao,ak);ao.appendChild(ak);if(V<S){aa[ah+1]=ak=ai.createTextNode(al.substring(W,S));ad.insertBefore(ak,ao.nextSibling)}}V=W;if(V>=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*</.test(S)?"default-markup":"default-code"}return t[T]}c(K,["default-code"]);c(g([],[[F,/^[^<?]+/],[E,/^<!\w[^>]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa<ac.length;++aa){for(var Z=0,V=ac[aa].length;Z<V;++Z){T.push(ac[aa][Z])}}ac=null;var W=Date;if(!W.now){W={now:function(){return +(new Date)}}}var X=0;var S;var ab=/\blang(?:uage)?-([\w.]+)(?!\S)/;var ae=/\bprettyprint\b/;function U(){var ag=(window.PR_SHOULD_USE_CONTINUATION?W.now()+250:Infinity);for(;X<T.length&&W.now()<ag;X++){var aj=T[X];var ai=aj.className;if(ai.indexOf("prettyprint")>=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X<T.length){setTimeout(U,250)}else{if(ad){ad()}}}U()}window.prettyPrintOne=y;window.prettyPrint=b;window.PR={createSimpleLexer:g,registerLangHandler:c,sourceDecorator:i,PR_ATTRIB_NAME:P,PR_ATTRIB_VALUE:n,PR_COMMENT:j,PR_DECLARATION:E,PR_KEYWORD:z,PR_LITERAL:G,PR_NOCODE:N,PR_PLAIN:F,PR_PUNCTUATION:L,PR_SOURCE:J,PR_STRING:C,PR_TAG:m,PR_TYPE:O}})();PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_DECLARATION,/^<!\w[^>]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^<script\b[^>]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:<!--|-->)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/frontend/coverage/sorter.js b/frontend/coverage/sorter.js index c3fbef4..4ed70ae 100644 --- a/frontend/coverage/sorter.js +++ b/frontend/coverage/sorter.js @@ -1,205 +1,210 @@ - -var addSorting = (function () { - 'use strict'; - var cols, - currentSort = { - index: 0, - desc: false, - }; +/* eslint-disable */ +var addSorting = (function() { + 'use strict'; + var cols, + currentSort = { + index: 0, + desc: false + }; - // returns the summary table element - function getTable() { - return document.querySelector('.coverage-summary'); - } - // returns the thead element of the summary table - function getTableHeader() { - return getTable().querySelector('thead tr'); - } - // returns the tbody element of the summary table - function getTableBody() { - return getTable().querySelector('tbody'); - } - // returns the th element for nth column - function getNthColumn(n) { - return getTableHeader().querySelectorAll('th')[n]; - } - - function onFilterInput() { - const searchValue = document.getElementById('fileSearch').value; - const rows = document.getElementsByTagName('tbody')[0].children; - - // Try to create a RegExp from the searchValue. If it fails (invalid regex), - // it will be treated as a plain text search - let searchRegex; - try { - searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive - } catch (error) { - searchRegex = null; + // returns the summary table element + function getTable() { + return document.querySelector('.coverage-summary'); + } + // returns the thead element of the summary table + function getTableHeader() { + return getTable().querySelector('thead tr'); + } + // returns the tbody element of the summary table + function getTableBody() { + return getTable().querySelector('tbody'); + } + // returns the th element for nth column + function getNthColumn(n) { + return getTableHeader().querySelectorAll('th')[n]; } - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; - let isMatch = false; - - if (searchRegex) { - // If a valid regex was created, use it for matching - isMatch = searchRegex.test(row.textContent); - } else { - // Otherwise, fall back to the original plain text search - isMatch = row.textContent.toLowerCase().includes(searchValue.toLowerCase()); - } + function onFilterInput() { + const searchValue = document.getElementById('fileSearch').value; + const rows = document.getElementsByTagName('tbody')[0].children; + + // Try to create a RegExp from the searchValue. If it fails (invalid regex), + // it will be treated as a plain text search + let searchRegex; + try { + searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive + } catch (error) { + searchRegex = null; + } - row.style.display = isMatch ? '' : 'none'; - } - } - - // loads the search box - function addSearchBox() { - var template = document.getElementById('filterTemplate'); - var templateClone = template.content.cloneNode(true); - templateClone.getElementById('fileSearch').oninput = onFilterInput; - template.parentElement.appendChild(templateClone); - } - - // loads all columns - function loadColumns() { - var colNodes = getTableHeader().querySelectorAll('th'), - colNode, - cols = [], - col, - i; - - for (i = 0; i < colNodes.length; i += 1) { - colNode = colNodes[i]; - col = { - key: colNode.getAttribute('data-col'), - sortable: !colNode.getAttribute('data-nosort'), - type: colNode.getAttribute('data-type') || 'string', - }; - cols.push(col); - if (col.sortable) { - col.defaultDescSort = col.type === 'number'; - colNode.innerHTML = colNode.innerHTML + '<span class="sorter"></span>'; - } + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + let isMatch = false; + + if (searchRegex) { + // If a valid regex was created, use it for matching + isMatch = searchRegex.test(row.textContent); + } else { + // Otherwise, fall back to the original plain text search + isMatch = row.textContent + .toLowerCase() + .includes(searchValue.toLowerCase()); + } + + row.style.display = isMatch ? '' : 'none'; + } } - return cols; - } - // attaches a data attribute to every tr element with an object - // of data values keyed by column name - function loadRowData(tableRow) { - var tableCols = tableRow.querySelectorAll('td'), - colNode, - col, - data = {}, - i, - val; - for (i = 0; i < tableCols.length; i += 1) { - colNode = tableCols[i]; - col = cols[i]; - val = colNode.getAttribute('data-value'); - if (col.type === 'number') { - val = Number(val); - } - data[col.key] = val; + + // loads the search box + function addSearchBox() { + var template = document.getElementById('filterTemplate'); + var templateClone = template.content.cloneNode(true); + templateClone.getElementById('fileSearch').oninput = onFilterInput; + template.parentElement.appendChild(templateClone); } - return data; - } - // loads all row data - function loadData() { - var rows = getTableBody().querySelectorAll('tr'), - i; - - for (i = 0; i < rows.length; i += 1) { - rows[i].data = loadRowData(rows[i]); + + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), + colNode, + cols = [], + col, + i; + + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = + colNode.innerHTML + '<span class="sorter"></span>'; + } + } + return cols; } - } - // sorts the table using the data for the ith column - function sortByIndex(index, desc) { - var key = cols[index].key, - sorter = function (a, b) { - a = a.data[key]; - b = b.data[key]; - return a < b ? -1 : a > b ? 1 : 0; - }, - finalSorter = sorter, - tableBody = document.querySelector('.coverage-summary tbody'), - rowNodes = tableBody.querySelectorAll('tr'), - rows = [], - i; - - if (desc) { - finalSorter = function (a, b) { - return -1 * sorter(a, b); - }; + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; - for (i = 0; i < rowNodes.length; i += 1) { - rows.push(rowNodes[i]); - tableBody.removeChild(rowNodes[i]); + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function(a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function(a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } - rows.sort(finalSorter); + rows.sort(finalSorter); - for (i = 0; i < rows.length; i += 1) { - tableBody.appendChild(rows[i]); - } - } - // removes sort indicators for current column being sorted - function removeSortIndicators() { - var col = getNthColumn(currentSort.index), - cls = col.className; - - cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); - col.className = cls; - } - // adds sort indicators for current column being sorted - function addSortIndicators() { - getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted'; - } - // adds event listeners for all sorter widgets - function enableUI() { - var i, - el, - ithSorter = function ithSorter(i) { - var col = cols[i]; - - return function () { - var desc = col.defaultDescSort; - - if (currentSort.index === i) { - desc = !currentSort.desc; - } - sortByIndex(i, desc); - removeSortIndicators(); - currentSort.index = i; - currentSort.desc = desc; - addSortIndicators(); - }; - }; - for (i = 0; i < cols.length; i += 1) { - if (cols[i].sortable) { - // add the click event handler on the th so users - // dont have to click on those tiny arrows - el = getNthColumn(i).querySelector('.sorter').parentElement; - if (el.addEventListener) { - el.addEventListener('click', ithSorter(i)); - } else { - el.attachEvent('onclick', ithSorter(i)); + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); } - } } - } - // adds sorting functionality to the UI - return function () { - if (!getTable()) { - return; + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc + ? ' sorted-desc' + : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function() { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i = 0; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } } - cols = loadColumns(); - loadData(); - addSearchBox(); - addSortIndicators(); - enableUI(); - }; + // adds sorting functionality to the UI + return function() { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(); + addSearchBox(); + addSortIndicators(); + enableUI(); + }; })(); window.addEventListener('load', addSorting); diff --git a/frontend/coverage/src/App.css.html b/frontend/coverage/src/App.css.html index a5aa753..5fca2a7 100644 --- a/frontend/coverage/src/App.css.html +++ b/frontend/coverage/src/App.css.html @@ -1,61 +1,68 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src/App.css</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../prettify.css" /> <link rel="stylesheet" href="../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> App.css</h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Statements</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Branches</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Functions</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Lines</span> - <span class="fraction">0/0</span> - </div> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Statements</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Branches</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Functions</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Lines</span> + <span class='fraction'>0/0</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line low"></div> - <pre><table class="coverage"> + </div> + <div class='status-line low'></div> + <pre><table class="coverage"> <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a> <a name='L2'></a><a href='#L2'>2</a> <a name='L3'></a><a href='#L3'>3</a> @@ -128,69 +135,7 @@ <a name='L70'></a><a href='#L70'>70</a> <a name='L71'></a><a href='#L71'>71</a> <a name='L72'></a><a href='#L72'>72</a> -<a name='L73'></a><a href='#L73'>73</a> -<a name='L74'></a><a href='#L74'>74</a> -<a name='L75'></a><a href='#L75'>75</a> -<a name='L76'></a><a href='#L76'>76</a> -<a name='L77'></a><a href='#L77'>77</a> -<a name='L78'></a><a href='#L78'>78</a> -<a name='L79'></a><a href='#L79'>79</a> -<a name='L80'></a><a href='#L80'>80</a> -<a name='L81'></a><a href='#L81'>81</a> -<a name='L82'></a><a href='#L82'>82</a> -<a name='L83'></a><a href='#L83'>83</a> -<a name='L84'></a><a href='#L84'>84</a> -<a name='L85'></a><a href='#L85'>85</a> -<a name='L86'></a><a href='#L86'>86</a> -<a name='L87'></a><a href='#L87'>87</a> -<a name='L88'></a><a href='#L88'>88</a> -<a name='L89'></a><a href='#L89'>89</a> -<a name='L90'></a><a href='#L90'>90</a> -<a name='L91'></a><a href='#L91'>91</a> -<a name='L92'></a><a href='#L92'>92</a> -<a name='L93'></a><a href='#L93'>93</a> -<a name='L94'></a><a href='#L94'>94</a> -<a name='L95'></a><a href='#L95'>95</a> -<a name='L96'></a><a href='#L96'>96</a> -<a name='L97'></a><a href='#L97'>97</a> -<a name='L98'></a><a href='#L98'>98</a> -<a name='L99'></a><a href='#L99'>99</a> -<a name='L100'></a><a href='#L100'>100</a> -<a name='L101'></a><a href='#L101'>101</a> -<a name='L102'></a><a href='#L102'>102</a> -<a name='L103'></a><a href='#L103'>103</a> -<a name='L104'></a><a href='#L104'>104</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> +<a name='L73'></a><a href='#L73'>73</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -269,8 +214,6 @@ body { margin: 0; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; } /* Dashboard Layout */ @@ -282,60 +225,28 @@ body { /* Prevent body scroll */ } -.dashboard-header { - /* Legacy didn't really have a top header, but we need one for settings/logout. - Keeping it minimal/flat or matching sidebar bg if we want to blend in. - For now, let's make it dark gray to stand out less or match legacy dark mode if applicable. - Actually, let's keep it distinct but apply the font styles. */ - background: #222; - color: white; - padding: 0.5rem 1rem; - display: flex; - justify-content: space-between; - align-items: center; - font-weight: bold; -} - -.dashboard-header h1 { - margin: 0; - font-size: 1.2rem; - font-variant: small-caps; - text-transform: lowercase; -} - -.nav-link, -.logout-btn { - font-weight: bold; - font-variant: small-caps; - text-transform: lowercase; - font-size: 1rem; - background: transparent; - border: none; - color: #ccc; - cursor: pointer; - margin-left: 1rem; -} - -.nav-link:hover, -.logout-btn:hover { - color: white; - text-decoration: underline; -} +/* Header styles removed as we moved to sidebar navigation */ .dashboard-content { display: flex; flex: 1; overflow: hidden; + position: relative; } .dashboard-sidebar { - width: 15rem; + width: 11rem; background: var(--sidebar-bg); - border-right: 1px solid #999; + border-right: 1px solid var(--border-color); display: flex; flex-direction: column; overflow-y: auto; - padding: 1rem; + transition: margin-left 0.4s ease; + /* No padding here, handled in FeedList */ +} + +.dashboard-sidebar.hidden { + margin-left: -11rem; } .dashboard-main { @@ -347,42 +258,44 @@ body { } .dashboard-main>* { - max-width: 600px; - margin: 0; + max-width: 35em; + margin: 0 auto; } -.logout-btn { +.fixed-toggle { + position: absolute; + top: 1rem; + left: 1rem; + z-index: 1000; background: transparent; - border: 1px solid rgba(255, 255, 255, 0.3); - color: white; - padding: 0.5rem 1rem; - border-radius: 4px; + border: none; + font-size: 2rem; + line-height: 1; cursor: pointer; - transition: all 0.2s; - font-size: 0.9rem; + padding: 0; + color: var(--text-color); + /* Inherit didn't work well if parent is transparent */ } -.logout-btn:hover { - background: rgba(255, 255, 255, 0.1); - border-color: rgba(255, 255, 255, 0.5); +.fixed-toggle:hover { + transform: scale(1.1); }</pre></td></tr></table></pre> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z - </div> - <script src="../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../sorter.js"></script> - <script src="../block-navigation.js"></script> - </body> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../sorter.js"></script> + <script src="../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/src/App.tsx.html b/frontend/coverage/src/App.tsx.html index ed02366..cd305cc 100644 --- a/frontend/coverage/src/App.tsx.html +++ b/frontend/coverage/src/App.tsx.html @@ -1,61 +1,68 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src/App.tsx</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../prettify.css" /> <link rel="stylesheet" href="../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> App.tsx</h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">78.94% </span> - <span class="quiet">Statements</span> - <span class="fraction">15/19</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">66.66% </span> - <span class="quiet">Branches</span> - <span class="fraction">4/6</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">77.77% </span> - <span class="quiet">Functions</span> - <span class="fraction">7/9</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">78.94% </span> - <span class="quiet">Lines</span> - <span class="fraction">15/19</span> - </div> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">72.72% </span> + <span class="quiet">Statements</span> + <span class='fraction'>16/22</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">62.5% </span> + <span class="quiet">Branches</span> + <span class='fraction'>10/16</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">62.5% </span> + <span class="quiet">Functions</span> + <span class='fraction'>5/8</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">72.72% </span> + <span class="quiet">Lines</span> + <span class='fraction'>16/22</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line medium"></div> - <pre><table class="coverage"> + </div> + <div class='status-line medium'></div> + <pre><table class="coverage"> <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a> <a name='L2'></a><a href='#L2'>2</a> <a name='L3'></a><a href='#L3'>3</a> @@ -146,7 +153,17 @@ <a name='L88'></a><a href='#L88'>88</a> <a name='L89'></a><a href='#L89'>89</a> <a name='L90'></a><a href='#L90'>90</a> -<a name='L91'></a><a href='#L91'>91</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<a name='L91'></a><a href='#L91'>91</a> +<a name='L92'></a><a href='#L92'>92</a> +<a name='L93'></a><a href='#L93'>93</a> +<a name='L94'></a><a href='#L94'>94</a> +<a name='L95'></a><a href='#L95'>95</a> +<a name='L96'></a><a href='#L96'>96</a> +<a name='L97'></a><a href='#L97'>97</a> +<a name='L98'></a><a href='#L98'>98</a> +<a name='L99'></a><a href='#L99'>99</a> +<a name='L100'></a><a href='#L100'>100</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -185,16 +202,18 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">1x</span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">1x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-no"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">1x</span> -<span class="cline-any cline-yes">1x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -215,8 +234,14 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">2x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">2x</span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral"> </span> @@ -237,9 +262,10 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import React, { useEffect, useState } from 'react'; -import { BrowserRouter, Routes, Route, Navigate, useLocation, useNavigate } from 'react-router-dom'; +import { BrowserRouter, Routes, Route, Navigate, useLocation } from 'react-router-dom'; import Login from './components/Login'; import './App.css'; +import { apiFetch } from './utils'; // Protected Route wrapper function RequireAuth({ children }: { children: React.ReactElement }) { @@ -247,7 +273,7 @@ function RequireAuth({ children }: { children: React.ReactElement }) { const location = useLocation(); useEffect(() => { - fetch('/api/auth') + apiFetch('/api/auth') .then((res) => { if (res.ok) { setAuth(true); @@ -273,26 +299,25 @@ import FeedList from './components/FeedList'; import FeedItems from './components/FeedItems'; import Settings from './components/Settings'; -function Dashboard() { - const navigate = useNavigate(); - return ( - <div className="dashboard"> - <header className="dashboard-header"> - <h1>Neko Reader</h1> - <nav> - <button onClick={<span class="fstat-no" title="function not covered" >() => <span class="cstat-no" title="statement not covered" >n</span>avigate('/settings')} c</span>lassName="nav-link" style={{ color: 'white', marginRight: '1rem', background: 'none', border: 'none', cursor: 'pointer', fontSize: 'inherit', fontFamily: 'inherit' }}>Settings</button> +function Dashboard({ theme, setTheme }: { theme: string; setTheme: (t: string) => void }) { + const [sidebarVisible, setSidebarVisible] = useState(true); - <button onClick={() => { - fetch('/api/logout', { method: 'POST' }) - .then(() => window.location.href = '/v2/login'); - }} className="logout-btn"> - Logout - </button> - </nav> - </header> + return ( + <div + className={`dashboard ${sidebarVisible ? 'sidebar-visible' : <span class="branch-1 cbranch-no" title="branch not covered" >'sidebar-hidden'}</span> theme-${theme}`} + > <div className="dashboard-content"> - <aside className="dashboard-sidebar"> - <FeedList /> + {!sidebarVisible && ( +<span class="branch-1 cbranch-no" title="branch not covered" > <button</span> + className="sidebar-toggle fixed-toggle" + onClick={<span class="fstat-no" title="function not covered" >() => <span class="cstat-no" title="statement not covered" >s</span>etSidebarVisible(true)}</span> + title="Show Sidebar" + > + 🐱 + </button> + )} + <aside className={`dashboard-sidebar ${sidebarVisible ? '' : <span class="branch-1 cbranch-no" title="branch not covered" >'hidden'}</span>`}> + <FeedList theme={theme} setTheme={setTheme} setSidebarVisible={setSidebarVisible} /> </aside> <main className="dashboard-main"> <Routes> @@ -308,15 +333,24 @@ function Dashboard() { } function App() { + const [theme, setTheme] = useState(localStorage.getItem('neko-theme') || 'light'); + + const handleSetTheme = <span class="fstat-no" title="function not covered" >(n</span>ewTheme: string) => { +<span class="cstat-no" title="statement not covered" > setTheme(newTheme);</span> +<span class="cstat-no" title="statement not covered" > localStorage.setItem('neko-theme', newTheme);</span> + }; + + const basename = window.location.pathname.startsWith('/v2') ? '/v2' : <span class="branch-1 cbranch-no" title="branch not covered" >'/';</span> + return ( - <BrowserRouter basename="/v2"> + <BrowserRouter basename={basename}> <Routes> <Route path="/login" element={<Login />} /> <Route path="/*" element={ <RequireAuth> - <Dashboard /> + <Dashboard theme={theme} setTheme={handleSetTheme} /> </RequireAuth> } /> @@ -328,22 +362,21 @@ function App() { export default App; </pre></td></tr></table></pre> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z - </div> - <script src="../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../sorter.js"></script> - <script src="../block-navigation.js"></script> - </body> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../sorter.js"></script> + <script src="../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/src/components/FeedItem.css.html b/frontend/coverage/src/components/FeedItem.css.html index f6fe1a3..213077f 100644 --- a/frontend/coverage/src/components/FeedItem.css.html +++ b/frontend/coverage/src/components/FeedItem.css.html @@ -1,64 +1,68 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src/components/FeedItem.css</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../../prettify.css" /> <link rel="stylesheet" href="../../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> - <h1> - <a href="../../index.html">All files</a> / - <a href="index.html">src/components</a> FeedItem.css - </h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Statements</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Branches</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Functions</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Lines</span> - <span class="fraction">0/0</span> - </div> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> + <h1><a href="../../index.html">All files</a> / <a href="index.html">src/components</a> FeedItem.css</h1> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Statements</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Branches</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Functions</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Lines</span> + <span class='fraction'>0/0</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line low"></div> - <pre><table class="coverage"> + </div> + <div class='status-line low'></div> + <pre><table class="coverage"> <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a> <a name='L2'></a><a href='#L2'>2</a> <a name='L3'></a><a href='#L3'>3</a> @@ -175,7 +179,25 @@ <a name='L114'></a><a href='#L114'>114</a> <a name='L115'></a><a href='#L115'>115</a> <a name='L116'></a><a href='#L116'>116</a> -<a name='L117'></a><a href='#L117'>117</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<a name='L117'></a><a href='#L117'>117</a> +<a name='L118'></a><a href='#L118'>118</a> +<a name='L119'></a><a href='#L119'>119</a> +<a name='L120'></a><a href='#L120'>120</a> +<a name='L121'></a><a href='#L121'>121</a> +<a name='L122'></a><a href='#L122'>122</a> +<a name='L123'></a><a href='#L123'>123</a> +<a name='L124'></a><a href='#L124'>124</a> +<a name='L125'></a><a href='#L125'>125</a> +<a name='L126'></a><a href='#L126'>126</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -292,139 +314,147 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">.feed-item { - padding: 1rem; - margin-top: 5rem; - list-style: none; - border-bottom: none; + padding: 1rem; + margin-top: 5rem; + list-style: none; + border-bottom: none; } -.feed-item.read .item-title { - color: #888; - font-weight: normal; -} - -.feed-item.unread .item-title { - font-weight: bold; -} +/* removed read/unread specific font-weight to keep it always bold as requested */ .item-header { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 0.5rem; + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 0.5rem; } .item-title { - font-size: 1.25rem; - font-weight: bold; - /* Legacy headers were bold */ - text-decoration: none; - color: #333; - display: block; - flex: 1; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-size: 1.8rem; + font-weight: bold; + text-decoration: none; + color: var(--link-color); + display: block; + flex: 1; } .item-title:hover { - text-decoration: none; - color: blue; - /* Legacy link color */ + text-decoration: none; + color: var(--link-color); } .item-actions { - display: flex; - gap: 0.5rem; - margin-left: 1rem; + display: flex; + gap: 0.5rem; + margin-left: 1rem; } /* Legacy controls were simple text/links, but buttons are fine if minimal */ .star-btn { - background: none; - border: none; - cursor: pointer; - font-size: 1.2rem; - padding: 0 0.5rem 0 0; - vertical-align: middle; - transition: color 0.2s; - line-height: 1; + background: none; + border: none; + cursor: pointer; + font-size: 1.25rem; + padding: 0 0 0 0.5rem; + vertical-align: middle; + transition: color 0.2s; + line-height: 1; } .star-btn.is-starred { - color: #ffd700; - /* Gold */ + color: blue; } .star-btn.is-unstarred { - color: #ccc; + color: var(--text-color); + opacity: 0.3; } .star-btn:hover { - color: #ffeb3b; + color: blue; } .action-btn { - background: whitesmoke; - border: none; - cursor: pointer; - padding: 2px 6px; - font-size: 1rem; - color: blue; - font-weight: bold; + background: var(--sidebar-bg); + border: 1px solid var(--border-color, #ccc); + cursor: pointer; + padding: 2px 6px; + font-size: 1rem; + color: blue; + font-weight: bold; } .action-btn:hover { - background-color: #eee; + background-color: #eee; } .dateline { - margin-top: 0; - font-weight: normal; - font-size: .75em; - color: #ccc; - margin-bottom: 1rem; + margin-top: 0; + font-weight: normal; + font-size: 0.75em; + color: #ccc; + margin-bottom: 1rem; } .dateline a { - color: #ccc; - text-decoration: none; + color: #ccc; + text-decoration: none; } .item-description { - color: #000; - line-height: 1.5; - font-size: 1rem; - margin-top: 1rem; + color: var(--text-color); + line-height: 1.5; + font-size: 1rem; + margin-top: 1rem; } .item-description img { - max-width: 100%; - height: auto; - display: block; - margin: 1rem 0; + max-width: 100%; + height: auto; + display: block; + margin: 1rem 0; } .item-description blockquote { - padding: 1rem 1rem 0 1rem; - border-left: 4px solid #ddd; - color: #666; - margin-left: 0; + padding: 1rem 1rem 0 1rem; + border-left: 4px solid var(--sidebar-bg); + color: var(--text-color); + opacity: 0.8; + margin-left: 0; +} + +.scrape-btn { + background: var(--bg-color); + border: 1px solid var(--border-color, #ccc); + color: blue; + cursor: pointer; + font-family: 'Helvetica Neue'; + font-weight: bold; + font-size: 0.8rem; + padding: 2px 6px; + margin-left: 0.5rem; +} + +.scrape-btn:hover { + background: var(--sidebar-bg); }</pre></td></tr></table></pre> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z - </div> - <script src="../../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../../sorter.js"></script> - <script src="../../block-navigation.js"></script> - </body> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../../sorter.js"></script> + <script src="../../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/src/components/FeedItem.tsx.html b/frontend/coverage/src/components/FeedItem.tsx.html index 5512b78..6e76131 100644 --- a/frontend/coverage/src/components/FeedItem.tsx.html +++ b/frontend/coverage/src/components/FeedItem.tsx.html @@ -1,64 +1,68 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src/components/FeedItem.tsx</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../../prettify.css" /> <link rel="stylesheet" href="../../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> - <h1> - <a href="../../index.html">All files</a> / - <a href="index.html">src/components</a> FeedItem.tsx - </h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">78.94% </span> - <span class="quiet">Statements</span> - <span class="fraction">15/19</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">88.88% </span> - <span class="quiet">Branches</span> - <span class="fraction">16/18</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">85.71% </span> - <span class="quiet">Functions</span> - <span class="fraction">6/7</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">78.94% </span> - <span class="quiet">Lines</span> - <span class="fraction">15/19</span> - </div> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> + <h1><a href="../../index.html">All files</a> / <a href="index.html">src/components</a> FeedItem.tsx</h1> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">78.12% </span> + <span class="quiet">Statements</span> + <span class='fraction'>25/32</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">86.95% </span> + <span class="quiet">Branches</span> + <span class='fraction'>20/23</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">83.33% </span> + <span class="quiet">Functions</span> + <span class='fraction'>10/12</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">80.64% </span> + <span class="quiet">Lines</span> + <span class='fraction'>25/31</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line medium"></div> - <pre><table class="coverage"> + </div> + <div class='status-line medium'></div> + <pre><table class="coverage"> <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a> <a name='L2'></a><a href='#L2'>2</a> <a name='L3'></a><a href='#L3'>3</a> @@ -143,7 +147,41 @@ <a name='L82'></a><a href='#L82'>82</a> <a name='L83'></a><a href='#L83'>83</a> <a name='L84'></a><a href='#L84'>84</a> -<a name='L85'></a><a href='#L85'>85</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<a name='L85'></a><a href='#L85'>85</a> +<a name='L86'></a><a href='#L86'>86</a> +<a name='L87'></a><a href='#L87'>87</a> +<a name='L88'></a><a href='#L88'>88</a> +<a name='L89'></a><a href='#L89'>89</a> +<a name='L90'></a><a href='#L90'>90</a> +<a name='L91'></a><a href='#L91'>91</a> +<a name='L92'></a><a href='#L92'>92</a> +<a name='L93'></a><a href='#L93'>93</a> +<a name='L94'></a><a href='#L94'>94</a> +<a name='L95'></a><a href='#L95'>95</a> +<a name='L96'></a><a href='#L96'>96</a> +<a name='L97'></a><a href='#L97'>97</a> +<a name='L98'></a><a href='#L98'>98</a> +<a name='L99'></a><a href='#L99'>99</a> +<a name='L100'></a><a href='#L100'>100</a> +<a name='L101'></a><a href='#L101'>101</a> +<a name='L102'></a><a href='#L102'>102</a> +<a name='L103'></a><a href='#L103'>103</a> +<a name='L104'></a><a href='#L104'>104</a> +<a name='L105'></a><a href='#L105'>105</a> +<a name='L106'></a><a href='#L106'>106</a> +<a name='L107'></a><a href='#L107'>107</a> +<a name='L108'></a><a href='#L108'>108</a> +<a name='L109'></a><a href='#L109'>109</a> +<a name='L110'></a><a href='#L110'>110</a> +<a name='L111'></a><a href='#L111'>111</a> +<a name='L112'></a><a href='#L112'>112</a> +<a name='L113'></a><a href='#L113'>113</a> +<a name='L114'></a><a href='#L114'>114</a> +<a name='L115'></a><a href='#L115'>115</a> +<a name='L116'></a><a href='#L116'>116</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -151,16 +189,18 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">33x</span> +<span class="cline-any cline-yes">33x</span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">21x</span> -<span class="cline-any cline-yes">21x</span> +<span class="cline-any cline-yes">33x</span> +<span class="cline-any cline-yes">16x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">21x</span> +<span class="cline-any cline-yes">33x</span> <span class="cline-any cline-yes">1x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">21x</span> +<span class="cline-any cline-yes">33x</span> <span class="cline-any cline-yes">1x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">1x</span> @@ -196,7 +236,28 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">21x</span> +<span class="cline-any cline-yes">33x</span> +<span class="cline-any cline-yes">1x</span> +<span class="cline-any cline-yes">1x</span> +<span class="cline-any cline-yes">1x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">1x</span> +<span class="cline-any cline-yes">1x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">1x</span> +<span class="cline-any cline-yes">1x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">33x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -227,108 +288,143 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import { useState } from 'react'; +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import { useState, useEffect } from 'react'; import type { Item } from '../types'; import './FeedItem.css'; +import { apiFetch } from '../utils'; + interface FeedItemProps { - item: Item; + item: Item; } export default function FeedItem({ item: initialItem }: FeedItemProps) { - const [item, setItem] = useState(initialItem); - const [loading, setLoading] = useState(false); + const [item, setItem] = useState(initialItem); + const [loading, setLoading] = useState(false); + + useEffect(() => { + setItem(initialItem); + }, [initialItem]); + const toggleStar = () => { + updateItem({ ...item, starred: !item.starred }); + }; - const toggleStar = () => { - updateItem({ ...item, starred: !item.starred }); - }; + const updateItem = (newItem: Item) => { + setLoading(true); + // Optimistic update + const previousItem = item; + setItem(newItem); - const updateItem = (newItem: Item) => { - setLoading(true); - // Optimistic update - const previousItem = item; - setItem(newItem); + apiFetch(`/api/item/${newItem._id}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + _id: newItem._id, + read: newItem.read, + starred: newItem.starred, + }), + }) + .then((res) => { + <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) { +<span class="cstat-no" title="statement not covered" > throw new Error('Failed to update item');</span> + } + return res.json(); + }) + .then(() => { + // Confirm with server response if needed, but for now we trust the optimistic update + // or we could setItem(updated) if the server returns the full object + setLoading(false); + }) + .catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => { +<span class="cstat-no" title="statement not covered" > console.error('Error updating item:', err);</span> + // Revert on error +<span class="cstat-no" title="statement not covered" > setItem(previousItem);</span> +<span class="cstat-no" title="statement not covered" > setLoading(false);</span> + }); + }; - fetch(`/api/item/${newItem._id}`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - _id: newItem._id, - read: newItem.read, - starred: newItem.starred, - }), - }) - .then((res) => { - <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) { -<span class="cstat-no" title="statement not covered" > throw new Error('Failed to update item');</span> - } - return res.json(); - }) - .then(() => { - // Confirm with server response if needed, but for now we trust the optimistic update - // or we could setItem(updated) if the server returns the full object - setLoading(false); - }) - .catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => { -<span class="cstat-no" title="statement not covered" > console.error('Error updating item:', err);</span> - // Revert on error -<span class="cstat-no" title="statement not covered" > setItem(previousItem);</span> -<span class="cstat-no" title="statement not covered" > setLoading(false);</span> - }); - }; + const loadFullContent = (e: React.MouseEvent) => { + e.stopPropagation(); + setLoading(true); + apiFetch(`/api/item/${item._id}`) + .then((res) => { + <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) <span class="cstat-no" title="statement not covered" >throw new Error('Failed to fetch full content');</span> + return res.json(); + }) + .then((data) => { + setItem({ ...item, ...data }); + setLoading(false); + }) + .catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => { +<span class="cstat-no" title="statement not covered" > console.error('Error fetching full content:', err);</span> +<span class="cstat-no" title="statement not covered" > setLoading(false);</span> + }); + }; - return ( - <li className={`feed-item ${item.read ? 'read' : 'unread'} ${loading ? 'loading' : ''}`}> - <div className="item-header"> - <button - onClick={(e) => { - e.stopPropagation(); - toggleStar(); - }} - className={`star-btn ${item.starred ? 'is-starred' : 'is-unstarred'}`} - title={item.starred ? "Unstar" : "Star"} - > - {item.starred ? '★' : '☆'} - </button> - <a href={item.url} target="_blank" rel="noopener noreferrer" className="item-title"> - {item.title || <span class="branch-1 cbranch-no" title="branch not covered" >'(No Title)'}</span> - </a> - </div> - <div className="dateline"> - <a href={item.url} target="_blank" rel="noopener noreferrer"> - {new Date(item.publish_date).toLocaleDateString()} - {item.feed_title && ` - ${item.feed_title}`} - </a> - <div className="item-actions" style={{ display: 'inline-block', float: 'right' }}> - </div> - </div> - {item.description && ( - <div className="item-description" dangerouslySetInnerHTML={{ __html: item.description }} /> - )} - </li> - ); + return ( + <li className={`feed-item ${item.read ? 'read' : 'unread'} ${loading ? 'loading' : ''}`}> + <div className="item-header"> + <a href={item.url} target="_blank" rel="noopener noreferrer" className="item-title"> + {item.title || <span class="branch-1 cbranch-no" title="branch not covered" >'(No Title)'}</span> + </a> + <button + onClick={(e) => { + e.stopPropagation(); + toggleStar(); + }} + className={`star-btn ${item.starred ? 'is-starred' : 'is-unstarred'}`} + title={item.starred ? 'Unstar' : 'Star'} + > + ★ + </button> + </div> + <div className="dateline"> + <a href={item.url} target="_blank" rel="noopener noreferrer"> + {new Date(item.publish_date).toLocaleDateString()} + {item.feed_title && ` - ${item.feed_title}`} + </a> + <div className="item-actions" style={{ display: 'inline-block', float: 'right' }}> + {!item.full_content && ( + <button onClick={loadFullContent} className="scrape-btn" title="Load Full Content"> + text + </button> + )} + </div> + </div> + {(item.full_content || item.description) && ( + <div + className="item-description" + dangerouslySetInnerHTML={{ __html: item.full_content || item.description }} + /> + )} + </li> + ); } </pre></td></tr></table></pre> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z - </div> - <script src="../../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../../sorter.js"></script> - <script src="../../block-navigation.js"></script> - </body> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../../sorter.js"></script> + <script src="../../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/src/components/FeedItems.css.html b/frontend/coverage/src/components/FeedItems.css.html index 0b1c77d..7a971c6 100644 --- a/frontend/coverage/src/components/FeedItems.css.html +++ b/frontend/coverage/src/components/FeedItems.css.html @@ -1,64 +1,68 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src/components/FeedItems.css</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../../prettify.css" /> <link rel="stylesheet" href="../../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> - <h1> - <a href="../../index.html">All files</a> / - <a href="index.html">src/components</a> FeedItems.css - </h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Statements</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Branches</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Functions</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Lines</span> - <span class="fraction">0/0</span> - </div> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> + <h1><a href="../../index.html">All files</a> / <a href="index.html">src/components</a> FeedItems.css</h1> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Statements</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Branches</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Functions</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Lines</span> + <span class='fraction'>0/0</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line low"></div> - <pre><table class="coverage"> + </div> + <div class='status-line low'></div> + <pre><table class="coverage"> <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a> <a name='L2'></a><a href='#L2'>2</a> <a name='L3'></a><a href='#L3'>3</a> @@ -81,23 +85,7 @@ <a name='L20'></a><a href='#L20'>20</a> <a name='L21'></a><a href='#L21'>21</a> <a name='L22'></a><a href='#L22'>22</a> -<a name='L23'></a><a href='#L23'>23</a> -<a name='L24'></a><a href='#L24'>24</a> -<a name='L25'></a><a href='#L25'>25</a> -<a name='L26'></a><a href='#L26'>26</a> -<a name='L27'></a><a href='#L27'>27</a> -<a name='L28'></a><a href='#L28'>28</a> -<a name='L29'></a><a href='#L29'>29</a> -<a name='L30'></a><a href='#L30'>30</a> -<a name='L31'></a><a href='#L31'>31</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> +<a name='L23'></a><a href='#L23'>23</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -120,53 +108,44 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">.feed-items { - padding: 1rem; + padding: 1rem 0; + /* Removing horizontal padding to avoid double-padding with FeedItem */ } .feed-items h2 { - margin-top: 0; - border-bottom: 2px solid #eee; - padding-bottom: 0.5rem; + margin-top: 0; + border-bottom: 2px solid var(--border-color); + padding-bottom: 0.5rem; } .item-list { - list-style: none; - padding: 0; -} - -.selected-item-container { - border-left: 4px solid #007bff; - background-color: #f8f9fa; - padding-left: 0.5rem; - margin-left: -0.5rem; - /* Compensate for padding/border to keep alignment */ - transition: background-color 0.2s; + list-style: none; + padding: 0; } .loading-more { - padding: 2rem; - text-align: center; - color: #888; - font-size: 0.9rem; - min-height: 50px; + padding: 2rem; + text-align: center; + color: #888; + font-size: 0.9rem; + min-height: 50px; }</pre></td></tr></table></pre> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z - </div> - <script src="../../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../../sorter.js"></script> - <script src="../../block-navigation.js"></script> - </body> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../../sorter.js"></script> + <script src="../../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/src/components/FeedItems.tsx.html b/frontend/coverage/src/components/FeedItems.tsx.html index e57acf9..f6b7493 100644 --- a/frontend/coverage/src/components/FeedItems.tsx.html +++ b/frontend/coverage/src/components/FeedItems.tsx.html @@ -1,64 +1,68 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src/components/FeedItems.tsx</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../../prettify.css" /> <link rel="stylesheet" href="../../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> - <h1> - <a href="../../index.html">All files</a> / - <a href="index.html">src/components</a> FeedItems.tsx - </h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">89.34% </span> - <span class="quiet">Statements</span> - <span class="fraction">109/122</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">77.21% </span> - <span class="quiet">Branches</span> - <span class="fraction">61/79</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">86.2% </span> - <span class="quiet">Functions</span> - <span class="fraction">25/29</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">89.09% </span> - <span class="quiet">Lines</span> - <span class="fraction">98/110</span> - </div> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> + <h1><a href="../../index.html">All files</a> / <a href="index.html">src/components</a> FeedItems.tsx</h1> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">88.97% </span> + <span class="quiet">Statements</span> + <span class='fraction'>113/127</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">75.3% </span> + <span class="quiet">Branches</span> + <span class='fraction'>61/81</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">86.2% </span> + <span class="quiet">Functions</span> + <span class='fraction'>25/29</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">88.69% </span> + <span class="quiet">Lines</span> + <span class='fraction'>102/115</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line high"></div> - <pre><table class="coverage"> + </div> + <div class='status-line high'></div> + <pre><table class="coverage"> <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a> <a name='L2'></a><a href='#L2'>2</a> <a name='L3'></a><a href='#L3'>3</a> @@ -282,7 +286,18 @@ <a name='L221'></a><a href='#L221'>221</a> <a name='L222'></a><a href='#L222'>222</a> <a name='L223'></a><a href='#L223'>223</a> -<a name='L224'></a><a href='#L224'>224</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<a name='L224'></a><a href='#L224'>224</a> +<a name='L225'></a><a href='#L225'>225</a> +<a name='L226'></a><a href='#L226'>226</a> +<a name='L227'></a><a href='#L227'>227</a> +<a name='L228'></a><a href='#L228'>228</a> +<a name='L229'></a><a href='#L229'>229</a> +<a name='L230'></a><a href='#L230'>230</a> +<a name='L231'></a><a href='#L231'>231</a> +<a name='L232'></a><a href='#L232'>232</a> +<a name='L233'></a><a href='#L233'>233</a> +<a name='L234'></a><a href='#L234'>234</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -298,6 +313,7 @@ <span class="cline-any cline-yes">27x</span> <span class="cline-any cline-yes">27x</span> <span class="cline-any cline-yes">27x</span> +<span class="cline-any cline-yes">27x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">27x</span> <span class="cline-any cline-yes">8x</span> @@ -323,6 +339,11 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">8x</span> +<span class="cline-any cline-yes">8x</span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">8x</span> <span class="cline-any cline-no"> </span> <span class="cline-any cline-yes">8x</span> <span class="cline-any cline-no"> </span> @@ -330,6 +351,8 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">8x</span> +<span class="cline-any cline-yes">8x</span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">8x</span> @@ -363,77 +386,79 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">27x</span> <span class="cline-any cline-yes">7x</span> +<span class="cline-any cline-yes">7x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">27x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">27x</span> -<span class="cline-any cline-yes">23x</span> -<span class="cline-any cline-yes">3x</span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">3x</span> -<span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> -<span class="cline-any cline-yes">2x</span> -<span class="cline-any cline-yes">1x</span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">27x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">3x</span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">1x</span> -<span class="cline-any cline-no"> </span> -<span class="cline-any cline-no"> </span> -<span class="cline-any cline-no"> </span> -<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-no"> </span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">1x</span> -<span class="cline-any cline-yes">1x</span> -<span class="cline-any cline-yes">1x</span> -<span class="cline-any cline-yes">1x</span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">27x</span> <span class="cline-any cline-yes">1x</span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">1x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">23x</span> -<span class="cline-any cline-yes">23x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-no"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">27x</span> +<span class="cline-any cline-yes">23x</span> +<span class="cline-any cline-yes">3x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">3x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">27x</span> <span class="cline-any cline-yes">2x</span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">3x</span> +<span class="cline-any cline-yes">2x</span> +<span class="cline-any cline-yes">1x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">1x</span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-no"> </span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">1x</span> +<span class="cline-any cline-yes">1x</span> +<span class="cline-any cline-yes">1x</span> +<span class="cline-any cline-yes">1x</span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">27x</span> <span class="cline-any cline-yes">1x</span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">1x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">23x</span> +<span class="cline-any cline-yes">23x</span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-no"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">27x</span> @@ -477,7 +502,6 @@ <span class="cline-any cline-yes">27x</span> <span class="cline-any cline-yes">14x</span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">13x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -510,242 +534,251 @@ import { useParams, useSearchParams } from 'react-router-dom'; import type { Item } from '../types'; import FeedItem from './FeedItem'; import './FeedItems.css'; +import { apiFetch } from '../utils'; export default function FeedItems() { - const { feedId, tagName } = useParams<{ feedId: string; tagName: string }>(); - const [searchParams] = useSearchParams(); - const filterFn = searchParams.get('filter') || 'unread'; + const { feedId, tagName } = useParams<{ feedId: string; tagName: string }>(); + const [searchParams] = useSearchParams(); + const filterFn = searchParams.get('filter') || 'unread'; - const [items, setItems] = useState<Item[]>([]); - const [loading, setLoading] = useState(true); - const [loadingMore, setLoadingMore] = useState(false); - const [hasMore, setHasMore] = useState(true); - const [error, setError] = useState(''); + const [items, setItems] = useState<Item[]>([]); + const [loading, setLoading] = useState(true); + const [loadingMore, setLoadingMore] = useState(false); + const [hasMore, setHasMore] = useState(true); + const [error, setError] = useState(''); + const [selectedIndex, setSelectedIndex] = useState(-1); - const fetchItems = (maxId?: string) => { - if (maxId) { - setLoadingMore(true); - } else { - setLoading(true); - setItems([]); - } - setError(''); + const fetchItems = (maxId?: string) => { + if (maxId) { + setLoadingMore(true); + } else { + setLoading(true); + setItems([]); + } + setError(''); - let url = '/api/stream'; - const params = new URLSearchParams(); + let url = '/api/stream'; + const params = new URLSearchParams(); - if (feedId) { - params.append('feed_id', feedId); - } else if (tagName) { - params.append('tag', tagName); - } + if (feedId) { + params.append('feed_id', feedId); + } else if (tagName) { + params.append('tag', tagName); + } - if (maxId) { - params.append('max_id', maxId); - } + if (maxId) { + params.append('max_id', maxId); + } + + // Apply filters + const searchQuery = searchParams.get('q'); + <span class="missing-if-branch" title="if path not taken" >I</span>if (searchQuery) { +<span class="cstat-no" title="statement not covered" > params.append('q', searchQuery);</span> + } + + <span class="missing-if-branch" title="if path not taken" >I</span>if (filterFn === 'all') { +<span class="cstat-no" title="statement not covered" > params.append('read_filter', 'all');</span> + <span class="missing-if-branch" title="if path not taken" >I</span>} else if (filterFn === 'starred') { +<span class="cstat-no" title="statement not covered" > params.append('starred', 'true');</span> +<span class="cstat-no" title="statement not covered" > params.append('read_filter', 'all');</span> + } else { + // default to unread + <span class="missing-if-branch" title="else path not taken" >E</span>if (!searchQuery) { + params.append('read_filter', 'unread'); + } + } + + const queryString = params.toString(); + <span class="missing-if-branch" title="else path not taken" >E</span>if (queryString) { + url += `?${queryString}`; + } - // Apply filters - <span class="missing-if-branch" title="if path not taken" >I</span>if (filterFn === 'all') { -<span class="cstat-no" title="statement not covered" > params.append('read_filter', 'all');</span> - <span class="missing-if-branch" title="if path not taken" >I</span>} else if (filterFn === 'starred') { -<span class="cstat-no" title="statement not covered" > params.append('starred', 'true');</span> -<span class="cstat-no" title="statement not covered" > params.append('read_filter', 'all');</span> + apiFetch(url) + .then((res) => { + <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) { +<span class="cstat-no" title="statement not covered" > throw new Error('Failed to fetch items');</span> + } + return res.json(); + }) + .then((data) => { + if (maxId) { + setItems((prev) => [...prev, ...data]); } else { - // default to unread - params.append('read_filter', 'unread'); + setItems(data); } + setHasMore(data.length > 0); + setLoading(false); + setLoadingMore(false); + }) + .catch((err) => { + setError(err.message); + setLoading(false); + setLoadingMore(false); + }); + }; - const queryString = params.toString(); - <span class="missing-if-branch" title="else path not taken" >E</span>if (queryString) { - url += `?${queryString}`; - } + useEffect(() => { + fetchItems(); + setSelectedIndex(-1); + }, [feedId, tagName, filterFn, searchParams]); - fetch(url) - .then((res) => { - <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) { -<span class="cstat-no" title="statement not covered" > throw new Error('Failed to fetch items');</span> - } - return res.json(); - }) - .then((data) => { - if (maxId) { - setItems((prev) => [...prev, ...data]); - } else { - setItems(data); - } - setHasMore(data.length > 0); - setLoading(false); - setLoadingMore(false); - }) - .catch((err) => { - setError(err.message); - setLoading(false); - setLoadingMore(false); - }); - }; - useEffect(() => { - fetchItems(); - }, [feedId, tagName, filterFn]); + const scrollToItem = (index: number) => { + const element = document.getElementById(`item-${index}`); + <span class="missing-if-branch" title="else path not taken" >E</span>if (element) { + element.scrollIntoView({ behavior: 'auto', block: 'start' }); + } + }; - const [selectedIndex, setSelectedIndex] = useState(-1); + const markAsRead = (item: Item) => { + const updatedItem = { ...item, read: true }; + // Optimistic update + setItems((prevItems) => prevItems.map((i) => (i._id === item._id ? updatedItem : i))); - useEffect(() => { - const handleKeyDown = (e: KeyboardEvent) => { - <span class="missing-if-branch" title="if path not taken" >I</span>if (items.length === 0) <span class="cstat-no" title="statement not covered" >return;</span> + apiFetch(`/api/item/${item._id}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ read: true, starred: item.starred }), + }).catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => <span class="cstat-no" title="statement not covered" >console.error('Failed to mark read', err))</span>; + }; - if (e.key === 'j') { - setSelectedIndex((prev) => { - const nextIndex = Math.min(prev + 1, items.length - 1); - <span class="missing-if-branch" title="else path not taken" >E</span>if (nextIndex !== prev) { - const item = items[nextIndex]; - if (!item.read) { - markAsRead(item); - } - scrollToItem(nextIndex); - } - return nextIndex; - }); - <span class="missing-if-branch" title="if path not taken" >I</span>} else if (e.key === 'k') { -<span class="cstat-no" title="statement not covered" > setSelectedIndex(<span class="fstat-no" title="function not covered" >(p</span>rev) => {</span> - const nextIndex = <span class="cstat-no" title="statement not covered" >Math.max(prev - 1, 0);</span> -<span class="cstat-no" title="statement not covered" > if (nextIndex !== prev) {</span> -<span class="cstat-no" title="statement not covered" > scrollToItem(nextIndex);</span> - } -<span class="cstat-no" title="statement not covered" > return nextIndex;</span> - }); - <span class="missing-if-branch" title="else path not taken" >E</span>} else if (e.key === 's') { - setSelectedIndex((currentIndex) => { - <span class="missing-if-branch" title="else path not taken" >E</span>if (currentIndex >= 0 && currentIndex < items.length) { - toggleStar(items[currentIndex]); - } - return currentIndex; - }); - } - }; + const toggleStar = (item: Item) => { + const updatedItem = { ...item, starred: !item.starred }; + // Optimistic update + setItems((prevItems) => prevItems.map((i) => (i._id === item._id ? updatedItem : i))); - window.addEventListener('keydown', handleKeyDown); - return () => window.removeEventListener('keydown', handleKeyDown); - }, [items]); + apiFetch(`/api/item/${item._id}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ read: item.read, starred: !item.starred }), + }).catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => <span class="cstat-no" title="statement not covered" >console.error('Failed to toggle star', err))</span>; + }; - const scrollToItem = (index: number) => { - const element = document.getElementById(`item-${index}`); - <span class="missing-if-branch" title="else path not taken" >E</span>if (element) { - element.scrollIntoView({ behavior: 'smooth', block: 'start' }); - } - }; + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + <span class="missing-if-branch" title="if path not taken" >I</span>if (items.length === 0) <span class="cstat-no" title="statement not covered" >return;</span> - const markAsRead = (item: Item) => { - const updatedItem = { ...item, read: true }; - // Optimistic update - setItems((prevItems) => prevItems.map((i) => (i._id === item._id ? updatedItem : i))); - - fetch(`/api/item/${item._id}`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ read: true, starred: item.starred }), - }).catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => <span class="cstat-no" title="statement not covered" >console.error('Failed to mark read', err))</span>; + if (e.key === 'j') { + setSelectedIndex((prev) => { + const nextIndex = Math.min(prev + 1, items.length - 1); + <span class="missing-if-branch" title="else path not taken" >E</span>if (nextIndex !== prev) { + const item = items[nextIndex]; + if (!item.read) { + markAsRead(item); + } + scrollToItem(nextIndex); + } + return nextIndex; + }); + <span class="missing-if-branch" title="if path not taken" >I</span>} else if (e.key === 'k') { +<span class="cstat-no" title="statement not covered" > setSelectedIndex(<span class="fstat-no" title="function not covered" >(p</span>rev) => {</span> + const nextIndex = <span class="cstat-no" title="statement not covered" >Math.max(prev - 1, 0);</span> +<span class="cstat-no" title="statement not covered" > if (nextIndex !== prev) {</span> +<span class="cstat-no" title="statement not covered" > scrollToItem(nextIndex);</span> + } +<span class="cstat-no" title="statement not covered" > return nextIndex;</span> + }); + <span class="missing-if-branch" title="else path not taken" >E</span>} else if (e.key === 's') { + setSelectedIndex((currentIndex) => { + <span class="missing-if-branch" title="else path not taken" >E</span>if (currentIndex >= 0 && currentIndex < items.length) { + toggleStar(items[currentIndex]); + } + return currentIndex; + }); + } }; - const toggleStar = (item: Item) => { - const updatedItem = { ...item, starred: !item.starred }; - // Optimistic update - setItems((prevItems) => prevItems.map((i) => (i._id === item._id ? updatedItem : i))); + window.addEventListener('keydown', handleKeyDown); + return () => window.removeEventListener('keydown', handleKeyDown); + }, [items]); - fetch(`/api/item/${item._id}`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ read: item.read, starred: !item.starred }), - }).catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => <span class="cstat-no" title="statement not covered" >console.error('Failed to toggle star', err))</span>; - }; - useEffect(() => { - const observer = new IntersectionObserver( - (entries) => { - entries.forEach((entry) => { - // Infinity scroll sentinel - if (entry.target.id === 'load-more-sentinel') { - <span class="missing-if-branch" title="else path not taken" >E</span>if (entry.isIntersecting && !loadingMore && hasMore && items.length > 0) { - fetchItems(String(items[items.length - 1]._id)); - } - return; - } - // If item is not intersecting and is above the viewport, it's been scrolled past - <span class="missing-if-branch" title="else path not taken" >E</span>if (!entry.isIntersecting && entry.boundingClientRect.top < 0) { - const index = Number(entry.target.getAttribute('data-index')); - <span class="missing-if-branch" title="else path not taken" >E</span>if (!isNaN(index) && index >= 0 && index < items.length) { - const item = items[index]; - <span class="missing-if-branch" title="else path not taken" >E</span>if (!item.read) { - markAsRead(item); - } - } - } - }); - }, - { root: null, threshold: 0 } - ); + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + // Infinity scroll sentinel + if (entry.target.id === 'load-more-sentinel') { + <span class="missing-if-branch" title="else path not taken" >E</span>if (entry.isIntersecting && !loadingMore && hasMore && items.length > 0) { + fetchItems(String(items[items.length - 1]._id)); + } + return; + } - items.forEach((_, index) => { - const el = document.getElementById(`item-${index}`); - <span class="missing-if-branch" title="else path not taken" >E</span>if (el) observer.observe(el); + // If item is not intersecting and is above the viewport, it's been scrolled past + <span class="missing-if-branch" title="else path not taken" >E</span>if (!entry.isIntersecting && entry.boundingClientRect.top < 0) { + const index = Number(entry.target.getAttribute('data-index')); + <span class="missing-if-branch" title="else path not taken" >E</span>if (!isNaN(index) && index >= 0 && index < items.length) { + const item = items[index]; + <span class="missing-if-branch" title="else path not taken" >E</span>if (!item.read) { + markAsRead(item); + } + } + } }); + }, + { root: null, threshold: 0 } + ); - const sentinel = document.getElementById('load-more-sentinel'); - if (sentinel) observer.observe(sentinel); + items.forEach((_, index) => { + const el = document.getElementById(`item-${index}`); + <span class="missing-if-branch" title="else path not taken" >E</span>if (el) observer.observe(el); + }); - return () => observer.disconnect(); - }, [items, loadingMore, hasMore]); + const sentinel = document.getElementById('load-more-sentinel'); + if (sentinel) observer.observe(sentinel); - if (loading) return <div className="feed-items-loading">Loading items...</div>; - if (error) return <div className="feed-items-error">Error: {error}</div>; + return () => observer.disconnect(); + }, [items, loadingMore, hasMore]); + if (loading) return <div className="feed-items-loading">Loading items...</div>; + if (error) return <div className="feed-items-error">Error: {error}</div>; - return ( - <div className="feed-items"> - {items.length === 0 ? ( -<span class="branch-0 cbranch-no" title="branch not covered" > <p>No items found.</p></span> - ) : ( - <ul className="item-list"> - {items.map((item, index) => ( - <div - id={`item-${index}`} - key={item._id} - data-index={index} - className={index === selectedIndex ? 'selected-item-container' : ''} - onClick={<span class="fstat-no" title="function not covered" >() => <span class="cstat-no" title="statement not covered" >s</span>etSelectedIndex(index)}</span> - > - <FeedItem item={item} /> - </div> - ))} - {hasMore && ( - <div id="load-more-sentinel" className="loading-more"> - {loadingMore ? 'Loading more...' : ''} - </div> - )} - </ul> - )} - </div> - ); + return ( + <div className="feed-items"> + {items.length === 0 ? ( +<span class="branch-0 cbranch-no" title="branch not covered" > <p>No items found.</p></span> + ) : ( + <ul className="item-list"> + {items.map((item, index) => ( + <div + id={`item-${index}`} + key={item._id} + data-index={index} + data-selected={index === selectedIndex} + onClick={<span class="fstat-no" title="function not covered" >() => <span class="cstat-no" title="statement not covered" >s</span>etSelectedIndex(index)}</span> + > + <FeedItem item={item} /> + </div> + ))} + {hasMore && ( + <div id="load-more-sentinel" className="loading-more"> + {loadingMore ? 'Loading more...' : ''} + </div> + )} + </ul> + )} + </div> + ); } </pre></td></tr></table></pre> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z - </div> - <script src="../../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../../sorter.js"></script> - <script src="../../block-navigation.js"></script> - </body> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../../sorter.js"></script> + <script src="../../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/src/components/FeedList.css.html b/frontend/coverage/src/components/FeedList.css.html index fe60b9d..2b93e18 100644 --- a/frontend/coverage/src/components/FeedList.css.html +++ b/frontend/coverage/src/components/FeedList.css.html @@ -1,64 +1,68 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src/components/FeedList.css</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../../prettify.css" /> <link rel="stylesheet" href="../../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> - <h1> - <a href="../../index.html">All files</a> / - <a href="index.html">src/components</a> FeedList.css - </h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Statements</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Branches</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Functions</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Lines</span> - <span class="fraction">0/0</span> - </div> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> + <h1><a href="../../index.html">All files</a> / <a href="index.html">src/components</a> FeedList.css</h1> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Statements</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Branches</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Functions</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Lines</span> + <span class='fraction'>0/0</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line low"></div> - <pre><table class="coverage"> + </div> + <div class='status-line low'></div> + <pre><table class="coverage"> <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a> <a name='L2'></a><a href='#L2'>2</a> <a name='L3'></a><a href='#L3'>3</a> @@ -156,7 +160,159 @@ <a name='L95'></a><a href='#L95'>95</a> <a name='L96'></a><a href='#L96'>96</a> <a name='L97'></a><a href='#L97'>97</a> -<a name='L98'></a><a href='#L98'>98</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<a name='L98'></a><a href='#L98'>98</a> +<a name='L99'></a><a href='#L99'>99</a> +<a name='L100'></a><a href='#L100'>100</a> +<a name='L101'></a><a href='#L101'>101</a> +<a name='L102'></a><a href='#L102'>102</a> +<a name='L103'></a><a href='#L103'>103</a> +<a name='L104'></a><a href='#L104'>104</a> +<a name='L105'></a><a href='#L105'>105</a> +<a name='L106'></a><a href='#L106'>106</a> +<a name='L107'></a><a href='#L107'>107</a> +<a name='L108'></a><a href='#L108'>108</a> +<a name='L109'></a><a href='#L109'>109</a> +<a name='L110'></a><a href='#L110'>110</a> +<a name='L111'></a><a href='#L111'>111</a> +<a name='L112'></a><a href='#L112'>112</a> +<a name='L113'></a><a href='#L113'>113</a> +<a name='L114'></a><a href='#L114'>114</a> +<a name='L115'></a><a href='#L115'>115</a> +<a name='L116'></a><a href='#L116'>116</a> +<a name='L117'></a><a href='#L117'>117</a> +<a name='L118'></a><a href='#L118'>118</a> +<a name='L119'></a><a href='#L119'>119</a> +<a name='L120'></a><a href='#L120'>120</a> +<a name='L121'></a><a href='#L121'>121</a> +<a name='L122'></a><a href='#L122'>122</a> +<a name='L123'></a><a href='#L123'>123</a> +<a name='L124'></a><a href='#L124'>124</a> +<a name='L125'></a><a href='#L125'>125</a> +<a name='L126'></a><a href='#L126'>126</a> +<a name='L127'></a><a href='#L127'>127</a> +<a name='L128'></a><a href='#L128'>128</a> +<a name='L129'></a><a href='#L129'>129</a> +<a name='L130'></a><a href='#L130'>130</a> +<a name='L131'></a><a href='#L131'>131</a> +<a name='L132'></a><a href='#L132'>132</a> +<a name='L133'></a><a href='#L133'>133</a> +<a name='L134'></a><a href='#L134'>134</a> +<a name='L135'></a><a href='#L135'>135</a> +<a name='L136'></a><a href='#L136'>136</a> +<a name='L137'></a><a href='#L137'>137</a> +<a name='L138'></a><a href='#L138'>138</a> +<a name='L139'></a><a href='#L139'>139</a> +<a name='L140'></a><a href='#L140'>140</a> +<a name='L141'></a><a href='#L141'>141</a> +<a name='L142'></a><a href='#L142'>142</a> +<a name='L143'></a><a href='#L143'>143</a> +<a name='L144'></a><a href='#L144'>144</a> +<a name='L145'></a><a href='#L145'>145</a> +<a name='L146'></a><a href='#L146'>146</a> +<a name='L147'></a><a href='#L147'>147</a> +<a name='L148'></a><a href='#L148'>148</a> +<a name='L149'></a><a href='#L149'>149</a> +<a name='L150'></a><a href='#L150'>150</a> +<a name='L151'></a><a href='#L151'>151</a> +<a name='L152'></a><a href='#L152'>152</a> +<a name='L153'></a><a href='#L153'>153</a> +<a name='L154'></a><a href='#L154'>154</a> +<a name='L155'></a><a href='#L155'>155</a> +<a name='L156'></a><a href='#L156'>156</a> +<a name='L157'></a><a href='#L157'>157</a> +<a name='L158'></a><a href='#L158'>158</a> +<a name='L159'></a><a href='#L159'>159</a> +<a name='L160'></a><a href='#L160'>160</a> +<a name='L161'></a><a href='#L161'>161</a> +<a name='L162'></a><a href='#L162'>162</a> +<a name='L163'></a><a href='#L163'>163</a> +<a name='L164'></a><a href='#L164'>164</a> +<a name='L165'></a><a href='#L165'>165</a> +<a name='L166'></a><a href='#L166'>166</a> +<a name='L167'></a><a href='#L167'>167</a> +<a name='L168'></a><a href='#L168'>168</a> +<a name='L169'></a><a href='#L169'>169</a> +<a name='L170'></a><a href='#L170'>170</a> +<a name='L171'></a><a href='#L171'>171</a> +<a name='L172'></a><a href='#L172'>172</a> +<a name='L173'></a><a href='#L173'>173</a> +<a name='L174'></a><a href='#L174'>174</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -254,120 +410,195 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">.feed-list { - /* Removed card styling */ - padding: 0; - background: transparent; + padding: 1rem; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + color: #777; + /* specific v1 color */ + font-size: 0.8rem; } -.feed-list h2 { - font-size: 1.2rem; - margin-bottom: 0.5rem; - border-bottom: 1px solid #999; - padding-bottom: 0.25rem; - text-transform: uppercase; - letter-spacing: 1px; +.feed-list h1.logo { + font-size: 2rem; + /* match v1 */ + margin: 0 0 1rem 0; + line-height: 1; + cursor: pointer; + position: sticky; + top: 0; + background: var(--sidebar-bg); + z-index: 10; + padding-bottom: 0.5rem; + color: var(--text-color); + /* Usually dark/white depending on theme, v1 was white on blue? No, white on fixed header? No, v1 logo class says color: white. But sidebar is #ccc. */ + /* In v1 logo was fixed top left (blue header bar?). In v2 sidebar is #ccc. + Let's use theme text color but maybe bolder? */ } -.feed-list-items, -.tag-list-items, -.filter-list { - list-style: none; - padding: 0; - margin: 0; +/* Override logo color if necessary for themes */ +.theme-light .feed-list h1.logo { + color: #333; } -.sidebar-feed-item { - padding: 0.25rem 0; - border-bottom: none; - /* Clean look */ - display: flex; - justify-content: space-between; - align-items: center; +.theme-dark .feed-list h1.logo { + color: #eee; } -.feed-title { - color: #333; - text-decoration: none; - font-size: 0.9rem; +.search-section { + margin-bottom: 1rem; } -.feed-title:hover { - text-decoration: underline; - color: #000; +.search-input { + width: 100%; + padding: 0.25rem; + border: 1px solid var(--border-color, #999); + background: var(--bg-color); + color: var(--text-color); + font-size: 0.8rem; + font-family: inherit; + border-radius: 0; + /* v1 didn't have rounded inputs usually */ } -.feed-category { - display: none; - /* Hide category in sidebar list to save space/match legacy simplicity if needed */ +.section-header { + font-size: 1rem; + /* v1 h4 size? */ + font-weight: bold; + margin: 1rem 0 0.25rem 0; + cursor: pointer; + user-select: none; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + color: #333; + /* Darker than list items */ + text-transform: lowercase; + font-variant: small-caps; +} + +.filter-list, +.tag-list-items, +.feed-list-items, +.nav-list { + list-style: none; + padding: 0; + margin: 0; } -.tag-section { - margin-top: 2rem; +.filter-list li, +.nav-list li { + margin-bottom: 0.1rem; } +.filter-list a, +.nav-list a, .tag-link, -.filter-list li a { - color: #333; - text-decoration: none; - font-size: 0.9rem; - display: block; - padding: 0.1rem 0; +.feed-title, +.logout-link { + text-decoration: none; + color: var(--link-color, blue); + font-size: 0.8rem; + /* Matches v1 .75em approx */ + display: block; + cursor: pointer; + background: none; + border: none; + padding: 0; + font-family: inherit; + font-variant: small-caps; + text-transform: lowercase; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } +.filter-list a:hover, +.nav-list a:hover, .tag-link:hover, -.filter-list li a:hover { - text-decoration: underline; - background: transparent; - /* No hover bg */ - color: #000; +.feed-title:hover, +.logout-link:hover { + text-decoration: underline; + color: var(--link-color, blue); } -.filter-section { - margin-bottom: 2rem; +.filter-list a.active, +.tag-link.active, +.feed-title.active { + font-weight: bold; + color: #000; + /* Active state black */ } -.filter-list { - display: block; - /* Stack vertically */ +.tag-item, +.sidebar-feed-item { + margin-bottom: 0; } -.filter-list { - display: block; +.feed-category { + display: none; } -.filter-list li a { - text-decoration: none; - color: #333; - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; - font-weight: bold; - font-variant: small-caps; - text-transform: lowercase; - font-size: 1.1rem; - display: block; - margin-bottom: 0.5rem; +.nav-section { + margin-top: 2rem; + border-top: 1px solid var(--border-color, #999); + padding-top: 0.5rem; } -.filter-list li a:hover { - color: blue; - background-color: transparent; +.logout-link { + text-align: left; + width: 100%; + color: #777; + /* Make logout less prominent */ +} + +.logout-link:hover { + color: var(--link-color, blue); +} + +.theme-section { + margin-top: 1rem; +} + +.theme-selector { + display: flex; + gap: 0.5rem; +} + +.theme-selector button { + background: transparent; + border: 1px solid var(--border-color, #999); + cursor: pointer; + padding: 0.1rem 0.3rem; + font-size: 0.9rem; + border-radius: 0; +} + +.theme-selector button.active { + background: var(--border-color, #999); + color: white; +} + +/* Scrollbar styling for webkit */ +.dashboard-sidebar::-webkit-scrollbar { + width: 4px; +} + +.dashboard-sidebar::-webkit-scrollbar-thumb { + background-color: var(--border-color, #999); }</pre></td></tr></table></pre> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z - </div> - <script src="../../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../../sorter.js"></script> - <script src="../../block-navigation.js"></script> - </body> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../../sorter.js"></script> + <script src="../../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/src/components/FeedList.tsx.html b/frontend/coverage/src/components/FeedList.tsx.html index ba7d81f..acb2ede 100644 --- a/frontend/coverage/src/components/FeedList.tsx.html +++ b/frontend/coverage/src/components/FeedList.tsx.html @@ -1,64 +1,68 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src/components/FeedList.tsx</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../../prettify.css" /> <link rel="stylesheet" href="../../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> - <h1> - <a href="../../index.html">All files</a> / - <a href="index.html">src/components</a> FeedList.tsx - </h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">91.66% </span> - <span class="quiet">Statements</span> - <span class="fraction">22/24</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">82.35% </span> - <span class="quiet">Branches</span> - <span class="fraction">14/17</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">100% </span> - <span class="quiet">Functions</span> - <span class="fraction">8/8</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">100% </span> - <span class="quiet">Lines</span> - <span class="fraction">20/20</span> - </div> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> + <h1><a href="../../index.html">All files</a> / <a href="index.html">src/components</a> FeedList.tsx</h1> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">79.54% </span> + <span class="quiet">Statements</span> + <span class='fraction'>35/44</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">64.86% </span> + <span class="quiet">Branches</span> + <span class='fraction'>24/37</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">64.7% </span> + <span class="quiet">Functions</span> + <span class='fraction'>11/17</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">82.05% </span> + <span class="quiet">Lines</span> + <span class='fraction'>32/39</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line high"></div> - <pre><table class="coverage"> + </div> + <div class='status-line medium'></div> + <pre><table class="coverage"> <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a> <a name='L2'></a><a href='#L2'>2</a> <a name='L3'></a><a href='#L3'>3</a> @@ -139,18 +143,153 @@ <a name='L78'></a><a href='#L78'>78</a> <a name='L79'></a><a href='#L79'>79</a> <a name='L80'></a><a href='#L80'>80</a> -<a name='L81'></a><a href='#L81'>81</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">11x</span> -<span class="cline-any cline-yes">11x</span> -<span class="cline-any cline-yes">11x</span> -<span class="cline-any cline-yes">11x</span> -<span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">11x</span> +<a name='L81'></a><a href='#L81'>81</a> +<a name='L82'></a><a href='#L82'>82</a> +<a name='L83'></a><a href='#L83'>83</a> +<a name='L84'></a><a href='#L84'>84</a> +<a name='L85'></a><a href='#L85'>85</a> +<a name='L86'></a><a href='#L86'>86</a> +<a name='L87'></a><a href='#L87'>87</a> +<a name='L88'></a><a href='#L88'>88</a> +<a name='L89'></a><a href='#L89'>89</a> +<a name='L90'></a><a href='#L90'>90</a> +<a name='L91'></a><a href='#L91'>91</a> +<a name='L92'></a><a href='#L92'>92</a> +<a name='L93'></a><a href='#L93'>93</a> +<a name='L94'></a><a href='#L94'>94</a> +<a name='L95'></a><a href='#L95'>95</a> +<a name='L96'></a><a href='#L96'>96</a> +<a name='L97'></a><a href='#L97'>97</a> +<a name='L98'></a><a href='#L98'>98</a> +<a name='L99'></a><a href='#L99'>99</a> +<a name='L100'></a><a href='#L100'>100</a> +<a name='L101'></a><a href='#L101'>101</a> +<a name='L102'></a><a href='#L102'>102</a> +<a name='L103'></a><a href='#L103'>103</a> +<a name='L104'></a><a href='#L104'>104</a> +<a name='L105'></a><a href='#L105'>105</a> +<a name='L106'></a><a href='#L106'>106</a> +<a name='L107'></a><a href='#L107'>107</a> +<a name='L108'></a><a href='#L108'>108</a> +<a name='L109'></a><a href='#L109'>109</a> +<a name='L110'></a><a href='#L110'>110</a> +<a name='L111'></a><a href='#L111'>111</a> +<a name='L112'></a><a href='#L112'>112</a> +<a name='L113'></a><a href='#L113'>113</a> +<a name='L114'></a><a href='#L114'>114</a> +<a name='L115'></a><a href='#L115'>115</a> +<a name='L116'></a><a href='#L116'>116</a> +<a name='L117'></a><a href='#L117'>117</a> +<a name='L118'></a><a href='#L118'>118</a> +<a name='L119'></a><a href='#L119'>119</a> +<a name='L120'></a><a href='#L120'>120</a> +<a name='L121'></a><a href='#L121'>121</a> +<a name='L122'></a><a href='#L122'>122</a> +<a name='L123'></a><a href='#L123'>123</a> +<a name='L124'></a><a href='#L124'>124</a> +<a name='L125'></a><a href='#L125'>125</a> +<a name='L126'></a><a href='#L126'>126</a> +<a name='L127'></a><a href='#L127'>127</a> +<a name='L128'></a><a href='#L128'>128</a> +<a name='L129'></a><a href='#L129'>129</a> +<a name='L130'></a><a href='#L130'>130</a> +<a name='L131'></a><a href='#L131'>131</a> +<a name='L132'></a><a href='#L132'>132</a> +<a name='L133'></a><a href='#L133'>133</a> +<a name='L134'></a><a href='#L134'>134</a> +<a name='L135'></a><a href='#L135'>135</a> +<a name='L136'></a><a href='#L136'>136</a> +<a name='L137'></a><a href='#L137'>137</a> +<a name='L138'></a><a href='#L138'>138</a> +<a name='L139'></a><a href='#L139'>139</a> +<a name='L140'></a><a href='#L140'>140</a> +<a name='L141'></a><a href='#L141'>141</a> +<a name='L142'></a><a href='#L142'>142</a> +<a name='L143'></a><a href='#L143'>143</a> +<a name='L144'></a><a href='#L144'>144</a> +<a name='L145'></a><a href='#L145'>145</a> +<a name='L146'></a><a href='#L146'>146</a> +<a name='L147'></a><a href='#L147'>147</a> +<a name='L148'></a><a href='#L148'>148</a> +<a name='L149'></a><a href='#L149'>149</a> +<a name='L150'></a><a href='#L150'>150</a> +<a name='L151'></a><a href='#L151'>151</a> +<a name='L152'></a><a href='#L152'>152</a> +<a name='L153'></a><a href='#L153'>153</a> +<a name='L154'></a><a href='#L154'>154</a> +<a name='L155'></a><a href='#L155'>155</a> +<a name='L156'></a><a href='#L156'>156</a> +<a name='L157'></a><a href='#L157'>157</a> +<a name='L158'></a><a href='#L158'>158</a> +<a name='L159'></a><a href='#L159'>159</a> +<a name='L160'></a><a href='#L160'>160</a> +<a name='L161'></a><a href='#L161'>161</a> +<a name='L162'></a><a href='#L162'>162</a> +<a name='L163'></a><a href='#L163'>163</a> +<a name='L164'></a><a href='#L164'>164</a> +<a name='L165'></a><a href='#L165'>165</a> +<a name='L166'></a><a href='#L166'>166</a> +<a name='L167'></a><a href='#L167'>167</a> +<a name='L168'></a><a href='#L168'>168</a> +<a name='L169'></a><a href='#L169'>169</a> +<a name='L170'></a><a href='#L170'>170</a> +<a name='L171'></a><a href='#L171'>171</a> +<a name='L172'></a><a href='#L172'>172</a> +<a name='L173'></a><a href='#L173'>173</a> +<a name='L174'></a><a href='#L174'>174</a> +<a name='L175'></a><a href='#L175'>175</a> +<a name='L176'></a><a href='#L176'>176</a> +<a name='L177'></a><a href='#L177'>177</a> +<a name='L178'></a><a href='#L178'>178</a> +<a name='L179'></a><a href='#L179'>179</a> +<a name='L180'></a><a href='#L180'>180</a> +<a name='L181'></a><a href='#L181'>181</a> +<a name='L182'></a><a href='#L182'>182</a> +<a name='L183'></a><a href='#L183'>183</a> +<a name='L184'></a><a href='#L184'>184</a> +<a name='L185'></a><a href='#L185'>185</a> +<a name='L186'></a><a href='#L186'>186</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-yes">2x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">13x</span> <span class="cline-any cline-yes">6x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">4x</span> @@ -172,8 +311,56 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">11x</span> -<span class="cline-any cline-yes">5x</span> +<span class="cline-any cline-yes">13x</span> +<span class="cline-any cline-yes">7x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">6x</span> +<span class="cline-any cline-yes">1x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">6x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">4x</span> <span class="cline-any cline-neutral"> </span> @@ -191,7 +378,20 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">3x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">2x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -207,7 +407,6 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> -<span class="cline-any cline-yes">3x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -216,107 +415,226 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import { useEffect, useState } from 'react'; -import { Link } from 'react-router-dom'; +import { Link, useNavigate, useSearchParams, useLocation, useParams } from 'react-router-dom'; import type { Feed, Category } from '../types'; import './FeedList.css'; +import { apiFetch } from '../utils'; + +export default function FeedList({ + theme, + setTheme, + setSidebarVisible, +}: { + theme: string; + setTheme: (t: string) => void; + setSidebarVisible: (visible: boolean) => void; +}) { + const [feeds, setFeeds] = useState<Feed[]>([]); + const [tags, setTags] = useState<Category[]>([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(''); + const [feedsExpanded, setFeedsExpanded] = useState(false); + const [searchQuery, setSearchQuery] = useState(''); + const navigate = useNavigate(); + const [searchParams] = useSearchParams(); + const location = useLocation(); + const { feedId, tagName } = useParams(); + + const currentFilter = + searchParams.get('filter') || + (location.pathname === '/' && !feedId && !tagName ? 'unread' : <span class="branch-1 cbranch-no" title="branch not covered" >'');</span> + + const handleSearch = <span class="fstat-no" title="function not covered" >(e</span>: React.FormEvent) => { +<span class="cstat-no" title="statement not covered" > e.preventDefault();</span> +<span class="cstat-no" title="statement not covered" > if (searchQuery.trim()) {</span> +<span class="cstat-no" title="statement not covered" > navigate(`/?q=${encodeURIComponent(searchQuery.trim())}`);</span> + } + }; + + const toggleFeeds = () => { + setFeedsExpanded(!feedsExpanded); + }; + + useEffect(() => { + Promise.all([ + apiFetch('/api/feed/').then((res) => { + <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) <span class="cstat-no" title="statement not covered" >throw new Error('Failed to fetch feeds');</span> + return res.json(); + }), + apiFetch('/api/tag').then((res) => { + <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) <span class="cstat-no" title="statement not covered" >throw new Error('Failed to fetch tags');</span> + return res.json(); + }), + ]) + .then(([feedsData, tagsData]) => { + setFeeds(feedsData); + setTags(tagsData); + setLoading(false); + }) + .catch((err) => { + setError(err.message); + setLoading(false); + }); + }, []); -export default function FeedList() { - const [feeds, setFeeds] = useState<Feed[]>([]); - const [tags, setTags] = useState<Category[]>([]); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(''); + if (loading) return <div className="feed-list-loading">Loading feeds...</div>; + if (error) return <div className="feed-list-error">Error: {error}</div>; - useEffect(() => { - Promise.all([ - fetch('/api/feed/').then(res => { - <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) <span class="cstat-no" title="statement not covered" >throw new Error('Failed to fetch feeds');</span> - return res.json(); - }), - fetch('/api/tag').then(res => { - <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) <span class="cstat-no" title="statement not covered" >throw new Error('Failed to fetch tags');</span> - return res.json(); - }) - ]) - .then(([feedsData, tagsData]) => { - setFeeds(feedsData); - setTags(tagsData); - setLoading(false); - }) - .catch((err) => { - setError(err.message); - setLoading(false); - }); - }, []); + const handleLogout = () => { + apiFetch('/api/logout', { method: 'POST' }).then(() => (window.location.href = '/v2/login')); + }; - if (loading) return <div className="feed-list-loading">Loading feeds...</div>; - if (error) return <div className="feed-list-error">Error: {error}</div>; + return ( + <div className="feed-list"> + <h1 className="logo" onClick={<span class="fstat-no" title="function not covered" >() => <span class="cstat-no" title="statement not covered" >s</span>etSidebarVisible(false)}></span> + 🐱 + </h1> - return ( - <div className="feed-list"> - <div className="filter-section"> - <ul className="filter-list"> - <li><Link to="/?filter=unread">Unread</Link></li> - <li><Link to="/?filter=all">All</Link></li> - <li><Link to="/?filter=starred">Starred</Link></li> - </ul> - </div> - <div className="feed-section"> - <h2>Feeds</h2> - {feeds.length === 0 ? ( - <p>No feeds found.</p> - ) : ( - <ul className="feed-list-items"> - {feeds.map((feed) => ( - <li key={feed._id} className="sidebar-feed-item"> - <Link to={`/feed/${feed._id}`} className="feed-title"> - {feed.title || <span class="branch-1 cbranch-no" title="branch not covered" >feed.url}</span> - </Link> - {feed.category && <span className="feed-category">{feed.category}</span>} - </li> - ))} - </ul> - )} - </div> + <div className="search-section"> + <form onSubmit={handleSearch} className="search-form"> + <input + type="search" + placeholder="search..." + value={searchQuery} + onChange={<span class="fstat-no" title="function not covered" >(e</span>) => <span class="cstat-no" title="statement not covered" >setSearchQuery(e.target.value)}</span> + className="search-input" + /> + </form> + </div> - {tags && tags.length > 0 && ( - <div className="tag-section"> - <h2>Tags</h2> - <ul className="tag-list-items"> - {tags.map((tag) => ( - <li key={tag.title} className="tag-item"> - <Link to={`/tag/${encodeURIComponent(tag.title)}`} className="tag-link"> - {tag.title} - </Link> - </li> - ))} - </ul> - </div> - )} + <div className="filter-section"> + <ul className="filter-list"> + <li className="unread_filter"> + <Link to="/?filter=unread" className={currentFilter === 'unread' ? 'active' : <span class="branch-1 cbranch-no" title="branch not covered" >''}></span> + unread + </Link> + </li> + <li className="all_filter"> + <Link to="/?filter=all" className={currentFilter === 'all' ? <span class="branch-0 cbranch-no" title="branch not covered" >'active' : '</span>'}> + all + </Link> + </li> + <li className="starred_filter"> + <Link to="/?filter=starred" className={currentFilter === 'starred' ? <span class="branch-0 cbranch-no" title="branch not covered" >'active' : '</span>'}> + starred + </Link> + </li> + </ul> + </div> + + <div className="tag-section"> + <h4 onClick={<span class="fstat-no" title="function not covered" >() => {</span> }} className="section-header"> + Tags + </h4> + <ul className="tag-list-items"> + {tags.map((tag) => ( + <li key={tag.title} className="tag-item"> + <Link + to={`/tag/${encodeURIComponent(tag.title)}`} + className={`tag-link ${tagName === tag.title ? <span class="branch-0 cbranch-no" title="branch not covered" >'active' : '</span>'}`} + > + {tag.title} + </Link> + </li> + ))} + </ul> + </div> + + <div className="feed-section"> + <h4 onClick={toggleFeeds} className="section-header"> + Feeds + </h4> + {feedsExpanded && + (feeds.length === 0 ? ( + <p>No feeds found.</p> + ) : ( + <ul className="feed-list-items"> + {feeds.map((feed) => ( + <li key={feed._id} className="sidebar-feed-item"> + <Link + to={`/feed/${feed._id}`} + className={`feed-title ${feedId === String(feed._id) ? <span class="branch-0 cbranch-no" title="branch not covered" >'active' : '</span>'}`} + > + {feed.title || <span class="branch-1 cbranch-no" title="branch not covered" >feed.url}</span> + </Link> + </li> + ))} + </ul> + ))} + </div> + + <div className="nav-section"> + <ul className="nav-list"> + <li> + <Link to="/settings" className="nav-link"> + settings + </Link> + </li> + <li> + <button onClick={handleLogout} className="logout-link"> + logout + </button> + </li> + </ul> + </div> + + <div className="theme-section"> + <div className="theme-selector"> + <button + onClick={<span class="fstat-no" title="function not covered" >() => <span class="cstat-no" title="statement not covered" >s</span>etTheme('light')}</span> + className={theme === 'light' ? 'active' : <span class="branch-1 cbranch-no" title="branch not covered" >''}</span> + title="Light Theme" + > + ☀️ + </button> + <button + onClick={<span class="fstat-no" title="function not covered" >() => <span class="cstat-no" title="statement not covered" >s</span>etTheme('dark')}</span> + className={theme === 'dark' ? <span class="branch-0 cbranch-no" title="branch not covered" >'active' : '</span>'} + title="Dark Theme" + > + 🌙 + </button> </div> - ); + </div> + </div> + ); } </pre></td></tr></table></pre> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z - </div> - <script src="../../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../../sorter.js"></script> - <script src="../../block-navigation.js"></script> - </body> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../../sorter.js"></script> + <script src="../../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/src/components/Login.css.html b/frontend/coverage/src/components/Login.css.html index bb3654e..031618b 100644 --- a/frontend/coverage/src/components/Login.css.html +++ b/frontend/coverage/src/components/Login.css.html @@ -1,64 +1,68 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src/components/Login.css</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../../prettify.css" /> <link rel="stylesheet" href="../../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> - <h1> - <a href="../../index.html">All files</a> / - <a href="index.html">src/components</a> Login.css - </h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Statements</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Branches</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Functions</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Lines</span> - <span class="fraction">0/0</span> - </div> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> + <h1><a href="../../index.html">All files</a> / <a href="index.html">src/components</a> Login.css</h1> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Statements</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Branches</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Functions</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Lines</span> + <span class='fraction'>0/0</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line low"></div> - <pre><table class="coverage"> + </div> + <div class='status-line low'></div> + <pre><table class="coverage"> <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a> <a name='L2'></a><a href='#L2'>2</a> <a name='L3'></a><a href='#L3'>3</a> @@ -233,7 +237,7 @@ text-align: center; } -button[type="submit"] { +button[type='submit'] { width: 100%; padding: 0.75rem; background-color: #007bff; @@ -245,27 +249,26 @@ button[type="submit"] { transition: background-color 0.2s; } -button[type="submit"]:hover { +button[type='submit']:hover { background-color: #0056b3; } </pre></td></tr></table></pre> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z - </div> - <script src="../../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../../sorter.js"></script> - <script src="../../block-navigation.js"></script> - </body> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../../sorter.js"></script> + <script src="../../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/src/components/Login.tsx.html b/frontend/coverage/src/components/Login.tsx.html index f29e3cb..43fb613 100644 --- a/frontend/coverage/src/components/Login.tsx.html +++ b/frontend/coverage/src/components/Login.tsx.html @@ -1,64 +1,68 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src/components/Login.tsx</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../../prettify.css" /> <link rel="stylesheet" href="../../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> - <h1> - <a href="../../index.html">All files</a> / - <a href="index.html">src/components</a> Login.tsx - </h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">100% </span> - <span class="quiet">Statements</span> - <span class="fraction">17/17</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">83.33% </span> - <span class="quiet">Branches</span> - <span class="fraction">5/6</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">100% </span> - <span class="quiet">Functions</span> - <span class="fraction">3/3</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">100% </span> - <span class="quiet">Lines</span> - <span class="fraction">17/17</span> - </div> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> + <h1><a href="../../index.html">All files</a> / <a href="index.html">src/components</a> Login.tsx</h1> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">100% </span> + <span class="quiet">Statements</span> + <span class='fraction'>17/17</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">83.33% </span> + <span class="quiet">Branches</span> + <span class='fraction'>5/6</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">100% </span> + <span class="quiet">Functions</span> + <span class='fraction'>3/3</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">100% </span> + <span class="quiet">Lines</span> + <span class='fraction'>17/17</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line high"></div> - <pre><table class="coverage"> + </div> + <div class='status-line high'></div> + <pre><table class="coverage"> <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a> <a name='L2'></a><a href='#L2'>2</a> <a name='L3'></a><a href='#L3'>3</a> @@ -113,7 +117,11 @@ <a name='L52'></a><a href='#L52'>52</a> <a name='L53'></a><a href='#L53'>53</a> <a name='L54'></a><a href='#L54'>54</a> -<a name='L55'></a><a href='#L55'>55</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<a name='L55'></a><a href='#L55'>55</a> +<a name='L56'></a><a href='#L56'>56</a> +<a name='L57'></a><a href='#L57'>57</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -171,74 +179,75 @@ import { useNavigate } from 'react-router-dom'; import './Login.css'; +import { apiFetch } from '../utils'; + export default function Login() { - const [password, setPassword] = useState(''); - const [error, setError] = useState(''); - const navigate = useNavigate(); + const [password, setPassword] = useState(''); + const [error, setError] = useState(''); + const navigate = useNavigate(); - const handleSubmit = async (e: FormEvent) => { - e.preventDefault(); - setError(''); + const handleSubmit = async (e: FormEvent) => { + e.preventDefault(); + setError(''); - try { - // Use URLSearchParams to send as form-urlencoded, matching backend expectation - const params = new URLSearchParams(); - params.append('password', password); + try { + // Use URLSearchParams to send as form-urlencoded, matching backend expectation + const params = new URLSearchParams(); + params.append('password', password); - const res = await fetch('/api/login', { - method: 'POST', - body: params, - }); + const res = await apiFetch('/api/login', { + method: 'POST', + body: params, + }); - if (res.ok) { - navigate('/'); - } else { - const data = await res.json(); - setError(data.message || <span class="branch-1 cbranch-no" title="branch not covered" >'Login failed')</span>; - } - } catch (err) { - setError('Network error'); - } - }; + if (res.ok) { + navigate('/'); + } else { + const data = await res.json(); + setError(data.message || <span class="branch-1 cbranch-no" title="branch not covered" >'Login failed')</span>; + } + } catch (err) { + setError('Network error'); + } + }; - return ( - <div className="login-container"> - <form onSubmit={handleSubmit} className="login-form"> - <h1>neko rss mode</h1> - <div className="form-group"> - <label htmlFor="password">password</label> - <input - id="password" - type="password" - value={password} - onChange={(e) => setPassword(e.target.value)} - autoFocus - /> - </div> - {error && <div className="error-message">{error}</div>} - <button type="submit">login</button> - </form> + return ( + <div className="login-container"> + <form onSubmit={handleSubmit} className="login-form"> + <h1>neko rss mode</h1> + <div className="form-group"> + <label htmlFor="password">password</label> + <input + id="password" + type="password" + value={password} + onChange={(e) => setPassword(e.target.value)} + autoFocus + /> </div> - ); + {error && <div className="error-message">{error}</div>} + <button type="submit">login</button> + </form> + </div> + ); } </pre></td></tr></table></pre> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z - </div> - <script src="../../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../../sorter.js"></script> - <script src="../../block-navigation.js"></script> - </body> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../../sorter.js"></script> + <script src="../../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/src/components/Settings.css.html b/frontend/coverage/src/components/Settings.css.html index 6a1155e..28a1915 100644 --- a/frontend/coverage/src/components/Settings.css.html +++ b/frontend/coverage/src/components/Settings.css.html @@ -1,64 +1,68 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src/components/Settings.css</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../../prettify.css" /> <link rel="stylesheet" href="../../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> - <h1> - <a href="../../index.html">All files</a> / - <a href="index.html">src/components</a> Settings.css - </h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Statements</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Branches</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Functions</span> - <span class="fraction">0/0</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">0% </span> - <span class="quiet">Lines</span> - <span class="fraction">0/0</span> - </div> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> + <h1><a href="../../index.html">All files</a> / <a href="index.html">src/components</a> Settings.css</h1> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Statements</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Branches</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Functions</span> + <span class='fraction'>0/0</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">0% </span> + <span class="quiet">Lines</span> + <span class='fraction'>0/0</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line low"></div> - <pre><table class="coverage"> + </div> + <div class='status-line low'></div> + <pre><table class="coverage"> <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a> <a name='L2'></a><a href='#L2'>2</a> <a name='L3'></a><a href='#L3'>3</a> @@ -141,7 +145,163 @@ <a name='L80'></a><a href='#L80'>80</a> <a name='L81'></a><a href='#L81'>81</a> <a name='L82'></a><a href='#L82'>82</a> -<a name='L83'></a><a href='#L83'>83</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<a name='L83'></a><a href='#L83'>83</a> +<a name='L84'></a><a href='#L84'>84</a> +<a name='L85'></a><a href='#L85'>85</a> +<a name='L86'></a><a href='#L86'>86</a> +<a name='L87'></a><a href='#L87'>87</a> +<a name='L88'></a><a href='#L88'>88</a> +<a name='L89'></a><a href='#L89'>89</a> +<a name='L90'></a><a href='#L90'>90</a> +<a name='L91'></a><a href='#L91'>91</a> +<a name='L92'></a><a href='#L92'>92</a> +<a name='L93'></a><a href='#L93'>93</a> +<a name='L94'></a><a href='#L94'>94</a> +<a name='L95'></a><a href='#L95'>95</a> +<a name='L96'></a><a href='#L96'>96</a> +<a name='L97'></a><a href='#L97'>97</a> +<a name='L98'></a><a href='#L98'>98</a> +<a name='L99'></a><a href='#L99'>99</a> +<a name='L100'></a><a href='#L100'>100</a> +<a name='L101'></a><a href='#L101'>101</a> +<a name='L102'></a><a href='#L102'>102</a> +<a name='L103'></a><a href='#L103'>103</a> +<a name='L104'></a><a href='#L104'>104</a> +<a name='L105'></a><a href='#L105'>105</a> +<a name='L106'></a><a href='#L106'>106</a> +<a name='L107'></a><a href='#L107'>107</a> +<a name='L108'></a><a href='#L108'>108</a> +<a name='L109'></a><a href='#L109'>109</a> +<a name='L110'></a><a href='#L110'>110</a> +<a name='L111'></a><a href='#L111'>111</a> +<a name='L112'></a><a href='#L112'>112</a> +<a name='L113'></a><a href='#L113'>113</a> +<a name='L114'></a><a href='#L114'>114</a> +<a name='L115'></a><a href='#L115'>115</a> +<a name='L116'></a><a href='#L116'>116</a> +<a name='L117'></a><a href='#L117'>117</a> +<a name='L118'></a><a href='#L118'>118</a> +<a name='L119'></a><a href='#L119'>119</a> +<a name='L120'></a><a href='#L120'>120</a> +<a name='L121'></a><a href='#L121'>121</a> +<a name='L122'></a><a href='#L122'>122</a> +<a name='L123'></a><a href='#L123'>123</a> +<a name='L124'></a><a href='#L124'>124</a> +<a name='L125'></a><a href='#L125'>125</a> +<a name='L126'></a><a href='#L126'>126</a> +<a name='L127'></a><a href='#L127'>127</a> +<a name='L128'></a><a href='#L128'>128</a> +<a name='L129'></a><a href='#L129'>129</a> +<a name='L130'></a><a href='#L130'>130</a> +<a name='L131'></a><a href='#L131'>131</a> +<a name='L132'></a><a href='#L132'>132</a> +<a name='L133'></a><a href='#L133'>133</a> +<a name='L134'></a><a href='#L134'>134</a> +<a name='L135'></a><a href='#L135'>135</a> +<a name='L136'></a><a href='#L136'>136</a> +<a name='L137'></a><a href='#L137'>137</a> +<a name='L138'></a><a href='#L138'>138</a> +<a name='L139'></a><a href='#L139'>139</a> +<a name='L140'></a><a href='#L140'>140</a> +<a name='L141'></a><a href='#L141'>141</a> +<a name='L142'></a><a href='#L142'>142</a> +<a name='L143'></a><a href='#L143'>143</a> +<a name='L144'></a><a href='#L144'>144</a> +<a name='L145'></a><a href='#L145'>145</a> +<a name='L146'></a><a href='#L146'>146</a> +<a name='L147'></a><a href='#L147'>147</a> +<a name='L148'></a><a href='#L148'>148</a> +<a name='L149'></a><a href='#L149'>149</a> +<a name='L150'></a><a href='#L150'>150</a> +<a name='L151'></a><a href='#L151'>151</a> +<a name='L152'></a><a href='#L152'>152</a> +<a name='L153'></a><a href='#L153'>153</a> +<a name='L154'></a><a href='#L154'>154</a> +<a name='L155'></a><a href='#L155'>155</a> +<a name='L156'></a><a href='#L156'>156</a> +<a name='L157'></a><a href='#L157'>157</a> +<a name='L158'></a><a href='#L158'>158</a> +<a name='L159'></a><a href='#L159'>159</a> +<a name='L160'></a><a href='#L160'>160</a> +<a name='L161'></a><a href='#L161'>161</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -224,105 +384,182 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">.settings-page { - padding: 2rem; - max-width: 800px; - margin: 0 auto; + padding: 2rem; + max-width: 800px; + margin: 0 auto; } .add-feed-section { - background: #f9f9f9; - padding: 1.5rem; - border-radius: 8px; - margin-bottom: 2rem; - border: 1px solid #eee; + background: var(--sidebar-bg); + padding: 1.5rem; + border-radius: 8px; + margin-bottom: 2rem; + border: 1px solid var(--border-color); } .add-feed-form { - display: flex; - gap: 1rem; + display: flex; + gap: 1rem; } .feed-input { - flex: 1; - padding: 0.5rem; - border: 1px solid #ccc; - border-radius: 4px; - font-size: 1rem; + flex: 1; + padding: 0.5rem; + border: 1px solid var(--border-color); + background: var(--bg-color); + color: var(--text-color); + border-radius: 4px; + font-size: 1rem; } .error-message { - color: #d32f2f; - margin-top: 1rem; + color: #d32f2f; + margin-top: 1rem; } .settings-feed-list { - list-style: none; - padding: 0; - border: 1px solid #eee; - border-radius: 8px; + list-style: none; + padding: 0; + border: 1px solid var(--border-color); + border-radius: 8px; } .settings-feed-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1rem; - border-bottom: 1px solid #eee; + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem; + border-bottom: 1px solid var(--border-color); } .settings-feed-item:last-child { - border-bottom: none; + border-bottom: none; } .feed-info { - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; } .feed-title { - font-weight: bold; - font-size: 1.1rem; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: 1.1rem; } .feed-url { - color: #666; - font-size: 0.9rem; + color: var(--text-color); + opacity: 0.6; + font-size: 0.9rem; } .delete-btn { - background: #ff5252; - color: white; - border: none; - padding: 0.5rem 1rem; - border-radius: 4px; - cursor: pointer; + background: #ff5252; + color: white; + border: none; + padding: 0.5rem 1rem; + border-radius: 4px; + cursor: pointer; } .delete-btn:hover { - background: #ff1744; + background: #ff1744; } .delete-btn:disabled { - background: #ffcdd2; - cursor: not-allowed; + background: #ffcdd2; + cursor: not-allowed; +} + +.import-export-section { + display: flex; + gap: 2rem; + margin-bottom: 2rem; +} + +@media (max-width: 600px) { + .import-export-section { + flex-direction: column; + } +} + +.import-section, +.export-section { + flex: 1; + background: var(--sidebar-bg); + padding: 1.5rem; + border-radius: 8px; + border: 1px solid var(--border-color); +} + +.import-form { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.file-input { + font-size: 0.9rem; + max-width: 100%; +} + +.export-buttons { + display: flex; + gap: 1rem; + flex-wrap: wrap; +} + +.export-btn { + display: inline-block; + padding: 0.5rem 1rem; + background: var(--bg-color); + color: var(--link-color); + text-decoration: none; + border: 1px solid var(--border-color); + border-radius: 4px; + font-weight: bold; + text-align: center; + min-width: 70px; +} + +.export-btn:hover { + background: var(--sidebar-bg); +} + +button { + cursor: pointer; + padding: 0.5rem 1rem; + border-radius: 4px; + border: 1px solid var(--border-color); + background: var(--bg-color); + color: var(--text-color); + font-weight: bold; +} + +button:hover:not(:disabled) { + background: var(--sidebar-bg); +} + +button:disabled { + opacity: 0.5; + cursor: not-allowed; }</pre></td></tr></table></pre> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z - </div> - <script src="../../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../../sorter.js"></script> - <script src="../../block-navigation.js"></script> - </body> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../../sorter.js"></script> + <script src="../../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/src/components/Settings.tsx.html b/frontend/coverage/src/components/Settings.tsx.html index df6d027..3d8d219 100644 --- a/frontend/coverage/src/components/Settings.tsx.html +++ b/frontend/coverage/src/components/Settings.tsx.html @@ -1,64 +1,68 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src/components/Settings.tsx</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../../prettify.css" /> <link rel="stylesheet" href="../../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> - <h1> - <a href="../../index.html">All files</a> / - <a href="index.html">src/components</a> Settings.tsx - </h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">75.55% </span> - <span class="quiet">Statements</span> - <span class="fraction">34/45</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">56.25% </span> - <span class="quiet">Branches</span> - <span class="fraction">9/16</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">82.35% </span> - <span class="quiet">Functions</span> - <span class="fraction">14/17</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">84.61% </span> - <span class="quiet">Lines</span> - <span class="fraction">33/39</span> - </div> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> + <h1><a href="../../index.html">All files</a> / <a href="index.html">src/components</a> Settings.tsx</h1> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">56.25% </span> + <span class="quiet">Statements</span> + <span class='fraction'>36/64</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">41.66% </span> + <span class="quiet">Branches</span> + <span class='fraction'>10/24</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">63.63% </span> + <span class="quiet">Functions</span> + <span class='fraction'>14/22</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">62.5% </span> + <span class="quiet">Lines</span> + <span class='fraction'>35/56</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line medium"></div> - <pre><table class="coverage"> + </div> + <div class='status-line medium'></div> + <pre><table class="coverage"> <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a> <a name='L2'></a><a href='#L2'>2</a> <a name='L3'></a><a href='#L3'>3</a> @@ -180,7 +184,67 @@ <a name='L119'></a><a href='#L119'>119</a> <a name='L120'></a><a href='#L120'>120</a> <a name='L121'></a><a href='#L121'>121</a> -<a name='L122'></a><a href='#L122'>122</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<a name='L122'></a><a href='#L122'>122</a> +<a name='L123'></a><a href='#L123'>123</a> +<a name='L124'></a><a href='#L124'>124</a> +<a name='L125'></a><a href='#L125'>125</a> +<a name='L126'></a><a href='#L126'>126</a> +<a name='L127'></a><a href='#L127'>127</a> +<a name='L128'></a><a href='#L128'>128</a> +<a name='L129'></a><a href='#L129'>129</a> +<a name='L130'></a><a href='#L130'>130</a> +<a name='L131'></a><a href='#L131'>131</a> +<a name='L132'></a><a href='#L132'>132</a> +<a name='L133'></a><a href='#L133'>133</a> +<a name='L134'></a><a href='#L134'>134</a> +<a name='L135'></a><a href='#L135'>135</a> +<a name='L136'></a><a href='#L136'>136</a> +<a name='L137'></a><a href='#L137'>137</a> +<a name='L138'></a><a href='#L138'>138</a> +<a name='L139'></a><a href='#L139'>139</a> +<a name='L140'></a><a href='#L140'>140</a> +<a name='L141'></a><a href='#L141'>141</a> +<a name='L142'></a><a href='#L142'>142</a> +<a name='L143'></a><a href='#L143'>143</a> +<a name='L144'></a><a href='#L144'>144</a> +<a name='L145'></a><a href='#L145'>145</a> +<a name='L146'></a><a href='#L146'>146</a> +<a name='L147'></a><a href='#L147'>147</a> +<a name='L148'></a><a href='#L148'>148</a> +<a name='L149'></a><a href='#L149'>149</a> +<a name='L150'></a><a href='#L150'>150</a> +<a name='L151'></a><a href='#L151'>151</a> +<a name='L152'></a><a href='#L152'>152</a> +<a name='L153'></a><a href='#L153'>153</a> +<a name='L154'></a><a href='#L154'>154</a> +<a name='L155'></a><a href='#L155'>155</a> +<a name='L156'></a><a href='#L156'>156</a> +<a name='L157'></a><a href='#L157'>157</a> +<a name='L158'></a><a href='#L158'>158</a> +<a name='L159'></a><a href='#L159'>159</a> +<a name='L160'></a><a href='#L160'>160</a> +<a name='L161'></a><a href='#L161'>161</a> +<a name='L162'></a><a href='#L162'>162</a> +<a name='L163'></a><a href='#L163'>163</a> +<a name='L164'></a><a href='#L164'>164</a> +<a name='L165'></a><a href='#L165'>165</a> +<a name='L166'></a><a href='#L166'>166</a> +<a name='L167'></a><a href='#L167'>167</a> +<a name='L168'></a><a href='#L168'>168</a> +<a name='L169'></a><a href='#L169'>169</a> +<a name='L170'></a><a href='#L170'>170</a> +<a name='L171'></a><a href='#L171'>171</a> +<a name='L172'></a><a href='#L172'>172</a> +<a name='L173'></a><a href='#L173'>173</a> +<a name='L174'></a><a href='#L174'>174</a> +<a name='L175'></a><a href='#L175'>175</a> +<a name='L176'></a><a href='#L176'>176</a> +<a name='L177'></a><a href='#L177'>177</a> +<a name='L178'></a><a href='#L178'>178</a> +<a name='L179'></a><a href='#L179'>179</a> +<a name='L180'></a><a href='#L180'>180</a> +<a name='L181'></a><a href='#L181'>181</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -191,8 +255,6 @@ <span class="cline-any cline-yes">14x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">14x</span> -<span class="cline-any cline-yes">3x</span> -<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">14x</span> <span class="cline-any cline-yes">4x</span> @@ -212,6 +274,10 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">14x</span> +<span class="cline-any cline-yes">3x</span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">14x</span> <span class="cline-any cline-yes">1x</span> <span class="cline-any cline-yes">1x</span> <span class="cline-any cline-neutral"> </span> @@ -254,6 +320,34 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">14x</span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-yes">14x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -281,6 +375,34 @@ <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-no"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> +<span class="cline-any cline-neutral"> </span> <span class="cline-any cline-yes">5x</span> <span class="cline-any cline-neutral"> </span> <span class="cline-any cline-neutral"> </span> @@ -304,142 +426,200 @@ <span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import React, { useEffect, useState } from 'react'; import type { Feed } from '../types'; import './Settings.css'; +import { apiFetch } from '../utils'; export default function Settings() { - const [feeds, setFeeds] = useState<Feed[]>([]); - const [newFeedUrl, setNewFeedUrl] = useState(''); - const [loading, setLoading] = useState(false); - const [error, setError] = useState<string | null>(null); + const [feeds, setFeeds] = useState<Feed[]>([]); + const [newFeedUrl, setNewFeedUrl] = useState(''); + const [loading, setLoading] = useState(false); + const [error, setError] = useState<string | null>(null); - useEffect(() => { + const [importFile, setImportFile] = useState<File | null>(null); + + const fetchFeeds = () => { + setLoading(true); + apiFetch('/api/feed/') + .then((res) => { + <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) <span class="cstat-no" title="statement not covered" >throw new Error('Failed to fetch feeds');</span> + return res.json(); + }) + .then((data) => { + setFeeds(data); + setLoading(false); + }) + .catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => { +<span class="cstat-no" title="statement not covered" > setError(err.message);</span> +<span class="cstat-no" title="statement not covered" > setLoading(false);</span> + }); + }; + + useEffect(() => { + fetchFeeds(); + }, []); + + const handleAddFeed = (e: React.FormEvent) => { + e.preventDefault(); + <span class="missing-if-branch" title="if path not taken" >I</span>if (!newFeedUrl) <span class="cstat-no" title="statement not covered" >return;</span> + + setLoading(true); + apiFetch('/api/feed/', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ url: newFeedUrl }), + }) + .then((res) => { + <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) <span class="cstat-no" title="statement not covered" >throw new Error('Failed to add feed');</span> + return res.json(); + }) + .then(() => { + setNewFeedUrl(''); fetchFeeds(); - }, []); + }) + .catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => { +<span class="cstat-no" title="statement not covered" > setError(err.message);</span> +<span class="cstat-no" title="statement not covered" > setLoading(false);</span> + }); + }; + + const handleDeleteFeed = (id: number) => { + <span class="missing-if-branch" title="if path not taken" >I</span>if (!globalThis.confirm('Are you sure you want to delete this feed?')) <span class="cstat-no" title="statement not covered" >return;</span> - const fetchFeeds = () => { - setLoading(true); - fetch('/api/feed/') - .then((res) => { - <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) <span class="cstat-no" title="statement not covered" >throw new Error('Failed to fetch feeds');</span> - return res.json(); - }) - .then((data) => { - setFeeds(data); - setLoading(false); - }) - .catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => { -<span class="cstat-no" title="statement not covered" > setError(err.message);</span> -<span class="cstat-no" title="statement not covered" > setLoading(false);</span> - }); - }; + setLoading(true); + apiFetch(`/api/feed/${id}`, { + method: 'DELETE', + }) + .then((res) => { + <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) <span class="cstat-no" title="statement not covered" >throw new Error('Failed to delete feed');</span> + setFeeds(feeds.filter((f) => f._id !== id)); + setLoading(false); + }) + .catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => { +<span class="cstat-no" title="statement not covered" > setError(err.message);</span> +<span class="cstat-no" title="statement not covered" > setLoading(false);</span> + }); + }; - const handleAddFeed = (e: React.FormEvent) => { - e.preventDefault(); - <span class="missing-if-branch" title="if path not taken" >I</span>if (!newFeedUrl) <span class="cstat-no" title="statement not covered" >return;</span> + const handleImport = <span class="fstat-no" title="function not covered" >(e</span>: React.FormEvent) => { +<span class="cstat-no" title="statement not covered" > e.preventDefault();</span> +<span class="cstat-no" title="statement not covered" > if (!importFile) <span class="cstat-no" title="statement not covered" >return;</span></span> - setLoading(true); - fetch('/api/feed/', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ url: newFeedUrl }), - }) - .then((res) => { - <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) <span class="cstat-no" title="statement not covered" >throw new Error('Failed to add feed');</span> - return res.json(); - }) - .then(() => { - setNewFeedUrl(''); - fetchFeeds(); // Refresh list (or we could append if server returns full feed object) - }) - .catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => { -<span class="cstat-no" title="statement not covered" > setError(err.message);</span> -<span class="cstat-no" title="statement not covered" > setLoading(false);</span> - }); - }; +<span class="cstat-no" title="statement not covered" > setLoading(true);</span> + const formData = <span class="cstat-no" title="statement not covered" >new FormData();</span> +<span class="cstat-no" title="statement not covered" > formData.append('file', importFile);</span> +<span class="cstat-no" title="statement not covered" > formData.append('format', 'opml');</span> - const handleDeleteFeed = (id: number) => { - <span class="missing-if-branch" title="if path not taken" >I</span>if (!globalThis.confirm('Are you sure you want to delete this feed?')) <span class="cstat-no" title="statement not covered" >return;</span> +<span class="cstat-no" title="statement not covered" > apiFetch('/api/import', {</span> + method: 'POST', + body: formData, + }) + .then(<span class="fstat-no" title="function not covered" >(r</span>es) => { +<span class="cstat-no" title="statement not covered" > if (!res.ok) <span class="cstat-no" title="statement not covered" >throw new Error('Failed to import feeds');</span></span> +<span class="cstat-no" title="statement not covered" > return res.json();</span> + }) + .then(<span class="fstat-no" title="function not covered" >() => {</span> +<span class="cstat-no" title="statement not covered" > setImportFile(null);</span> +<span class="cstat-no" title="statement not covered" > fetchFeeds();</span> +<span class="cstat-no" title="statement not covered" > alert('Import successful!');</span> + }) + .catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => { +<span class="cstat-no" title="statement not covered" > setError(err.message);</span> +<span class="cstat-no" title="statement not covered" > setLoading(false);</span> + }); + }; - setLoading(true); - fetch(`/api/feed/${id}`, { - method: 'DELETE', - }) - .then((res) => { - <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.ok) <span class="cstat-no" title="statement not covered" >throw new Error('Failed to delete feed');</span> - setFeeds(feeds.filter((f) => f._id !== id)); - setLoading(false); - }) - .catch(<span class="fstat-no" title="function not covered" >(e</span>rr) => { -<span class="cstat-no" title="statement not covered" > setError(err.message);</span> -<span class="cstat-no" title="statement not covered" > setLoading(false);</span> - }); - }; + return ( + <div className="settings-page"> + <h2>Settings</h2> - return ( - <div className="settings-page"> - <h2>Settings</h2> + <div className="add-feed-section"> + <h3>Add New Feed</h3> + <form onSubmit={handleAddFeed} className="add-feed-form"> + <input + type="url" + value={newFeedUrl} + onChange={(e) => setNewFeedUrl(e.target.value)} + placeholder="https://example.com/feed.xml" + required + className="feed-input" + disabled={loading} + /> + <button type="submit" disabled={loading}> + Add Feed + </button> + </form> + </div> - <div className="add-feed-section"> - <h3>Add New Feed</h3> - <form onSubmit={handleAddFeed} className="add-feed-form"> - <input - type="url" - value={newFeedUrl} - onChange={(e) => setNewFeedUrl(e.target.value)} - placeholder="https://example.com/feed.xml" - required - className="feed-input" - disabled={loading} - /> - <button type="submit" disabled={loading}> - Add Feed - </button> - </form> - {error && <span class="branch-1 cbranch-no" title="branch not covered" ><p className="error-message">{error}</p>}</span> - </div> + <div className="import-export-section"> + <div className="import-section"> + <h3>Import Feeds (OPML)</h3> + <form onSubmit={handleImport} className="import-form"> + <input + type="file" + accept=".opml,.xml,.txt" + onChange={<span class="fstat-no" title="function not covered" >(e</span>) => <span class="cstat-no" title="statement not covered" >setImportFile(e.target.files?.[0] || null)}</span> + className="file-input" + disabled={loading} + /> + <button type="submit" disabled={!importFile || <span class="branch-1 cbranch-no" title="branch not covered" >loading}></span> + Import + </button> + </form> + </div> - <div className="feed-list-section"> - <h3>Manage Feeds</h3> - {loading && <p>Loading...</p>} - <ul className="settings-feed-list"> - {feeds.map((feed) => ( - <li key={feed._id} className="settings-feed-item"> - <div className="feed-info"> - <span className="feed-title">{feed.title || <span class="branch-1 cbranch-no" title="branch not covered" >'(No Title)'}<</span>/span> - <span className="feed-url">{feed.url}</span> - </div> - <button - onClick={() => handleDeleteFeed(feed._id)} - className="delete-btn" - disabled={loading} - title="Delete Feed" - > - Delete - </button> - </li> - ))} - </ul> - </div> + <div className="export-section"> + <h3>Export Feeds</h3> + <div className="export-buttons"> + <a href="/api/export/opml" className="export-btn">OPML</a> + <a href="/api/export/text" className="export-btn">Text</a> + <a href="/api/export/json" className="export-btn">JSON</a> + </div> </div> - ); + </div> + + {error && <span class="branch-1 cbranch-no" title="branch not covered" ><p className="error-message">{error}</p>}</span> + + <div className="feed-list-section"> + <h3>Manage Feeds</h3> + {loading && <p>Loading...</p>} + <ul className="settings-feed-list"> + {feeds.map((feed) => ( + <li key={feed._id} className="settings-feed-item"> + <div className="feed-info"> + <span className="feed-title">{feed.title || <span class="branch-1 cbranch-no" title="branch not covered" >'(No Title)'}<</span>/span> + <span className="feed-url">{feed.url}</span> + </div> + <button + onClick={() => handleDeleteFeed(feed._id)} + className="delete-btn" + disabled={loading} + title="Delete Feed" + > + Delete + </button> + </li> + ))} + </ul> + </div> + </div> + ); } </pre></td></tr></table></pre> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z - </div> - <script src="../../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../../sorter.js"></script> - <script src="../../block-navigation.js"></script> - </body> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../../sorter.js"></script> + <script src="../../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/src/components/index.html b/frontend/coverage/src/components/index.html index 7e1a0b7..66ca900 100644 --- a/frontend/coverage/src/components/index.html +++ b/frontend/coverage/src/components/index.html @@ -1,303 +1,251 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src/components</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../../prettify.css" /> <link rel="stylesheet" href="../../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> <h1><a href="../../index.html">All files</a> src/components</h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">86.78% </span> - <span class="quiet">Statements</span> - <span class="fraction">197/227</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">77.2% </span> - <span class="quiet">Branches</span> - <span class="fraction">105/136</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">87.5% </span> - <span class="quiet">Functions</span> - <span class="fraction">56/64</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">89.26% </span> - <span class="quiet">Lines</span> - <span class="fraction">183/205</span> - </div> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">79.57% </span> + <span class="quiet">Statements</span> + <span class='fraction'>226/284</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">70.17% </span> + <span class="quiet">Branches</span> + <span class='fraction'>120/171</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">75.9% </span> + <span class="quiet">Functions</span> + <span class='fraction'>63/83</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">81.78% </span> + <span class="quiet">Lines</span> + <span class='fraction'>211/258</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line high"></div> - <div class="pad1"> - <table class="coverage-summary"> - <thead> - <tr> - <th data-col="file" data-fmt="html" data-html="true" class="file">File</th> - <th - data-col="pic" - data-type="number" - data-fmt="html" - data-html="true" - class="pic" - ></th> - <th data-col="statements" data-type="number" data-fmt="pct" class="pct"> - Statements - </th> - <th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th> - <th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th> - <th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th> - <th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th> - <th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th> - <th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th> - <th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th> - </tr> - </thead> - <tbody> - <tr> - <td class="file empty" data-value="FeedItem.css"> - <a href="FeedItem.css.html">FeedItem.css</a> - </td> - <td data-value="0" class="pic empty"> - <div class="chart"> - <div class="cover-fill" style="width: 0%"></div> - <div class="cover-empty" style="width: 100%"></div> - </div> - </td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - </tr> + </div> + <div class='status-line medium'></div> + <div class="pad1"> +<table class="coverage-summary"> +<thead> +<tr> + <th data-col="file" data-fmt="html" data-html="true" class="file">File</th> + <th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th> + <th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th> + <th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th> + <th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th> + <th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th> + <th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th> + <th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th> + <th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th> + <th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th> +</tr> +</thead> +<tbody><tr> + <td class="file empty" data-value="FeedItem.css"><a href="FeedItem.css.html">FeedItem.css</a></td> + <td data-value="0" class="pic empty"> + <div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div> + </td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + </tr> - <tr> - <td class="file medium" data-value="FeedItem.tsx"> - <a href="FeedItem.tsx.html">FeedItem.tsx</a> - </td> - <td data-value="78.94" class="pic medium"> - <div class="chart"> - <div class="cover-fill" style="width: 78%"></div> - <div class="cover-empty" style="width: 22%"></div> - </div> - </td> - <td data-value="78.94" class="pct medium">78.94%</td> - <td data-value="19" class="abs medium">15/19</td> - <td data-value="88.88" class="pct high">88.88%</td> - <td data-value="18" class="abs high">16/18</td> - <td data-value="85.71" class="pct high">85.71%</td> - <td data-value="7" class="abs high">6/7</td> - <td data-value="78.94" class="pct medium">78.94%</td> - <td data-value="19" class="abs medium">15/19</td> - </tr> +<tr> + <td class="file medium" data-value="FeedItem.tsx"><a href="FeedItem.tsx.html">FeedItem.tsx</a></td> + <td data-value="78.12" class="pic medium"> + <div class="chart"><div class="cover-fill" style="width: 78%"></div><div class="cover-empty" style="width: 22%"></div></div> + </td> + <td data-value="78.12" class="pct medium">78.12%</td> + <td data-value="32" class="abs medium">25/32</td> + <td data-value="86.95" class="pct high">86.95%</td> + <td data-value="23" class="abs high">20/23</td> + <td data-value="83.33" class="pct high">83.33%</td> + <td data-value="12" class="abs high">10/12</td> + <td data-value="80.64" class="pct high">80.64%</td> + <td data-value="31" class="abs high">25/31</td> + </tr> - <tr> - <td class="file empty" data-value="FeedItems.css"> - <a href="FeedItems.css.html">FeedItems.css</a> - </td> - <td data-value="0" class="pic empty"> - <div class="chart"> - <div class="cover-fill" style="width: 0%"></div> - <div class="cover-empty" style="width: 100%"></div> - </div> - </td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - </tr> +<tr> + <td class="file empty" data-value="FeedItems.css"><a href="FeedItems.css.html">FeedItems.css</a></td> + <td data-value="0" class="pic empty"> + <div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div> + </td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + </tr> - <tr> - <td class="file high" data-value="FeedItems.tsx"> - <a href="FeedItems.tsx.html">FeedItems.tsx</a> - </td> - <td data-value="89.34" class="pic high"> - <div class="chart"> - <div class="cover-fill" style="width: 89%"></div> - <div class="cover-empty" style="width: 11%"></div> - </div> - </td> - <td data-value="89.34" class="pct high">89.34%</td> - <td data-value="122" class="abs high">109/122</td> - <td data-value="77.21" class="pct medium">77.21%</td> - <td data-value="79" class="abs medium">61/79</td> - <td data-value="86.2" class="pct high">86.2%</td> - <td data-value="29" class="abs high">25/29</td> - <td data-value="89.09" class="pct high">89.09%</td> - <td data-value="110" class="abs high">98/110</td> - </tr> +<tr> + <td class="file high" data-value="FeedItems.tsx"><a href="FeedItems.tsx.html">FeedItems.tsx</a></td> + <td data-value="88.97" class="pic high"> + <div class="chart"><div class="cover-fill" style="width: 88%"></div><div class="cover-empty" style="width: 12%"></div></div> + </td> + <td data-value="88.97" class="pct high">88.97%</td> + <td data-value="127" class="abs high">113/127</td> + <td data-value="75.3" class="pct medium">75.3%</td> + <td data-value="81" class="abs medium">61/81</td> + <td data-value="86.2" class="pct high">86.2%</td> + <td data-value="29" class="abs high">25/29</td> + <td data-value="88.69" class="pct high">88.69%</td> + <td data-value="115" class="abs high">102/115</td> + </tr> - <tr> - <td class="file empty" data-value="FeedList.css"> - <a href="FeedList.css.html">FeedList.css</a> - </td> - <td data-value="0" class="pic empty"> - <div class="chart"> - <div class="cover-fill" style="width: 0%"></div> - <div class="cover-empty" style="width: 100%"></div> - </div> - </td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - </tr> +<tr> + <td class="file empty" data-value="FeedList.css"><a href="FeedList.css.html">FeedList.css</a></td> + <td data-value="0" class="pic empty"> + <div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div> + </td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + </tr> - <tr> - <td class="file high" data-value="FeedList.tsx"> - <a href="FeedList.tsx.html">FeedList.tsx</a> - </td> - <td data-value="91.66" class="pic high"> - <div class="chart"> - <div class="cover-fill" style="width: 91%"></div> - <div class="cover-empty" style="width: 9%"></div> - </div> - </td> - <td data-value="91.66" class="pct high">91.66%</td> - <td data-value="24" class="abs high">22/24</td> - <td data-value="82.35" class="pct high">82.35%</td> - <td data-value="17" class="abs high">14/17</td> - <td data-value="100" class="pct high">100%</td> - <td data-value="8" class="abs high">8/8</td> - <td data-value="100" class="pct high">100%</td> - <td data-value="20" class="abs high">20/20</td> - </tr> +<tr> + <td class="file medium" data-value="FeedList.tsx"><a href="FeedList.tsx.html">FeedList.tsx</a></td> + <td data-value="79.54" class="pic medium"> + <div class="chart"><div class="cover-fill" style="width: 79%"></div><div class="cover-empty" style="width: 21%"></div></div> + </td> + <td data-value="79.54" class="pct medium">79.54%</td> + <td data-value="44" class="abs medium">35/44</td> + <td data-value="64.86" class="pct medium">64.86%</td> + <td data-value="37" class="abs medium">24/37</td> + <td data-value="64.7" class="pct medium">64.7%</td> + <td data-value="17" class="abs medium">11/17</td> + <td data-value="82.05" class="pct high">82.05%</td> + <td data-value="39" class="abs high">32/39</td> + </tr> - <tr> - <td class="file empty" data-value="Login.css"> - <a href="Login.css.html">Login.css</a> - </td> - <td data-value="0" class="pic empty"> - <div class="chart"> - <div class="cover-fill" style="width: 0%"></div> - <div class="cover-empty" style="width: 100%"></div> - </div> - </td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - </tr> +<tr> + <td class="file empty" data-value="Login.css"><a href="Login.css.html">Login.css</a></td> + <td data-value="0" class="pic empty"> + <div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div> + </td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + </tr> - <tr> - <td class="file high" data-value="Login.tsx"> - <a href="Login.tsx.html">Login.tsx</a> - </td> - <td data-value="100" class="pic high"> - <div class="chart"> - <div class="cover-fill cover-full" style="width: 100%"></div> - <div class="cover-empty" style="width: 0%"></div> - </div> - </td> - <td data-value="100" class="pct high">100%</td> - <td data-value="17" class="abs high">17/17</td> - <td data-value="83.33" class="pct high">83.33%</td> - <td data-value="6" class="abs high">5/6</td> - <td data-value="100" class="pct high">100%</td> - <td data-value="3" class="abs high">3/3</td> - <td data-value="100" class="pct high">100%</td> - <td data-value="17" class="abs high">17/17</td> - </tr> +<tr> + <td class="file high" data-value="Login.tsx"><a href="Login.tsx.html">Login.tsx</a></td> + <td data-value="100" class="pic high"> + <div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div> + </td> + <td data-value="100" class="pct high">100%</td> + <td data-value="17" class="abs high">17/17</td> + <td data-value="83.33" class="pct high">83.33%</td> + <td data-value="6" class="abs high">5/6</td> + <td data-value="100" class="pct high">100%</td> + <td data-value="3" class="abs high">3/3</td> + <td data-value="100" class="pct high">100%</td> + <td data-value="17" class="abs high">17/17</td> + </tr> - <tr> - <td class="file empty" data-value="Settings.css"> - <a href="Settings.css.html">Settings.css</a> - </td> - <td data-value="0" class="pic empty"> - <div class="chart"> - <div class="cover-fill" style="width: 0%"></div> - <div class="cover-empty" style="width: 100%"></div> - </div> - </td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - </tr> +<tr> + <td class="file empty" data-value="Settings.css"><a href="Settings.css.html">Settings.css</a></td> + <td data-value="0" class="pic empty"> + <div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div> + </td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + </tr> - <tr> - <td class="file medium" data-value="Settings.tsx"> - <a href="Settings.tsx.html">Settings.tsx</a> - </td> - <td data-value="75.55" class="pic medium"> - <div class="chart"> - <div class="cover-fill" style="width: 75%"></div> - <div class="cover-empty" style="width: 25%"></div> - </div> - </td> - <td data-value="75.55" class="pct medium">75.55%</td> - <td data-value="45" class="abs medium">34/45</td> - <td data-value="56.25" class="pct medium">56.25%</td> - <td data-value="16" class="abs medium">9/16</td> - <td data-value="82.35" class="pct high">82.35%</td> - <td data-value="17" class="abs high">14/17</td> - <td data-value="84.61" class="pct high">84.61%</td> - <td data-value="39" class="abs high">33/39</td> - </tr> - </tbody> - </table> - </div> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z - </div> - <script src="../../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../../sorter.js"></script> - <script src="../../block-navigation.js"></script> - </body> +<tr> + <td class="file medium" data-value="Settings.tsx"><a href="Settings.tsx.html">Settings.tsx</a></td> + <td data-value="56.25" class="pic medium"> + <div class="chart"><div class="cover-fill" style="width: 56%"></div><div class="cover-empty" style="width: 44%"></div></div> + </td> + <td data-value="56.25" class="pct medium">56.25%</td> + <td data-value="64" class="abs medium">36/64</td> + <td data-value="41.66" class="pct low">41.66%</td> + <td data-value="24" class="abs low">10/24</td> + <td data-value="63.63" class="pct medium">63.63%</td> + <td data-value="22" class="abs medium">14/22</td> + <td data-value="62.5" class="pct medium">62.5%</td> + <td data-value="56" class="abs medium">35/56</td> + </tr> + +</tbody> +</table> +</div> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../../sorter.js"></script> + <script src="../../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/coverage/src/index.html b/frontend/coverage/src/index.html index 14e9f51..19a8dfd 100644 --- a/frontend/coverage/src/index.html +++ b/frontend/coverage/src/index.html @@ -1,139 +1,146 @@ + <!doctype html> <html lang="en"> - <head> + +<head> <title>Code coverage report for src</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../prettify.css" /> <link rel="stylesheet" href="../base.css" /> <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style type="text/css"> - .coverage-summary .sorter { - background-image: url(../sort-arrow-sprite.png); - } + <style type='text/css'> + .coverage-summary .sorter { + background-image: url(../sort-arrow-sprite.png); + } </style> - </head> - - <body> - <div class="wrapper"> - <div class="pad1"> +</head> + +<body> +<div class='wrapper'> + <div class='pad1'> <h1><a href="../index.html">All files</a> src</h1> - <div class="clearfix"> - <div class="fl pad1y space-right2"> - <span class="strong">78.94% </span> - <span class="quiet">Statements</span> - <span class="fraction">15/19</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">66.66% </span> - <span class="quiet">Branches</span> - <span class="fraction">4/6</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">77.77% </span> - <span class="quiet">Functions</span> - <span class="fraction">7/9</span> - </div> - - <div class="fl pad1y space-right2"> - <span class="strong">78.94% </span> - <span class="quiet">Lines</span> - <span class="fraction">15/19</span> - </div> + <div class='clearfix'> + + <div class='fl pad1y space-right2'> + <span class="strong">76.47% </span> + <span class="quiet">Statements</span> + <span class='fraction'>26/34</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">69.23% </span> + <span class="quiet">Branches</span> + <span class='fraction'>18/26</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">70% </span> + <span class="quiet">Functions</span> + <span class='fraction'>7/10</span> + </div> + + + <div class='fl pad1y space-right2'> + <span class="strong">78.78% </span> + <span class="quiet">Lines</span> + <span class='fraction'>26/33</span> + </div> + + </div> <p class="quiet"> - Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, - <em>p</em> or <em>k</em> for the previous block. + Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block. </p> <template id="filterTemplate"> - <div class="quiet"> - Filter: - <input type="search" id="fileSearch" /> - </div> + <div class="quiet"> + Filter: + <input type="search" id="fileSearch"> + </div> </template> - </div> - <div class="status-line medium"></div> - <div class="pad1"> - <table class="coverage-summary"> - <thead> - <tr> - <th data-col="file" data-fmt="html" data-html="true" class="file">File</th> - <th - data-col="pic" - data-type="number" - data-fmt="html" - data-html="true" - class="pic" - ></th> - <th data-col="statements" data-type="number" data-fmt="pct" class="pct"> - Statements - </th> - <th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th> - <th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th> - <th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th> - <th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th> - <th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th> - <th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th> - <th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th> - </tr> - </thead> - <tbody> - <tr> - <td class="file empty" data-value="App.css"><a href="App.css.html">App.css</a></td> - <td data-value="0" class="pic empty"> - <div class="chart"> - <div class="cover-fill" style="width: 0%"></div> - <div class="cover-empty" style="width: 100%"></div> - </div> - </td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - <td data-value="0" class="pct empty">0%</td> - <td data-value="0" class="abs empty">0/0</td> - </tr> - - <tr> - <td class="file medium" data-value="App.tsx"><a href="App.tsx.html">App.tsx</a></td> - <td data-value="78.94" class="pic medium"> - <div class="chart"> - <div class="cover-fill" style="width: 78%"></div> - <div class="cover-empty" style="width: 22%"></div> - </div> - </td> - <td data-value="78.94" class="pct medium">78.94%</td> - <td data-value="19" class="abs medium">15/19</td> - <td data-value="66.66" class="pct medium">66.66%</td> - <td data-value="6" class="abs medium">4/6</td> - <td data-value="77.77" class="pct medium">77.77%</td> - <td data-value="9" class="abs medium">7/9</td> - <td data-value="78.94" class="pct medium">78.94%</td> - <td data-value="19" class="abs medium">15/19</td> - </tr> - </tbody> - </table> - </div> - <div class="push"></div> - <!-- for sticky footer --> - </div> - <!-- /wrapper --> - <div class="footer quiet pad2 space-top1 center small"> - Code coverage generated by - <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> - at 2026-02-13T21:49:58.924Z </div> - <script src="../prettify.js"></script> - <script> - window.onload = function () { - prettyPrint(); - }; - </script> - <script src="../sorter.js"></script> - <script src="../block-navigation.js"></script> - </body> + <div class='status-line medium'></div> + <div class="pad1"> +<table class="coverage-summary"> +<thead> +<tr> + <th data-col="file" data-fmt="html" data-html="true" class="file">File</th> + <th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th> + <th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th> + <th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th> + <th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th> + <th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th> + <th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th> + <th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th> + <th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th> + <th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th> +</tr> +</thead> +<tbody><tr> + <td class="file empty" data-value="App.css"><a href="App.css.html">App.css</a></td> + <td data-value="0" class="pic empty"> + <div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div> + </td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + <td data-value="0" class="pct empty">0%</td> + <td data-value="0" class="abs empty">0/0</td> + </tr> + +<tr> + <td class="file medium" data-value="App.tsx"><a href="App.tsx.html">App.tsx</a></td> + <td data-value="72.72" class="pic medium"> + <div class="chart"><div class="cover-fill" style="width: 72%"></div><div class="cover-empty" style="width: 28%"></div></div> + </td> + <td data-value="72.72" class="pct medium">72.72%</td> + <td data-value="22" class="abs medium">16/22</td> + <td data-value="62.5" class="pct medium">62.5%</td> + <td data-value="16" class="abs medium">10/16</td> + <td data-value="62.5" class="pct medium">62.5%</td> + <td data-value="8" class="abs medium">5/8</td> + <td data-value="72.72" class="pct medium">72.72%</td> + <td data-value="22" class="abs medium">16/22</td> + </tr> + +<tr> + <td class="file high" data-value="utils.ts"><a href="utils.ts.html">utils.ts</a></td> + <td data-value="83.33" class="pic high"> + <div class="chart"><div class="cover-fill" style="width: 83%"></div><div class="cover-empty" style="width: 17%"></div></div> + </td> + <td data-value="83.33" class="pct high">83.33%</td> + <td data-value="12" class="abs high">10/12</td> + <td data-value="80" class="pct high">80%</td> + <td data-value="10" class="abs high">8/10</td> + <td data-value="100" class="pct high">100%</td> + <td data-value="2" class="abs high">2/2</td> + <td data-value="90.9" class="pct high">90.9%</td> + <td data-value="11" class="abs high">10/11</td> + </tr> + +</tbody> +</table> +</div> + <div class='push'></div><!-- for sticky footer --> + </div><!-- /wrapper --> + <div class='footer quiet pad2 space-top1 center small'> + Code coverage generated by + <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> + at 2026-02-14T18:02:09.004Z + </div> + <script src="../prettify.js"></script> + <script> + window.onload = function () { + prettyPrint(); + }; + </script> + <script src="../sorter.js"></script> + <script src="../block-navigation.js"></script> + </body> </html> +
\ No newline at end of file diff --git a/frontend/src/components/Settings.test.tsx b/frontend/src/components/Settings.test.tsx index f46ce6f..b7de3bb 100644 --- a/frontend/src/components/Settings.test.tsx +++ b/frontend/src/components/Settings.test.tsx @@ -98,4 +98,42 @@ describe('Settings Component', () => { expect(screen.queryByText('Tech News')).not.toBeInTheDocument(); }); }); + + it('imports an OPML file', async () => { + (global.fetch as any) + .mockResolvedValueOnce({ ok: true, json: async () => [] }) // Initial load + .mockResolvedValueOnce({ ok: true, json: async () => ({ status: 'ok' }) }) // Import + .mockResolvedValueOnce({ + ok: true, + json: async () => [{ _id: 1, title: 'Imported Feed', url: 'http://imported.com/rss' }], + }); // Refresh load + + render(<Settings />); + + const file = new File(['<opml>...</opml>'], 'feeds.opml', { type: 'text/xml' }); + const fileInput = screen.getByLabelText(/import feeds/i, { selector: 'input[type="file"]' }); + const importButton = screen.getByText('Import'); + + fireEvent.change(fileInput, { target: { files: [file] } }); + await waitFor(() => { + expect(importButton).not.toBeDisabled(); + }); + + fireEvent.click(importButton); + + await waitFor(() => { + expect(global.fetch).toHaveBeenCalledWith( + '/api/import', + expect.objectContaining({ + method: 'POST', + body: expect.any(FormData), + }) + ); + }); + + // Check if refresh happens + await waitFor(() => { + expect(screen.getByText('Imported Feed')).toBeInTheDocument(); + }); + }); }); diff --git a/frontend/src/components/Settings.tsx b/frontend/src/components/Settings.tsx index 6b6dab1..16cf6a3 100644 --- a/frontend/src/components/Settings.tsx +++ b/frontend/src/components/Settings.tsx @@ -131,6 +131,7 @@ export default function Settings() { <input type="file" accept=".opml,.xml,.txt" + aria-label="Import Feeds" onChange={(e) => setImportFile(e.target.files?.[0] || null)} className="file-input" disabled={loading} |
