<commit_before>// third party imports
import MediaQuery from 'mediaquery'
import transform from 'lodash/transform'
import reduce from 'lodash/reduce'
// local imports
import CALCULATE_RESPONSIVE_STATE from '../actions/types/CALCULATE_RESPONSIVE_STATE'

// default breakpoints
export const defaultBreakpoints = {
    extraSmall: 480,
    small: 768,
    medium: 992,
    large: 1200,
}
// media type to default to when no `window` present
const defaultMediaType = 'infinity'
// orientation to default to when no `window` present
const defaultOrientation = null

/**
 * Compute a mapping of media type to its ordering where ordering is defined
 * such that large > medium > small.
 * @args (object) breakpoints - the breakpoint object
 */
export function getOrderMap(bps) {
    // grab the keys in the appropriate order
    const keys = Object.keys(bps).sort((a, b) => {
        // get the associated values
        const valueA = bps[a]
        const valueB = bps[b]

        // if a is a number and b is a string
        if (typeof valueA === 'number' && typeof valueB === 'string') {
            // put the number first
            return -1
        } else if (typeof valueB === 'number' && typeof valueA === 'string') {
            // return the number first
            return 1
        }

        // otherwise treat it like normal
        return valueA >= valueB ? 1 : -1
    })

    // map the original breakpoint object
    return transform(bps, (result, breakpoint, mediaType) => {
        // figure out the index of the mediatype
        const index = keys.indexOf(mediaType)
        // if there is an entry in the sort for this
        if (index !== -1) {
            // to its index in the sorted list
            result[mediaType] = index
        }
    })
}

/**
 * Compute the `lessThan` object based on the browser width.
 * @arg {number} browserWidth - Width of the browser.
 * @arg {object} breakpoints - The breakpoints object.
 * @arg {currentMediaType} breakpoints - The curent media type.
 * @returns {object} The `lessThan` object.  Its keys are the same as the
 * keys of the breakpoints object.  The value for each key indicates whether
 * or not the browser width is less than the breakpoint.
 */
export function getLessThan(currentMediaType, breakpointOrder) {
    // get the ordering of the current media type
    const currentOrder = breakpointOrder[currentMediaType]

    return transform(breakpointOrder, (result, breakpoint, mediaType) => {
        // if the breakpoint is a number
        if (typeof breakpoint === 'number' && breakpointOrder[mediaType]) {
            // store wether or not it is less than the breakpoint
            result[mediaType] = currentOrder < breakpointOrder[mediaType]
        // handle non numerical breakpoints specially
        } else {
            result[mediaType] = false
        }
    })
}

/**
 * Compute the `lessThan` object based on the browser width.
 * @arg {object} breakpoints - The breakpoints object.
 * @arg {currentMediaType} breakpoints - The curent media type.
 * @returns {object} The `lessThan` object.  Its keys are the same as the
 * keys of the breakpoints object.  The value for each key indicates whether
 * or not the browser width is less than the breakpoint.
 */
export function getIs(currentMediaType, breakpoints) {
    return transform(breakpoints, (result, breakpoint, mediaType) => {
        // if the breakpoint is a number
        if (typeof breakpoint === 'number' && breakpoints[mediaType]) {
            // store wether or not it is less than the breakpoint
            result[mediaType] = mediaType === currentMediaType
        // handle non numerical breakpoints specially
        } else {
            result[mediaType] = false
        }
    })
}

/**
 * Compute the `greaterThan` object based on the browser width.
 * @arg {number} browserWidth - Width of the browser.
 * @arg {object} breakpoints - The breakpoints object.
 * @returns {object} The `greaterThan` object.  Its keys are the same as the
 * keys of the breakpoints object.  The value for each key indicates whether
 * or not the browser width is greater than the breakpoint.
 */
export function getGreaterThan(currentMediaType, breakpointOrder) {
    // get the ordering of the current media type
    const currentOrder = breakpointOrder[currentMediaType]

    return transform(breakpointOrder, (result, breakpoint, mediaType) => {
        // if the breakpoint is a number
        if (typeof breakpoint === 'number') {
            // store wether or not it is less than the breakpoint
            result[mediaType] = currentOrder > breakpointOrder[mediaType]
        // handle non numerical breakpoints specially
        } else {
            result[mediaType] = false
        }
    })
}

/**
 * Gets the current media type from the global `window`.
 * @arg {object} mediaQueries - The media queries object.
 * @arg {string} infinityMediaType - The infinity media type.
 * @returns {string} The window's current media type.  This is the key of the
 * breakpoint that is the next breakpoint larger than the window.
 */
function getMediaType(matchMedia, mediaQueries, infinityMediaType) {
    // if there's no window
    if (typeof matchMedia === 'undefined') {
        // return the infinity media type
        return infinityMediaType
    }

    // there is a window, so compute the true media type
    return reduce(mediaQueries, (result, query, type) => {
        // return the new type if the query matches otherwise the previous one
        return matchMedia(query).matches ? type : result
    // use the infinity media type
    }, infinityMediaType)
}

/**
 * Gets the current media type from the global `window`.
 * @arg {object} mediaQueries - The media queries object.
 * @returns {string} The window's current media type.  This is the key of the
 * breakpoint that is the next breakpoint larger than the window.
 */
function getOrientation(matchMedia) {
    // if there's no window
    if (typeof matchMedia === 'undefined') {
        // return the default
        return defaultOrientation
    }

    const mediaQueries = {
        portrait: '(orientation: portrait)',
        landscape: '(orientation: landscape)',
    }

    // there is a window, so compute the true orientation
    return reduce(mediaQueries, (result, query, type) => {
        // return the new type if the query matches otherwise the previous one
        return matchMedia(query).matches ? type : result
    // use the default orientation
    }, defaultOrientation)
}

// export the reducer factory
export default (breakpoints, { initialMediaType, infinity = defaultMediaType, extraFields = () => ({}) } = {}) => {
    // accept null values
    if (!breakpoints) {
        breakpoints = defaultBreakpoints // eslint-disable-line
    }

    // add `infinity` breakpoint for upper bound
    breakpoints[infinity] = Infinity
    // media queries associated with the breakpoints
    const mediaQueries = MediaQuery.asObject(breakpoints)
    // figure out the ordering
    const mediaOrdering = getOrderMap(breakpoints)

    // return reducer for handling the responsive state
    return (state, {type, matchMedia}) => {
        // if told to recalculate state or state has not yet been initialized
        if (type === CALCULATE_RESPONSIVE_STATE || typeof state === 'undefined') {
            // the current media type
            const mediaType = !state && initialMediaType
                                        ? initialMediaType
                                        : getMediaType(matchMedia, mediaQueries, infinity)

            // the current orientation
            const orientation = getOrientation(matchMedia)
            // build the responsive state
            const responsiveState = {
                _responsiveState: true,
                lessThan: getLessThan(mediaType, mediaOrdering),
                greaterThan: getGreaterThan(mediaType, mediaOrdering),
                is: getIs(mediaType, breakpoints),
                mediaType,
                orientation,
                breakpoints,
            }

            // return calculated state
            return {
                ...responsiveState,
                ...extraFields(responsiveState),
            }
        }
        // otherwise return the previous state
        return state
    }
}
<commit_msg>added missing comment<commit_after>// third party imports
import MediaQuery from 'mediaquery'
import transform from 'lodash/transform'
import reduce from 'lodash/reduce'
// local imports
import CALCULATE_RESPONSIVE_STATE from '../actions/types/CALCULATE_RESPONSIVE_STATE'

// default breakpoints
export const defaultBreakpoints = {
    extraSmall: 480,
    small: 768,
    medium: 992,
    large: 1200,
}
// media type to default to when no `window` present
const defaultMediaType = 'infinity'
// orientation to default to when no `window` present
const defaultOrientation = null

/**
 * Compute a mapping of media type to its ordering where ordering is defined
 * such that large > medium > small.
 * @args (object) breakpoints - the breakpoint object
 */
export function getOrderMap(bps) {
    // grab the keys in the appropriate order
    const keys = Object.keys(bps).sort((a, b) => {
        // get the associated values
        const valueA = bps[a]
        const valueB = bps[b]

        // if a is a number and b is a string
        if (typeof valueA === 'number' && typeof valueB === 'string') {
            // put the number first
            return -1
        } else if (typeof valueB === 'number' && typeof valueA === 'string') {
            // return the number first
            return 1
        }

        // otherwise treat it like normal
        return valueA >= valueB ? 1 : -1
    })

    // map the original breakpoint object
    return transform(bps, (result, breakpoint, mediaType) => {
        // figure out the index of the mediatype
        const index = keys.indexOf(mediaType)
        // if there is an entry in the sort for this
        if (index !== -1) {
            // to its index in the sorted list
            result[mediaType] = index
        }
    })
}

/**
 * Compute the `lessThan` object based on the browser width.
 * @arg {number} browserWidth - Width of the browser.
 * @arg {object} breakpoints - The breakpoints object.
 * @arg {currentMediaType} breakpoints - The curent media type.
 * @returns {object} The `lessThan` object.  Its keys are the same as the
 * keys of the breakpoints object.  The value for each key indicates whether
 * or not the browser width is less than the breakpoint.
 */
export function getLessThan(currentMediaType, breakpointOrder) {
    // get the ordering of the current media type
    const currentOrder = breakpointOrder[currentMediaType]

    return transform(breakpointOrder, (result, breakpoint, mediaType) => {
        // if the breakpoint is a number
        if (typeof breakpoint === 'number' && breakpointOrder[mediaType]) {
            // store wether or not it is less than the breakpoint
            result[mediaType] = currentOrder < breakpointOrder[mediaType]
        // handle non numerical breakpoints specially
        } else {
            result[mediaType] = false
        }
    })
}

/**
 * Compute the `lessThan` object based on the browser width.
 * @arg {object} breakpoints - The breakpoints object.
 * @arg {currentMediaType} breakpoints - The curent media type.
 * @returns {object} The `lessThan` object.  Its keys are the same as the
 * keys of the breakpoints object.  The value for each key indicates whether
 * or not the browser width is less than the breakpoint.
 */
export function getIs(currentMediaType, breakpoints) {
    return transform(breakpoints, (result, breakpoint, mediaType) => {
        // if the breakpoint is a number
        if (typeof breakpoint === 'number' && breakpoints[mediaType]) {
            // store wether or not it is less than the breakpoint
            result[mediaType] = mediaType === currentMediaType
        // handle non numerical breakpoints specially
        } else {
            result[mediaType] = false
        }
    })
}

/**
 * Compute the `greaterThan` object based on the browser width.
 * @arg {number} browserWidth - Width of the browser.
 * @arg {object} breakpoints - The breakpoints object.
 * @returns {object} The `greaterThan` object.  Its keys are the same as the
 * keys of the breakpoints object.  The value for each key indicates whether
 * or not the browser width is greater than the breakpoint.
 */
export function getGreaterThan(currentMediaType, breakpointOrder) {
    // get the ordering of the current media type
    const currentOrder = breakpointOrder[currentMediaType]

    return transform(breakpointOrder, (result, breakpoint, mediaType) => {
        // if the breakpoint is a number
        if (typeof breakpoint === 'number') {
            // store wether or not it is less than the breakpoint
            result[mediaType] = currentOrder > breakpointOrder[mediaType]
        // handle non numerical breakpoints specially
        } else {
            result[mediaType] = false
        }
    })
}

