<commit_before>odoo.define('website_product_configurator.config_form', function (require) {
    'use strict';

    var ajax = require('web.ajax');
    var time = require('web.time');

	$(document).ready(function () {
	    var config_form = $("#product_config_form");
        var datetimepickers_options = {
            calendarWeeks: true,
            icons : {
                time: 'fa fa-clock-o',
                date: 'fa fa-calendar',
                next: 'fa fa-chevron-right',
                previous: 'fa fa-chevron-left',
                up: 'fa fa-chevron-up',
                down: 'fa fa-chevron-down',
               },
            locale : moment.locale(),
            widgetParent: 'body',
            allowInputToggle: true,
            showClose: true,
            format : time.getLangDatetimeFormat(),
        };

        var datepickers_options = $.extend({}, datetimepickers_options, {format: time.getLangDateFormat()})

        config_form.find('.product_config_datetimepicker').datetimepicker(datetimepickers_options);
        config_form.find('.product_config_datepicker').datetimepicker(datepickers_options);

	 	/* Monitor input changes in the configuration form and call the backend onchange method*/
	 	config_form.find('.config_attribute').change(function(ev) {
			ajax.jsonRpc("/website_product_configurator/onchange", 'call', {
                form_values: config_form.serializeArray(),
                field_name: $(this)[0].name,
            }).then(function(data) {
                if (data.error) {
                    alert(data.error);
                };
                var values = data.value;
                var domains = data.domain;
                var open_cfg_step_lines = data.open_cfg_step_lines;

                _applyDomainOnValues(domains);
                _handleOpenSteps(open_cfg_step_lines)

            });
            _handleCustomAttribute(ev)
		});

        function _handleCustomAttribute(event) {
            var container = $(event.currentTarget).closest('.tab-pane.container');
            var attribute_id = $(event.currentTarget).attr('data-oe-id');
            var custom_value = container.find('.custom_config_value[data-oe-id=' + attribute_id + ']');
            var custom_value_container = custom_value.closest('.custom_field_container[data-oe-id=' + attribute_id + ']');
            if ($(event.currentTarget.selectedOptions[0]).hasClass('custom_config_attr_value') && custom_value_container.hasClass('hidden')) {
                custom_value_container.removeClass('hidden');
                var is_required = $(event.currentTarget).hasClass('required_config_attrib');
                if (is_required) {
                    custom_value.addClass('required_config_attrib');
                }
            } else if (!custom_value_container.hasClass('hidden')){
                custom_value_container.addClass('hidden');
                if (custom_value.hasClass('required_config_attrib')) {
                    custom_value.removeClass('required_config_attrib');
                }
            }
        }

        function _handleOpenSteps(open_cfg_step_lines) {
            var $steps = config_form.find('.config_step');
            _.each($steps, function (step) {
                step = $(step);
                var step_id = step.attr('data-step-id');
                if ($.inArray(step_id, open_cfg_step_lines) < 0) {
                    if (!step.hasClass('hidden')) {
                        step.addClass('hidden');
                    };
                } else {
                    if (step.hasClass('hidden')) {
                        step.removeClass('hidden');
                    };
                };
            });
        }

        function _applyDomainOnValues(domains) {
            _.each(domains, function (domain, attr_id) {
                var $selection = config_form.find('#' + attr_id);
                var $options = $selection.find('.config_attr_value');
                _.each($options, function (option) {
                    var condition = domain[0][1];
                    if (condition == 'in' || config_form == '=') {
                        if ($.inArray(parseInt(option.value), domain[0][2]) < 0) {
                            $(option).attr('disabled', true);
                            if (option.selected) {
                                option.selected = false;
                            };
                        } else {
                            $(option).attr('disabled', false);
                        };
                    } else if (condition == 'not in' || config_form == '!=') {
                        if ($.inArray(parseInt(option.value), domain[0][2]) < 0) {
                            $(option).attr('disabled', false);
                        } else {
                            $(option).attr('disabled', true);
                            if (option.selected) {
                                option.selected = false;
                            };
                        };
                    };
                });
            });
        }

        function _onChangeConfigStep(event, next_step) {
            var flag = _checkRequiredFields(event)
            var config_step_header = config_form.find('.nav.nav-tabs');
            var current_config_step = config_step_header.find('.nav-item.config_step.active').attr('data-step-id');
            if (flag) {
                return ajax.jsonRpc("/website_product_configurator/save_configuration", 'call', {
                    form_values: config_form.serializeArray(),
                    next_step: next_step || false,
                    current_step: current_config_step || false,
                }).then(function(data) {
                    if (data.error) {
                        alert(data.error);
                    };
                    return data;
                });
            } else {
                return false;
            }
        };

        function _displayTooltip(config_attribut, message) {
            $(config_attribut).focus();
            $(config_attribut).tooltip({
                title: message,
                placement: "bottom",
                trigger: "manual",
                delay: {show: 500, hide: 500},
                template: "

"
            }).tooltip('show');
            setTimeout(function(){
                $(config_attribut).tooltip('hide');
            }, 2000);
        };

        function _checkRequiredFields(event) {
            var active_step = config_form.find('.tab-content').find('.tab-pane.active.in');
            var config_attr = active_step.find('.form-control.required_config_attrib');
            var flag = true;
            for (var i = 0; i < config_attr.length; i++) {
               if (!config_attr[i].value) {
                    flag = false;
                    if (config_attr[i].tagName == 'SELECT') {
                        var message = "Please select an item in the list."
                    } else if (config_attr[i].tagName == 'INPUT') {
                        var message = "Please enter value."
                    }
                    _displayTooltip(config_attr[i], message);
                    break;
               };
            };
            return flag;
        };

        config_form.find('.config_step').click(function (event) {
            var next_step = event.currentTarget.getAttribute('data-step-id');
            var result = _onChangeConfigStep(event, next_step);
            if (!result) {
                event.preventDefault();
                event.stopPropagation();
            };
        });

        function _openNextStep(step) {
            var config_step_header = config_form.find('.nav.nav-tabs');
            var config_step = config_step_header.find('.nav-item.config_step.active');
            if (config_step.length) {
                config_step.removeClass('active');
            }
            var active_step = config_form.find('.tab-content').find('.tab-pane.active.in');
            active_step.removeClass('active in');

            var next_step = config_step_header.find('.nav-item.config_step[data-step-id=' + step + ']');
            if (next_step.length) {
                next_step.addClass('active');
                var selector = next_step.find('a:first-child').attr('href');
                var step_to_active = config_form.find('.tab-content').find(selector);
                step_to_active.addClass('active in');
            }
        };

        function addRequiredAttr(config_step) {
            config_step = config_form.find('.tab-content').find('tab-pane container[data-step-id=' + config_step + ']');
            _.each(config_step.find('.form-control.config_attribute'), function(attribute_field) {
                $(attribute_field).attr('required', true);
            });
        };

        config_form.submit(function (event) {
            event.preventDefault();
            event.stopPropagation();

            var result = _onChangeConfigStep(event);
            if (result) {
                result.then(function (data) {
                    if (data) {
                        if (data.next_step) {
                            _openNextStep(data.next_step);
                        };
                        if (data.redirect_url) {
                            window.location = data.redirect_url;
                        };
                    };
                });
            }
        });

        function _disableEnableAddRemoveQtyButton(quantity, max_val, min_val) {
            if (quantity >= max_val) {
                $('.js_add_qty').addClass('btn-disabled');
            } else if (quantity < max_val && $('.js_add_qty').hasClass('btn-disabled')) {
                $('.js_add_qty').removeClass('btn-disabled');
            }
            if (quantity <= min_val) {
                $('.js_remove_qty').addClass('btn-disabled');
            } else if (quantity > min_val && $('.js_remove_qty').hasClass('btn-disabled')) {
                $('.js_remove_qty').removeClass('btn-disabled');
            }
        }

        function _handleSppinerCustomValue(ev) {
            var current_target = $(ev.currentTarget);
            var container = current_target.closest('.custom_field_container');
            var custom_value = container.find('input.custom_config_value');
            var quantity = parseFloat(custom_value.val());
            var max_val = parseFloat(container.find('input.custom_config_value').attr('max'));
            var min_value = parseFloat(container.find('input.custom_config_value').attr('min'));
            if (isNaN(min_value)) {
                min_value = 0;
            }
            if (current_target.hasClass('js_add_qty')) {
                quantity = quantity + 1;
                custom_value.val(quantity);
                _disableEnableAddRemoveQtyButton(quantity ,max_val ,min_value);
            } else if (current_target.hasClass('js_remove_qty')) {
                quantity = quantity - 1;
                custom_value.val(quantity);
                _disableEnableAddRemoveQtyButton(quantity ,max_val ,min_value);
            }
            return {'quantity': quantity, 'max_val': max_val, 'min_val': min_value}
        }

        $('.custom_config_value').change(function(ev) {
            var result = _handleSppinerCustomValue(ev);
            var container = $(ev.currentTarget).closest('.custom_field_container');
            var custom_value = container.find('input.custom_config_value');
            var old_value = parseFloat(custom_value.attr('data-old-value'));
            if (isNaN(old_value)) {
                old_value = '';
            }
            var quantity = result.quantity;
            if (result.quantity > result.max_val) {
                alert("Maximum allowed value is" + " " +result.max_val);
                custom_value.val(old_value);
                quantity = parseFloat(old_value);
            }
            else if (result.quantity < result.min_val) {
                alert("Minimum allowed value is" + " " +result.min_val);
                custom_value.val(old_value);
                quantity = parseFloat(old_value);
            }
            else {
                parseFloat(custom_value.attr('data-old-value', quantity));
            }
            _disableEnableAddRemoveQtyButton(quantity ,result.max_val ,result.min_val)
        });

        $('.js_add_qty').on('click', function(ev) {
            var result = _handleSppinerCustomValue(ev);
        });

        $('.js_remove_qty').on('click', function(ev) {
            var result = _handleSppinerCustomValue(ev);
        });
	});

})<commit_msg>[ADD][#T2720]website_product_configurator:solved the issue of when no value in input then it was taken Nan and when old value is Nan then it will consider blank string<commit_after>odoo.define('website_product_configurator.config_form', function (require) {
    'use strict';

    var ajax = require('web.ajax');
    var time = require('web.time');

	$(document).ready(function () {
	    var config_form = $("#product_config_form");
        var datetimepickers_options = {
            calendarWeeks: true,
            icons : {
                time: 'fa fa-clock-o',
                date: 'fa fa-calendar',
                next: 'fa fa-chevron-right',
                previous: 'fa fa-chevron-left',
                up: 'fa fa-chevron-up',
                down: 'fa fa-chevron-down',
               },
            locale : moment.locale(),
            widgetParent: 'body',
            allowInputToggle: true,
            showClose: true,
            format : time.getLangDatetimeFormat(),
        };

        var datepickers_options = $.extend({}, datetimepickers_options, {format: time.getLangDateFormat()})

        config_form.find('.product_config_datetimepicker').datetimepicker(datetimepickers_options);
        config_form.find('.product_config_datepicker').datetimepicker(datepickers_options);

	 	/* Monitor input changes in the configuration form and call the backend onchange method*/
	 	config_form.find('.config_attribute').change(function(ev) {
			ajax.jsonRpc("/website_product_configurator/onchange", 'call', {
                form_values: config_form.serializeArray(),
                field_name: $(this)[0].name,
            }).then(function(data) {
                if (data.error) {
                    alert(data.error);
                };
                var values = data.value;
                var domains = data.domain;
                var open_cfg_step_lines = data.open_cfg_step_lines;

                _applyDomainOnValues(domains);
                _handleOpenSteps(open_cfg_step_lines)

            });
            _handleCustomAttribute(ev)
		});

        function _handleCustomAttribute(event) {
            var container = $(event.currentTarget).closest('.tab-pane.container');
            var attribute_id = $(event.currentTarget).attr('data-oe-id');
            var custom_value = container.find('.custom_config_value[data-oe-id=' + attribute_id + ']');
            var custom_value_container = custom_value.closest('.custom_field_container[data-oe-id=' + attribute_id + ']');
            if ($(event.currentTarget.selectedOptions[0]).hasClass('custom_config_attr_value') && custom_value_container.hasClass('hidden')) {
                custom_value_container.removeClass('hidden');
                var is_required = $(event.currentTarget).hasClass('required_config_attrib');
                if (is_required) {
                    custom_value.addClass('required_config_attrib');
                }
            } else if (!custom_value_container.hasClass('hidden')){
                custom_value_container.addClass('hidden');
                if (custom_value.hasClass('required_config_attrib')) {
                    custom_value.removeClass('required_config_attrib');
                }
            }
        }

        function _handleOpenSteps(open_cfg_step_lines) {
            var $steps = config_form.find('.config_step');
            _.each($steps, function (step) {
                step = $(step);
                var step_id = step.attr('data-step-id');
                if ($.inArray(step_id, open_cfg_step_lines) < 0) {
                    if (!step.hasClass('hidden')) {
                        step.addClass('hidden');
                    };
                } else {
                    if (step.hasClass('hidden')) {
                        step.removeClass('hidden');
                    };
                };
            });
        }

        function _applyDomainOnValues(domains) {
            _.each(domains, function (domain, attr_id) {
                var $selection = config_form.find('#' + attr_id);
                var $options = $selection.find('.config_attr_value');
                _.each($options, function (option) {
                    var condition = domain[0][1];
                    if (condition == 'in' || config_form == '=') {
                        if ($.inArray(parseInt(option.value), domain[0][2]) < 0) {
                            $(option).attr('disabled', true);
                            if (option.selected) {
                                option.selected = false;
                            };
                        } else {
                            $(option).attr('disabled', false);
                        };
                    } else if (condition == 'not in' || config_form == '!=') {
                        if ($.inArray(parseInt(option.value), domain[0][2]) < 0) {
                            $(option).attr('disabled', false);
                        } else {
                            $(option).attr('disabled', true);
                            if (option.selected) {
                                option.selected = false;
                            };
                        };
                    };
                });
            });
        }

        function _onChangeConfigStep(event, next_step) {
            var flag = _checkRequiredFields(event)
            var config_step_header = config_form.find('.nav.nav-tabs');
            var current_config_step = config_step_header.find('.nav-item.config_step.active').attr('data-step-id');
            if (flag) {
                return ajax.jsonRpc("/website_product_configurator/save_configuration", 'call', {
                    form_values: config_form.serializeArray(),
                    next_step: next_step || false,
                    current_step: current_config_step || false,
                }).then(function(data) {
                    if (data.error) {
                        alert(data.error);
                    };
                    return data;
                });
            } else {
                return false;
            }
        };

        function _displayTooltip(config_attribut, message) {
            $(config_attribut).focus();
            $(config_attribut).tooltip({
                title: message,
                placement: "bottom",
                trigger: "manual",
                delay: {show: 500, hide: 500},
                template: "

"
            }).tooltip('show');
            setTimeout(function(){
                $(config_attribut).tooltip('hide');
            }, 2000);
        };

        function _checkRequiredFields(event) {
            var active_step = config_form.find('.tab-content').find('.tab-pane.active.in');
            var config_attr = active_step.find('.form-control.required_config_attrib');
            var flag = true;
            for (var i = 0; i < config_attr.length; i++) {
               if (!config_attr[i].value) {
                    flag = false;
                    if (config_attr[i].tagName == 'SELECT') {
                        var message = "Please select an item in the list."
                    } else if (config_attr[i].tagName == 'INPUT') {
                        var message = "Please enter value."
                    }
                    _displayTooltip(config_attr[i], message);
                    break;
               };
            };
            return flag;
        };

        config_form.find('.config_step').click(function (event) {
            var next_step = event.currentTarget.getAttribute('data-step-id');
            var result = _onChangeConfigStep(event, next_step);
            if (!result) {
                event.preventDefault();
                event.stopPropagation();
            };
        });

        function _openNextStep(step) {
            var config_step_header = config_form.find('.nav.nav-tabs');
            var config_step = config_step_header.find('.nav-item.config_step.active');
            if (config_step.length) {
                config_step.removeClass('active');
            }
            var active_step = config_form.find('.tab-content').find('.tab-pane.active.in');
            active_step.removeClass('active in');

            var next_step = config_step_header.find('.nav-item.config_step[data-step-id=' + step + ']');
            if (next_step.length) {
                next_step.addClass('active');
                var selector = next_step.find('a:first-child').attr('href');
                var step_to_active = config_form.find('.tab-content').find(selector);
                step_to_active.addClass('active in');
            }
        };

        function addRequiredAttr(config_step) {
            config_step = config_form.find('.tab-content').find('tab-pane container[data-step-id=' + config_step + ']');
            _.each(config_step.find('.form-control.config_attribute'), function(attribute_field) {
                $(attribute_field).attr('required', true);
            });
        };

        config_form.submit(function (event) {
            event.preventDefault();
            event.stopPropagation();

            var result = _onChangeConfigStep(event);
            if (result) {
                result.then(function (data) {
                    if (data) {
                        if (data.next_step) {
                            _openNextStep(data.next_step);
                        };
                        if (data.redirect_url) {
                            window.location = data.redirect_url;
                        };
                    };
                });
            }
        });

        function _disableEnableAddRemoveQtyButton(quantity, max_val, min_val) {
            if (quantity >= max_val) {
                $('.js_add_qty').addClass('btn-disabled');
            } else if (quantity < max_val && $('.js_add_qty').hasClass('btn-disabled')) {
                $('.js_add_qty').removeClass('btn-disabled');
            }
            if (quantity <= min_val) {
                $('.js_remove_qty').addClass('btn-disabled');
            } else if (quantity > min_val && $('.js_remove_qty').hasClass('btn-disabled')) {
                $('.js_remove_qty').removeClass('btn-disabled');
            }
        }

        function _handleSppinerCustomValue(ev) {
            var current_target = $(ev.currentTarget);
            var container = current_target.closest('.custom_field_container');
            var custom_value = container.find('input.custom_config_value');
            var quantity = parseFloat(custom_value.val());
            var max_val = parseFloat(container.find('input.custom_config_value').attr('max'));
            var min_value = parseFloat(container.find('input.custom_config_value').attr('min'));
            if (isNaN(min_value)) {
                min_value = 0;
            }
            if (isNaN(quantity)) {
                quantity = min_value;
            }
            if (current_target.hasClass('js_add_qty')) {
                quantity = quantity + 1;
                custom_value.val(quantity);
                _disableEnableAddRemoveQtyButton(quantity ,max_val ,min_value);
            } else if (current_target.hasClass('js_remove_qty')) {
                quantity = quantity - 1;
                custom_value.val(quantity);
                _disableEnableAddRemoveQtyButton(quantity ,max_val ,min_value);
            }
            return {'quantity': quantity, 'max_val': max_val, 'min_val': min_value}
        }

        $('.custom_config_value').change(function(ev) {
            var result = _handleSppinerCustomValue(ev);
            var container = $(ev.currentTarget).closest('.custom_field_container');
            var custom_value = container.find('input.custom_config_value');
            var old_value = parseFloat(custom_value.attr('data-old-value'));
            if (isNaN(old_value)) {
                old_value = '';
            }
            var quantity = result.quantity;
            if (result.quantity > result.max_val) {
                alert("Maximum allowed value is" + " " +result.max_val);
                custom_value.val(old_value);
                quantity = parseFloat(old_value);
            }
            else if (result.quantity < result.min_val) {
                alert("Minimum allowed value is" + " " +result.min_val);
                custom_value.val(old_value);
                quantity = parseFloat(old_value);
            }
            else {
                parseFloat(custom_value.attr('data-old-value', quantity));
            }
            _disableEnableAddRemoveQtyButton(quantity ,result.max_val ,result.min_val)
        });

        $('.js_add_qty').on('click', function(ev) {
            var result = _handleSppinerCustomValue(ev);
        });

        $('.js_remove_qty').on('click', function(ev) {
            var result = _handleSppinerCustomValue(ev);
        });
	});

})<|endoftext|>


