// jquery.repeater version 1.2.2

// https://github.com/DubFriend/jquery.repeater

// (MIT) 15-04-2022

// Brian Detering <BDeterin@gmail.com> (http://www.briandetering.net/)

(function ($) {

    'use strict';



    var identity = function (x) {

        return x;

    };



    var isArray = function (value) {

        return $.isArray(value);

    };



    var isObject = function (value) {

        return !isArray(value) && (value instanceof Object);

    };



    var isNumber = function (value) {

        return value instanceof Number;

    };



    var isFunction = function (value) {

        return value instanceof Function;

    };



    var indexOf = function (object, value) {

        return $.inArray(value, object);

    };



    var inArray = function (array, value) {

        return indexOf(array, value) !== -1;

    };



    var foreach = function (collection, callback) {

        for(var i in collection) {

            if(collection.hasOwnProperty(i)) {

                callback(collection[i], i, collection);

            }

        }

    };





    var last = function (array) {

        return array[array.length - 1];

    };



    var argumentsToArray = function (args) {

        return Array.prototype.slice.call(args);

    };



    var extend = function () {

        var extended = {};

        foreach(argumentsToArray(arguments), function (o) {

            foreach(o, function (val, key) {

                extended[key] = val;

            });

        });

        return extended;

    };



    var mapToArray = function (collection, callback) {

        var mapped = [];

        foreach(collection, function (value, key, coll) {

            mapped.push(callback(value, key, coll));

        });

        return mapped;

    };



    var mapToObject = function (collection, callback, keyCallback) {

        var mapped = {};

        foreach(collection, function (value, key, coll) {

            key = keyCallback ? keyCallback(key, value) : key;

            mapped[key] = callback(value, key, coll);

        });

        return mapped;

    };



    var map = function (collection, callback, keyCallback) {

        return isArray(collection) ?

            mapToArray(collection, callback) :

            mapToObject(collection, callback, keyCallback);

    };



    var pluck = function (arrayOfObjects, key) {

        return map(arrayOfObjects, function (val) {

            return val[key];

        });

    };



    var filter = function (collection, callback) {

        var filtered;



        if(isArray(collection)) {

            filtered = [];

            foreach(collection, function (val, key, coll) {

                if(callback(val, key, coll)) {

                    filtered.push(val);

                }

            });

        }

        else {

            filtered = {};

            foreach(collection, function (val, key, coll) {

                if(callback(val, key, coll)) {

                    filtered[key] = val;

                }

            });

        }



        return filtered;

    };



    var call = function (collection, functionName, args) {

        return map(collection, function (object, name) {

            return object[functionName].apply(object, args || []);

        });

    };



//execute callback immediately and at most one time on the minimumInterval,

//ignore block attempts

    var throttle = function (minimumInterval, callback) {

        var timeout = null;

        return function () {

            var that = this, args = arguments;

            if(timeout === null) {

                timeout = setTimeout(function () {

                    timeout = null;

                }, minimumInterval);

                callback.apply(that, args);

            }

        };

    };





    var mixinPubSub = function (object) {

        object = object || {};

        var topics = {};



        object.publish = function (topic, data) {

            foreach(topics[topic], function (callback) {

                callback(data);

            });

        };



        object.subscribe = function (topic, callback) {

            topics[topic] = topics[topic] || [];

            topics[topic].push(callback);

        };



        object.unsubscribe = function (callback) {

            foreach(topics, function (subscribers) {

                var index = indexOf(subscribers, callback);

                if(index !== -1) {

                    subscribers.splice(index, 1);

                }

            });

        };



        return object;

    };



// jquery.input version 0.0.0

// https://github.com/DubFriend/jquery.input

// (MIT) 09-04-2014

// Brian Detering <BDeterin@gmail.com> (http://www.briandetering.net/)

    (function ($) {

        'use strict';



        var createBaseInput = function (fig, my) {

            var self = mixinPubSub(),

                $self = fig.$;



            self.getType = function () {

                throw 'implement me (return type. "text", "radio", etc.)';

            };



            self.$ = function (selector) {

                return selector ? $self.find(selector) : $self;

            };



            self.disable = function () {

                self.$().prop('disabled', true);

                self.publish('isEnabled', false);

            };



            self.enable = function () {

                self.$().prop('disabled', false);

                self.publish('isEnabled', true);

            };



            my.equalTo = function (a, b) {

                return a === b;

            };



            my.publishChange = (function () {

                var oldValue;

                return function (e, domElement) {

                    var newValue = self.get();

                    if(!my.equalTo(newValue, oldValue)) {

                        self.publish('change', { e: e, domElement: domElement });

                    }

                    oldValue = newValue;

                };

            }());



            return self;

        };





        var createInput = function (fig, my) {

            var self = createBaseInput(fig, my);



            self.get = function () {

                return self.$().val();

            };



            self.set = function (newValue) {

                self.$().val(newValue);

            };



            self.clear = function () {

                self.set('');

            };



            my.buildSetter = function (callback) {

                return function (newValue) {

                    callback.call(self, newValue);

                };

            };



            return self;

        };



        var createInputText = function (fig) {

            var my = {},

                self = createInput(fig, my);



            self.getType = function () {

                return 'text';

            };



            self.$().on('change keyup keydown', function (e) {

                my.publishChange(e, this);

            });



            return self;

        };



        var inputEqualToArray = function (a, b) {

            a = isArray(a) ? a : [a];

            b = isArray(b) ? b : [b];



            var isEqual = true;

            if(a.length !== b.length) {

                isEqual = false;

            }

            else {

                foreach(a, function (value) {

                    if(!inArray(b, value)) {

                        isEqual = false;

                    }

                });

            }



            return isEqual;

        };



        var createInputButton = function (fig) {

            var my = {},

                self = createInput(fig, my);



            self.getType = function () {

                return 'button';

            };



            self.$().on('change', function (e) {

                my.publishChange(e, this);

            });



            return self;

        };



        var createInputCheckbox = function (fig) {

            var my = {},

                self = createInput(fig, my);



            self.getType = function () {

                return 'checkbox';

            };



            self.get = function () {

                var values = [];

                self.$().filter(':checked').each(function () {

                    values.push($(this).val());

                });

                return values;

            };



            self.set = function (newValues) {

                newValues = isArray(newValues) ? newValues : [newValues];



                self.$().each(function () {

                    $(this).prop('checked', false);

                });



                foreach(newValues, function (value) {

                    self.$().filter('[value="' + value + '"]')

                        .prop('checked', true);

                });

            };



            my.equalTo = inputEqualToArray;



            self.$().change(function (e) {

                my.publishChange(e, this);

            });



            return self;

        };



        var createInputEmail = function (fig) {

            var my = {},

                self = createInputText(fig, my);



            self.getType = function () {

                return 'email';

            };



            return self;

        };



        var createInputFile = function (fig) {

            var my = {},

                self = createBaseInput(fig, my);



            self.getType = function () {

                return 'file';

            };



            self.get = function () {

                return last(self.$().val().split('\\'));

            };



            self.clear = function () {

                // http://stackoverflow.com/questions/1043957/clearing-input-type-file-using-jquery

                this.$().each(function () {

                    $(this).wrap('<form>').closest('form').get(0).reset();

                    $(this).unwrap();

                });

            };



            self.$().change(function (e) {

                my.publishChange(e, this);

                // self.publish('change', self);

            });



            return self;

        };



        var createInputHidden = function (fig) {

            var my = {},

                self = createInput(fig, my);



            self.getType = function () {

                return 'hidden';

            };



            self.$().change(function (e) {

                my.publishChange(e, this);

            });



            return self;

        };

        var createInputMultipleFile = function (fig) {

            var my = {},

                self = createBaseInput(fig, my);



            self.getType = function () {

                return 'file[multiple]';

            };



            self.get = function () {

                // http://stackoverflow.com/questions/14035530/how-to-get-value-of-html-5-multiple-file-upload-variable-using-jquery

                var fileListObject = self.$().get(0).files || [],

                    names = [], i;



                for(i = 0; i < (fileListObject.length || 0); i += 1) {

                    names.push(fileListObject[i].name);

                }



                return names;

            };



            self.clear = function () {

                // http://stackoverflow.com/questions/1043957/clearing-input-type-file-using-jquery

                this.$().each(function () {

                    $(this).wrap('<form>').closest('form').get(0).reset();

                    $(this).unwrap();

                });

            };



            self.$().change(function (e) {

                my.publishChange(e, this);

            });



            return self;

        };



        var createInputMultipleSelect = function (fig) {

            var my = {},

                self = createInput(fig, my);



            self.getType = function () {

                return 'select[multiple]';

            };



            self.get = function () {

                return self.$().val() || [];

            };



            self.set = function (newValues) {

                self.$().val(

                    newValues === '' ? [] : isArray(newValues) ? newValues : [newValues]

                );

            };



            my.equalTo = inputEqualToArray;



            self.$().change(function (e) {

                my.publishChange(e, this);

            });



            return self;

        };



        var createInputPassword = function (fig) {

            var my = {},

                self = createInputText(fig, my);



            self.getType = function () {

                return 'password';

            };



            return self;

        };



        var createInputRadio = function (fig) {

            var my = {},

                self = createInput(fig, my);



            self.getType = function () {

                return 'radio';

            };



            self.get = function () {

                return self.$().filter(':checked').val() || null;

            };



            self.set = function (newValue) {

                if(!newValue) {

                    self.$().each(function () {

                        $(this).prop('checked', false);

                    });

                }

                else {

                    self.$().filter('[value="' + newValue + '"]').prop('checked', true);

                }

            };



            self.$().change(function (e) {

                my.publishChange(e, this);

            });



            return self;

        };



        var createInputRange = function (fig) {

            var my = {},

                self = createInput(fig, my);



            self.getType = function () {

                return 'range';

            };



            self.$().change(function (e) {

                my.publishChange(e, this);

            });



            return self;

        };



        var createInputSelect = function (fig) {

            var my = {},

                self = createInput(fig, my);



            self.getType = function () {

                return 'select';

            };



            self.$().change(function (e) {

                my.publishChange(e, this);

            });



            return self;

        };



        var createInputTextarea = function (fig) {

            var my = {},

                self = createInput(fig, my);



            self.getType = function () {

                return 'textarea';

            };



            self.$().on('change keyup keydown', function (e) {

                my.publishChange(e, this);

            });



            return self;

        };



        var createInputURL = function (fig) {

            var my = {},

                self = createInputText(fig, my);



            self.getType = function () {

                return 'url';

            };



            return self;

        };



        var createInputColor = function(fig) {

            var my = {},

                self = createInputText(fig, my);



            self.getType = function () {

                return 'color';

            };



            return self;

        };



        var createInputDate = function(fig) {

            var my = {},

                self = createInputText(fig, my);



            self.getType = function () {

                return 'date';

            };



            return self;

        };



        var createInputDateTimeLocal = function(fig) {

            var my = {},

                self = createInputText(fig, my);



            self.getType = function () {

                return 'datetime-local';

            };



            return self;

        };



        var createInputMonth = function(fig) {

            var my = {},

                self = createInputText(fig, my);



            self.getType = function () {

                return 'month';

            };



            return self;

        };



        var createInputNumber = function(fig) {

            var my = {},

                self = createInputText(fig, my);



            self.getType = function () {

                return 'number';

            };



            return self;

        };



        var createInputSearch = function(fig) {

            var my = {},

                self = createInputText(fig, my);



            self.getType = function () {

                return 'search';

            };



            return self;

        };



        var createInputTel = function(fig) {

            var my = {},

                self = createInputText(fig, my);



            self.getType = function () {

                return 'tel';

            };



            return self;

        };



        var createInputTime = function(fig) {

            var my = {},

                self = createInputText(fig, my);



            self.getType = function () {

                return 'time';

            };



            return self;

        };



        var createInputWeek = function(fig) {

            var my = {},

                self = createInputText(fig, my);



            self.getType = function () {

                return 'week';

            };



            return self;

        };





        var buildFormInputs = function (fig) {

            var inputs = {},

                $self = fig.$;

            var constructor = fig.constructorOverride || {

                color:createInputColor,

                date:createInputDate,

                datetimeLocal:createInputDateTimeLocal,

                month:createInputMonth,

                number:createInputNumber,

                search:createInputSearch,

                tel:createInputTel,

                time:createInputTime,

                week:createInputWeek,

                button: createInputButton,

                text: createInputText,

                url: createInputURL,

                email: createInputEmail,

                password: createInputPassword,

                range: createInputRange,

                textarea: createInputTextarea,

                select: createInputSelect,

                'select[multiple]': createInputMultipleSelect,

                radio: createInputRadio,

                checkbox: createInputCheckbox,

                file: createInputFile,

                'file[multiple]': createInputMultipleFile,

                hidden: createInputHidden

            };



            var addInputsBasic = function (type, selector) {

                var $input = isObject(selector) ? selector : $self.find(selector);



                $input.each(function () {

                    var name = $(this).attr('name');

                    inputs[name] = constructor[type]({

                        $: $(this)

                    });

                });

            };



            var addInputsGroup = function (type, selector) {

                var names = [],

                    $input = isObject(selector) ? selector : $self.find(selector);



                if(isObject(selector)) {

                    inputs[$input.attr('name')] = constructor[type]({

                        $: $input

                    });

                }

                else {

                    // group by name attribute

                    $input.each(function () {

                        if(indexOf(names, $(this).attr('name')) === -1) {

                            names.push($(this).attr('name'));

                        }

                    });



                    foreach(names, function (name) {

                        inputs[name] = constructor[type]({

                            $: $self.find('input[name="' + name + '"]')

                        });

                    });

                }

            };





            if($self.is('input, select, textarea')) {

                if($self.is('input[type="button"], button, input[type="submit"]')) {

                    addInputsBasic('button', $self);

                }

                else if($self.is('textarea')) {

                    addInputsBasic('textarea', $self);

                }

                else if(

                    $self.is('input[type="text"]') ||

                    $self.is('input') && !$self.attr('type')

                ) {

                    addInputsBasic('text', $self);

                }

                else if($self.is('input[type="password"]')) {

                    addInputsBasic('password', $self);

                }

                else if($self.is('input[type="email"]')) {

                    addInputsBasic('email', $self);

                }

                else if($self.is('input[type="url"]')) {

                    addInputsBasic('url', $self);

                }

                else if($self.is('input[type="color"]')) {

                    addInputsBasic('color', $self);

                }

                else if($self.is('input[type="date"]')) {

                    addInputsBasic('date', $self);

                }

                else if($self.is('input[type="datetime-local"]')) {

                    addInputsBasic('datetimeLocal', $self);

                }

                else if($self.is('input[type="month"]')) {

                    addInputsBasic('month', $self);

                }

                else if($self.is('input[type="number"]')) {

                    addInputsBasic('number', $self);

                }

                else if($self.is('input[type="search"]')) {

                    addInputsBasic('search', $self);

                }

                else if($self.is('input[type="tel"]')) {

                    addInputsBasic('tel', $self);

                }

                else if($self.is('input[type="time"]')) {

                    addInputsBasic('time', $self);

                }

                else if($self.is('input[type="week"]')) {

                    addInputsBasic('week', $self);

                }

                else if($self.is('input[type="range"]')) {

                    addInputsBasic('range', $self);

                }

                else if($self.is('select')) {

                    if($self.is('[multiple]')) {

                        addInputsBasic('select[multiple]', $self);

                    }

                    else {

                        addInputsBasic('select', $self);

                    }

                }

                else if($self.is('input[type="file"]')) {

                    if($self.is('[multiple]')) {

                        addInputsBasic('file[multiple]', $self);

                    }

                    else {

                        addInputsBasic('file', $self);

                    }

                }

                else if($self.is('input[type="hidden"]')) {

                    addInputsBasic('hidden', $self);

                }

                else if($self.is('input[type="radio"]')) {

                    addInputsGroup('radio', $self);

                }

                else if($self.is('input[type="checkbox"]')) {

                    addInputsGroup('checkbox', $self);

                }

                else {

                    //in all other cases default to a "text" input interface.

                    addInputsBasic('text', $self);

                }

            }

            else {

                addInputsBasic('button', 'input[type="button"], button, input[type="submit"]');

                addInputsBasic('text', 'input[type="text"]');

                addInputsBasic('color', 'input[type="color"]');

                addInputsBasic('date', 'input[type="date"]');

                addInputsBasic('datetimeLocal', 'input[type="datetime-local"]');

                addInputsBasic('month', 'input[type="month"]');

                addInputsBasic('number', 'input[type="number"]');

                addInputsBasic('search', 'input[type="search"]');

                addInputsBasic('tel', 'input[type="tel"]');

                addInputsBasic('time', 'input[type="time"]');

                addInputsBasic('week', 'input[type="week"]');

                addInputsBasic('password', 'input[type="password"]');

                addInputsBasic('email', 'input[type="email"]');

                addInputsBasic('url', 'input[type="url"]');

                addInputsBasic('range', 'input[type="range"]');

                addInputsBasic('textarea', 'textarea');

                addInputsBasic('select', 'select:not([multiple])');

                addInputsBasic('select[multiple]', 'select[multiple]');

                addInputsBasic('file', 'input[type="file"]:not([multiple])');

                addInputsBasic('file[multiple]', 'input[type="file"][multiple]');

                addInputsBasic('hidden', 'input[type="hidden"]');

                addInputsGroup('radio', 'input[type="radio"]');

                addInputsGroup('checkbox', 'input[type="checkbox"]');

            }



            return inputs;

        };



        $.fn.inputVal = function (newValue) {

            var $self = $(this);



            var inputs = buildFormInputs({ $: $self });



            if($self.is('input, textarea, select')) {

                if(typeof newValue === 'undefined') {

                    return inputs[$self.attr('name')].get();

                }

                else {

                    inputs[$self.attr('name')].set(newValue);

                    return $self;

                }

            }

            else {

                if(typeof newValue === 'undefined') {

                    return call(inputs, 'get');

                }

                else {

                    foreach(newValue, function (value, inputName) {

                        inputs[inputName].set(value);

                    });

                    return $self;

                }

            }

        };



        $.fn.inputOnChange = function (callback) {

            var $self = $(this);

            var inputs = buildFormInputs({ $: $self });

            foreach(inputs, function (input) {

                input.subscribe('change', function (data) {

                    callback.call(data.domElement, data.e);

                });

            });

            return $self;

        };



        $.fn.inputDisable = function () {

            var $self = $(this);

            call(buildFormInputs({ $: $self }), 'disable');

            return $self;

        };



        $.fn.inputEnable = function () {

            var $self = $(this);

            call(buildFormInputs({ $: $self }), 'enable');

            return $self;

        };



        $.fn.inputClear = function () {

            var $self = $(this);

            call(buildFormInputs({ $: $self }), 'clear');

            return $self;

        };



    }(jQuery));



    $.fn.repeaterVal = function () {

        var parse = function (raw) {

            var parsed = [];



            foreach(raw, function (val, key) {

                var parsedKey = [];

                if(key !== "undefined") {

                    parsedKey.push(key.match(/^[^\[]*/)[0]);

                    parsedKey = parsedKey.concat(map(

                        key.match(/\[[^\]]*\]/g),

                        function (bracketed) {

                            return bracketed.replace(/[\[\]]/g, '');

                        }

                    ));



                    parsed.push({

                        val: val,

                        key: parsedKey

                    });

                }

            });



            return parsed;

        };



        var build = function (parsed) {

            if(

                parsed.length === 1 &&

                (parsed[0].key.length === 0 || parsed[0].key.length === 1 && !parsed[0].key[0])

            ) {

                return parsed[0].val;

            }



            foreach(parsed, function (p) {

                p.head = p.key.shift();

            });



            var grouped = (function () {

                var grouped = {};



                foreach(parsed, function (p) {

                    if(!grouped[p.head]) {

                        grouped[p.head] = [];

                    }

                    grouped[p.head].push(p);

                });



                return grouped;

            }());



            var built;



            if(/^[0-9]+$/.test(parsed[0].head)) {

                built = [];

                foreach(grouped, function (group) {

                    built.push(build(group));

                });

            }

            else {

                built = {};

                foreach(grouped, function (group, key) {

                    built[key] = build(group);

                });

            }



            return built;

        };



        return build(parse($(this).inputVal()));

    };



    $.fn.repeater = function (fig) {

        fig = fig || {};



        var setList;



        $(this).each(function () {



            var $self = $(this);



            var show = fig.show || function () {

                $(this).show();

            };



            var hide = fig.hide || function (removeElement) {

                removeElement();

            };



            var $list = $self.find('[data-repeater-list]').first();



            var $filterNested = function ($items, repeaters) {

                return $items.filter(function () {

                    return repeaters ?

                        $(this).closest(

                            pluck(repeaters, 'selector').join(',')

                        ).length === 0 : true;

                });

            };



            var $items = function () {

                return $filterNested($list.find('[data-repeater-item]'), fig.repeaters);

            };



            var $itemTemplate = $list.find('[data-repeater-item]')

                .first().clone().hide();



            var $firstDeleteButton = $filterNested(

                $filterNested($(this).find('[data-repeater-item]'), fig.repeaters)

                    .first().find('[data-repeater-delete]'),

                fig.repeaters

            );



            if(fig.isFirstItemUndeletable && $firstDeleteButton) {

                $firstDeleteButton.remove();

            }



            var getGroupName = function () {

                var groupName = $list.data('repeater-list');

                return fig.$parent ?

                    fig.$parent.data('item-name') + '[' + groupName + ']' :

                    groupName;

            };



            var initNested = function ($listItems) {

                if(fig.repeaters) {

                    $listItems.each(function () {

                        var $item = $(this);

                        foreach(fig.repeaters, function (nestedFig) {

                            $item.find(nestedFig.selector).repeater(extend(

                                nestedFig, { $parent: $item }

                            ));

                        });

                    });

                }

            };



            var $foreachRepeaterInItem = function (repeaters, $item, cb) {

                if(repeaters) {

                    foreach(repeaters, function (nestedFig) {

                        cb.call($item.find(nestedFig.selector)[0], nestedFig);

                    });

                }

            };



            var setIndexes = function ($items, groupName, repeaters) {

                $items.each(function (index) {

                    var $item = $(this);

                    $item.data('item-name', groupName + '[' + index + ']');

                    $filterNested($item.find('[name]'), repeaters)

                        .each(function () {

                            var $input = $(this);

                            // match non empty brackets (ex: "[foo]")

                            var matches = $input.attr('name').match(/\[[^\]]+\]/g);



                            var name = matches ?

                                // strip "[" and "]" characters

                                last(matches).replace(/\[|\]/g, '') :

                                $input.attr('name');





                            var newName = groupName + '[' + index + '][' + name + ']' +

                                ($input.is(':checkbox') || $input.attr('multiple') ? '[]' : '');



                            $input.attr('name', newName);



                            $foreachRepeaterInItem(repeaters, $item, function (nestedFig) {

                                var $repeater = $(this);

                                setIndexes(

                                    $filterNested($repeater.find('[data-repeater-item]'), nestedFig.repeaters || []),

                                    groupName + '[' + index + ']' +

                                    '[' + $repeater.find('[data-repeater-list]').first().data('repeater-list') + ']',

                                    nestedFig.repeaters

                                );

                            });

                        });

                });



                $list.find('input[name][checked]')

                    .removeAttr('checked')

                    .prop('checked', true);

            };



            setIndexes($items(), getGroupName(), fig.repeaters);

            initNested($items());

            if(fig.initEmpty) {

                $items().remove();

            }



            if(fig.ready) {

                fig.ready(function () {

                    setIndexes($items(), getGroupName(), fig.repeaters);

                });

            }



            var appendItem = (function () {

                var setItemsValues = function ($item, data, repeaters) {

                    if(data || fig.defaultValues) {

                        var inputNames = {};

                        $filterNested($item.find('[name]'), repeaters).each(function () {

                            var key = $(this).attr('name').match(/\[([^\]]*)(\]|\]\[\])$/)[1];

                            inputNames[key] = $(this).attr('name');

                        });



                        $item.inputVal(map(

                            filter(data || fig.defaultValues, function (val, name) {

                                return inputNames[name];

                            }),

                            identity,

                            function (name) {

                                return inputNames[name];

                            }

                        ));

                    }





                    $foreachRepeaterInItem(repeaters, $item, function (nestedFig) {

                        var $repeater = $(this);

                        $filterNested(

                            $repeater.find('[data-repeater-item]'),

                            nestedFig.repeaters

                        )

                            .each(function () {

                                var fieldName = $repeater.find('[data-repeater-list]').data('repeater-list');

                                if(data && data[fieldName]) {

                                    var $template = $(this).clone();

                                    $repeater.find('[data-repeater-item]').remove();

                                    foreach(data[fieldName], function (data) {

                                        var $item = $template.clone();

                                        setItemsValues(

                                            $item,

                                            data,

                                            nestedFig.repeaters || []

                                        );

                                        $repeater.find('[data-repeater-list]').append($item);

                                    });

                                }

                                else {

                                    setItemsValues(

                                        $(this),

                                        nestedFig.defaultValues,

                                        nestedFig.repeaters || []

                                    );

                                }

                            });

                    });



                };



                return function ($item, data) {

                    $list.append($item);

                    setIndexes($items(), getGroupName(), fig.repeaters);

                    $item.find('[name]').each(function () {

                        $(this).inputClear();

                    });

                    setItemsValues($item, data || fig.defaultValues, fig.repeaters);

                };

            }());



            var addItem = function (data) {

                var $item = $itemTemplate.clone();

                appendItem($item, data);

                if(fig.repeaters) {

                    initNested($item);

                }

                show.call($item.get(0));

            };



            setList = function (rows) {

                $items().remove();

                foreach(rows, addItem);

            };



            $filterNested($self.find('[data-repeater-create]'), fig.repeaters).click(function () {

                addItem();

            });



            $list.on('click', '[data-repeater-delete]', function () {

                var self = $(this).closest('[data-repeater-item]').get(0);

                hide.call(self, function () {

                    $(self).remove();

                    setIndexes($items(), getGroupName(), fig.repeaters);

                });

            });

        });



        this.setList = setList;



        return this;

    };



}(jQuery));