/**
 * Gets the current media type from the global `window`.
 * @arg {object} mediaQueries - The media queries object.
 * @arg {string} infinityMediaType - The infinity media type.
 * @returns {string} The window's current media type.  This is the key of the
 * breakpoint that is the next breakpoint larger than the window.
 */
function getMediaType(matchMedia, mediaQueries, infinityMediaType) {
    // if there's no window
    if (typeof matchMedia === 'undefined') {
        // return the infinity media type
        return infinityMediaType
    }

    // there is a window, so compute the true media type
    return reduce(mediaQueries, (result, query, type) => {
        // return the new type if the query matches otherwise the previous one
        return matchMedia(query).matches ? type : result
    // use the infinity media type
    }, infinityMediaType)
}

/**
 * Gets the current media type from the global `window`.
 * @arg {object} mediaQueries - The media queries object.
 * @returns {string} The window's current media type.  This is the key of the
 * breakpoint that is the next breakpoint larger than the window.
 */
function getOrientation(matchMedia) {
    // if there's no window
    if (typeof matchMedia === 'undefined') {
        // return the default
        return defaultOrientation
    }

    const mediaQueries = {
        portrait: '(orientation: portrait)',
        landscape: '(orientation: landscape)',
    }

    // there is a window, so compute the true orientation
    return reduce(mediaQueries, (result, query, type) => {
        // return the new type if the query matches otherwise the previous one
        return matchMedia(query).matches ? type : result
    // use the default orientation
    }, defaultOrientation)
}

// export the reducer factory
export default (breakpoints, { initialMediaType, infinity = defaultMediaType, extraFields = () => ({}) } = {}) => {
    // accept null values
    if (!breakpoints) {
        breakpoints = defaultBreakpoints // eslint-disable-line
    }

    // add `infinity` breakpoint for upper bound
    breakpoints[infinity] = Infinity
    // media queries associated with the breakpoints
    const mediaQueries = MediaQuery.asObject(breakpoints)
    // figure out the ordering
    const mediaOrdering = getOrderMap(breakpoints)

    // return reducer for handling the responsive state
    return (state, {type, matchMedia}) => {
        // if told to recalculate state or state has not yet been initialized
        if (type === CALCULATE_RESPONSIVE_STATE || typeof state === 'undefined') {
            // if the state has never been set before and we have an initial type
            const mediaType = !state && initialMediaType
                                        // use it
                                        ? initialMediaType
                                        // otherwise figure out the media type from the browser
                                        : getMediaType(matchMedia, mediaQueries, infinity)

            // the current orientation
            const orientation = getOrientation(matchMedia)
            // build the responsive state
            const responsiveState = {
                _responsiveState: true,
                lessThan: getLessThan(mediaType, mediaOrdering),
                greaterThan: getGreaterThan(mediaType, mediaOrdering),
                is: getIs(mediaType, breakpoints),
                mediaType,
                orientation,
                breakpoints,
            }

            // return calculated state
            return {
                ...responsiveState,
                ...extraFields(responsiveState),
            }
        }
        // otherwise return the previous state
        return state
    }
}
<|endoftext|>


<commit_before>/*
 * This file is part of wger Workout Manager.
 *
 * wger Workout Manager is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * wger Workout Manager is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 */

/*
 * wger Nutriton functions
 */

"use strict";