<commit_before>import React, {Component} from 'react';

import Tab from 'dist/Tab';
import Widget from 'dist/Widget';
import WidgetHeader from 'dist/WidgetHeader';

import PropTypeDescTable from '../PropTypeDescTable';
import TabDoc from 'assets/propTypes/Tab.json';

import 'sass/containers/app/modules/layout/TabExamples.scss';

export default class TabExamples extends Component {

    constructor(props) {

        super(props);

        this.activeHandle = this::this.activeHandle;

    }

    activeHandle(tab) {
        alert(`${tab.value} activated.`);
    }

    render() {
        return (

Tabs

                    Tabs make it easy to explore and switch between different views or functional aspects
                    of an app or to browse categorized data sets.

Examples

                <Widget>

                    <WidgetHeader className="example-header" title="Full Width Tabs Example"/>

                                    A simple example of Tabs. The third tab demonstrates the onActive property of Tab.

                                <Tab tabs={[{
                                    value: 'Tab 1',
                                    renderer:

Tab 1

                                }, {
                                    value: 'Tab 2',
                                    renderer:

Tab 2

                                }, {
                                    value: 'onActive',
                                    renderer:

onActive

,
                                    onActive: this.activeHandle
                                }, {
                                    value: 'Disabled',
                                    disabled: true
                                }]}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="Tabs Example"/>

                                    Tabs use full container width by default.Set the isTabFullWidth property to false
                                    for partial width.

                                <Tab tabs={[{
                                    value: 'Tab 1',
                                    renderer:

Tab 1

                                }, {
                                    value: 'Tab 2',
                                    renderer:

Tab 2

                                }, {
                                    value: 'onActive',
                                    renderer:

onActive

,
                                    onActive: this.activeHandle
                                }, {
                                    value: 'Disabled',
                                    disabled: true
                                }]}
                                     isTabFullWidth={false}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="Tabs Example"/>

                                    Tabs without icons by default.Set the iconCls property for left icons.

                                <Tab tabs={[{
                                    value: 'Bicycle',
                                    iconCls: 'fa fa-bicycle',
                                    renderer:

Bicycle

                                }, {
                                    value: 'Taxi',
                                    iconCls: 'fa fa-taxi',
                                    renderer:

Taxi

                                }, {
                                    value: 'Plane',
                                    iconCls: 'fa fa-plane',
                                    renderer:

Plane

,
                                    onActive: this.activeHandle
                                }, {
                                    value: 'Rocket',
                                    iconCls: 'fa fa-rocket',
                                    disabled: true
                                }]}
                                     isTabFullWidth={false}/>

                </Widget>

Properties

                <PropTypeDescTable data={TabDoc}/>

        );
    }
};<commit_msg>update Tab examples<commit_after>import React, {Component} from 'react';

