[
  {
    "path": "README.md",
    "content": "Created primarily for the /r/keto community on Reddit.\n\n<h2>Remember this script <b>REQUIRES</b> the following columns: Fat, Protein, Carbs, Fiber!</h2>\n\n<h1>Install:</h1>\n<ul>\n<li><b>Chrome</b>: Install <a href=\"https://chrome.google.com/webstore/detail/dhdgffkkebhmkfjojejmpbldmpobfkfo\">Tampermonkey</a>.</li>\n<li><b>Safari</b>: Install <a href=\"https://tampermonkey.net/?ext=dhdg&browser=safari\">Tampermonkey</a>.</li>\n<li><b>Firefox</b>: Install <a href=\"https://addons.mozilla.org/en-US/firefox/addon/tampermonkey/\">Tampermonkey</a></li>\n<li><b>Internet Explorer</b>: Not sure anymore, old plugin is gone.</li>\n<li><b>ALL: After installing the plugin, go to <a href=\"../../raw/master/mfpketo.user.js\">mfpketo.user.js</a> to install.</b>\n</ul>\n\n<h1>Upgrade:</h1>\n<ul>\n<li>Just visit <a href=\"../../raw/master/mfpketo.user.js\">mfpketo.user.js</a> and click Upgrade.</li>\n</ul>\n\n<h1>FAQ:</h1>\n<ul>\n<li>Q: Food item shows up in red and says bad data?! What gives?!</li>\n<li>A: Someone added the food item incorrectly, and put net carbs in the carbs value, and so the fiber subtracts from it, making negative carbs. Nothing I can really do about this without modifying more data than I wish to.</li>\n\n<li>Q: I get NaN's in the Net Carb column!</li>\n<li>A: It may be you didn't have all the required columns added, go to http://www.myfitnesspal.com/account/diary_settings and make sure all the columns required are there (most likely, you need to add the fiber column).</li>\n\n<li>Q: What about sugar alcohols?</li>\n<li>A: Since MFP does not recognize these as a seperate nutrition, it will simply be up to the data entry (don't include it in carbs) or the user will have to know to ignore it.</li>\n</ul>\n"
  },
  {
    "path": "mfpketo.user.js",
    "content": "// ==UserScript==\n// @name            MyFitnessPal Percentages and Net Carbs\n// @version         1.16\n// @namespace       surye\n// @description     Adds display of Carb/Protein/Fat percentages to any daily food diary page. Also adds \"Real Calories\" calcalation based off 4/4/9 algorithm. Based on \"MyFitnessPal Percentages and Net Carbs\"\n// @downloadURL     https://github.com/Surye/mfp-keto-userscript/raw/master/mfpketo.user.js\n// @include         http*://www.myfitnesspal.com/food/diary*\n// ==/UserScript==\n\n/*\n *  ------------------------------------------------------------\n *  Much credit to Bompus, author of the original script!\n *  Thanks to kt123 and Wickity for the fixes.\n *  ------------------------------------------------------------\n */\n\n\nfunction exec(fn) {\n    var script = document.createElement('script');\n    script.setAttribute(\"type\", \"application/javascript\");\n    script.textContent = '(' + fn + ')();';\n    document.body.appendChild(script); // run the script\n    document.body.removeChild(script); // clean up\n}\n\nfunction startRun() {\n    // Load Google API for Charts\n    var script = document.createElement(\"script\");\n    script.setAttribute(\"src\", \"//www.google.com/jsapi\");\n    script.addEventListener('load', function() {\n        exec(jsapiLoaded);\n    }, false);\n    document.body.appendChild(script);\n\n    // Load jQuery\n    script = document.createElement(\"script\");\n    script.setAttribute(\"src\", \"//ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js\");\n    script.addEventListener('load', function() {\n        exec(\"jQuery.noConflict()\");\n    }, false);\n    document.body.appendChild(script);\n\n    // Inject this script into page.\n    script = document.createElement('script');\n    script.setAttribute(\"type\", \"application/javascript\");\n    script.textContent = main;\n    document.body.appendChild(script);\n}\n\nstartRun();\n\nfunction jsapiLoaded() {\n    google.load(\"visualization\", \"1\", { packages: [\"corechart\"], \"callback\": main });\n}\n\nfunction main() {\n    var calories_i = 0;\n    var net_carbs_i = 0;\n    var carbs_i = 0;\n    var fiber_i = 0;\n    var protein_i = 0;\n    var fat_i = 0;\n\n    var daily_total_carbs = 0;\n    var daily_total_protein = 0;\n    var daily_total_fat = 0;\n\n    var net_carb_total = 0;\n    var net_carb_total_goal = 0;\n\n    var header_tr_element = jQuery('.food_container tr.meal_header:first');\n\n    var elem_i = 0;\n    header_tr_element.find('td').each(function() {\n        var myval = jQuery(this).text().toLowerCase().trim();\n        if (myval.indexOf('calories') !== -1) { calories_i = elem_i; }\n        if (myval.indexOf('carbs') !== -1) { carbs_i = elem_i; }\n        if (myval.indexOf('fiber') !== -1) { fiber_i = elem_i; }\n        if (myval.indexOf('fat') !== -1) { fat_i = elem_i; }\n        if (myval.indexOf('protein') !== -1) { protein_i = elem_i; }\n\n        elem_i += 1;\n    });\n\n\n    // Add new column for net carbs\n    var net_carb_tr_elements = jQuery('tr');\n    net_carb_tr_elements.each(function() {\n        var tds = jQuery(this).find('td');\n        jQuery('<td></td>').insertBefore(tds.eq(carbs_i));\n\n    });\n\n    // Recalculate offsets\n    net_carbs_i = carbs_i;\n    calories_i = calories_i >= net_carbs_i ? calories_i + 1 : calories_i;\n    carbs_i = carbs_i >= net_carbs_i ? carbs_i + 1 : carbs_i;\n    fiber_i = fiber_i >= net_carbs_i ? fiber_i + 1 : fiber_i;\n    protein_i = protein_i >= net_carbs_i ? protein_i + 1 : protein_i;\n    fat_i = fat_i >= net_carbs_i ? fat_i + 1 : fat_i;\n\n    // Set header\n    header_tr_element.find('td').eq(net_carbs_i).text(\"Net Carbs\");\n    header_tr_element.find('td').eq(net_carbs_i).addClass(\"alt\");\n    header_tr_element.find('td').eq(net_carbs_i).addClass(\"nutrient-column\");\n\n\n\n    // Change to say net carbs\n    var footer_tr_element = jQuery('tfoot tr');\n    footer_tr_element.find('td').eq(net_carbs_i).text(\"Net Carbs\");\n    footer_tr_element.find('td').eq(net_carbs_i).addClass(\"alt\");\n    header_tr_element.find('td').eq(net_carbs_i).addClass(\"nutrient-column\");\n\n\n    var alreadyCountedFiber = [0];\n    var alreadyCountedFiberIdx = 0;\n    var food_tr_elements = jQuery('tr');\n\n    food_tr_elements.each(function() {\n        if($(this).hasClass('bottom')) {\n            alreadyCountedFiberIdx++;\n            alreadyCountedFiber[alreadyCountedFiberIdx] = 0;\n        }\n\n        var tds = jQuery(this).find('td');\n        var carbs = parseFloat(tds.eq(carbs_i).text());\n        var fiber = parseFloat(tds.eq(fiber_i).text());\n\n        // Find only food rows!\n        var delete_td = tds.eq(tds.length - 1);\n        if (delete_td.hasClass('delete')) {\n\t\t\tvar name = jQuery(this).find('.js-show-edit-food').text().toLowerCase();\n\n\t\t\ttds.eq(net_carbs_i).text(carbs - fiber);\n\n            if (name.indexOf(\"net carbs\") !== -1 || (carbs - fiber) < 0) {\n                alreadyCountedFiber[alreadyCountedFiberIdx] += Number(fiber);\n                tds.eq(net_carbs_i).text(carbs);\n            }\n        }\n    });\n\n    var totalAlreadyCountedFiber = 0;\n    for (var i=0; i < alreadyCountedFiber.length; i++){ totalAlreadyCountedFiber += alreadyCountedFiber[i];}\n\n\n    var bottom_tr_elements = jQuery('.food_container tr.bottom, .food_container tr.total');\n    var meal_idx = 0;\n    bottom_tr_elements.each(function() {\n\n        if (jQuery(this).hasClass('remaining')) {\n            return false; /* continue */\n        }\n\n        var tds = jQuery(this).find('td');\n        var cals = parseFloat(tds.eq(calories_i).text());\n        var carbs = 0;\n        if($(this).hasClass('bottom')) {\n            carbs = parseFloat(tds.eq(carbs_i).text());\n        } else {\n            carbs = parseFloat(tds.eq(carbs_i).text()) + totalAlreadyCountedFiber;\n        }\n        var fiber = parseFloat(tds.eq(fiber_i).text());\n        var protein = parseFloat(tds.eq(protein_i).text());\n        var fat = parseFloat(tds.eq(fat_i).text());\n\n        var net_carbs = carbs;\n\n        // HACK to show net carbs\n        if (!jQuery(this).hasClass('alt')) {\n            net_carbs = carbs - fiber + alreadyCountedFiber[meal_idx];\n            if (!isNaN(net_carbs)) {\n                tds.eq(net_carbs_i).text(net_carbs);\n            } else if (jQuery(this).hasClass(\"total\")) {\n                tds.eq(net_carbs_i).text(\"0\");\n            }\n        } else {\n            // record goal\n            net_carb_total_goal = net_carbs;\n        }\n\n\n        /* do nothing if cannot calculate for the row */\n        if (isNaN(cals) ||\n            isNaN(carbs) ||\n            isNaN(protein) ||\n            isNaN(fat) ||\n            isNaN(fiber) ||\n            isNaN(net_carbs) ||\n            cals === 0) {\n            meal_idx++;\n            return true;\n\n        }\n\n        tds.eq(net_carbs_i).text(net_carbs);\n\n\n        // if (net_carbs == 0 &&\n        //     protein == 0 &&\n        //     fat == 0) {\n        //     return true;\n        // }\n\n        var carb_cals = (net_carbs * 4);\n        var protein_cals = (protein * 4);\n        var fat_cals = (fat * 9);\n\n        if (jQuery(this).hasClass('total') &&\n            !jQuery(this).hasClass('alt') &&\n            daily_total_carbs === 0) {\n\n            daily_total_carbs = carb_cals;\n            daily_total_protein = protein_cals;\n            daily_total_fat = fat_cals;\n            net_carb_total = net_carbs - totalAlreadyCountedFiber;\n\n        }\n\n        var real_cals = carb_cals + protein_cals + fat_cals;\n\n        var carb_pct = ((carb_cals / real_cals) * 100).toFixed(2);\n        var fat_pct = ((fat_cals / real_cals) * 100).toFixed(2);\n        var protein_pct = ((protein_cals / real_cals) * 100).toFixed(2);\n\n        //alert(daily_total_carbs + \", \" + daily_total_protein + \", \" + daily_total_fat + \", \" + net_carb_total);\n\n        carb_pct = Math.round(carb_pct);\n        fat_pct = Math.round(fat_pct);\n        protein_pct = Math.round(protein_pct);\n\n        tds.each(function() {\n            jQuery(this).append('<div class=\"myfp_us\" style=\"color:#0a0;font-size:9px;text-align:center;\">&nbsp;</div>');\n        });\n\n        tds.eq(0).find('div.myfp_us').html(\"\");\n\n        /*tds.eq(calories_i).find('div.myfp_us').html(real_cals);*/\n\n        if (!isNaN(carb_pct)) {\n            tds.eq(net_carbs_i).find('div.myfp_us').html(carb_pct + \"%\");\n        }\n\n        if (!isNaN(fat_pct)) {\n            tds.eq(fat_i).find('div.myfp_us').html(fat_pct + \"%\");\n        }\n\n        if (!isNaN(protein_pct)) {\n            tds.eq(protein_i).find('div.myfp_us').html(protein_pct + \"%\");\n        }\n\n        meal_idx++;\n    });\n\n    var remaining_tr_elements = jQuery('.food_container tr.total.remaining');\n\n    remaining_tr_elements.each(function() {\n\n        // Show remaining as net carbs\n        var net_carbs = net_carb_total_goal - net_carb_total - totalAlreadyCountedFiber;\n        var tds = jQuery(this).find('td');\n        tds.eq(net_carbs_i).text(parseInt(net_carbs));\n\n        // Fix color\n        tds.eq(net_carbs_i).removeClass(\"positive\");\n        tds.eq(net_carbs_i).removeClass(\"negative\");\n\n        if (net_carbs < 0) {\n            tds.eq(net_carbs_i).addClass(\"negative\");\n        } else {\n            tds.eq(net_carbs_i).addClass(\"positive\");\n        }\n\n    });\n\n\n\n\n    if (daily_total_carbs !== 0 ||\n        daily_total_protein !== 0 ||\n        daily_total_fat !== 0) {\n\n        jQuery('.food_container').append('<div id=\"google_graph_1\"></div>');\n\n        var data1 = new google.visualization.DataTable();\n        data1.addColumn('string', 'Type');\n        data1.addColumn('number', 'Cals');\n        data1.addRows(\n            [\n                ['Net Carbs', daily_total_carbs],\n                ['Protein', daily_total_protein],\n                ['Fat', daily_total_fat]\n            ]\n        );\n\n        var chart = new google.visualization.PieChart(document.getElementById('google_graph_1'));\n        chart.draw(data1, {\n            width: 350,\n            height: 300,\n            title: 'Daily Totals by Calories (This is what you use for your macro ratios)'\n        });\n        document.getElementById('google_graph_1').style.cssFloat = \"left\";\n\n        jQuery('.food_container').append('<div id=\"google_graph_2\"></div>');\n\n        var carb_grams = daily_total_carbs / 4;\n        var pro_grams = daily_total_protein / 4;\n        var fat_grams = daily_total_fat / 9;\n\n        var data2 = new google.visualization.DataTable();\n        data2.addColumn('string', 'Type');\n        data2.addColumn('number', 'Grams');\n        data2.addRows(\n            [\n                ['Net Carbs (' + carb_grams + 'g)', carb_grams],\n                ['Protein (' + pro_grams + 'g)', pro_grams],\n                ['Fat (' + fat_grams + 'g)', fat_grams]\n            ]\n        );\n\n        var chart2 = new google.visualization.PieChart(document.getElementById('google_graph_2'));\n        chart2.draw(data2, {\n            width: 350,\n            height: 300,\n            title: 'Daily Totals by Grams'\n        });\n        document.getElementById('google_graph_2').style.cssFloat = \"right\";\n    }\n}\n"
  }
]