function update_ingredient_value(url)
{
    var form_data = $('#nutritional-values-form').serializeArray();
    $.get(url, form_data, function(data) {

        // Show any validation errors
        $('#calculator-errors').html('');
        if (data['errors'])
        {
            $.each(data['errors'], function(index, value) {
                $('#calculator-errors').append('
'+value+'
');
            });
        }

        // Replace the nutritional values
        $('#value-energy').html(parseFloat(data['energy']).toFixed(2));
        $('#value-protein').html(parseFloat(data['protein']).toFixed(2));
        $('#value-carbohydrates').html(parseFloat(data['carbohydrates']).toFixed(2));
        $('#value-carbohydrates-sugar').html(parseFloat(data['carbohydrates_sugar']).toFixed(2));
        $('#value-fat').html(parseFloat(data['fat']).toFixed(2));
        $('#value-fat-saturated').html(parseFloat(data['fat_saturated']).toFixed(2));
        $('#value-fibres').html(parseFloat(data['fibres']).toFixed(2));
        $('#value-sodium').html(parseFloat(data['sodium']).toFixed(2));
    });
}

function init_ingredient_detail(url)
{
    // Prevent the form from being sent
    $('#nutritional-values-form').submit(function(e) {
        e.preventDefault();
    });

    $('#id_amount').keyup(function(){
        update_ingredient_value(url);
    });

    $('#id_unit').change(function(){
        update_ingredient_value(url);
    });
}

/*
 * Update the user's preferences
 */
function init_ingredient_autocompleter()
{
    // Init the autocompleter
    $('#id_ingredient_searchfield').devbridgeAutocomplete({
        serviceUrl: '/api/v2/ingredient/search/',
        onSelect: function (suggestion) {
            var ingredient_id = suggestion.data.id;

            // After clicking on a result set the value of the hidden field
            $('#id_ingredient').val(ingredient_id);
            $('#exercise_name').html(suggestion.value);

            // See if the ingredient has any units and set the values for the forms
            $.get('/api/v2/ingredientweightunit/?ingredient=' + ingredient_id, function(unit_data) {

                // Remove any old units, if any
                var options = $('#id_weight_unit').find('option');
                $.each(options, function(index, option_obj) {
                    if (option_obj.value != '')
                    {
                        $(option_obj).remove();
                    }
                });

                // Add new units, if any
                $.each(unit_data.results, function(index, value) {
                    $.get('/api/v2/weightunit/' + value.unit + '/', function(unit) {
                        var unit_name = unit.name + ' (' + value.gram + 'g)';
                        $('#id_unit').append(new Option(unit_name, value.id));
                        $('#id_weight_unit').append(new Option(unit_name, value.id));
                    });
                });
            });
        },
        paramName: 'term',
        transformResult: function(response) {
            // why is response not already a JSON object??
            var jsonResponse = $.parseJSON(response);
            return {
                suggestions: $.map(jsonResponse, function(item) {
                    return {value: item.value, data: {id: item.id}};
                })
            };
        }
    });
}

/*
 * Draw the BMI chart
 */
function render_bmi(width_factor)
{
    // Delete the other diagrams
    d3.selectAll('svg').remove();

    // Calculate the size
    var width_factor = typeof width_factor !== 'undefined' ? width_factor: 600;
    var height_factor = width_factor / 600 * 300;

    var margin = {top: 20, right: 80, bottom: 30, left: 50},
        width = width_factor - margin.left - margin.right,
        height = height_factor - margin.top - margin.bottom;

    var x = d3.scaleLinear()
        .range([0, width]);

    var y = d3.scaleLinear()
        .range([height, 0]);

    var z = d3.scaleOrdinal().range(['#000080', '#0000ff', '#00ffff', '#00ff00', '#ffff00', '#ff7f2a', '#ff0000', '#800000']);

    var xAxis = d3.axisBottom(x);

    var yAxis = d3.axisLeft(y);

    var stack = d3.stack();

    var nest = d3.nest()
        .key(function(d) { return d.key; });

    var area = d3.area()
        .x(function(d) { return x(d.height); })
        .y1(function(d) { return y(d.weight); });

    var svg = d3.select("#bmi-chart").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    // Clip path, drawings outside are removed
    svg.append("defs").append("clipPath")
        .attr("id", "clip")
      .append("rect")
        .attr("width", width)
        .attr("height", height);

    d3.json("/nutrition/calculator/bmi/chart-data", function(data) {

        stack.keys(["filler", "severe_thinness","moderate_thinness","mild_thinness","normal_range","pre_obese","obese_class_2","obese_class_3"]);
        var layers = stack(nest.entries(data));

        // Manually set the domains
        x.domain([150, 200]); // height, in cm
        y.domain([30, 160]);  // weight, in kg

      svg.selectAll(".layer")
          .data(layers)
        .enter().append("path")
          .attr("class", "layer")
          .attr("id", function(d, i) { return "key-" + d.key; })
          .attr("clip-path", "url(#clip)")
          .attr("d", function(d, i) { return area(d[i].data.values); })
          .style("fill", function(d, i) { return z(i); })
          .style("opacity", 1);

      svg.append("g")
          .attr("class", "x axis")
          .attr("transform", "translate(0," + height + ")")
          .call(xAxis);

      svg.append("g")
          //.attr("transform", "translate(" + width + ",0)")
          .attr("class", "y axis")
          .call(yAxis);

      var url = $("#bmi-form").attr( 'action' );

        $.post(url,
           $("#bmi-form").serialize(),
           function(data) {
               $('#bmi-result-container').show();
               $('#bmi-result-value').html(data.bmi);
               svg.append("circle")
                .attr("cx", x(data.height))
                .attr("cy", y(data.weight))
                .attr("fill", "black")
                .attr("r", 5);
           });
    });

}

/*
 * Calories calculator
 */
function init_calories_calculator()
{
    $("#form-transfer-calories").click(function(e){
        e.preventDefault();
        var base_calories = Number($('#id_base_calories').html());
        $('#id_calories').val(base_calories);
    });

    $("#add-calories-total").click(function(e){
        e.preventDefault();
        var base_calories = Number($('#id_base_calories').html());
        var additional_calories = Number($('#id_additional_calories').val());
        $('#id_calories').val(base_calories + additional_calories);
    });

    $("#form-update-calories").click(function(e){
        e.preventDefault();

        // Get own ID and update the user profile
        $.get('/api/v2/userprofile', function(data) {
        }).done(function(userprofile) {
            var total_calories = $("#id_calories")[0].value;
            $.ajax({
                url:'/api/v2/userprofile/' + userprofile.results[0].id + '/',
                type: 'PATCH',
                data: {calories: total_calories}
            });
        });
    });

    $(".calories-autoform").click(function(e){
        e.preventDefault();

        // BMR
        var bmr_url = $("#bmr-form").attr('action');
        $.post(bmr_url,
               $("#bmr-form").serialize(),
               function(data) {
                   $('#bmr-result-container').show();
                   $('#bmr-result-value').html(data.bmr);

                   // Activities
                   var activities_url = $("#activities-form").attr('action');
                   $.post(activities_url,
                          $("#activities-form").serialize(),
                          function(data) {
                              $('#activities-result-container').show();
                              $('#activities-result-value').html(data.factor);

                              // Total calories
                              $('#id_base_calories').html(data.activities);
                          });
            });
    });
}
<commit_msg>Get x and y axis from json request<commit_after>/*
 * This file is part of wger Workout Manager.
 *
 * wger Workout Manager is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * wger Workout Manager is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 */

/*
 * wger Nutriton functions
 */

"use strict";

function update_ingredient_value(url)
{
    var form_data = $('#nutritional-values-form').serializeArray();
    $.get(url, form_data, function(data) {

        // Show any validation errors
        $('#calculator-errors').html('');
        if (data['errors'])
        {
            $.each(data['errors'], function(index, value) {
                $('#calculator-errors').append('
'+value+'
');
            });
        }

        // Replace the nutritional values
        $('#value-energy').html(parseFloat(data['energy']).toFixed(2));
        $('#value-protein').html(parseFloat(data['protein']).toFixed(2));
        $('#value-carbohydrates').html(parseFloat(data['carbohydrates']).toFixed(2));
        $('#value-carbohydrates-sugar').html(parseFloat(data['carbohydrates_sugar']).toFixed(2));
        $('#value-fat').html(parseFloat(data['fat']).toFixed(2));
        $('#value-fat-saturated').html(parseFloat(data['fat_saturated']).toFixed(2));
        $('#value-fibres').html(parseFloat(data['fibres']).toFixed(2));
        $('#value-sodium').html(parseFloat(data['sodium']).toFixed(2));
    });
}

function init_ingredient_detail(url)
{
    // Prevent the form from being sent
    $('#nutritional-values-form').submit(function(e) {
        e.preventDefault();
    });

    $('#id_amount').keyup(function(){
        update_ingredient_value(url);
    });

    $('#id_unit').change(function(){
        update_ingredient_value(url);
    });
}

/*
 * Update the user's preferences
 */
function init_ingredient_autocompleter()
{
    // Init the autocompleter
    $('#id_ingredient_searchfield').devbridgeAutocomplete({
        serviceUrl: '/api/v2/ingredient/search/',
        onSelect: function (suggestion) {
            var ingredient_id = suggestion.data.id;

            // After clicking on a result set the value of the hidden field
            $('#id_ingredient').val(ingredient_id);
            $('#exercise_name').html(suggestion.value);

            // See if the ingredient has any units and set the values for the forms
            $.get('/api/v2/ingredientweightunit/?ingredient=' + ingredient_id, function(unit_data) {

                // Remove any old units, if any
                var options = $('#id_weight_unit').find('option');
                $.each(options, function(index, option_obj) {
                    if (option_obj.value != '')
                    {
                        $(option_obj).remove();
                    }
                });

                // Add new units, if any
                $.each(unit_data.results, function(index, value) {
                    $.get('/api/v2/weightunit/' + value.unit + '/', function(unit) {
                        var unit_name = unit.name + ' (' + value.gram + 'g)';
                        $('#id_unit').append(new Option(unit_name, value.id));
                        $('#id_weight_unit').append(new Option(unit_name, value.id));
                    });
                });
            });
        },
        paramName: 'term',
        transformResult: function(response) {
            // why is response not already a JSON object??
            var jsonResponse = $.parseJSON(response);
            return {
                suggestions: $.map(jsonResponse, function(item) {
                    return {value: item.value, data: {id: item.id}};
                })
            };
        }
    });
}

/*
 * Draw the BMI chart
 */
function render_bmi(width_factor)
{
    // Delete the other diagrams
    d3.selectAll('svg').remove();

    // Calculate the size
    var width_factor = typeof width_factor !== 'undefined' ? width_factor: 600;
    var height_factor = width_factor / 600 * 300;

    var margin = {top: 20, right: 80, bottom: 30, left: 50},
        width = width_factor - margin.left - margin.right,
        height = height_factor - margin.top - margin.bottom;

    var x = d3.scaleLinear()
        .range([0, width]);

    var y = d3.scaleLinear()
        .range([height, 0]);

    var z = d3.scaleOrdinal().range(['#000080', '#0000ff', '#00ffff', '#00ff00', '#ffff00', '#ff7f2a', '#ff0000', '#800000']);

    var xAxis = d3.axisBottom(x);

    var yAxis = d3.axisLeft(y);

    var stack = d3.stack();

    var nest = d3.nest()
        .key(function(d) { return d.key; });

    var area = d3.area()
        .x(function(d) { return x(d.height); })
        .y1(function(d) { return y(d.weight); });

    var svg = d3.select("#bmi-chart").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    // Clip path, drawings outside are removed
    svg.append("defs").append("clipPath")
        .attr("id", "clip")
      .append("rect")
        .attr("width", width)
        .attr("height", height);

    d3.json("/nutrition/calculator/bmi/chart-data", function(data) {

        stack.keys(["filler", "severe_thinness","moderate_thinness","mild_thinness","normal_range","pre_obese","obese_class_2","obese_class_3"]);
        var layers = stack(nest.entries(data));

        x.domain(data.map(function(d) { return d.height; }));
        y.domain([d3.min(data, function(d) { return d.weight; }), d3.max(data, function(d) { return d.weight; }) ]);

      svg.selectAll(".layer")
          .data(layers)
        .enter().append("path")
          .attr("class", "layer")
          .attr("id", function(d, i) { return "key-" + d.key; })
          .attr("clip-path", "url(#clip)")
          .attr("d", function(d, i) { return area(d[i].data.values); })
          .style("fill", function(d, i) { return z(i); })
          .style("opacity", 1);

      svg.append("g")
          .attr("class", "x axis")
          .attr("transform", "translate(0," + height + ")")
          .call(xAxis);

      svg.append("g")
          //.attr("transform", "translate(" + width + ",0)")
          .attr("class", "y axis")
          .call(yAxis);

      var url = $("#bmi-form").attr( 'action' );

        $.post(url,
           $("#bmi-form").serialize(),
           function(data) {
               $('#bmi-result-container').show();
               $('#bmi-result-value').html(data.bmi);
               svg.append("circle")
                .attr("cx", x(data.height))
                .attr("cy", y(data.weight))
                .attr("fill", "black")
                .attr("r", 5);
           });
    });

}

/*
 * Calories calculator
 */
function init_calories_calculator()
{
    $("#form-transfer-calories").click(function(e){
        e.preventDefault();
        var base_calories = Number($('#id_base_calories').html());
        $('#id_calories').val(base_calories);
    });

    $("#add-calories-total").click(function(e){
        e.preventDefault();
        var base_calories = Number($('#id_base_calories').html());
        var additional_calories = Number($('#id_additional_calories').val());
        $('#id_calories').val(base_calories + additional_calories);
    });

    $("#form-update-calories").click(function(e){
        e.preventDefault();

        // Get own ID and update the user profile
        $.get('/api/v2/userprofile', function(data) {
        }).done(function(userprofile) {
            var total_calories = $("#id_calories")[0].value;
            $.ajax({
                url:'/api/v2/userprofile/' + userprofile.results[0].id + '/',
                type: 'PATCH',
                data: {calories: total_calories}
            });
        });
    });

    $(".calories-autoform").click(function(e){
        e.preventDefault();

        // BMR
        var bmr_url = $("#bmr-form").attr('action');
        $.post(bmr_url,
               $("#bmr-form").serialize(),
               function(data) {
                   $('#bmr-result-container').show();
                   $('#bmr-result-value').html(data.bmr);

                   // Activities
                   var activities_url = $("#activities-form").attr('action');
                   $.post(activities_url,
                          $("#activities-form").serialize(),
                          function(data) {
                              $('#activities-result-container').show();
                              $('#activities-result-value').html(data.factor);

                              // Total calories
                              $('#id_base_calories').html(data.activities);
                          });
            });
    });
}
<|endoftext|>


<commit_before>define([], function() {
    return [{
        id: 1,
        text: '1N',
        meridian: 'UB'
    }, {
        id: 3,
        text: '2N',
        meridian: 'UB'
    }, {
        id: 5,
        text: '3N',
        meridian: 'UB'
    }, {
        id: 7,
        text: '4N',
        meridian: 'UB'
    }, {
        id: 9,
        text: '5N',
        meridian: 'UB'
    }, {
        id: 2,
        text: '1S',
        meridian: 'UB'
    }, {
        id: 4,
        text: '2S',
        meridian: 'UB'
    }, {
        id: 6,
        text: '3S',
        meridian: 'UB'
    }, {
        id: 8,
        text: '4S',
        meridian: 'UB'
    }, {
        id: 10,
        text: '5S',
        meridian: 'UB'
    }, {
        id: 11,
        text: '6S',
        meridian: 'UB'
    }, {
        id: 12,
        text: '7S',
        meridian: 'UB'
    }, {
        id: 13,
        text: '1N',
        meridian: 'SL'
    }, {
        id: 16,
        text: '2N',
        meridian: 'SL'
    }, {
        id: 18,
        text: '3N',
        meridian: 'SL'
    }, {
        id: 20,
        text: '4N',
        meridian: 'SL'
    }, {
        id: 22,
        text: '5N',
        meridian: 'SL'
    }, {
        id: 24,
        text: '6N',
        meridian: 'SL'
    }, {
        id: 26,
        text: '7N',
        meridian: 'SL'
    }, {
        id: 28,
        text: '8N',
        meridian: 'SL'
    }, {
        id: 30,
        text: '9N',
        meridian: 'SL'
    }, {
        id: 32,
        text: '10N',
        meridian: 'SL'
    }, {
        id: 34,
        text: '10.5N',
        meridian: 'SL'
    }, {
        id: 35,
        text: '11N',
        meridian: 'SL'
    }, {
        id: 38,
        text: '12N',
        meridian: 'SL'
    }, {
        id: 40,
        text: '13N',
        meridian: 'SL'
    }, {
        id: 42,
        text: '14N',
        meridian: 'SL'
    }, {
        id: 44,
        text: '15N',
        meridian: 'SL'
    }, {
        id: 14,
        text: '1S',
        meridian: 'SL'
    }, {
        id: 15,
        text: '1.5S',
        meridian: 'SL'
    }, {
        id: 17,
        text: '2S',
        meridian: 'SL'
    }, {
        id: 19,
        text: '3S',
        meridian: 'SL'
    }, {
        id: 21,
        text: '4S',
        meridian: 'SL'
    }, {
        id: 23,
        text: '5S',
        meridian: 'SL'
    }, {
        id: 25,
        text: '6S',
        meridian: 'SL'
    }, {
        id: 27,
        text: '7S',
        meridian: 'SL'
    }, {
        id: 29,
        text: '8S',
        meridian: 'SL'
    }, {
        id: 31,
        text: '9S',
        meridian: 'SL'
    }, {
        id: 33,
        text: '10S',
        meridian: 'SL'
    }, {
        id: 36,
        text: '11S',
        meridian: 'SL'
    }, {
        id: 37,
        text: '11.5S',
        meridian: 'SL'
    }, {
        id: 39,
        text: '12S',
        meridian: 'SL'
    }, {
        id: 41,
        text: '13S',
        meridian: 'SL'
    }, {
        id: 43,
        text: '14S',
        meridian: 'SL'
    }, {
        id: 45,
        text: '15S',
        meridian: 'SL'
    }, {
        id: 46,
        text: '15.5S',
        meridian: 'SL'
    }, {
        id: 47,
        text: '16S',
        meridian: 'SL'
    }, {
        id: 48,
        text: '17S',
        meridian: 'SL'
    }, {
        id: 49,
        text: '18S',
        meridian: 'SL'
    }, {
        id: 50,
        text: '19S',
        meridian: 'SL'
    }, {
        id: 51,
        text: '19.5S',
        meridian: 'SL'
    }, {
        id: 52,
        text: '20S',
        meridian: 'SL'
    }, {
        id: 53,
        text: '20.5S',
        meridian: 'SL'
    }, {
        id: 54,
        text: '21S',
        meridian: 'SL'
    }, {
        id: 55,
        text: '22S',
        meridian: 'SL'
    }, {
        id: 56,
        text: '23S',
        meridian: 'SL'
    }, {
        id: 57,
        text: '24S',
        meridian: 'SL'
    }, {
        id: 58,
        text: '25S',
        meridian: 'SL'
    }, {
        id: 59,
        text: '26S',
        meridian: 'SL'
    }, {
        id: 60,
        text: '27S',
        meridian: 'SL'
    }, {
        id: 61,
        text: '28S',
        meridian: 'SL'
    }, {
        id: 62,
        text: '28.5S',
        meridian: 'SL'
    }, {
        id: 63,
        text: '29S',
        meridian: 'SL'
    }, {
        id: 64,
        text: '29.5S',
        meridian: 'SL'
    }, {
        id: 65,
        text: '30S',
        meridian: 'SL'
    }, {
        id: 66,
        text: '30.5S',
        meridian: 'SL'
    }, {
        id: 67,
        text: '31S',
        meridian: 'SL'
    }, {
        id: 68,
        text: '32S',
        meridian: 'SL'
    }, {
        id: 69,
        text: '32.5S',
        meridian: 'SL'
    }, {
        id: 70,
        text: '33S',
        meridian: 'SL'
    }, {
        id: 71,
        text: '34S',
        meridian: 'SL'
    }, {
        id: 72,
        text: '35S',
        meridian: 'SL'
    }, {
        id: 73,
        text: '35.5S',
        meridian: 'SL'
    }, {
        id: 74,
        text: '36S',
        meridian: 'SL'
    }, {
        id: 75,
        text: '37S',
        meridian: 'SL'
    }, {
        id: 76,
        text: '37.5S',
        meridian: 'SL'
    }, {
        id: 77,
        text: '38S',
        meridian: 'SL'
    }, {
        id: 78,
        text: '38.5S',
        meridian: 'SL'
    }, {
        id: 79,
        text: '39S',
        meridian: 'SL'
    }, {
        id: 80,
        text: '40S',
        meridian: 'SL'
    }, {
        id: 81,
        text: '40.5S',
        meridian: 'SL'
    }, {
        id: 82,
        text: '41S',
        meridian: 'SL'
    }, {
        id: 83,
        text: '42S',
        meridian: 'SL'
    }, {
        id: 84,
        text: '42.5S',
        meridian: 'SL'
    }, {
        id: 85,
        text: '43S',
        meridian: 'SL'
    }, {
        id: 86,
        text: '44S',
        meridian: 'SL'
    }];
});<commit_msg>remove unused folder<commit_after><|endoftext|>


<commit_before>
function msg (from, to, text, ev1, tt) {
    var typ = from.secure ? Diagram.LINETYPE.SOLID : Diagram.LINETYPE.DOTTED;
    return new Diagram.Signal(from, typ | (Diagram.ARROWTYPE.FILLED << 2), to, text, ev1, tt)
}

function lookupchap (msg) {
    switch (msg) {
        case 'ChangeCipherSpec'  : return '.chapter-7-1'
        case 'HelloRequest'      : return '.chapter-7-4-1-1'
        case 'ClientHello'       : return '.chapter-7-4-1-2'
        case 'ServerHello'       : return '.chapter-7-4-1-3'
        case 'Certificate'       : return '.chapter-7-4-2'
        case 'ServerKeyExchange' : return '.chapter-7-4-3'
        case 'ServerHelloDone'   : return '.chapter-7-4-5'
        case 'ClientKeyExchange' : return '.chapter-7-4-7'
        case 'Finished'          : return '.chapter-7-4-9'
        default                  : return '.chapter-10'
    }
}

function rfc_cb (sig, msg, moredata) {
    var chap = lookupchap(msg);
    _.each (moredata, function (datum) {
        var dat = datum[0] != '' ? datum[0] + ': ' : '' ;
        var txt = dat + datum[1];
        sig.data.push (txt);
    })
    return function () {
        $('.rfc-chapter').hide() ;
        $(chap).show('fast');
        $('#details').empty().append(
          _.map (sig.data, function (d) {
            return $("

").find('pre').append(d).end()
          })
        )
    }
}

function handle_sec (from, msg) {
    if (msg == 'ChangeCipherSpec')
        from.secure = true
}

var updating = false;

function process (me, you, in_record) {
    var txt = in_record.message;
    if (in_record.event == 'message') {
        //msg
        var from = me ;
        var to = you ;
        if (in_record.direction == 'in') {
            from = you ; to = me ;
        }
        var r = msg(from, to, txt);
        handle_sec(from, txt);
        return r;
    } else if (in_record.event == 'note') {
        //note
        if (in_record.data == '')
            return new Diagram.Note(me, Diagram.PLACEMENT.RIGHTOF, txt)
        return new Diagram.Note(me, Diagram.PLACEMENT.RIGHTOF, txt, null, in_record.data);
    }
}

function insertSignals (diagram, signals, data) {

    var last = null;

    for ( var i = 0 ; i < signals.length ; i++ ) {
        var now = signals[i];
        if (now.type == 'Signal') {
            var txt = now.message;
            if (last != null && last.actorA == now.actorA &&
                (last.message == txt || last.message == txt + '*' )) {
                var cb = rfc_cb(last, txt, data[i].data);
                last.ev1 = cb;
                if (last.message == txt) {
                    last.message = last.message + "*";
                }
            } else {
                var cb = rfc_cb(now, txt, data[i].data);
                now.ev1 = cb;
                diagram.addSignal(now);
                last = now;
            }
        } else {
            diagram.addSignal(now);
        }
    }
}

var data = [] ;

function getData () {
  $.ajax({ url: "/diagram.json" }).done( function( data1 ) {
      var diagram = new Diagram();
      var you = diagram.getActor('Client');
      var me = diagram.getActor('Server');

      data = data.concat (data1);

      var signals = _.map(data, function (x) { return process(me, you, x) });
      insertSignals(diagram, signals, data);

      var options = {
          theme: 'simple'
      };

      $('#diagram, #details').empty ();
      $('.rfc-chapter').hide() ;
      $('.chapter-NONE').show();

      // Draw
      diagram.drawSVG($('#diagram')[0], options);
      updating = false;
      $('#request').val('Renegotiate!').attr('disabled', false);
  });
}

function initialise () {
    $('.chapter-NONE').show();

    getData();

    var req = document.getElementById("request")
    request.onclick = function () {
        if (! updating) {
            updating = true;
            req.value = 'renegotiating...';
            req.disabled = true;
            $.ajax({ url: "/rekey" }).done( function () {
                setTimeout(getData, 500)
            })
        }
    }
}
<commit_msg>unbreak rekeying<commit_after>
function msg (from, to, text, ev1, tt) {
    var typ = from.secure ? Diagram.LINETYPE.SOLID : Diagram.LINETYPE.DOTTED;
    return new Diagram.Signal(from, typ | (Diagram.ARROWTYPE.FILLED << 2), to, text, ev1, tt)
}

function lookupchap (msg) {
    switch (msg) {
        case 'ChangeCipherSpec'  : return '.chapter-7-1'
        case 'HelloRequest'      : return '.chapter-7-4-1-1'
        case 'ClientHello'       : return '.chapter-7-4-1-2'
        case 'ServerHello'       : return '.chapter-7-4-1-3'
        case 'Certificate'       : return '.chapter-7-4-2'
        case 'ServerKeyExchange' : return '.chapter-7-4-3'
        case 'ServerHelloDone'   : return '.chapter-7-4-5'
        case 'ClientKeyExchange' : return '.chapter-7-4-7'
        case 'Finished'          : return '.chapter-7-4-9'
        default                  : return '.chapter-10'
    }
}

function rfc_cb (sig, msg, moredata) {
    var chap = lookupchap(msg);
    _.each (moredata, function (datum) {
        var dat = datum[0] != '' ? datum[0] + ': ' : '' ;
        var txt = dat + datum[1];
        sig.data.push (txt);
    })
    return function () {
        $('.rfc-chapter').hide() ;
        $(chap).show('fast');
        $('#details').empty().append(
          _.map (sig.data, function (d) {
            return $("

").find('pre').append(d).end()
          })
        )
    }
}

function handle_sec (from, msg) {
    if (msg == 'ChangeCipherSpec')
        from.secure = true
}

var updating = false;

function process (me, you, in_record) {
    var txt = in_record.message;
    if (in_record.event == 'message') {
        //msg
        var from = me ;
        var to = you ;
        if (in_record.direction == 'in') {
            from = you ; to = me ;
        }
        var r = msg(from, to, txt);
        handle_sec(from, txt);
        return r;
    } else if (in_record.event == 'note') {
        //note
        if (in_record.data == '')
            return new Diagram.Note(me, Diagram.PLACEMENT.RIGHTOF, txt)
        return new Diagram.Note(me, Diagram.PLACEMENT.RIGHTOF, txt, null, in_record.data);
    }
}

function insertSignals (diagram, signals, data) {

    var last = null;

    for ( var i = 0 ; i < signals.length ; i++ ) {
        var now = signals[i];
        if (now.type == 'Signal') {
            var txt = now.message;
            if (last != null && last.actorA == now.actorA &&
                (last.message == txt || last.message == txt + '*' )) {
                var cb = rfc_cb(last, txt, data[i].data);
                last.ev1 = cb;
                if (last.message == txt) {
                    last.message = last.message + "*";
                }
            } else {
                var cb = rfc_cb(now, txt, data[i].data);
                now.ev1 = cb;
                diagram.addSignal(now);
                last = now;
            }
        } else {
            diagram.addSignal(now);
        }
    }
}

var data = [] ;

function getData () {
  $.ajax({ url: "/diagram.json" }).done( function( data1 ) {
      var diagram = new Diagram();
      var you = diagram.getActor('Client');
      var me = diagram.getActor('Server');

      data = data.concat (data1);

      var signals = _.map(data, function (x) { return process(me, you, x) });
      insertSignals(diagram, signals, data);

      var options = {
          theme: 'simple'
      };

      $('#diagram, #details').empty ();
      $('.rfc-chapter').hide() ;
      $('.chapter-NONE').show();

      // Draw
      diagram.drawSVG($('#diagram')[0], options);
      updating = false;
      $('#request').val('Renegotiate!').attr('disabled', false);
  });
}

function initialise () {
    $('.chapter-NONE').show();

    getData();

    $('#request').click( function () {
        if (! updating) {
            updating = true;
            $('#request').val('renegotiating...').attr('disabled', true);
            $.ajax({ url: "/rekey" }).done( function () {
                setTimeout(getData, 500)
            })
        }
    })
}
<|endoftext|>


<commit_before>/* global process:false */

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
const autoprefixer = require('autoprefixer');
const glob = require('glob');
const basename = require('basename');

const thisPackage = require('./package.json');
const vendorLibraries = Object.keys(thisPackage.dependencies);

// There's a builtin/default keybinding that we call `ace`.
const allKeybindingFiles = glob.sync('./node_modules/brace/keybinding/*.js');
const allKeybindings = allKeybindingFiles.map(basename).concat(['ace']).sort();

const allThemeFiles = glob.sync('./node_modules/brace/theme/*.js');
const allThemes = allThemeFiles.map(basename);

module.exports = {
  entry: {
    app: ['./index.js', './index.scss'],
    vendor: vendorLibraries,
  },

  output: {
    path: './build',
    filename: '[name]-[chunkhash].js',
    chunkFilename: '[chunkhash].js',
  },

  resolve: {
    extensions: ['', '.js', '.jsx'],
  },

  module: {
    loaders: [
      {
        test: [/\.js$/, /\.jsx$/],
        exclude: /node_modules/,
        loader: 'babel',
      },
      {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract("style", ["css", "postcss", "sass"]),
      },
    ],
  },

  plugins: [
    new webpack.EnvironmentPlugin(["NODE_ENV"]),
    new webpack.DefinePlugin({
      ACE_KEYBINDINGS: JSON.stringify(allKeybindings),
      ACE_THEMES: JSON.stringify(allThemes),
    }),
    new HtmlWebpackPlugin({
      title: "Rust Playground",
      template: 'index.ejs',
      chunksSortMode: 'dependency',
    }),
    new ExtractTextPlugin("styles-[chunkhash].css"),
    new webpack.optimize.CommonsChunkPlugin({
      names: ['vendor', 'manifest'],
    }),
  ],

  postcss: function () {
    return [autoprefixer];
  },
};

if (process.env.NODE_ENV === 'production') {
  module.exports.plugins.push(
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
      },
    }),
    new webpack.optimize.OccurrenceOrderPlugin(),
    new CompressionPlugin({ algorithm: 'zopfli' })
  );
}
<commit_msg>Include themes and keybindings in the vendor chunk<commit_after>/* global process:false */

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
const autoprefixer = require('autoprefixer');
const glob = require('glob');
const basename = require('basename');

const thisPackage = require('./package.json');
const dependencies = Object.keys(thisPackage.dependencies);

const allKeybindingNames = glob.sync('./node_modules/brace/keybinding/*.js').map(basename);
const allKeybindingRequires = allKeybindingNames.map(n => `brace/keybinding/${n}`);

const allThemeNames = glob.sync('./node_modules/brace/theme/*.js').map(basename);
const allThemeRequires = allThemeNames.map(n => `brace/theme/${n}`);

// There's a builtin/default keybinding that we call `ace`.
const allKeybindings = allKeybindingNames.concat(['ace']).sort();
const allThemes = allThemeNames;

// Perhaps we could place each of these in a separate chunk and load them on demand?
const vendorLibraries = dependencies.concat(allKeybindingRequires, allThemeRequires);

module.exports = {
  entry: {
    app: ['./index.js', './index.scss'],
    vendor: vendorLibraries,
  },

  output: {
    path: './build',
    filename: '[name]-[chunkhash].js',
    chunkFilename: '[chunkhash].js',
  },

  resolve: {
    extensions: ['', '.js', '.jsx'],
  },

  module: {
    loaders: [
      {
        test: [/\.js$/, /\.jsx$/],
        exclude: /node_modules/,
        loader: 'babel',
      },
      {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract("style", ["css", "postcss", "sass"]),
      },
    ],
  },

  plugins: [
    new webpack.EnvironmentPlugin(["NODE_ENV"]),
    new webpack.DefinePlugin({
      ACE_KEYBINDINGS: JSON.stringify(allKeybindings),
      ACE_THEMES: JSON.stringify(allThemes),
    }),
    new HtmlWebpackPlugin({
      title: "Rust Playground",
      template: 'index.ejs',
      chunksSortMode: 'dependency',
    }),
    new ExtractTextPlugin("styles-[chunkhash].css"),
    new webpack.optimize.CommonsChunkPlugin({
      names: ['vendor', 'manifest'],
    }),
  ],

  postcss: function () {
    return [autoprefixer];
  },
};

if (process.env.NODE_ENV === 'production') {
  module.exports.plugins.push(
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
      },
    }),
    new webpack.optimize.OccurrenceOrderPlugin(),
    new CompressionPlugin({ algorithm: 'zopfli' })
  );
}
<|endoftext|>