import Tab from 'dist/Tab';
import Widget from 'dist/Widget';
import WidgetHeader from 'dist/WidgetHeader';

import PropTypeDescTable from '../PropTypeDescTable';
import TabDoc from 'assets/propTypes/Tab.json';

import 'sass/containers/app/modules/layout/TabExamples.scss';

export default class TabExamples extends Component {

    constructor(props) {

        super(props);

        this.activeHandle = this::this.activeHandle;

    }

    activeHandle(tab) {
        alert(`${tab.value} activated.`);
    }

    render() {
        return (

Tabs

                    Tabs make it easy to explore and switch between different views or functional aspects
                    of an app or to browse categorized data sets.

Examples

                <Widget>

                    <WidgetHeader className="example-header" title="Full Width Tabs Example"/>

                                    A simple example of Tabs. The third tab demonstrates the onActive property of Tab.

                                <Tab tabs={[{
                                    value: 'Tab 1',
                                    renderer:

Tab 1

                                }, {
                                    value: 'Tab 2',
                                    renderer:

Tab 2

                                }, {
                                    value: 'onActive',
                                    renderer:

onActive

,
                                    onActive: this.activeHandle
                                }, {
                                    value: 'Disabled',
                                    disabled: true
                                }]}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="Tabs Example"/>

                                    Tabs use full container width by default.Set the isTabFullWidth property to false
                                    for partial width.

                                <Tab tabs={[{
                                    value: 'Tab 1',
                                    renderer:

Tab 1

                                }, {
                                    value: 'Tab 2',
                                    renderer:

Tab 2

                                }, {
                                    value: 'onActive',
                                    renderer:

onActive

,
                                    onActive: this.activeHandle
                                }, {
                                    value: 'Disabled',
                                    disabled: true
                                }]}
                                     isTabFullWidth={false}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="Tabs Example"/>

                                    Tabs without icons by default.Set the iconCls property for left icons.

                                <Tab tabs={[{
                                    value: 'Bicycle',
                                    iconCls: 'fa fa-bicycle',
                                    renderer:

Bicycle

                                }, {
                                    value: 'Taxi',
                                    iconCls: 'fa fa-taxi',
                                    renderer:

Taxi

                                }, {
                                    value: 'Plane',
                                    iconCls: 'fa fa-plane',
                                    renderer:

Plane

                                }, {
                                    value: 'Rocket',
                                    iconCls: 'fa fa-rocket',
                                    renderer:

Rocket

                                }]}
                                     isTabFullWidth={false}/>

                </Widget>

Properties

                <PropTypeDescTable data={TabDoc}/>

        );
    }
};<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import SpellIcon from 'common/SpellIcon';
import { formatNumber, formatPercentage } from 'common/format';
import Toggle from 'react-toggle';
import ReactTooltip from 'react-tooltip';

