Full Code of Surye/mfp-keto-userscript for AI

master 56cbab7e84ca cached
2 files
12.3 KB
3.5k tokens
4 symbols
1 requests
Download .txt
Repository: Surye/mfp-keto-userscript
Branch: master
Commit: 56cbab7e84ca
Files: 2
Total size: 12.3 KB

Directory structure:
gitextract_t26z3t9u/

├── README.md
└── mfpketo.user.js

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
Created primarily for the /r/keto community on Reddit.

<h2>Remember this script <b>REQUIRES</b> the following columns: Fat, Protein, Carbs, Fiber!</h2>

<h1>Install:</h1>
<ul>
<li><b>Chrome</b>: Install <a href="https://chrome.google.com/webstore/detail/dhdgffkkebhmkfjojejmpbldmpobfkfo">Tampermonkey</a>.</li>
<li><b>Safari</b>: Install <a href="https://tampermonkey.net/?ext=dhdg&browser=safari">Tampermonkey</a>.</li>
<li><b>Firefox</b>: Install <a href="https://addons.mozilla.org/en-US/firefox/addon/tampermonkey/">Tampermonkey</a></li>
<li><b>Internet Explorer</b>: Not sure anymore, old plugin is gone.</li>
<li><b>ALL: After installing the plugin, go to <a href="../../raw/master/mfpketo.user.js">mfpketo.user.js</a> to install.</b>
</ul>

<h1>Upgrade:</h1>
<ul>
<li>Just visit <a href="../../raw/master/mfpketo.user.js">mfpketo.user.js</a> and click Upgrade.</li>
</ul>

<h1>FAQ:</h1>
<ul>
<li>Q: Food item shows up in red and says bad data?! What gives?!</li>
<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>

<li>Q: I get NaN's in the Net Carb column!</li>
<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>

<li>Q: What about sugar alcohols?</li>
<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>
</ul>


================================================
FILE: mfpketo.user.js
================================================
// ==UserScript==
// @name            MyFitnessPal Percentages and Net Carbs
// @version         1.16
// @namespace       surye
// @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"
// @downloadURL     https://github.com/Surye/mfp-keto-userscript/raw/master/mfpketo.user.js
// @include         http*://www.myfitnesspal.com/food/diary*
// ==/UserScript==

/*
 *  ------------------------------------------------------------
 *  Much credit to Bompus, author of the original script!
 *  Thanks to kt123 and Wickity for the fixes.
 *  ------------------------------------------------------------
 */


function exec(fn) {
    var script = document.createElement('script');
    script.setAttribute("type", "application/javascript");
    script.textContent = '(' + fn + ')();';
    document.body.appendChild(script); // run the script
    document.body.removeChild(script); // clean up
}

function startRun() {
    // Load Google API for Charts
    var script = document.createElement("script");
    script.setAttribute("src", "//www.google.com/jsapi");
    script.addEventListener('load', function() {
        exec(jsapiLoaded);
    }, false);
    document.body.appendChild(script);

    // Load jQuery
    script = document.createElement("script");
    script.setAttribute("src", "//ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js");
    script.addEventListener('load', function() {
        exec("jQuery.noConflict()");
    }, false);
    document.body.appendChild(script);

    // Inject this script into page.
    script = document.createElement('script');
    script.setAttribute("type", "application/javascript");
    script.textContent = main;
    document.body.appendChild(script);
}

startRun();

function jsapiLoaded() {
    google.load("visualization", "1", { packages: ["corechart"], "callback": main });
}