<commit_before>/**  @author Gilles Coomans <gilles.coomans@gmail.com> */

var utils = require('./utils'),
	Template = require('./template'),
	Virtual = require('./virtual'),
	Container = require('./container'),
	Context = require('./context');
//____________________________________________________ VIEW
var View = function View(opt) {
	opt = opt || {};
	if (opt.componentName)
		addComponent(opt.componentName, this);
	this.factory = opt.factory;
	Context.call(this, opt);
	Container.call(this, opt);
}
utils.mergeProto(Template.prototype, View.prototype);
utils.mergeProto(Context.prototype, View.prototype);
utils.mergeProto(Container.prototype, View.prototype);
View.prototype.done = function(fn) {
	fn.call(this, this, this.factory || (utils.isServer ? Virtual : document)); // apply directly toElement handler on this
	return this;
};
View.prototype.destroy = function() {
	Container.prototype.destroy.call(this);
	Context.prototype.destroy.call(this);
};
delete View.prototype['catch'];
delete View.prototype.call;
delete View.prototype.toElement;
delete View.prototype.id;
delete View.prototype.attr;
delete View.prototype.setClass;
delete View.prototype.visible;
delete View.prototype.css;
delete View.prototype.val;
delete View.prototype.contentEditable;

module.exports = View;
<commit_msg>add first global promises management<commit_after>/**  @author Gilles Coomans <gilles.coomans@gmail.com> */