class HealingEfficiencyBreakdown extends React.Component {
  static propTypes = {
    tracker: PropTypes.object.isRequired,
  };

  constructor() {
    super();
    this.state = {
      showHealing: true,
      showDamage: false,
      showPercentages: true,
    };
  }

  Table = (props) => {
    const { tracker } = props;
    const spellDetails = tracker.spellDetails;

    const detailsArray = Object.keys(spellDetails).map(function (key) {
      return spellDetails[key];
    });
    detailsArray.sort((a, b) => {
      if (a.healingDone  b.healingDone) {
        return -1;
      }
      else {
        if (a.damageDone  b.damageDone) {
          return -1;
        }
      }
      return 0;
    });

    const spellRows = detailsArray.map((value => {
      if (value.casts > 0) {
        return this.SpellRow(value);
      }
      return null;
    }));

    return spellRows;
  };

  SpellRow = (spellDetail) => {
    const hasHealing = spellDetail.healingDone;
    const hasOverhealing = spellDetail.healingDone > 0 || spellDetail.overhealingDone > 0;
    const hasDamage = spellDetail.damageDone > 0;

    return (

          <SpellIcon id={spellDetail.spell.id} /> {spellDetail.spell.name}

        {spellDetail.casts} ({spellDetail.healingHits + spellDetail.damageHits})

          {formatNumber(spellDetail.manaSpent)}
          {this.state.showPercentages ? ' (' + formatPercentage(spellDetail.manaPercentSpent) + '%)' : ''}

        {this.state.showHealing &&
        <>

            {hasHealing ? formatNumber(spellDetail.healingDone) : '-'}
            {hasHealing && this.state.showPercentages ? ' (' + formatPercentage(spellDetail.percentHealingDone) + '%)' : ''}

            {hasOverhealing ? formatNumber(spellDetail.overhealingDone) : '-'}
            {hasOverhealing && this.state.showPercentages ? ' (' + formatPercentage(spellDetail.percentOverhealingDone) + '%)' : ''}

          {hasHealing ? formatNumber(spellDetail.hpm) : '-'}
          {hasHealing ? formatNumber(spellDetail.healingPerTimeSpentCasting * 1000) : '-'}
        </>
        }
        {this.state.showDamage &&
        <>

            {hasDamage ? formatNumber(spellDetail.damageDone) : '-'}
            {hasDamage && this.state.showPercentages ? ' (' + formatPercentage(spellDetail.percentDamageDone) + '%)' : ''}

          {hasDamage ? formatNumber(spellDetail.dpm) : '-'}
          {hasDamage ? formatNumber(spellDetail.damagePerTimeSpentCasting * 1000) : '-'}
        </>
        }

    );
  };

  componentDidUpdate() {
    ReactTooltip.rebuild();
  }

  render() {
    const { tracker } = this.props;

    return (

              <Toggle
                defaultChecked={false}
                icons={false}
                onChange={event => this.setState({ showDamage: event.target.checked })}
                id="damage-toggle"
              />

                Show Damage

              <Toggle
                defaultChecked
                icons={false}
                onChange={event => this.setState({ showHealing: event.target.checked })}
                id="healing-toggle"
              />

                Show Healing

              <Toggle
                defaultChecked
                icons={false}
                onChange={event => this.setState({ showPercentages: event.target.checked })}
                id="percent-toggle"
              />

                Show Percentages

                  Ability

                    <dfn data-tip={`Total Casts (Number of targets hit)`}>Casts</dfn>

                  Mana Spent
                  {this.state.showHealing &&
                  <>
                    Healing Done
                    Overhealing

                      <dfn data-tip={`Healing per mana spent casting the spell`}>HPM</dfn>

                      <dfn data-tip={`Healing per second spent casting the spell`}>HPET</dfn>

                  </>
                  }
                  {this.state.showDamage &&
                  <>
                    Damage Done

                      <dfn data-tip={`Damage per mana spent casting the spell`}>DPM</dfn>

                      <dfn data-tip={`Damage per second spent casting the spell`}>DPET</dfn>

                  </>
                  }

                <this.Table tracker={tracker} showHealing={this.state.showHealing} showDamage={this.state.showDamage} />

    );
  }
}

export default HealingEfficiencyBreakdown;
<commit_msg>adding detailed view toggle<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import SpellIcon from 'common/SpellIcon';
import { formatNumber, formatPercentage } from 'common/format';
import Toggle from 'react-toggle';
import ReactTooltip from 'react-tooltip';

class HealingEfficiencyBreakdown extends React.Component {
  static propTypes = {
    tracker: PropTypes.object.isRequired,
  };

  constructor() {
    super();
    this.state = {
      showHealing: true,
      showDamage: false,
      showPercentages: true,
      detailedView: false,
    };
  }

