<commit_before>CloudPebble.Compile = (function() {
    var COMPILE_SUCCESS_STATES = {
        1: {english: "Pending", cls: "info", label: 'info'},
        2: {english: "Failed", cls: "error", label: 'important'},
        3: {english: "Succeeded", cls: "success", label: 'success'}
    };

    var mPendingCallbacks = [];
    var mRunningBuild = false;

    var build_history_row = function(build) {
        var tr = $('<tr>');
        tr.append($('<td>' + (build.id === null ? '?' : build.id) + '</td>'));
        tr.append($('<td>' + CloudPebble.Utils.FormatDatetime(build.started) + '</td>'));
        tr.append($('<td>' + COMPILE_SUCCESS_STATES[build.state].english + '</td>'));
        tr.append($('<td>' + (build.size.total !== null ? Math.round(build.size.total / 1024) + ' KiB' : '') + '</td>'));
        tr.append($('<td>' + (build.state == 3 ? ('<a href="'+build.pbw+'">pbw</a>') : ' ') + '</td>'));
        // Build log thingy.
        var td = $('<td>');
        if(build.state > 1) {
            var a = $('<a href="'+build.log+'">build log</a>').click(function(e) {
                if(e.ctrlKey || e.metaKey) {
                    ga('send', 'event', 'build log', 'show', 'external');
                    return true;
                }
                e.preventDefault();
                show_build_log(build.id);
                ga('send', 'event', 'build log', 'show', 'in-app');
            });
            td.append(a);
        }
        tr.append(td);
        tr.addClass(COMPILE_SUCCESS_STATES[build.state].cls);
        return tr;
    };

    var show_build_log = function(build) {
        $.getJSON('/ide/project/' + PROJECT_ID + '/build/' + build + '/log', function(data) {
            if(!data.success) {
                alert("Something went wrong:\n\n" + data.error);
                return;
            }
            CloudPebble.Sidebar.SuspendActive();
            // Sanitise the HTML.
            var log = data.log.replace('&', '&amp;').replace('<', '&lt;');
            // Now do clever things.
            log = log.replace("\nBuild failed\n", '\n<span class="log-error">Build failed</span>\n');
            log = log.replace(/(.+\berror:.+)/g, '<span class="log-error">$1</span>');
            log = log.replace(/(.+\bnote:.+)/g, '<span class="log-note">$1</span>');
            log = log.replace(/(.+\bwarn(?:ing)?:.+)/g, '<span class="log-warning">$1</span>');
            log = log.replace(/(.+In function .+)/g, '<span class="log-note">$1</span>');
            log = log.replace(/(.+' finished successfully \(.+)/g, '<span class="log-success">$1</span>');
            log = log.replace(/(cc1: .+)/g, '<span class="log-note">$1</span>');
            log = log.replace(/(cc1: all warnings .+)/g, '<span class="log-warning">$1</span>');
            // JavaScript linting failures are errors:
            log = log.replace(/^(src\/js\/.*)$/gm, '<span class="log-error">$1</span>');
            log = log.replace(/^(JavaScript linting failed.*)$/gm, '<span class="log-note">$1</span>');
            log = '<pre class="build-log" style="height: 100%;">' + log + '</pre>';
            var browserHeight = document.documentElement.clientHeight;
            log = $(log).css({'height': (browserHeight - 130) + 'px', 'overflow': 'auto'});
            CloudPebble.Sidebar.SetActivePane(log);
            // Scroll to the first error, if any.
            setTimeout(function() { if(log.find('.log-error').length) {
                log.scrollTop($(log.find('.log-error')[0]).offset().top - log.offset().top + log.scrollTop());
            }}, 1);
        });
    };

    var update_build_history = function(pane) {
        $.getJSON('/ide/project/' + PROJECT_ID + '/build/history', function(data) {
            CloudPebble.ProgressBar.Hide();
            pane.removeClass('hide');
            if(!data.success) {
                alert("Something went wrong:\n" + data.error); // This should be prettier.
                CloudPebble.Sidebar.DestroyActive();
                return;
            }
            if(data.builds.length > 0) {
                update_last_build(pane, data.builds[0]);
            } else {
                update_last_build(pane, null);
            }
            pane.find('#run-build-table').html('');
            $.each(data.builds, function(index, value) {
                pane.find('#run-build-table').append(build_history_row(value));
            });
            if(data.builds.length > 0 && data.builds[0].state == 1) {
                setTimeout(function() { update_build_history(pane); }, 1000);
            } else if(mRunningBuild) {
                mRunningBuild = false;
                _.each(mPendingCallbacks, function(callback) {
                    callback(data.builds[0].state == 3);
                });
                mPendingCallbacks = [];
            }
        });
    };

    var pane = null;
    var init = function() {
        pane = $('#compilation-pane-template').clone();
        pane.find('#install-on-phone-btn').click(function(e) {
            e.preventDefault();
            install_on_watch();
        });
        pane.find('#show-app-logs-btn').click(function(e) {
            e.preventDefault();
            show_app_logs();
        });
        pane.find('#screenshot-btn').click(function(e) {
            e.preventDefault();
            take_screenshot();
        });
        pane.find('#show-legacy-link').click(function(e) {
            e.preventDefault();
            show_legacy_ip_input();
        });
        pane.find('#show-phone-list-link').click(function(e) {
            e.preventDefault();
            show_phone_picker();
        });
        if(navigator.userAgent.indexOf('Firefox') != -1) {
            pane.find('#firefox-warning').removeClass('hide');
        }
        update_phone_list();
        mCrashAnalyser = new CloudPebble.CrashChecker(CloudPebble.ProjectInfo.app_uuid);
        pane.find('#compilation-run-build-button').click(run_build);


        if(localStorage['cp-last-phone-ip']) {
            pane.find('#phone-ip').val(localStorage['cp-last-phone-ip']);
        }

        pane.find('#phone').change(function() {
            var selected = $(this).val();
            console.log(selected);
            if(_.has(mKnownPhones, selected)) {
                mSelectedPhoneID = selected;
                localStorage['cp-last-picked-phone'] = mSelectedPhoneID;
            }
        });
    };

    var show_phone_picker = function() {
        pane.find('.phone-listing').show();
        pane.find('.legacy-ip').hide();
        mUsingLegacyIP = false;
    };

    var show_legacy_ip_input = function() {
        pane.find('.legacy-ip').show();
        pane.find('.phone-listing').hide();
        mUsingLegacyIP = true;
    }

    var m_build_count = 0;
    var show_compile_pane = function() {
        CloudPebble.Sidebar.SuspendActive();
        if(CloudPebble.Sidebar.Restore("compile")) {
            return;
        }

        update_build_history(pane);
        CloudPebble.Sidebar.SetActivePane(pane, 'compile');
        CloudPebble.ProgressBar.Show();
    };

    var update_phone_list = function() {
        $.getJSON("/ide/list_phones", function(data) {
            if(data.success) {
                pane.find('#phone').empty();
                var usable_devices = [];
                _.each(data.devices, function(device) {
                    if(!device_is_usable(device)) return;
                    usable_devices.push(device);
                    mKnownPhones[device.id] = device;
                    pane.find('#phone')
                        .append($('<option>')
                            .attr('value', device.id)
                            .text(device_name(device)));
                });
                if(usable_devices.length > 0) {
                    var last_phone = localStorage['cp-last-picked-phone'];
                    if(last_phone && _.has(mKnownPhones, last_phone)) {
                        mSelectedPhoneID = last_phone;
                        pane.find('#phone').val(last_phone);
                    } else if(usable_devices.length == 1) {
                        mSelectedPhoneID = usable_devices[0].id;
                        pane.find('#phone').val(mSelectedPhoneID);
                    }
                } else {
                    show_legacy_ip_input();
                }
            }
        })
    };

    var device_is_usable = function(device) {
        if(device.type == 'ios') {
            if(device.app_version) { // if version is not null, it's good enough for us.
                return true;
            } else {
                return false;<commit_msg>Don't show phones that we know to have push disabled.<commit_after>CloudPebble.Compile = (function() {
    var COMPILE_SUCCESS_STATES = {
        1: {english: "Pending", cls: "info", label: 'info'},
        2: {english: "Failed", cls: "error", label: 'important'},
        3: {english: "Succeeded", cls: "success", label: 'success'}
    };

    var mPendingCallbacks = [];
    var mRunningBuild = false;

    var build_history_row = function(build) {
        var tr = $('<tr>');
        tr.append($('<td>' + (build.id === null ? '?' : build.id) + '</td>'));
        tr.append($('<td>' + CloudPebble.Utils.FormatDatetime(build.started) + '</td>'));
        tr.append($('<td>' + COMPILE_SUCCESS_STATES[build.state].english + '</td>'));
        tr.append($('<td>' + (build.size.total !== null ? Math.round(build.size.total / 1024) + ' KiB' : '') + '</td>'));
        tr.append($('<td>' + (build.state == 3 ? ('<a href="'+build.pbw+'">pbw</a>') : ' ') + '</td>'));
        // Build log thingy.
        var td = $('<td>');
        if(build.state > 1) {
            var a = $('<a href="'+build.log+'">build log</a>').click(function(e) {
                if(e.ctrlKey || e.metaKey) {
                    ga('send', 'event', 'build log', 'show', 'external');
                    return true;
                }
                e.preventDefault();
                show_build_log(build.id);
                ga('send', 'event', 'build log', 'show', 'in-app');
            });
            td.append(a);
        }
        tr.append(td);
        tr.addClass(COMPILE_SUCCESS_STATES[build.state].cls);
        return tr;
    };

    var show_build_log = function(build) {
        $.getJSON('/ide/project/' + PROJECT_ID + '/build/' + build + '/log', function(data) {
            if(!data.success) {
                alert("Something went wrong:\n\n" + data.error);
                return;
            }
            CloudPebble.Sidebar.SuspendActive();
            // Sanitise the HTML.
            var log = data.log.replace('&', '&amp;').replace('<', '&lt;');
            // Now do clever things.
            log = log.replace("\nBuild failed\n", '\n<span class="log-error">Build failed</span>\n');
            log = log.replace(/(.+\berror:.+)/g, '<span class="log-error">$1</span>');
            log = log.replace(/(.+\bnote:.+)/g, '<span class="log-note">$1</span>');
            log = log.replace(/(.+\bwarn(?:ing)?:.+)/g, '<span class="log-warning">$1</span>');
            log = log.replace(/(.+In function .+)/g, '<span class="log-note">$1</span>');
            log = log.replace(/(.+' finished successfully \(.+)/g, '<span class="log-success">$1</span>');
            log = log.replace(/(cc1: .+)/g, '<span class="log-note">$1</span>');
            log = log.replace(/(cc1: all warnings .+)/g, '<span class="log-warning">$1</span>');
            // JavaScript linting failures are errors:
            log = log.replace(/^(src\/js\/.*)$/gm, '<span class="log-error">$1</span>');
            log = log.replace(/^(JavaScript linting failed.*)$/gm, '<span class="log-note">$1</span>');
            log = '<pre class="build-log" style="height: 100%;">' + log + '</pre>';
            var browserHeight = document.documentElement.clientHeight;
            log = $(log).css({'height': (browserHeight - 130) + 'px', 'overflow': 'auto'});
            CloudPebble.Sidebar.SetActivePane(log);
            // Scroll to the first error, if any.
            setTimeout(function() { if(log.find('.log-error').length) {
                log.scrollTop($(log.find('.log-error')[0]).offset().top - log.offset().top + log.scrollTop());
            }}, 1);
        });
    };

    var update_build_history = function(pane) {
        $.getJSON('/ide/project/' + PROJECT_ID + '/build/history', function(data) {
            CloudPebble.ProgressBar.Hide();
            pane.removeClass('hide');
            if(!data.success) {
                alert("Something went wrong:\n" + data.error); // This should be prettier.
                CloudPebble.Sidebar.DestroyActive();
                return;
            }
            if(data.builds.length > 0) {
                update_last_build(pane, data.builds[0]);
            } else {
                update_last_build(pane, null);
            }
            pane.find('#run-build-table').html('');
            $.each(data.builds, function(index, value) {
                pane.find('#run-build-table').append(build_history_row(value));
            });
            if(data.builds.length > 0 && data.builds[0].state == 1) {
                setTimeout(function() { update_build_history(pane); }, 1000);
            } else if(mRunningBuild) {
                mRunningBuild = false;
                _.each(mPendingCallbacks, function(callback) {
                    callback(data.builds[0].state == 3);
                });
                mPendingCallbacks = [];
            }
        });
    };

    var pane = null;
    var init = function() {
        pane = $('#compilation-pane-template').clone();
        pane.find('#install-on-phone-btn').click(function(e) {
            e.preventDefault();
            install_on_watch();
        });
        pane.find('#show-app-logs-btn').click(function(e) {
            e.preventDefault();
            show_app_logs();
        });
        pane.find('#screenshot-btn').click(function(e) {
            e.preventDefault();
            take_screenshot();
        });
        pane.find('#show-legacy-link').click(function(e) {
            e.preventDefault();
            show_legacy_ip_input();
        });
        pane.find('#show-phone-list-link').click(function(e) {
            e.preventDefault();
            show_phone_picker();
        });
        if(navigator.userAgent.indexOf('Firefox') != -1) {
            pane.find('#firefox-warning').removeClass('hide');
        }
        update_phone_list();
        mCrashAnalyser = new CloudPebble.CrashChecker(CloudPebble.ProjectInfo.app_uuid);
        pane.find('#compilation-run-build-button').click(run_build);


        if(localStorage['cp-last-phone-ip']) {
            pane.find('#phone-ip').val(localStorage['cp-last-phone-ip']);
        }

        pane.find('#phone').change(function() {
            var selected = $(this).val();
            console.log(selected);
            if(_.has(mKnownPhones, selected)) {
                mSelectedPhoneID = selected;
                localStorage['cp-last-picked-phone'] = mSelectedPhoneID;
            }
        });
    };

    var show_phone_picker = function() {
        pane.find('.phone-listing').show();
        pane.find('.legacy-ip').hide();
        mUsingLegacyIP = false;
    };

    var show_legacy_ip_input = function() {
        pane.find('.legacy-ip').show();
        pane.find('.phone-listing').hide();
        mUsingLegacyIP = true;
    }

    var m_build_count = 0;
    var show_compile_pane = function() {
        CloudPebble.Sidebar.SuspendActive();
        if(CloudPebble.Sidebar.Restore("compile")) {
            return;
        }

        update_build_history(pane);
        CloudPebble.Sidebar.SetActivePane(pane, 'compile');
        CloudPebble.ProgressBar.Show();
    };

    var update_phone_list = function() {
        $.getJSON("/ide/list_phones", function(data) {
            if(data.success) {
                pane.find('#phone').empty();
                var usable_devices = [];
                _.each(data.devices, function(device) {
                    if(!device_is_usable(device)) return;
                    usable_devices.push(device);
                    mKnownPhones[device.id] = device;
                    pane.find('#phone')
                        .append($('<option>')
                            .attr('value', device.id)
                            .text(device_name(device)));
                });
                if(usable_devices.length > 0) {
                    var last_phone = localStorage['cp-last-picked-phone'];
                    if(last_phone && _.has(mKnownPhones, last_phone)) {
                        mSelectedPhoneID = last_phone;
                        pane.find('#phone').val(last_phone);
                    } else if(usable_devices.length == 1) {
                        mSelectedPhoneID = usable_devices[0].id;
                        pane.find('#phone').val(mSelectedPhoneID);
                    }
                } else {
                    show_legacy_ip_input();
                }
            }
        })
    };

    var device_is_usable = function(device) {
        if(!device.push_enabled) {
            return false;
        }
        if(device.type == 'ios') {
            if(device.app_version) { // if version is not null, it's good enough for us.
                return true;
            } else {
                return false;
{'fraction_non_alphanumeric': 0.17737759622576377, 'fraction_numerical': 0.005062999827397733, 'mean_word_length': 1.7985831589116084, 'pattern_counts': {'":': 0, '<': 83, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5602059', 'n_tokens_mistral': 5293, 'n_tokens_neox': 5110, 'n_words': 797}