var utils = require('./utils'),
	Template = require('./template'),
	Virtual = require('./virtual'),
	Container = require('./container'),
	Context = require('./context');
//____________________________________________________ VIEW
var View = function View(opt) {
	opt = opt || {};
	if (opt.componentName)
		addComponent(opt.componentName, this);
	this.factory = opt.factory;
	Context.call(this, opt);
	Container.call(this, opt);
	this.promises = [];
}
utils.mergeProto(Template.prototype, View.prototype);
utils.mergeProto(Context.prototype, View.prototype);
utils.mergeProto(Container.prototype, View.prototype);
View.prototype.done = function(fn) {
	fn.call(this, this, this.factory || (utils.isServer ? Virtual : document), this.promises); // apply directly toElement handler on this
	return this;
};
View.prototype.destroy = function() {
	Container.prototype.destroy.call(this);
	Context.prototype.destroy.call(this);
};
delete View.prototype['catch'];
delete View.prototype.call;
delete View.prototype.toElement;
delete View.prototype.id;
delete View.prototype.attr;
delete View.prototype.setClass;
delete View.prototype.visible;
delete View.prototype.css;
delete View.prototype.val;
delete View.prototype.contentEditable;

module.exports = View;
<|endoftext|>


<commit_before>!function() {
	var app = {};

	app.start = function() {
		setTimeout(function() {
			console.log('app started');
		});
	}

	alert('hello again');

	app.start();
}()<commit_msg>Remove eroneous alert<commit_after>!function() {
	var app = {};

	app.start = function() {
		setTimeout(function() {
			console.log('app started');
		});
	}

	app.start();
}()<|endoftext|>


<commit_before>/* global Promise */

'use strict';

var d3        = require('d3');
var _         = require('lodash');
var moment    = require('moment');

var coolgray  = require('../colors/coolgray');

var api       = require('../data/api');

var bullet    = require('../data/model/bullet');
var series    = require('../data/model/series');

var add       = require('../data/transform/add');
var color     = require('../data/transform/color');
var cumsum    = require('../data/transform/cumsum');
var each      = require('../data/transform/each');
var facet     = require('../data/transform/facet');
var map       = require('../data/transform/map');
var ratio     = require('../data/transform/ratio');
var sort      = require('../data/transform/sort');
var variables = require('../data/transform/variables');

var OFFICE = {
	1: 23,   // Nigeria
	2: 4404, // Afghanistan
	3: 128   // Pakistan
};

/**
 * Utility for filling in default ranges.
 *
 * Adds a default range property to each entry in the array. A stopgap for
 * indicators not currently supporting qualitative ranges.
 */
function rangeFactory(data) {
	if (data.hasOwnProperty('ranges')) {
		return;
	}

	data.ranges = [{
		name: 'bad',
		start: 0,
		end: 0.5
	}, {
		name: 'ok',
		start: 0.5,
		end: 0.85
	}, {
		name: 'good',
		start: 0.85,
		end: 1
	}];
}

function indicators(ids, opts) {
	function emptyPromise(fulfill) {
		fulfill({
			meta: {},
			objects: []
		});
	}

	// Create a copy of the options so that we can modify the query object
	var q = _.assign({}, opts);

	if (ids instanceof Array) {
		if (ids.length === 0) {
			return new Promise(emptyPromise);
		}

		q.indicator__in = ids.join(',');
	} else {
		if (typeof ids === 'undefined' || ids === null || ids === '') {
			return new Promise(emptyPromise);
		}

		q.indicator__in = ids;
	}

	return api.datapoints(q);
}

function objects(data) {
	return data.objects || data;
}