  Table = (props) => {
    const { tracker } = props;
    const spellDetails = tracker.spellDetails;

    const detailsArray = Object.keys(spellDetails).map(function (key) {
      return spellDetails[key];
    });
    detailsArray.sort((a, b) => {
      if (a.healingDone  b.healingDone) {
        return -1;
      }
      else {
        if (a.damageDone  b.damageDone) {
          return -1;
        }
      }
      return 0;
    });

    const spellRows = detailsArray.map((value => {
      if (value.casts > 0) {
        return this.SpellRow(value);
      }
      return null;
    }));

    return spellRows;
  };

  SpellRow = (spellDetail) => {
    return (

          <SpellIcon id={spellDetail.spell.id} /> {spellDetail.spell.name}

        {this.state.detailedView ? <this.DetailView spellDetail={spellDetail} /> : <this.BarView spellDetail={spellDetail} />}

    );
  };

  BarHeader = (props) => {
    return (
      <>
        {this.state.showHealing &&
        <>

            <dfn data-tip={`Healing per mana spent casting the spell`}>HPM</dfn>

            <dfn data-tip={`Healing per second spent casting the spell`}>HPET</dfn>

        </>
        }
        {this.state.showDamage &&
        <>
          Damage Done

            <dfn data-tip={`Damage per mana spent casting the spell`}>DPM</dfn>

            <dfn data-tip={`Damage per second spent casting the spell`}>DPET</dfn>

        </>
        }
      </>
    );
  };

  BarView = (props) => {
    const { spellDetail } = props;
    const hasHealing = spellDetail.healingDone;
    const hasDamage = spellDetail.damageDone > 0;

    return (
      <>
        {this.state.showHealing &&
        <>
          {hasHealing ? formatNumber(spellDetail.hpm) : '-'}
          {hasHealing ? formatNumber(spellDetail.hpm) : '-'}
        </>
        }
        {this.state.showDamage &&
        <>
          {hasDamage ? formatNumber(spellDetail.dpm) : '-'}
          {hasHealing ? formatNumber(spellDetail.hpm) : '-'}
        </>
        }
      </>
    );
  };

  DetailHeader = (props) => {
    return (
      <>

          <dfn data-tip={`Total Casts (Number of targets hit)`}>Casts</dfn>

        Mana Spent
        {this.state.showHealing &&
        <>
          Healing Done
          Overhealing

            <dfn data-tip={`Healing per mana spent casting the spell`}>HPM</dfn>

            <dfn data-tip={`Healing per second spent casting the spell`}>HPET</dfn>

        </>
        }
        {this.state.showDamage &&
        <>
          Damage Done

            <dfn data-tip={`Damage per mana spent casting the spell`}>DPM</dfn>

            <dfn data-tip={`Damage per second spent casting the spell`}>DPET</dfn>

        </>
        }
      </>
    );
  };

  DetailView = (props) => {
    const { spellDetail } = props;
    const hasHealing = spellDetail.healingDone;
    const hasOverhealing = spellDetail.healingDone > 0 || spellDetail.overhealingDone > 0;
    const hasDamage = spellDetail.damageDone > 0;

    return (
      <>
        {spellDetail.casts} ({spellDetail.healingHits + spellDetail.damageHits})

          {formatNumber(spellDetail.manaSpent)}
          {this.state.showPercentages ? ' (' + formatPercentage(spellDetail.manaPercentSpent) + '%)' : ''}

        {this.state.showHealing &&
        <>

            {hasHealing ? formatNumber(spellDetail.healingDone) : '-'}
            {hasHealing && this.state.showPercentages ? ' (' + formatPercentage(spellDetail.percentHealingDone) + '%)' : ''}

            {hasOverhealing ? formatNumber(spellDetail.overhealingDone) : '-'}
            {hasOverhealing && this.state.showPercentages ? ' (' + formatPercentage(spellDetail.percentOverhealingDone) + '%)' : ''}

          {hasHealing ? formatNumber(spellDetail.hpm) : '-'}
          {hasHealing ? formatNumber(spellDetail.healingPerTimeSpentCasting * 1000) : '-'}
        </>
        }
        {this.state.showDamage &&
        <>

            {hasDamage ? formatNumber(spellDetail.damageDone) : '-'}
            {hasDamage && this.state.showPercentages ? ' (' + formatPercentage(spellDetail.percentDamageDone) + '%)' : ''}

          {hasDamage ? formatNumber(spellDetail.dpm) : '-'}
          {hasDamage ? formatNumber(spellDetail.damagePerTimeSpentCasting * 1000) : '-'}
        </>
        }
      </>
    );
  };

  componentDidUpdate() {
    ReactTooltip.rebuild();
  }

  render() {
    const { tracker } = this.props;

    return (

              <Toggle
                defaultChecked={false}
                icons={false}
                onChange={event => this.setState({ showDamage: event.target.checked })}
                id="damage-toggle"
              />

                Show Damage

              <Toggle
                defaultChecked
                icons={false}
                onChange={event => this.setState({ showHealing: event.target.checked })}
                id="healing-toggle"
              />

                Show Healing

              <Toggle
                defaultChecked
                icons={false}
                onChange={event => this.setState({ showPercentages: event.target.checked })}
                id="percent-toggle"
              />

                Show Percentages

              <Toggle
                defaultChecked={false}
                icons={false}
                onChange={event => this.setState({ detailedView: event.target.checked })}
                id="detailed-toggle"
              />

                Detailed View

                  Ability
                  {this.state.detailedView ? <this.DetailHeader /> : <this.BarHeader />}

                <this.Table tracker={tracker} showHealing={this.state.showHealing} showDamage={this.state.showDamage} />

    );
  }
}

export default HealingEfficiencyBreakdown;
<|endoftext|>


<commit_before>var svgSetup = function (val) {
  var
    svg = document.createElement('svg'),
    elem = document.createDocumentFragment()
    ;

  svg.innerHTML = val;
  elem.appendChild(svg);

  return elem;
};

var questions = [
  {
    question: 'Make circle: center `(50,50)`; radius: `100`',
    incorrect: document.querySelector('[data-question="1"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var circle = elem.querySelector('circle');

      if (!circle) return false;
      if (circle.getAttribute('cx') != 50) return false;
      if (circle.getAttribute('cy') != 50) return false;
      if (circle.getAttribute('r') != 100) return false;

      return true;
    }
  },
  {
    question: 'Change the circle’s colour',
    incorrect: document.querySelector('[data-question="2"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var circle = elem.querySelector('circle');

      if (!circle) return false;
      if (!circle.getAttribute('fill')) return false;

      return true;
    }
  },
  {
    question: 'Draw a rectangle that’s 100×50',
    incorrect: document.querySelector('[data-question="3"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var rect = elem.querySelector('rect');

      if (!rect) return false;
      if (rect.getAttribute('width') != 100) return false;
      if (rect.getAttribute('height') != 50) return false;

      return true;
    }
  },
  {
    question: 'Add a stroke to the rectangle',
    incorrect: document.querySelector('[data-question="4"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var rect = elem.querySelector('rect');

      if (!rect) return false;
      if (!rect.getAttribute('stroke')) return false;

      return true;
    }
  },
  {
    question: 'Round the rectangle’s corners',
    incorrect: document.querySelector('[data-question="5"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var rect = elem.querySelector('rect');

      if (!rect) return false;
      if (!rect.getAttribute('rx')) return false;
      if (!rect.getAttribute('ry')) return false;

      return true;
    }
  },
  {
    question: 'Draw a line from `(0,0)` to `(100,100)`',
    incorrect: document.querySelector('[data-question="6"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var line = elem.querySelector('line');

      if (!line) return false;
      if (line.getAttribute('x1') != 0) return false;
      if (line.getAttribute('y1') != 0) return false;
      if (line.getAttribute('x2') != 100) return false;
      if (line.getAttribute('y2') != 100) return false;

      return true;
    }
  },
  {
    question: 'Group these paths together',
    incorrect: document.querySelector('[data-question="7"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var g = elem.querySelector('g');
      var paths = g.querySelectorAll('path');

      if (!g) return false;
      if (!paths) return false;
      if (paths.length != 3) return false;

      return true;
    }
  },
  {
    question: 'Add a class to the group',
    incorrect: document.querySelector('[data-question="8"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var g = elem.querySelector('g');

      if (!g) return false;
      if (g.classList.length <= 0) return false;

      return true;
    }
  },
  {
    question: 'Put the word `Awesome!` into SVG text',
    incorrect: document.querySelector('[data-question="9"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var text = elem.querySelector('text');

      if (!text) return false;
      if (text.innerHTML != 'Awesome!') return false;

      return true;
    }
  },
  {
    question: 'Fix the indentation',
    incorrect: document.querySelector('[data-question="10"]').value,
    correct: document.querySelector('[data-answer="10"]').value
  },
];