function main() {
    var calories_i = 0;
    var net_carbs_i = 0;
    var carbs_i = 0;
    var fiber_i = 0;
    var protein_i = 0;
    var fat_i = 0;

    var daily_total_carbs = 0;
    var daily_total_protein = 0;
    var daily_total_fat = 0;

    var net_carb_total = 0;
    var net_carb_total_goal = 0;

    var header_tr_element = jQuery('.food_container tr.meal_header:first');

    var elem_i = 0;
    header_tr_element.find('td').each(function() {
        var myval = jQuery(this).text().toLowerCase().trim();
        if (myval.indexOf('calories') !== -1) { calories_i = elem_i; }
        if (myval.indexOf('carbs') !== -1) { carbs_i = elem_i; }
        if (myval.indexOf('fiber') !== -1) { fiber_i = elem_i; }
        if (myval.indexOf('fat') !== -1) { fat_i = elem_i; }
        if (myval.indexOf('protein') !== -1) { protein_i = elem_i; }

        elem_i += 1;
    });


    // Add new column for net carbs
    var net_carb_tr_elements = jQuery('tr');
    net_carb_tr_elements.each(function() {
        var tds = jQuery(this).find('td');
        jQuery('<td></td>').insertBefore(tds.eq(carbs_i));

    });

    // Recalculate offsets
    net_carbs_i = carbs_i;
    calories_i = calories_i >= net_carbs_i ? calories_i + 1 : calories_i;
    carbs_i = carbs_i >= net_carbs_i ? carbs_i + 1 : carbs_i;
    fiber_i = fiber_i >= net_carbs_i ? fiber_i + 1 : fiber_i;
    protein_i = protein_i >= net_carbs_i ? protein_i + 1 : protein_i;
    fat_i = fat_i >= net_carbs_i ? fat_i + 1 : fat_i;

    // Set header
    header_tr_element.find('td').eq(net_carbs_i).text("Net Carbs");
    header_tr_element.find('td').eq(net_carbs_i).addClass("alt");
    header_tr_element.find('td').eq(net_carbs_i).addClass("nutrient-column");



    // Change to say net carbs
    var footer_tr_element = jQuery('tfoot tr');
    footer_tr_element.find('td').eq(net_carbs_i).text("Net Carbs");
    footer_tr_element.find('td').eq(net_carbs_i).addClass("alt");
    header_tr_element.find('td').eq(net_carbs_i).addClass("nutrient-column");


    var alreadyCountedFiber = [0];
    var alreadyCountedFiberIdx = 0;
    var food_tr_elements = jQuery('tr');

    food_tr_elements.each(function() {
        if($(this).hasClass('bottom')) {
            alreadyCountedFiberIdx++;
            alreadyCountedFiber[alreadyCountedFiberIdx] = 0;
        }

        var tds = jQuery(this).find('td');
        var carbs = parseFloat(tds.eq(carbs_i).text());
        var fiber = parseFloat(tds.eq(fiber_i).text());

        // Find only food rows!
        var delete_td = tds.eq(tds.length - 1);
        if (delete_td.hasClass('delete')) {
			var name = jQuery(this).find('.js-show-edit-food').text().toLowerCase();

			tds.eq(net_carbs_i).text(carbs - fiber);

            if (name.indexOf("net carbs") !== -1 || (carbs - fiber) < 0) {
                alreadyCountedFiber[alreadyCountedFiberIdx] += Number(fiber);
                tds.eq(net_carbs_i).text(carbs);
            }
        }
    });

    var totalAlreadyCountedFiber = 0;
    for (var i=0; i < alreadyCountedFiber.length; i++){ totalAlreadyCountedFiber += alreadyCountedFiber[i];}


    var bottom_tr_elements = jQuery('.food_container tr.bottom, .food_container tr.total');
    var meal_idx = 0;
    bottom_tr_elements.each(function() {

        if (jQuery(this).hasClass('remaining')) {
            return false; /* continue */
        }

        var tds = jQuery(this).find('td');
        var cals = parseFloat(tds.eq(calories_i).text());
        var carbs = 0;
        if($(this).hasClass('bottom')) {
            carbs = parseFloat(tds.eq(carbs_i).text());
        } else {
            carbs = parseFloat(tds.eq(carbs_i).text()) + totalAlreadyCountedFiber;
        }
        var fiber = parseFloat(tds.eq(fiber_i).text());
        var protein = parseFloat(tds.eq(protein_i).text());
        var fat = parseFloat(tds.eq(fat_i).text());

        var net_carbs = carbs;

        // HACK to show net carbs
        if (!jQuery(this).hasClass('alt')) {
            net_carbs = carbs - fiber + alreadyCountedFiber[meal_idx];
            if (!isNaN(net_carbs)) {
                tds.eq(net_carbs_i).text(net_carbs);
            } else if (jQuery(this).hasClass("total")) {
                tds.eq(net_carbs_i).text("0");
            }
        } else {
            // record goal
            net_carb_total_goal = net_carbs;
        }


        /* do nothing if cannot calculate for the row */
        if (isNaN(cals) ||
            isNaN(carbs) ||
            isNaN(protein) ||
            isNaN(fat) ||
            isNaN(fiber) ||
            isNaN(net_carbs) ||
            cals === 0) {
            meal_idx++;
            return true;

        }

        tds.eq(net_carbs_i).text(net_carbs);


        // if (net_carbs == 0 &&
        //     protein == 0 &&
        //     fat == 0) {
        //     return true;
        // }

        var carb_cals = (net_carbs * 4);
        var protein_cals = (protein * 4);
        var fat_cals = (fat * 9);

        if (jQuery(this).hasClass('total') &&
            !jQuery(this).hasClass('alt') &&
            daily_total_carbs === 0) {

            daily_total_carbs = carb_cals;
            daily_total_protein = protein_cals;
            daily_total_fat = fat_cals;
            net_carb_total = net_carbs - totalAlreadyCountedFiber;

        }

        var real_cals = carb_cals + protein_cals + fat_cals;

        var carb_pct = ((carb_cals / real_cals) * 100).toFixed(2);
        var fat_pct = ((fat_cals / real_cals) * 100).toFixed(2);
        var protein_pct = ((protein_cals / real_cals) * 100).toFixed(2);

        //alert(daily_total_carbs + ", " + daily_total_protein + ", " + daily_total_fat + ", " + net_carb_total);

        carb_pct = Math.round(carb_pct);
        fat_pct = Math.round(fat_pct);
        protein_pct = Math.round(protein_pct);

        tds.each(function() {
            jQuery(this).append('<div class="myfp_us" style="color:#0a0;font-size:9px;text-align:center;">&nbsp;</div>');
        });

        tds.eq(0).find('div.myfp_us').html("");

        /*tds.eq(calories_i).find('div.myfp_us').html(real_cals);*/

        if (!isNaN(carb_pct)) {
            tds.eq(net_carbs_i).find('div.myfp_us').html(carb_pct + "%");
        }

        if (!isNaN(fat_pct)) {
            tds.eq(fat_i).find('div.myfp_us').html(fat_pct + "%");
        }

        if (!isNaN(protein_pct)) {
            tds.eq(protein_i).find('div.myfp_us').html(protein_pct + "%");
        }

        meal_idx++;
    });

    var remaining_tr_elements = jQuery('.food_container tr.total.remaining');

    remaining_tr_elements.each(function() {

        // Show remaining as net carbs
        var net_carbs = net_carb_total_goal - net_carb_total - totalAlreadyCountedFiber;
        var tds = jQuery(this).find('td');
        tds.eq(net_carbs_i).text(parseInt(net_carbs));

        // Fix color
        tds.eq(net_carbs_i).removeClass("positive");
        tds.eq(net_carbs_i).removeClass("negative");

        if (net_carbs < 0) {
            tds.eq(net_carbs_i).addClass("negative");
        } else {
            tds.eq(net_carbs_i).addClass("positive");
        }

    });




    if (daily_total_carbs !== 0 ||
        daily_total_protein !== 0 ||
        daily_total_fat !== 0) {

        jQuery('.food_container').append('<div id="google_graph_1"></div>');

        var data1 = new google.visualization.DataTable();
        data1.addColumn('string', 'Type');
        data1.addColumn('number', 'Cals');
        data1.addRows(
            [
                ['Net Carbs', daily_total_carbs],
                ['Protein', daily_total_protein],
                ['Fat', daily_total_fat]
            ]
        );

        var chart = new google.visualization.PieChart(document.getElementById('google_graph_1'));
        chart.draw(data1, {
            width: 350,
            height: 300,
            title: 'Daily Totals by Calories (This is what you use for your macro ratios)'
        });
        document.getElementById('google_graph_1').style.cssFloat = "left";

        jQuery('.food_container').append('<div id="google_graph_2"></div>');

        var carb_grams = daily_total_carbs / 4;
        var pro_grams = daily_total_protein / 4;
        var fat_grams = daily_total_fat / 9;

        var data2 = new google.visualization.DataTable();
        data2.addColumn('string', 'Type');
        data2.addColumn('number', 'Grams');
        data2.addRows(
            [
                ['Net Carbs (' + carb_grams + 'g)', carb_grams],
                ['Protein (' + pro_grams + 'g)', pro_grams],
                ['Fat (' + fat_grams + 'g)', fat_grams]
            ]
        );

        var chart2 = new google.visualization.PieChart(document.getElementById('google_graph_2'));
        chart2.draw(data2, {
            width: 350,
            height: 300,
            title: 'Daily Totals by Grams'
        });
        document.getElementById('google_graph_2').style.cssFloat = "right";
    }
}
Download .txt
gitextract_t26z3t9u/

├── README.md
└── mfpketo.user.js
Download .txt
SYMBOL INDEX (4 symbols across 1 files)

FILE: mfpketo.user.js
  function exec (line 18) | function exec(fn) {
  function startRun (line 26) | function startRun() {
  function jsapiLoaded (line 52) | function jsapiLoaded() {
  function main (line 56) | function main() {
Condensed preview — 2 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (13K chars).
[
  {
    "path": "README.md",
    "chars": 1703,
    "preview": "Created primarily for the /r/keto community on Reddit.\n\n<h2>Remember this script <b>REQUIRES</b> the following columns: "
  },
  {
    "path": "mfpketo.user.js",
    "chars": 10932,
    "preview": "// ==UserScript==\n// @name            MyFitnessPal Percentages and Net Carbs\n// @version         1.16\n// @namespace     "
  }
]

About this extraction

This page contains the full source code of the Surye/mfp-keto-userscript GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 2 files (12.3 KB), approximately 3.5k tokens, and a symbol index with 4 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!