module.exports = {
	replace : true,
	template: require('./management.html'),

	data: function () {
		return {
			offices    : [],
			campaigns  : [],
			region     : null,
			start      : new Date(),
			cases      : {
				lines: [],
				domain: [1, 12],
				xFmt : function (d) {
					return moment(d, 'M').format('MMM');
				}
			},
			conversions: {
				lines: [],
				x    : d3.time.scale(),
				yFmt : d3.format('.0%')
			},
			capacity   : [{
				name: 'Soc. Mob. Coverage',
				indicators: []
			}, {
				name: 'IPC Skills',
				indicators: []
			}, {
				name: 'Network Size',
				indicators: [36, 35]
			}, {
				name: 'Training on Polio+',
				indicators: []
			}, {
				name: 'Local Vaccinators',
				indicators: []
			}, {
				name: 'Supervision',
				indicators: []
			}, {
				name: 'Female Vaccinators',
				indicators: [37, 38]
			}, {
				name: 'Timely Payment',
				indicators: [46, 36]
			}, {
				name: 'Female Mobilizers',
				indicators: [40, 36]
			}],
			polio     : [{
				name: 'Penta3 Coverage',
				indicators: [48, 47]
			}, {
				name: 'RI Knowledge',
				indicators: [50, 29]
			}, {
				name: 'RI Defaulters Tracking',
				indicators: []
			}, {
				name: 'Convergence Activities',
				indicators: []
			}, {
				name: 'RI No Stockouts',
				indicators: [53, 52],
			}],
			supply     : [{
				name: 'Delayed OPV Supply',
				indicators: [],
				ranges: [{
					name: 'bad',
					start: 0.5,
					end: 1
				}, {
					name: 'ok',
					start: 0.3,
					end: 0.5
				}, {
					name: 'good',
					start: 0,
					end: 0.3
				}]
			}, {
				name: 'OPV Wastage Rate',
				indicators: [],
				ranges: [{
					name: 'bad',
					start: 0.5,
					end: 1
				}, {
					name: 'ok',
					start: 0.3,
					end: 0.5
				}, {
					name: 'good',
					start: 0,
					end: 0.3
				}]
			}, {
				name: 'Cold Chain Function',
				indicators: []
			}, {
				name: 'Stock Reporting',
				indicators: []
			}],
			resources  : [{
				name: 'Funding',
				indicators: []
			}, {
				name: 'Human Resources',
				indicators: []
			}],
			microplans: []
		};
	},

	created: function () {
		var self  = this;

		// FIXME: Hack to fill out hard-coded bullet chart VMs
		this.capacity.forEach(rangeFactory);
		this.supply.forEach(rangeFactory);
		this.polio.forEach(rangeFactory);
		this.resources.forEach(rangeFactory);

		this.$on('selection-changed', function () {
			function isSelected(d) {
				return d.selected;
			}

			self.region = OFFICE[self.offices.filter(isSelected)[0].value];
			self.loadData();
		});

		api.office().done(function (data) {
			var offices = data.objects.map(function (o) {
				return {
					title   : o.name,
					value   : o.id,
					selected: false
				};
			});

			offices[0].selected = true;
			self.region = OFFICE[offices[0].value];
			self.offices = offices;

			api.campaign({ office: offices[0].value }).done(function (data) {
				self.$set('campaigns', data.objects.map(function (o) {
					var startDate = moment(o.start_date, 'YYYY-MM-DD');

					return {
						title   : startDate.format('MMM YYYY'),
						value   : o.start_date,
						sortVal : startDate.format('YYYYMMDD'),
						selected: false
					};
				}));

				self.campaigns[0].selected = true;

				self.loadData();
			});
		});
	},

	methods: {
		loadData: function () {
			// Curried function for setting a keypath on the VM that can be used as a
			// callback for when API calls complete.
			function set(keypath) {
				return function (data) {
					self.$set(keypath, data);
				};
			}

			function campaignStart(d) {
				return d.campaign.start_date;
			}

			function fetchBullets(keypath, q) {
				var section = self.$get(keypath);

				section.forEach(function (o, i) {
					if (o.indicators.length === 2) {
						indicators(o.indicators, q)
							.then(objects)
							.then(sort(campaignStart))
							.then(bullet(o.name, o.indicators[0], o.indicators[1], o.ranges))
							.done(function (data) {
								// FIXME: This is really redundant with the existing set
								// function, should just modify set to take a keypath and the
								// VM on which the keypath is set
								section.$set(i, data);
							});
					} else {
						o.value  = null;
						o.marker = null;
					}
				});
			}

			var self  = this;
			var start = moment(this.campaigns.filter(function (d) {
					return d.selected;
				})[0].value, 'YYYY-MM-DD');

			// Query parameters shared by all queries
			var q = {
				parent_region : self.region,
				campaign_start: start.clone().subtract(2, 'years').format('YYYY-MM-DD'),
				campaign_end  : start.format('YYYY-MM-DD')
			};

			console.log(q.campaign_start);

			// Polio Cases YTD
			indicators([69, 70, 159, 160, 161, 162], q)
				.then(objects)
				.then(add([69, 70, 159, 160, 161, 162]))
				.then(facet(function (d) { return d.campaign.start_date.getFullYear(); }))
				.then(map(sort(campaignStart)))
				.then(each(cumsum(
					function (d) { return d.value; },
					function (d, v) { d.value = v; return d; }
					)))
				.then(each(variables({
					x: function (d) { return d.campaign.start_date.getMonth() + 1; },
					y: function (d) { return d.value; }
				})))
				.then(map(series(function (d) {
					return d[0].campaign.start_date.getFullYear();
				})))
				.done(set('cases.lines'));

			// Immunity Gap
			indicators([], q).done(set('immunity'));

			// Missed Children
			indicators([20, 22, 23, 24, 55], q)
				.then(objects)
				.then(sort(campaignStart))
				.then(ratio([20, 22, 23, 24], 55))
				.then(each(variables({
					x: function (d) { return d.campaign.start_date; },
					y: function (d) { return d.value; }
				})))
				.then(map(function (data) {
					// The line chart expects an array of objects with a points property
					return { points: data };
				}))
				.then(each(color(coolgray)))
				.done(set('missed'));

			// Conversions
			indicators([25, 26], q)
				.then(objects)
				.then(sort(campaignStart))
				.then(ratio(26, 25))
				.then(each(variables({
					x: function (d) { return d.campaign.start_date; },
					y: function (d) { return 1 - d.value; }
				})))
				.then(map(function (data) {
					return { points: data };
				}))
				.done(set('conversions.lines'));

			// Microplans with social data
			indicators([27, 28], q)
				.then(objects)
				.then(sort(campaignStart))
				.then(function (data) {
					if (!data || data.length < 1) {
						return [];
					}

					var d          = data[data.length - 1];
					var indicators = _.indexBy(d.indicators, 'indicator');
					var microplans = indicators[27].value;
					var socialData = indicators[28].value;

					return [{
						value: socialData,
						color: coolgray[5]
					}, {
						value: microplans - socialData,
						color: coolgray[0]
					}];
				}).done(set('microplans'));

			q.campaign_start = start.clone().subtract(4, 'months').format('YYYY-MM-DD');

			console.log(q.campaign_start);

			fetchBullets('capacity', q);
			fetchBullets('supply', q);
			fetchBullets('polio', q);
			fetchBullets('resources', q);
		}
	},
};
<commit_msg>Update campaigns when the office changes.<commit_after>/* global Promise */

'use strict';

var d3        = require('d3');
var _         = require('lodash');
var moment    = require('moment');

var coolgray  = require('../colors/coolgray');

var api       = require('../data/api');

var bullet    = require('../data/model/bullet');
var series    = require('../data/model/series');

var add       = require('../data/transform/add');
var color     = require('../data/transform/color');
var cumsum    = require('../data/transform/cumsum');
var each      = require('../data/transform/each');
var facet     = require('../data/transform/facet');
var map       = require('../data/transform/map');
var ratio     = require('../data/transform/ratio');
var sort      = require('../data/transform/sort');
var variables = require('../data/transform/variables');

var OFFICE = {
	1: 23,   // Nigeria
	2: 4404, // Afghanistan
	3: 128   // Pakistan
};

/**
 * Utility for filling in default ranges.
 *
 * Adds a default range property to each entry in the array. A stopgap for
 * indicators not currently supporting qualitative ranges.
 */
function rangeFactory(data) {
	if (data.hasOwnProperty('ranges')) {
		return;
	}

	data.ranges = [{
		name: 'bad',
		start: 0,
		end: 0.5
	}, {
		name: 'ok',
		start: 0.5,
		end: 0.85
	}, {
		name: 'good',
		start: 0.85,
		end: 1
	}];
}

function indicators(ids, opts) {
	function emptyPromise(fulfill) {
		fulfill({
			meta: {},
			objects: []
		});
	}

	// Create a copy of the options so that we can modify the query object
	var q = _.assign({}, opts);

	if (ids instanceof Array) {
		if (ids.length === 0) {
			return new Promise(emptyPromise);
		}

		q.indicator__in = ids.join(',');
	} else {
		if (typeof ids === 'undefined' || ids === null || ids === '') {
			return new Promise(emptyPromise);
		}

		q.indicator__in = ids;
	}

	return api.datapoints(q);
}

function objects(data) {
	return data.objects || data;
}

module.exports = {
	replace : true,
	template: require('./management.html'),

	data: function () {
		return {
			offices    : [],
			campaigns  : [],
			region     : null,
			start      : new Date(),
			cases      : {
				lines: [],
				domain: [1, 12],
				xFmt : function (d) {
					return moment(d, 'M').format('MMM');
				}
			},
			conversions: {
				lines: [],
				x    : d3.time.scale(),
				yFmt : d3.format('.0%')
			},
			capacity   : [{
				name: 'Soc. Mob. Coverage',
				indicators: []
			}, {
				name: 'IPC Skills',
				indicators: []
			}, {
				name: 'Network Size',
				indicators: [36, 35]
			}, {
				name: 'Training on Polio+',
				indicators: []
			}, {
				name: 'Local Vaccinators',
				indicators: []
			}, {
				name: 'Supervision',
				indicators: []
			}, {
				name: 'Female Vaccinators',
				indicators: [37, 38]
			}, {
				name: 'Timely Payment',
				indicators: [46, 36]
			}, {
				name: 'Female Mobilizers',
				indicators: [40, 36]
			}],
			polio     : [{
				name: 'Penta3 Coverage',
				indicators: [48, 47]
			}, {
				name: 'RI Knowledge',
				indicators: [50, 29]
			}, {
				name: 'RI Defaulters Tracking',
				indicators: []
			}, {
				name: 'Convergence Activities',
				indicators: []
			}, {
				name: 'RI No Stockouts',
				indicators: [53, 52],
			}],
			supply     : [{
				name: 'Delayed OPV Supply',
				indicators: [],
				ranges: [{
					name: 'bad',
					start: 0.5,
					end: 1
				}, {
					name: 'ok',
					start: 0.3,
					end: 0.5
				}, {
					name: 'good',
					start: 0,
					end: 0.3
				}]
			}, {
				name: 'OPV Wastage Rate',
				indicators: [],
				ranges: [{
					name: 'bad',
					start: 0.5,
					end: 1
				}, {
					name: 'ok',
					start: 0.3,
					end: 0.5
				}, {
					name: 'good',
					start: 0,
					end: 0.3
				}]
			}, {
				name: 'Cold Chain Function',
				indicators: []
			}, {
				name: 'Stock Reporting',
				indicators: []
			}],
			resources  : [{
				name: 'Funding',
				indicators: []
			}, {
				name: 'Human Resources',
				indicators: []
			}],
			microplans: []
		};
	},

	created: function () {
		var self  = this;

		// FIXME: Hack to fill out hard-coded bullet chart VMs
		this.capacity.forEach(rangeFactory);
		this.supply.forEach(rangeFactory);
		this.polio.forEach(rangeFactory);
		this.resources.forEach(rangeFactory);

		this.$on('selection-changed', function () {
			function isSelected(d) {
				return d.selected;
			}

			var office = self.offices.filter(isSelected)[0].value;
			var region = OFFICE[office];

			if (region !== self.region) {
				self.region = region;
				api.campaign({ office: office }).done(self.loadCampaigns);
			} else {
				self.loadData();
			}
		});

		api.office().done(function (data) {
			var offices = data.objects.map(function (o) {
				return {
					title   : o.name,
					value   : o.id,
					selected: false
				};
			});

			offices[0].selected = true;
			self.region = OFFICE[offices[0].value];
			self.offices = offices;

			api.campaign({ office: offices[0].value }).done(self.loadCampaigns);
		});
	},

	methods: {
		loadCampaigns: function (data) {
			this.campaigns = data.objects.map(function (o) {
				var startDate = moment(o.start_date, 'YYYY-MM-DD');

				return {
					title   : startDate.format('MMM YYYY'),
					value   : o.start_date,
					sortVal : startDate.format('YYYYMMDD'),
					selected: false
				};
			});

			this.campaigns[0].selected = true;

			this.loadData();
		},

		loadData: function () {
			// Curried function for setting a keypath on the VM that can be used as a
			// callback for when API calls complete.
			function set(keypath) {
				return function (data) {
					self.$set(keypath, data);
				};
			}

			function campaignStart(d) {
				return d.campaign.start_date;
			}

			function fetchBullets(keypath, q) {
				var section = self.$get(keypath);

				section.forEach(function (o, i) {
					if (o.indicators.length === 2) {
						indicators(o.indicators, q)
							.then(objects)
							.then(sort(campaignStart))
							.then(bullet(o.name, o.indicators[0], o.indicators[1], o.ranges))
							.done(function (data) {
								// FIXME: This is really redundant with the existing set
								// function, should just modify set to take a keypath and the
								// VM on which the keypath is set
								section.$set(i, data);
							});
					} else {
						o.value  = null;
						o.marker = null;
					}
				});
			}

			var self  = this;
			var start = moment(this.campaigns.filter(function (d) {
					return d.selected;
				})[0].value, 'YYYY-MM-DD');

			// Query parameters shared by all queries
			var q = {
				parent_region : self.region,
				campaign_start: start.clone().subtract(2, 'years').format('YYYY-MM-DD'),
				campaign_end  : start.format('YYYY-MM-DD')
			};

			// Polio Cases YTD
			indicators([69, 70, 159, 160, 161, 162], q)
				.then(objects)
				.then(add([69, 70, 159, 160, 161, 162]))
				.then(facet(function (d) { return d.campaign.start_date.getFullYear(); }))
				.then(map(sort(campaignStart)))
				.then(each(cumsum(
					function (d) { return d.value; },
					function (d, v) { d.value = v; return d; }
					)))
				.then(each(variables({
					x: function (d) { return d.campaign.start_date.getMonth() + 1; },
					y: function (d) { return d.value; }
				})))
				.then(map(series(function (d) {
					return d[0].campaign.start_date.getFullYear();
				})))
				.done(set('cases.lines'));

			// Immunity Gap
			indicators([], q).done(set('immunity'));

			// Missed Children
			indicators([20, 22, 23, 24, 55], q)
				.then(objects)
				.then(sort(campaignStart))
				.then(ratio([20, 22, 23, 24], 55))
				.then(each(variables({
					x: function (d) { return d.campaign.start_date; },
					y: function (d) { return d.value; }
				})))
				.then(map(function (data) {
					// The line chart expects an array of objects with a points property
					return { points: data };
				}))
				.then(each(color(coolgray)))
				.done(set('missed'));

			// Conversions
			indicators([25, 26], q)
				.then(objects)
				.then(sort(campaignStart))
				.then(ratio(26, 25))
				.then(each(variables({
					x: function (d) { return d.campaign.start_date; },
					y: function (d) { return 1 - d.value; }
				})))
				.then(map(function (data) {
					return { points: data };
				}))
				.done(set('conversions.lines'));

			// Microplans with social data
			indicators([27, 28], q)
				.then(objects)
				.then(sort(campaignStart))
				.then(function (data) {
					if (!data || data.length < 1) {
						return [];
					}

					var d          = data[data.length - 1];
					var indicators = _.indexBy(d.indicators, 'indicator');
					var microplans = indicators[27].value;
					var socialData = indicators[28].value;

					return [{
						value: socialData,
						color: coolgray[5]
					}, {
						value: microplans - socialData,
						color: coolgray[0]
					}];
				}).done(set('microplans'));

			q.campaign_start = start.clone().subtract(4, 'months').format('YYYY-MM-DD');

			fetchBullets('capacity', q);
			fetchBullets('supply', q);
			fetchBullets('polio', q);
			fetchBullets('resources', q);
		}
	},
};
<|endoftext|>