CodeCompare(ActivityRunner(), questions);
<commit_msg>Fix a bug in the SVG quiz where an element was used before its existence was confirmed<commit_after>var svgSetup = function (val) {
  var svg = document.createElement('svg');
  var elem = document.createDocumentFragment();

  svg.innerHTML = val;
  elem.appendChild(svg);

  return elem;
};

var questions = [
  {
    question: 'Make circle: center `(50,50)`; radius: `100`',
    incorrect: document.querySelector('[data-question="1"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var circle = elem.querySelector('circle');

      if (!circle) return false;
      if (circle.getAttribute('cx') != 50) return false;
      if (circle.getAttribute('cy') != 50) return false;
      if (circle.getAttribute('r') != 100) return false;

      return true;
    }
  },
  {
    question: 'Change the circle’s colour',
    incorrect: document.querySelector('[data-question="2"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var circle = elem.querySelector('circle');

      if (!circle) return false;
      if (!circle.getAttribute('fill')) return false;

      return true;
    }
  },
  {
    question: 'Draw a rectangle that’s 100×50',
    incorrect: document.querySelector('[data-question="3"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var rect = elem.querySelector('rect');

      if (!rect) return false;
      if (rect.getAttribute('width') != 100) return false;
      if (rect.getAttribute('height') != 50) return false;

      return true;
    }
  },
  {
    question: 'Add a stroke to the rectangle',
    incorrect: document.querySelector('[data-question="4"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var rect = elem.querySelector('rect');

      if (!rect) return false;
      if (!rect.getAttribute('stroke')) return false;

      return true;
    }
  },
  {
    question: 'Round the rectangle’s corners',
    incorrect: document.querySelector('[data-question="5"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var rect = elem.querySelector('rect');

      if (!rect) return false;
      if (!rect.getAttribute('rx')) return false;
      if (!rect.getAttribute('ry')) return false;

      return true;
    }
  },
  {
    question: 'Draw a line from `(0,0)` to `(100,100)`',
    incorrect: document.querySelector('[data-question="6"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var line = elem.querySelector('line');

      if (!line) return false;
      if (line.getAttribute('x1') != 0) return false;
      if (line.getAttribute('y1') != 0) return false;
      if (line.getAttribute('x2') != 100) return false;
      if (line.getAttribute('y2') != 100) return false;

      return true;
    }
  },
  {
    question: 'Group these paths together',
    incorrect: document.querySelector('[data-question="7"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var g = elem.querySelector('g');
      var paths;

      if (!g) return false;

      paths = g.querySelectorAll('path');

      if (!paths) return false;
      if (paths.length != 3) return false;

      return true;
    }
  },
  {
    question: 'Add a class to the group',
    incorrect: document.querySelector('[data-question="8"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var g = elem.querySelector('g');

      if (!g) return false;
      if (g.classList.length <= 0) return false;

      return true;
    }
  },
  {
    question: 'Put the word `Awesome!` into SVG text',
    incorrect: document.querySelector('[data-question="9"]').value,
    correct: function (val) {
      var elem = svgSetup(val);
      var text = elem.querySelector('text');

      if (!text) return false;
      if (text.innerHTML != 'Awesome!') return false;

      return true;
    }
  },
  {
    question: 'Fix the indentation',
    incorrect: document.querySelector('[data-question="10"]').value,
    correct: document.querySelector('[data-answer="10"]').value
  },
];

CodeCompare(ActivityRunner(), questions);
<|endoftext|>


<commit_before>"use strict";

var fs = require("fs"),
    gulp = require("gulp"),
    csso = require("gulp-csso"),
    rimraf = require("gulp-rimraf"),
    uglify = require("gulp-uglify"),
    stylus = require("gulp-stylus"),
    concat = require("gulp-concat"),
    browserSync = require("browser-sync"),
    sourcemaps = require("gulp-sourcemaps"),
    autoprefixer = require("gulp-autoprefixer"),

    defaults = function (obj, def) {
        function req(obj, def) {
            for (var key in def) {
                if (obj[key]) {
                    if (typeof obj[key] == "object") {
                        req(obj[key], def[key]);
                    }
                } else {
                    obj[key] = def[key];
                }
            }
        }

        req(obj, def);

        return obj;
    },

    settings = defaults(
        JSON.parse(fs.readFileSync("Gulpfile.json", "utf8")),
        {
            "path": {
                "src": "./src",
                "root": "./",
                "dest": "./assets/"
            },
            "proxy": {
                "path": "localhost",
                "port": 8888
            }
        }
    ),
    path = {
        src: settings.path.src,
        root: settings.path.root,
        dest: settings.path.dest,

        include: function () {
            var a = Array.from(arguments);
            return a.join("/").replace(/\/+/g, "/");
        },
        exclude: function () {
            return "!" + path.include.apply(this, arguments);
        }
    };

gulp.task("stylus:clear", function () {
    return gulp
        .src([
            path.include(path.dest, "css")
        ], {read: false})
        .pipe(rimraf({force: true}));
});
gulp.task("stylus:main", ["stylus:clear"], function () {
    return gulp
        .src([
            path.include(path.src, "stylus/**/**.{styl,css}"),

            path.exclude(path.src, "stylus/separate/**/**.{styl,css}"),
            path.exclude(path.src, "stylus/imports/**/**.{styl,css}")
        ])
        .pipe(sourcemaps.init())
        .pipe(stylus({
            compress: true
        }))
        .pipe(csso({
            sourceMap: true
        }))
        .pipe(concat("style.css"))
        .pipe(sourcemaps.write("./"))
        .pipe(gulp.dest(path.include(path.dest, "css")))
        .pipe(browserSync.stream());
});
gulp.task("stylus:separate", ["stylus:clear"], function () {
    return gulp
        .src([
            path.include(path.src, "stylus/separate/**/**.{styl,css}")
        ])
        .pipe(sourcemaps.init())
        .pipe(stylus({
            compress: true
        }))
        .pipe(sourcemaps.write("./"))
        .pipe(gulp.dest(path.include(path.dest, "css")))
        .pipe(browserSync.stream());
});