<commit_before>var global = require('../../global');

module.exports = function(unitReceiptNote) {

    var items = [].concat.apply([], unitReceiptNote.items);

    var iso = "FM.FP-GB-15-005/R2";
    var number = unitReceiptNote.no;

    var locale = global.config.locale;

    var moment = require('moment');
    moment.locale(locale.name);

    var header = [{
        columns: [{
            alignment: "center",
            text: 'BON PENERIMAAN BARANG',
            style: ['size10', 'bold']
        },
        {
            columns: [{
                width: '*',
                stack: [{
                    text: 'PT DAN LIRIS',
                    style: ['size15', 'bold']
                }, {
                    text: 'BANARAN SUKOHARJO',
                    style: ['size09']
                }]
            }]

        },
        {
            columns: [{
                width: '*',
                stack: [{
                    alignment: "right",
                    text: ' ',
                    style: ['size08', 'bold']
                }, {
                    alignment: "right",
                    text: iso,
                    style: ['size08', 'bold']
                }]
            }]

        }]
    }];

    var subHeader = [{
        columns: [
            {
                width: '40%',
                columns: [{
                    width: '35%',
                    stack: ['Tanggal', 'Diterima dari']
                }, {
                    width: '5%',
                    stack: [':', ':']
                }, {
                    width: '*',
                    stack: [`${moment(unitReceiptNote.date).format(locale.date.format)}`, unitReceiptNote.supplier.name]
                }],
                style: ['size08']

            },
            {
                width: '30%',
                text: ''
            },
            {
                width: '30%',
                columns: [{
                    width: '25%',
                    stack: ['Bagian', 'No.']
                }, {
                    width: '5%',
                    stack: [':', ':']
                }, {
                    width: '*',
                    stack: [unitReceiptNote.unit.subDivision, unitReceiptNote.no]
                }],
                style: ['size08']
            }
        ]
    }, '\n'];

    var line = [{
        canvas: [{
            type: 'line',
            x1: 0,
            y1: 5,
            x2: 378,
            y2: 5,
            lineWidth: 0.5
        }
        ]
    }, '\n'];

    var thead = [{
        text: 'No.',
        style: 'tableHeader'
    }, {
        text: 'Nama barang',
        style: 'tableHeader'
    }, {
        text: 'Jumlah',
        style: 'tableHeader'
    }, {
        text: 'Satuan',
        style: 'tableHeader'
    }, {
        text: 'Keterangan',
        style: 'tableHeader'
    }];

    var tbody = items.map(function(item, index) {
        return [{
            text: (index + 1).toString() || '',
            style: ['size07', 'center']
        }, {
            text: item.product.code + " - " + item.product.name,
            style: ['size07', 'left']
        }, {
            text: parseFloat(item.deliveredQuantity).toLocaleString(locale, locale.decimal),
            style: ['size07', 'center']
        }, {
            text: item.deliveredUom.unit,
            style: ['size07', 'center']
        }, {
            text: item.remark || '',
            style: ['size07', 'left']
        }];
    });

    tbody = tbody.length > 0 ? tbody : [
        [{
            text: "tidak ada barang",
            style: ['size08', 'center'],
            colSpan: 5
        }, "", "", "", ""]
    ];

    var table = [{
        table: {
            widths: ['5%', '40%', '20%', '10%', '25%'],
            headerRows: 1,
            body: [].concat([thead], tbody)
        }
    }];

    var footer = [
        '\n', {
            stack: [{
                text: `Sukoharjo, ${moment(unitReceiptNote.date).format(locale.date.format)}`,
                alignment: "right"
            }, {
                columns: [{
                    width: '35%',
                    stack: ['Mengetahui\n\n\n\n\n', '(_______________________)'],
                    style: 'center'
                }, {
                    width: '30%',
                    text: ''
                }, {
                    width: '35%',
                    stack: ['Yang Menerima\n\n\n\n\n', '(_______________________)'],
                    style: 'center'
                },]
            }
            ],
            style: ['size08']
        }
    ];

    var dd = {
        pageSize: 'A6',
        pageOrientation: 'landscape',
        pageMargins: 20,
        content: [].concat(header, line, subHeader, table, footer),
        styles: {
            size06: {
                fontSize: 6
            },
            size07: {
                fontSize: 7
            },
            size08: {
                fontSize: 8
            },
            size09: {
                fontSize: 9
            },
            size10: {
                fontSize: 10
            },
            size15: {
                fontSize: 15
            },
            bold: {
                bold: true
            },
            center: {
                alignment: 'center'
            },
            left: {
                alignment: 'left'
            },
            right: {
                alignment: 'right'
            },
            justify: {
                alignment: 'justify'
            },
            tableHeader: {
                bold: true,
                fontSize: 8,
                color: 'black',
                alignment: 'center'
            }
        }
    };

    return dd;
}<commit_msg>fix iso unit receipt note<commit_after>var global = require('../../global');

module.exports = function(unitReceiptNote) {

    var items = [].concat.apply([], unitReceiptNote.items);

    var iso = "FM.PB-00-06-006";
    var number = unitReceiptNote.no;

    var locale = global.config.locale;

    var moment = require('moment');
    moment.locale(locale.name);

    var header = [{
        columns: [{
            alignment: "center",
            text: 'BON PENERIMAAN BARANG',
            style: ['size10', 'bold']
        },
        {
            columns: [{
                width: '*',
                stack: [{
                    text: 'PT DAN LIRIS',
                    style: ['size15', 'bold']
                }, {
                    text: 'BANARAN SUKOHARJO',
                    style: ['size09']
                }]
            }]

        },
        {
            columns: [{
                width: '*',
                stack: [{
                    alignment: "right",
                    text: ' ',
                    style: ['size08', 'bold']
                }, {
                    alignment: "right",
                    text: iso,
                    style: ['size08', 'bold']
                }]
            }]

        }]
    }];

    var subHeader = [{
        columns: [
            {
                width: '40%',
                columns: [{
                    width: '35%',
                    stack: ['Tanggal', 'Diterima dari']
                }, {
                    width: '5%',
                    stack: [':', ':']
                }, {
                    width: '*',
                    stack: [`${moment(unitReceiptNote.date).format(locale.date.format)}`, unitReceiptNote.supplier.name]
                }],
                style: ['size08']

            },
            {
                width: '30%',
                text: ''
            },
            {
                width: '30%',
                columns: [{
                    width: '25%',
                    stack: ['Bagian', 'No.']
                }, {
                    width: '5%',
                    stack: [':', ':']
                }, {
                    width: '*',
                    stack: [unitReceiptNote.unit.subDivision, unitReceiptNote.no]
                }],
                style: ['size08']
            }
        ]
    }, '\n'];

    var line = [{
        canvas: [{
            type: 'line',
            x1: 0,
            y1: 5,
            x2: 378,
            y2: 5,
            lineWidth: 0.5
        }
        ]
    }, '\n'];

    var thead = [{
        text: 'No.',
        style: 'tableHeader'
    }, {
        text: 'Nama barang',
        style: 'tableHeader'
    }, {
        text: 'Jumlah',
        style: 'tableHeader'
    }, {
        text: 'Satuan',
        style: 'tableHeader'
    }, {
        text: 'Keterangan',
        style: 'tableHeader'
    }];

    var tbody = items.map(function(item, index) {
        return [{
            text: (index + 1).toString() || '',
            style: ['size07', 'center']
        }, {
            text: item.product.code + " - " + item.product.name,
            style: ['size07', 'left']
        }, {
            text: parseFloat(item.deliveredQuantity).toLocaleString(locale, locale.decimal),
            style: ['size07', 'center']
        }, {
            text: item.deliveredUom.unit,
            style: ['size07', 'center']
        }, {
            text: item.remark || '',
            style: ['size07', 'left']
        }];
    });

    tbody = tbody.length > 0 ? tbody : [
        [{
            text: "tidak ada barang",
            style: ['size08', 'center'],
            colSpan: 5
        }, "", "", "", ""]
    ];

    var table = [{
        table: {
            widths: ['5%', '40%', '20%', '10%', '25%'],
            headerRows: 1,
            body: [].concat([thead], tbody)
        }
    }];

    var footer = [
        '\n', {
            stack: [{
                text: `Sukoharjo, ${moment(unitReceiptNote.date).format(locale.date.format)}`,
                alignment: "right"
            }, {
                columns: [{
                    width: '35%',
                    stack: ['Mengetahui\n\n\n\n\n', '(_______________________)'],
                    style: 'center'
                }, {
                    width: '30%',
                    text: ''
                }, {
                    width: '35%',
                    stack: ['Yang Menerima\n\n\n\n\n', '(_______________________)'],
                    style: 'center'
                },]
            }
            ],
            style: ['size08']
        }
    ];

    var dd = {
        pageSize: 'A6',
        pageOrientation: 'landscape',
        pageMargins: 20,
        content: [].concat(header, line, subHeader, table, footer),
        styles: {
            size06: {
                fontSize: 6
            },
            size07: {
                fontSize: 7
            },
            size08: {
                fontSize: 8
            },
            size09: {
                fontSize: 9
            },
            size10: {
                fontSize: 10
            },
            size15: {
                fontSize: 15
            },
            bold: {
                bold: true
            },
            center: {
                alignment: 'center'
            },
            left: {
                alignment: 'left'
            },
            right: {
                alignment: 'right'
            },
            justify: {
                alignment: 'justify'
            },
            tableHeader: {
                bold: true,
                fontSize: 8,
                color: 'black',
                alignment: 'center'
            }
        }
    };

    return dd;
}<|endoftext|>


<commit_before>'use strict';

var Base = require('base-methods');
var cloneStats = require('clone-stats');
var Stream = require('stream');
var Vinyl = require('vinyl');
var utils = require('./utils');

/**
 * Create an instance of `View`. Optionally pass a default object
 * to use.
 *
 * ```js
 * var view = new View({
 *   path: 'foo.html',
 *   content: '...'
 * });
 * ```
 * @param {Object} `view`
 * @api public
 */

function View(view) {
  this.isView = true;

  view = view || {};
  utils.syncContents(this, view.contents || view.content);
  this.options = view.options || {};
  this.locals = view.locals || {};
  this.data = view.data || {};

  this.define('_contents', null);
  this.define('_content', null);
  this.define('contents', {
    configurable: true,
    enumerable: false,
    get: function () {
      return this._contents;
    },
    set: function (val) {
      utils.syncContents(this, val);
    }
  });

  Vinyl.call(this, view);
  Base.call(this, view);

  for (var key in view) {
    var val = view[key];
    if (key === 'stat' && isObject(val) && val.mode) {
      this.set(key, cloneStats(val));
    } else if (val) {
      this.set(key, val);
    }
  }

  this.define('_dest', null);
  this.define('dest', {
    configurable: true,
    get: function () {
      return utils.destWrapper(this);
    },
    set: function (val) {
      this._dest = val;
    }
  });
}

/**
 * Inherit `Base` and `Vinyl`
 */

Base.extend(View);
Base.inherit(View, Vinyl);

/**
 * Run a plugin on the `view` instance.
 *
 * ```js
 * var view = new View({path: 'abc', contents: '...'})
 *   .use(require('foo'))
 *   .use(require('bar'))
 *   .use(require('baz'))
 * ```
 * @param {Function} `fn`
 * @return {Object}
 * @api public
 */

View.prototype.use = function(fn) {
  fn.call(this, this);
  this.emit('use');
  return this;
};

/**
 * Synchronously compile a view.
 *
 * ```js
 * var view = page.compile();
 * view.fn({title: 'A'});
 * view.fn({title: 'B'});
 * view.fn({title: 'C'});
 * ```
 *
 * @param  {Object} `locals` Optionally pass locals to the engine.
 * @return {Object} `View` instance, for chaining.
 * @api public
 */

View.prototype.compile = function (settings) {
  this.fn = utils.engine.compile(this.content, settings);
  return this;
};

/**
 * Asynchronously render a view.
 *
 * ```js
 * view.render({title: 'Home'}, function(err, res) {
 *   //=> view object with rendered `content`
 * });
 * ```
 * @param  {Object} `locals` Optionally pass locals to the engine.
 * @return {Object} `View` instance, for chaining.
 * @api public
 */

View.prototype.render = function (locals, cb) {
  if (typeof locals === 'function') return this.render({}, locals);
  if (typeof this.fn !== 'function') this.compile(locals);

  this.locals = utils.merge({}, this.locals, locals);
  var context = utils.merge({}, this.locals, this.data);
  for (var key in this) {
    if (this.hasOwnProperty(key)) {
      context[key] = context[key] || this[key];
    }
  }

  context.path = this.path;

  utils.engine.render(this.fn, context, function (err, res) {
    if (err) return cb(err);
    this.contents = new Buffer(res);
    cb(null, this);
  }.bind(this));
  return this;
};

/**
 * Re-decorate View methods after calling
 * vinyl's `.clone()` method.
 *
 * ```js
 * view.clone({deep: true}); // false by default
 * ```
 * @param  {Object} `options`
 * @return {Object} `view` Cloned instance
 * @api public
 */

View.prototype.clone = function (opts) {
  opts = opts || {};

  if (typeof opts === 'boolean') {
    opts = {deep: true};
  }

  opts.deep = opts.deep === true;
  opts.contents = opts.contents !== false;

  // clone the instance's view contents
  var contents = this.contents;
  if (this.isStream()) {
    contents = this.contents.pipe(new Stream.PassThrough());
    this.contents = this.contents.pipe(new Stream.PassThrough());
  } else if (this.isBuffer()) {
    contents = opts.contents ? cloneBuffer(this.contents) : this.contents;
  }

  var view = new View({
    cwd: this.cwd,
    base: this.base,
    stat: (this.stat ? cloneStats(this.stat) : null),
    history: this.history.slice(),
    contents: contents
  });

  var ignored = ['_contents', 'stat', 'history', 'path', 'base', 'cwd'];
  for (var key in this) {
    if (ignored.indexOf(key) < 0) {
      utils.define(view, key, opts.deep ? utils.clone(this[key], true) : this[key]);
    }
  }
  return view;
};

/**
 * Override the vinyl `inspect` method.
 */

View.prototype.inspect = function () {
  var inspect = [];

  // use relative path if possible
  var filepath = (this.base && this.path) ? this.relative : this.path;

  if (filepath) {
    inspect.push('"' + filepath + '"');
  }

  if (this.isBuffer()) {
    inspect.push(this.contents.inspect());
  }

  if (this.isStream()) {
    inspect.push(inspectStream(this.contents));
  }
  return '<View ' + inspect.join(' ') + '>';
};

/**
 *
 */

utils.define(View.prototype, 'content', {
  set: function(val) {
    utils.syncContents(this, val);
  },
  get: function() {
    return this._content;
  }
});

/**
 * Ensure that the `layout` property is set on a view.
 */

utils.define(View.prototype, 'layout', {
  set: function (val) {
    this.define('_layout', val);
  },
  get: function () {
    return this._layout || this.data.layout || this.locals.layout || this.options.layout;
  }
});

function inspectStream(stream) {
  var type = stream.constructor.name;
  return '<' + (type !== 'Stream' ? type + 'Stream>' : '');
}

function cloneBuffer(buffer) {
  var res = new Buffer(buffer.length);
  buffer.copy(res);
  return res;
}

function isObject(val) {
  return val && typeof val === 'object';
}

/**
 * Expose `View`
 */

module.exports = View;
<commit_msg>remove `dest` from view for now<commit_after>'use strict';

var Base = require('base-methods');
var cloneStats = require('clone-stats');
var Stream = require('stream');
var Vinyl = require('vinyl');
var utils = require('./utils');

/**
 * Create an instance of `View`. Optionally pass a default object
 * to use.
 *
 * ```js
 * var view = new View({
 *   path: 'foo.html',
 *   content: '...'
 * });
 * ```
 * @param {Object} `view`
 * @api public
 */

function View(view) {
  this.isView = true;

  view = view || {};
  utils.syncContents(this, view.contents || view.content);
  this.options = view.options || {};
  this.locals = view.locals || {};
  this.data = view.data || {};

  this.define('_contents', null);
  this.define('_content', null);
  this.define('contents', {
    configurable: true,
    enumerable: false,
    get: function () {
      return this._contents;
    },
    set: function (val) {
      utils.syncContents(this, val);
    }
  });

  Vinyl.call(this, view);
  Base.call(this, view);

  for (var key in view) {
    var val = view[key];
    if (key === 'stat' && isObject(val) && val.mode) {
      this.set(key, cloneStats(val));
    } else if (val) {
      this.set(key, val);
    }
  }
}

/**
 * Inherit `Base` and `Vinyl`
 */

Base.extend(View);
Base.inherit(View, Vinyl);

/**
 * Run a plugin on the `view` instance.
 *
 * ```js
 * var view = new View({path: 'abc', contents: '...'})
 *   .use(require('foo'))
 *   .use(require('bar'))
 *   .use(require('baz'))
 * ```
 * @param {Function} `fn`
 * @return {Object}
 * @api public
 */

View.prototype.use = function(fn) {
  fn.call(this, this);
  this.emit('use');
  return this;
};

/**
 * Synchronously compile a view.
 *
 * ```js
 * var view = page.compile();
 * view.fn({title: 'A'});
 * view.fn({title: 'B'});
 * view.fn({title: 'C'});
 * ```
 *
 * @param  {Object} `locals` Optionally pass locals to the engine.
 * @return {Object} `View` instance, for chaining.
 * @api public
 */

View.prototype.compile = function (settings) {
  this.fn = utils.engine.compile(this.content, settings);
  return this;
};

/**
 * Asynchronously render a view.
 *
 * ```js
 * view.render({title: 'Home'}, function(err, res) {
 *   //=> view object with rendered `content`
 * });
 * ```
 * @param  {Object} `locals` Optionally pass locals to the engine.
 * @return {Object} `View` instance, for chaining.
 * @api public
 */

View.prototype.render = function (locals, cb) {
  if (typeof locals === 'function') return this.render({}, locals);
  if (typeof this.fn !== 'function') this.compile(locals);

  this.locals = utils.merge({}, this.locals, locals);
  var context = utils.merge({}, this.locals, this.data);
  for (var key in this) {
    if (this.hasOwnProperty(key)) {
      context[key] = context[key] || this[key];
    }
  }

  context.path = this.path;

  utils.engine.render(this.fn, context, function (err, res) {
    if (err) return cb(err);
    this.contents = new Buffer(res);
    cb(null, this);
  }.bind(this));
  return this;
};

/**
 * Re-decorate View methods after calling
 * vinyl's `.clone()` method.
 *
 * ```js
 * view.clone({deep: true}); // false by default
 * ```
 * @param  {Object} `options`
 * @return {Object} `view` Cloned instance
 * @api public
 */

View.prototype.clone = function (opts) {
  opts = opts || {};

  if (typeof opts === 'boolean') {
    opts = {deep: true};
  }

  opts.deep = opts.deep === true;
  opts.contents = opts.contents !== false;

  // clone the instance's view contents
  var contents = this.contents;
  if (this.isStream()) {
    contents = this.contents.pipe(new Stream.PassThrough());
    this.contents = this.contents.pipe(new Stream.PassThrough());
  } else if (this.isBuffer()) {
    contents = opts.contents ? cloneBuffer(this.contents) : this.contents;
  }

  var view = new View({
    cwd: this.cwd,
    base: this.base,
    stat: (this.stat ? cloneStats(this.stat) : null),
    history: this.history.slice(),
    contents: contents
  });

  var ignored = ['_contents', 'stat', 'history', 'path', 'base', 'cwd'];
  for (var key in this) {
    if (ignored.indexOf(key) < 0) {
      utils.define(view, key, opts.deep ? utils.clone(this[key], true) : this[key]);
    }
  }
  return view;
};

/**
 * Override the vinyl `inspect` method.
 */

View.prototype.inspect = function () {
  var inspect = [];

  // use relative path if possible
  var filepath = (this.base && this.path) ? this.relative : this.path;

  if (filepath) {
    inspect.push('"' + filepath + '"');
  }

  if (this.isBuffer()) {
    inspect.push(this.contents.inspect());
  }

  if (this.isStream()) {
    inspect.push(inspectStream(this.contents));
  }
  return '<View ' + inspect.join(' ') + '>';
};

/**
 *
 */

utils.define(View.prototype, 'content', {
  set: function(val) {
    utils.syncContents(this, val);
  },
  get: function() {
    return this._content;
  }
});

/**
 * Ensure that the `layout` property is set on a view.
 */

utils.define(View.prototype, 'layout', {
  set: function (val) {
    this.define('_layout', val);
  },
  get: function () {
    return this._layout || this.data.layout || this.locals.layout || this.options.layout;
  }
});

function inspectStream(stream) {
  var type = stream.constructor.name;
  return '<' + (type !== 'Stream' ? type + 'Stream>' : '');
}

function cloneBuffer(buffer) {
  var res = new Buffer(buffer.length);
  buffer.copy(res);
  return res;
}

function isObject(val) {
  return val && typeof val === 'object';
}

/**
 * Expose `View`
 */

module.exports = View;
<|endoftext|>