gulp.task("js:clear", function () {
    return gulp
        .src([
            path.include(path.dest, "js")
        ], {read: false})
        .pipe(rimraf({force: true}));
});
gulp.task("js:main", ["js:clear"], function () {
    return gulp
        .src([
            path.include(path.src, "js/**/**.js"),

            path.exclude(path.src, "js/separate/**/**.js")
        ])
        .pipe(sourcemaps.init())
        .pipe(uglify({
            compress: true
        }))
        .pipe(concat("main.js"))
        .pipe(sourcemaps.write("./"))
        .pipe(gulp.dest(path.include(path.dest, "js")));
});
gulp.task("js:separate", ["js:clear"], function () {
    return gulp
        .src([
            path.include(path.src, "js/separate/**/**.js")
        ])
        .pipe(sourcemaps.init())
        .pipe(uglify({
            compress: true
        }))
        .pipe(sourcemaps.write("./"))
        .pipe(gulp.dest(path.include(path.dest, "js")));
});
gulp.task("js:reload", ["js:main", "js:separate"], function () {
    return gulp
        .src([
            path.include(path.src + "js/**/**.js")
        ])
        .pipe(browserSync.stream());
});

gulp.task("images:clear", function () {
    return gulp
        .src([
            path.include(path.dist, "images")
        ], {read: false})
        .pipe(rimraf({force: true}));
});
gulp.task("images:copy", function () {
    return gulp
        .src([
            path.include(path.src, "images/**/**.*")
        ])
        .pipe(gulp.dest(path.include(path.dest, "images")));
});

gulp.task("php-html", function () {
    return gulp
        .src([
            path.include(path.root, "**/**.php"),
            path.include(path.root, "**/**.html")
        ])
        .pipe(browserSync.stream());
});

gulp.task("stylus", [
    "stylus:clear",
    "stylus:main",
    "stylus:separate"
]);
gulp.task("js", [
    "js:clear",
    "js:main",
    "js:separate",
    "js:reload"
]);
gulp.task("images", [
    "images:clear",
    "images:copy"
]);

gulp.task("watch", function (cb) {
    browserSync.init({
        notify: true,
        https: false,
        open: true,
        proxy: {
            target: "http://" + settings.proxy.path + (settings.proxy.port != "80" ? (":" + settings.proxy.port) : ""),
            ws: true
        },

        serveStatic: [
            "./assets"
        ],
        localOnly: true
    }, cb);

    process.on("exit", function () {
        browserSync.exit();
    });

    gulp.watch([
        path.include(path.src, "stylus/**/**.styl")
    ], ["stylus"]);
    gulp.watch([
        path.include(path.src, "js/**/**.js")
    ], ["js"]);
    gulp.watch([
        path.include(path.src, "images/**/**.*")
    ], ["images"]);
    gulp.watch([
        path.include(path.root, "**/**.php"),
        path.include(path.root, "**/**.html")
    ], ["php-html"]);

});

gulp.task("build", ["stylus", "js", "images"]);

gulp.task("default", ["build", "watch"]);
<commit_msg>Add .gitignore file to destination folder<commit_after>"use strict";

var fs = require("fs"),
    gulp = require("gulp"),
    csso = require("gulp-csso"),
    file = require('gulp-file'),
    rimraf = require("gulp-rimraf"),
    uglify = require("gulp-uglify"),
    stylus = require("gulp-stylus"),
    concat = require("gulp-concat"),
    browserSync = require("browser-sync"),
    sourcemaps = require("gulp-sourcemaps"),
    autoprefixer = require("gulp-autoprefixer"),

    defaults = function (obj, def) {
        function req(obj, def) {
            for (var key in def) {
                if (obj[key]) {
                    if (typeof obj[key] == "object") {
                        req(obj[key], def[key]);
                    }
                } else {
                    obj[key] = def[key];
                }
            }
        }

        req(obj, def);

        return obj;
    },

    settings = defaults(
        JSON.parse(fs.readFileSync("Gulpfile.json", "utf8")),
        {
            "path": {
                "src": "./src",
                "root": "./",
                "dest": "./assets/"
            },
            "proxy": {
                "path": "localhost",
                "port": 8888
            }
        }
    ),
    path = {
        src: settings.path.src,
        root: settings.path.root,
        dest: settings.path.dest,

        include: function () {
            var a = Array.from(arguments);
            return a.join("/").replace(/\/+/g, "/");
        },
        exclude: function () {
            return "!" + path.include.apply(this, arguments);
        }
    };

gulp.task("stylus:clear", function () {
    return gulp
        .src([
            path.include(path.dest, "css")
        ], {read: false})
        .pipe(rimraf({force: true}));
});
gulp.task("stylus:main", ["stylus:clear"], function () {
    return gulp
        .src([
            path.include(path.src, "stylus/**/**.{styl,css}"),

            path.exclude(path.src, "stylus/separate/**/**.{styl,css}"),
            path.exclude(path.src, "stylus/imports/**/**.{styl,css}")
        ])
        .pipe(sourcemaps.init())
        .pipe(stylus({
            compress: true
        }))
        .pipe(csso({
            sourceMap: true
        }))
        .pipe(concat("style.css"))
        .pipe(sourcemaps.write("./"))
        .pipe(gulp.dest(path.include(path.dest, "css")))
        .pipe(browserSync.stream());
});
gulp.task("stylus:separate", ["stylus:clear"], function () {
    return gulp
        .src([
            path.include(path.src, "stylus/separate/**/**.{styl,css}")
        ])
        .pipe(sourcemaps.init())
        .pipe(stylus({
            compress: true
        }))
        .pipe(sourcemaps.write("./"))
        .pipe(gulp.dest(path.include(path.dest, "css")))
        .pipe(browserSync.stream());
});

gulp.task("js:clear", function () {
    return gulp
        .src([
            path.include(path.dest, "js")
        ], {read: false})
        .pipe(rimraf({force: true}));
});
gulp.task("js:main", ["js:clear"], function () {
    return gulp
        .src([
            path.include(path.src, "js/**/**.js"),

            path.exclude(path.src, "js/separate/**/**.js")
        ])
        .pipe(sourcemaps.init())
        .pipe(uglify({
            compress: true
        }))
        .pipe(concat("main.js"))
        .pipe(sourcemaps.write("./"))
        .pipe(gulp.dest(path.include(path.dest, "js")));
});
gulp.task("js:separate", ["js:clear"], function () {
    return gulp
        .src([
            path.include(path.src, "js/separate/**/**.js")
        ])
        .pipe(sourcemaps.init())
        .pipe(uglify({
            compress: true
        }))
        .pipe(sourcemaps.write("./"))
        .pipe(gulp.dest(path.include(path.dest, "js")));
});
gulp.task("js:reload", ["js:main", "js:separate"], function () {
    return gulp
        .src([
            path.include(path.src + "js/**/**.js")
        ])
        .pipe(browserSync.stream());
});

gulp.task("images:clear", function () {
    return gulp
        .src([
            path.include(path.dist, "images")
        ], {read: false})
        .pipe(rimraf({force: true}));
});
gulp.task("images:copy", function () {
    return gulp
        .src([
            path.include(path.src, "images/**/**.*")
        ])
        .pipe(gulp.dest(path.include(path.dest, "images")));
});

gulp.task("git-ignore", function () {
    return file(".gitignore", "*", {src: true})
        .pipe(gulp.dest(path.dest));
});

gulp.task("php-html", function () {
    return gulp
        .src([
            path.include(path.root, "**/**.php"),
            path.include(path.root, "**/**.html")
        ])
        .pipe(browserSync.stream());
});

gulp.task("stylus", [
    "stylus:clear",
    "stylus:main",
    "stylus:separate"
]);
gulp.task("js", [
    "js:clear",
    "js:main",
    "js:separate",
    "js:reload"
]);
gulp.task("images", [
    "images:clear",
    "images:copy"
]);

gulp.task("watch", function (cb) {
    browserSync.init({
        notify: true,
        https: false,
        open: true,
        proxy: {
            target: "http://" + settings.proxy.path + (settings.proxy.port != "80" ? (":" + settings.proxy.port) : ""),
            ws: true
        },

        serveStatic: [
            "./assets"
        ],
        localOnly: true
    }, cb);

    process.on("exit", function () {
        browserSync.exit();
    });

    gulp.watch([
        path.include(path.src, "stylus/**/**.styl")
    ], ["stylus"]);
    gulp.watch([
        path.include(path.src, "js/**/**.js")
    ], ["js"]);
    gulp.watch([
        path.include(path.src, "images/**/**.*")
    ], ["images"]);
    gulp.watch([
        path.include(path.root, "**/**.php"),
        path.include(path.root, "**/**.html")
    ], ["php-html"]);

});

gulp.task("build", ["git-ignore", "stylus", "js", "images"]);

gulp.task("default", ["build", "watch"]);
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Form } from 'formsy-react';
import { Input, Select, Textarea, RadioGroup } from '../src';

class MyForm extends Component {
  submit(model) {
    console.log(model);
  }

  render() {
    return (
      <Form onValidSubmit={::this.submit}>

          <Input type="text" name="name" />

          <RadioGroup name="fruit" defaultValue="apple">
            {Radio => (

                <Radio value="apple" />Apple
                <Radio value="orange" />Orange
                <Radio value="watermelon" />Watermelon

            )}
          </RadioGroup>

          <Select name="gender">
            <option value></option>
            <option value="m">Male</option>
            <option value="f">Female</option>
          </Select>

          <Textarea name="bio"></Textarea>

        <button type="submit">Submit</button>
      </Form>
    );
  }
}

React.render(<MyForm />, document.getElementById('app'));
<commit_msg>Fix example<commit_after>import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Form } from 'formsy-react';
import { Input, Select, Textarea, RadioGroup } from '../src';

const styles = {
  formGroup: {
    margin: '10px'
  }
}

class MyForm extends Component {
  submit(model) {
    console.log(model);
  }

  render() {
    return (
      <Form onValidSubmit={::this.submit}>

          <Input type="text" name="name" />

          <RadioGroup name="fruit" defaultValue="apple">
            {Radio => (

                <Radio value="apple" />Apple
                <Radio value="orange" />Orange
                <Radio value="watermelon" />Watermelon

            )}
          </RadioGroup>

          <Select name="gender">
            <option value></option>
            <option value="m">Male</option>
            <option value="f">Female</option>
          </Select>

          <Textarea name="bio"></Textarea>

          <button type="submit">Submit</button>

      </Form>
    );
  }
}

ReactDOM.render(<MyForm />, document.getElementById('app'));
<|endoftext|>


<commit_before>import React, {Component} from 'react';

import Tab from 'src/Tab';
import Widget from 'src/Widget';
import WidgetHeader from 'src/WidgetHeader';

import PropTypeDescTable from 'components/PropTypeDescTable';
import TabDoc from 'assets/propTypes/Tab.json';

export default class TabExamples extends Component {

    constructor(props) {

        super(props);

        this.activeHandle = this::this.activeHandle;

    }

    activeHandle(tab) {
        alert(`${tab.value} activated.`);
    }

    render() {
        return (

Tabs

                    Tabs make it easy to explore and switch between different views or functional aspects
                    of an app or to browse categorized data sets.

Examples

                <Widget>

                    <WidgetHeader className="example-header" title="Full Width Tabs Example"/>

                                    A simple example of Tabs. The third tab demonstrates the onActive property of Tab.

                                <Tab tabs={[{
                                    value: 'Tab 1',
                                    renderer:

Tab 1

                                }, {
                                    value: 'Tab 2',
                                    renderer:

Tab 2

                                }, {
                                    value: 'onActive',
                                    renderer:

onActive

,
                                    onActive: this.activeHandle
                                }, {
                                    value: 'Disabled',
                                    disabled: true
                                }]}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="Tabs Example"/>

                                    Tabs use full container width by default.Set the isTabFullWidth property to false
                                    for partial width.

                                <Tab tabs={[{
                                    value: 'Tab 1',
                                    renderer:

Tab 1

                                }, {
                                    value: 'Tab 2',
                                    renderer:

Tab 2

                                }, {
                                    value: 'onActive',
                                    renderer:

onActive

,
                                    onActive: this.activeHandle
                                }, {
                                    value: 'Disabled',
                                    disabled: true
                                }]}
                                     isTabFullWidth={false}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="Tabs Example"/>

                                    Tabs without icons by default.Set the iconCls property for left icons.

                                <Tab tabs={[{
                                    value: 'Bicycle',
                                    iconCls: 'fa fa-bicycle',
                                    renderer:

Bicycle

                                }, {
                                    value: 'Taxi',
                                    iconCls: 'fa fa-taxi',
                                    renderer:

Taxi

                                }, {
                                    value: 'Plane',
                                    iconCls: 'fa fa-plane',
                                    renderer:

Plane

                                }, {
                                    value: 'Rocket',
                                    iconCls: 'fa fa-rocket',
                                    renderer:

Rocket

                                }]}
                                     isTabFullWidth={false}/>

                </Widget>

Properties

                <PropTypeDescTable data={TabDoc}/>

        );
    }
};<commit_msg>update Tab examples<commit_after>import React, {Component} from 'react';

import Tab from 'src/Tab';
import Widget from 'src/Widget';
import WidgetHeader from 'src/WidgetHeader';

import PropTypeDescTable from 'components/PropTypeDescTable';
import doc from 'assets/propTypes/Tab.json';

export default class TabExamples extends Component {

    constructor(props) {
        super(props);
    }

    activeHandle(tab) {
        alert(`${tab.value} activated.`);
    }

    render() {
        return (

Tabs

                    Tabs make it easy to explore and switch between different views or functional aspects
                    of an app or to browse categorized data sets.

Examples

                <Widget>

                    <WidgetHeader className="example-header" title="Full Width Tabs Example"/>

                                    A simple example of Tabs. The third tab demonstrates the onActive property of Tab.

                                <Tab tabs={[{
                                    value: 'Tab 1',
                                    renderer:

Tab 1

                                }, {
                                    value: 'Tab 2',
                                    renderer:

Tab 2

                                }, {
                                    value: 'onActive',
                                    renderer:

onActive

,
                                    onActive: this.activeHandle
                                }, {
                                    value: 'Disabled',
                                    disabled: true
                                }]}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="Tabs Example"/>

                                    Tabs use full container width by default.Set the isTabFullWidth property to false
                                    for partial width.

                                <Tab tabs={[{
                                    value: 'Tab 1',
                                    renderer:

Tab 1

                                }, {
                                    value: 'Tab 2',
                                    renderer:

Tab 2

                                }, {
                                    value: 'onActive',
                                    renderer:

onActive

,
                                    onActive: this.activeHandle
                                }, {
                                    value: 'Disabled',
                                    disabled: true
                                }]}
                                     isTabFullWidth={false}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="Tabs Example"/>

                                    Tabs without icons by default.Set the iconCls property for left icons.

                                <Tab tabs={[{
                                    value: 'Bicycle',
                                    iconCls: 'fa fa-bicycle',
                                    renderer:

Bicycle

                                }, {
                                    value: 'Taxi',
                                    iconCls: 'fa fa-taxi',
                                    renderer:

Taxi

                                }, {
                                    value: 'Plane',
                                    iconCls: 'fa fa-plane',
                                    renderer:

Plane

                                }, {
                                    value: 'Rocket',
                                    iconCls: 'fa fa-rocket',
                                    renderer:

Rocket

                                }]}
                                     isTabFullWidth={false}/>

                </Widget>

Properties

                <PropTypeDescTable data={doc}/>

        );
    }
};<|endoftext|>


<commit_before><commit_msg>classes<commit_after><|endoftext|>