/**
 *
 * -----------------------------------------------------------
 *
 * Codestar Framework
 * A Simple and Lightweight WordPress Option Framework
 *
 * -----------------------------------------------------------
 *
 */
;(function ($, window, document, undefined) {
    'use strict';

    //
    // Constants
    //
    var CSF = CSF || {};

    CSF.funcs = {};

    CSF.vars = {
        onloaded: false,
        $body: $('body'),
        $window: $(window),
        $document: $(document),
        $form_warning: null,
        is_confirm: false,
        form_modified: false,
        code_themes: [],
        is_rtl: $('body').hasClass('rtl'),
    };

    //
    // Helper Functions
    //
    CSF.helper = {

        //
        // Generate UID
        //
        uid: function (prefix) {
            return (prefix || '') + Math.random().toString(36).substr(2, 9);
        },

        // Quote regular expression characters
        //
        preg_quote: function (str) {
            return (str + '').replace(/(\[|\])/g, "\\$1");
        },

        //
        // Reneme input names
        //
        name_nested_replace: function ($selector, field_id) {

            var checks = [];
            var regex = new RegExp(CSF.helper.preg_quote(field_id + '[\\d+]'), 'g');

            $selector.find(':radio').each(function () {
                if (this.checked || this.orginal_checked) {
                    this.orginal_checked = true;
                }
            });

            $selector.each(function (index) {
                $(this).find(':input').each(function () {
                    this.name = this.name.replace(regex, field_id + '[' + index + ']');
                    if (this.orginal_checked) {
                        this.checked = true;
                    }
                });
            });

        },

        //
        // Debounce
        //
        debounce: function (callback, threshold, immediate) {
            var timeout;
            return function () {
                var context = this, args = arguments;
                var later = function () {
                    timeout = null;
                    if (!immediate) {
                        callback.apply(context, args);
                    }
                };
                var callNow = (immediate && !timeout);
                clearTimeout(timeout);
                timeout = setTimeout(later, threshold);
                if (callNow) {
                    callback.apply(context, args);
                }
            };
        },

    };

    //
    // Custom clone for textarea and select clone() bug
    //
    $.fn.csf_clone = function () {

        var base = $.fn.clone.apply(this, arguments),
            clone = this.find('select').add(this.filter('select')),
            cloned = base.find('select').add(base.filter('select'));

        for (var i = 0; i < clone.length; ++i) {
            for (var j = 0; j < clone[i].options.length; ++j) {

                if (clone[i].options[j].selected === true) {
                    cloned[i].options[j].selected = true;
                }

            }
        }

        this.find(':radio').each(function () {
            this.orginal_checked = this.checked;
        });

        return base;

    };

    //
    // Expand All Options
    //
    $.fn.csf_expand_all = function () {
        return this.each(function () {
            $(this).on('click', function (e) {

                e.preventDefault();
                $('.csf-wrapper').toggleClass('csf-show-all');
                $('.csf-section').csf_reload_script();
                $(this).find('.fa').toggleClass('fa-indent').toggleClass('fa-outdent');

            });
        });
    };

    //
    // Options Navigation
    //
    $.fn.csf_nav_options = function () {
        return this.each(function () {

            var $nav = $(this),
                $window = $(window),
                $wpwrap = $('#wpwrap'),
                $links = $nav.find('a'),
                $last;

            $window.on('hashchange csf.hashchange', function () {

                var hash = window.location.hash.replace('#tab=', '');
                var slug = hash ? hash : $links.first().attr('href').replace('#tab=', '');
                var $link = $('[data-tab-id="' + slug + '"]');

                if ($link.length) {

                    $link.closest('.csf-tab-item').addClass('csf-tab-expanded').siblings().removeClass('csf-tab-expanded');

                    if ($link.next().is('ul')) {

                        $link = $link.next().find('li').first().find('a');
                        slug = $link.data('tab-id');

                    }

                    $links.removeClass('csf-active');
                    $link.addClass('csf-active');

                    if ($last) {
                        $last.addClass('hidden');
                    }

                    var $section = $('[data-section-id="' + slug + '"]');

                    $section.removeClass('hidden');
                    $section.csf_reload_script();

                    $('.csf-section-id').val($section.index() + 1);

                    $last = $section;

                    if ($wpwrap.hasClass('wp-responsive-open')) {
                        $('html, body').animate({scrollTop: ($section.offset().top - 50)}, 200);
                        $wpwrap.removeClass('wp-responsive-open');
                    }

                }

            }).trigger('csf.hashchange');

        });
    };

    //
    // Metabox Tabs
    //
    $.fn.csf_nav_metabox = function () {
        return this.each(function () {

            var $nav = $(this),
                $links = $nav.find('a'),
                $sections = $nav.parent().find('.csf-section'),
                $last;

            $links.each(function (index) {

                $(this).on('click', function (e) {

                    e.preventDefault();

                    var $link = $(this);

                    $links.removeClass('csf-active');
                    $link.addClass('csf-active');

                    if ($last !== undefined) {
                        $last.addClass('hidden');
                    }

                    var $section = $sections.eq(index);

                    $section.removeClass('hidden');
                    $section.csf_reload_script();

                    $last = $section;

                });

            });

            $links.first().trigger('click');

        });
    };

    //
    // Metabox Page Templates Listener
    //
    $.fn.csf_page_templates = function () {
        if (this.length) {

            $(document).on('change', '.editor-page-attributes__template select, #page_template, .edit-post-post-status + div select', function () {

                var maybe_value = $(this).val() || 'default';

                $('.csf-page-templates').removeClass('csf-metabox-show').addClass('csf-metabox-hide');
                $('.csf-page-' + maybe_value.toLowerCase().replace(/[^a-zA-Z0-9]+/g, '-')).removeClass('csf-metabox-hide').addClass('csf-metabox-show');

            });

        }
    };

    //
    // Metabox Post Formats Listener
    //
    $.fn.csf_post_formats = function () {
        if (this.length) {

            $(document).on('change', '.editor-post-format select, #formatdiv input[name="post_format"]', function () {

                var maybe_value = $(this).val() || 'default';

                // Fallback for classic editor version
                maybe_value = (maybe_value === '0') ? 'default' : maybe_value;

                $('.csf-post-formats').removeClass('csf-metabox-show').addClass('csf-metabox-hide');
                $('.csf-post-format-' + maybe_value).removeClass('csf-metabox-hide').addClass('csf-metabox-show');

            });

        }
    };

    //
    // Search
    //
    $.fn.csf_search = function () {
        return this.each(function () {

            var $this = $(this),
                $input = $this.find('input');

            $input.on('change keyup', function () {

                var value = $(this).val(),
                    $wrapper = $('.csf-wrapper'),
                    $section = $wrapper.find('.csf-section'),
                    $fields = $section.find('> .csf-field:not(.csf-depend-on)'),
                    $titles = $fields.find('> .csf-title, .csf-search-tags');

                if (value.length > 3) {

                    $fields.addClass('csf-metabox-hide');
                    $wrapper.addClass('csf-search-all');

                    $titles.each(function () {

                        var $title = $(this);

                        if ($title.text().match(new RegExp('.*?' + value + '.*?', 'i'))) {

                            var $field = $title.closest('.csf-field');

                            $field.removeClass('csf-metabox-hide');
                            $field.parent().csf_reload_script();

                        }

                    });

                } else {

                    $fields.removeClass('csf-metabox-hide');
                    $wrapper.removeClass('csf-search-all');

                }

            });

        });
    };

    //
    // Sticky Header
    //
    $.fn.csf_sticky = function () {
        return this.each(function () {

            var $this = $(this),
                $window = $(window),
                $inner = $this.find('.csf-header-inner'),
                padding = parseInt($inner.css('padding-left')) + parseInt($inner.css('padding-right')),
                offset = 32,
                scrollTop = 0,
                lastTop = 0,
                ticking = false,
                stickyUpdate = function () {

                    var offsetTop = $this.offset().top,
                        stickyTop = Math.max(offset, offsetTop - scrollTop),
                        winWidth = $window.innerWidth();

                    if (stickyTop <= offset && winWidth > 782) {
                        $inner.css({width: $this.outerWidth() - padding});
                        $this.css({height: $this.outerHeight()}).addClass('csf-sticky');
                    } else {
                        $inner.removeAttr('style');
                        $this.removeAttr('style').removeClass('csf-sticky');
                    }

                },
                requestTick = function () {

                    if (!ticking) {
                        requestAnimationFrame(function () {
                            stickyUpdate();
                            ticking = false;
                        });
                    }

                    ticking = true;

                },
                onSticky = function () {

                    scrollTop = $window.scrollTop();
                    requestTick();

                };

            $window.on('scroll resize', onSticky);

            onSticky();

        });
    };

    //
    // Dependency System
    //
    $.fn.csf_dependency = function () {
        return this.each(function () {

            var $this = $(this),
                $fields = $this.children('[data-controller]');

            if ($fields.length) {

                var normal_ruleset = $.csf_deps.createRuleset(),
                    global_ruleset = $.csf_deps.createRuleset(),
                    normal_depends = [],
                    global_depends = [];

                $fields.each(function () {

                    var $field = $(this),
                        controllers = $field.data('controller').split('|'),
                        conditions = $field.data('condition').split('|'),
                        values = $field.data('value').toString().split('|'),
                        is_global = $field.data('depend-global') ? true : false,
                        ruleset = (is_global) ? global_ruleset : normal_ruleset;

                    $.each(controllers, function (index, depend_id) {

                        var value = values[index] || '',
                            condition = conditions[index] || conditions[0];

                        ruleset = ruleset.createRule('[data-depend-id="' + depend_id + '"]', condition, value);

                        ruleset.include($field);

                        if (is_global) {
                            global_depends.push(depend_id);
                        } else {
                            normal_depends.push(depend_id);
                        }

                    });

                });

                if (normal_depends.length) {
                    $.csf_deps.enable($this, normal_ruleset, normal_depends);
                }

                if (global_depends.length) {
                    $.csf_deps.enable(CSF.vars.$body, global_ruleset, global_depends);
                }

            }

        });
    };

    //
    // Field: accordion
    //
    $.fn.csf_field_accordion = function () {
        return this.each(function () {

            var $titles = $(this).find('.csf-accordion-title');

            $titles.on('click', function () {

                var $title = $(this),
                    $icon = $title.find('.csf-accordion-icon'),
                    $content = $title.next();

                if ($icon.hasClass('fa-angle-right')) {
                    $icon.removeClass('fa-angle-right').addClass('fa-angle-down');
                } else {
                    $icon.removeClass('fa-angle-down').addClass('fa-angle-right');
                }

                if (!$content.data('opened')) {

                    $content.csf_reload_script();
                    $content.data('opened', true);

                }

                $content.toggleClass('csf-accordion-open');

            });

        });
    };

    //
    // Field: backup
    //
    $.fn.csf_field_backup = function () {
        return this.each(function () {

            if (window.wp.customize === undefined) {
                return;
            }

            var base = this,
                $this = $(this),
                $body = $('body'),
                $import = $this.find('.csf-import'),
                $reset = $this.find('.csf-reset');

            base.notificationOverlay = function () {

                if (wp.customize.notifications && wp.customize.OverlayNotification) {

                    // clear if there is any saved data.
                    if (!wp.customize.state('saved').get()) {
                        wp.customize.state('changesetStatus').set('trash');
                        wp.customize.each(function (setting) {
                            setting._dirty = false;
                        });
                        wp.customize.state('saved').set(true);
                    }

                    // then show a notification overlay
                    wp.customize.notifications.add(new wp.customize.OverlayNotification('csf_field_backup_notification', {
                        type: 'default',
                        message: '&nbsp;',
                        loading: true
                    }));

                }

            };

            $reset.on('click', function (e) {

                e.preventDefault();

                if (CSF.vars.is_confirm) {

                    base.notificationOverlay();

                    window.wp.ajax.post('csf-reset', {
                        unique: $reset.data('unique'),
                        nonce: $reset.data('nonce')
                    })
                        .done(function (response) {
                            window.location.reload(true);
                        })
                        .fail(function (response) {
                            alert(response.error);
                            wp.customize.notifications.remove('csf_field_backup_notification');
                        });

                }

            });

            $import.on('click', function (e) {

                e.preventDefault();

                if (CSF.vars.is_confirm) {

                    base.notificationOverlay();

                    window.wp.ajax.post('csf-import', {
                        unique: $import.data('unique'),
                        nonce: $import.data('nonce'),
                        data: $this.find('.csf-import-data').val()
                    }).done(function (response) {
                        window.location.reload(true);
                    }).fail(function (response) {
                        alert(response.error);
                        wp.customize.notifications.remove('csf_field_backup_notification');
                    });

                }

            });

        });
    };

    //
    // Field: background
    //
    $.fn.csf_field_background = function () {
        return this.each(function () {
            $(this).find('.csf--background-image').csf_reload_script();
        });
    };

    //
    // Field: code_editor
    //
    $.fn.csf_field_code_editor = function () {
        return this.each(function () {

            if (typeof CodeMirror !== 'function') {
                return;
            }

            var $this = $(this),
                $textarea = $this.find('textarea'),
                $inited = $this.find('.CodeMirror'),
                data_editor = $textarea.data('editor');

            if ($inited.length) {
                $inited.remove();
            }

            var interval = setInterval(function () {
                if ($this.is(':visible')) {

                    var code_editor = CodeMirror.fromTextArea($textarea[0], data_editor);

                    // load code-mirror theme css.
                    if (data_editor.theme !== 'default' && CSF.vars.code_themes.indexOf(data_editor.theme) === -1) {

                        var $cssLink = $('<link>');

                        $('#csf-codemirror-css').after($cssLink);

                        $cssLink.attr({
                            rel: 'stylesheet',
                            id: 'csf-codemirror-' + data_editor.theme + '-css',
                            href: data_editor.cdnURL + '/theme/' + data_editor.theme + '.min.css',
                            type: 'text/css',
                            media: 'all'
                        });

                        CSF.vars.code_themes.push(data_editor.theme);

                    }

                    CodeMirror.modeURL = data_editor.cdnURL + '/mode/%N/%N.min.js';
                    CodeMirror.autoLoadMode(code_editor, data_editor.mode);

                    code_editor.on('change', function (editor, event) {
                        $textarea.val(code_editor.getValue()).trigger('change');
                    });

                    clearInterval(interval);

                }
            });

        });
    };

    //
    // Field: date
    //
    $.fn.csf_field_date = function () {
        return this.each(function () {

            var $this = $(this),
                $inputs = $this.find('input'),
                settings = $this.find('.csf-date-settings').data('settings'),
                wrapper = '<div class="csf-datepicker-wrapper"></div>';

            var defaults = {
                showAnim: '',
                beforeShow: function (input, inst) {
                    $(inst.dpDiv).addClass('csf-datepicker-wrapper');
                },
                onClose: function (input, inst) {
                    $(inst.dpDiv).removeClass('csf-datepicker-wrapper');
                },
            };

            settings = $.extend({}, settings, defaults);

            if ($inputs.length === 2) {

                settings = $.extend({}, settings, {
                    onSelect: function (selectedDate) {

                        var $this = $(this),
                            $from = $inputs.first(),
                            option = ($inputs.first().attr('id') === $(this).attr('id')) ? 'minDate' : 'maxDate',
                            date = $.datepicker.parseDate(settings.dateFormat, selectedDate);

                        $inputs.not(this).datepicker('option', option, date);

                    }
                });

            }

            $inputs.each(function () {

                var $input = $(this);

                if ($input.hasClass('hasDatepicker')) {
                    $input.removeAttr('id').removeClass('hasDatepicker');
                }

                $input.datepicker(settings);

            });

        });
    };

    //
    // Field: datetime
    //
    $.fn.csf_field_datetime = function () {
        return this.each(function () {

            var $this = $(this),
                $inputs = $this.find('input'),
                settings = $this.find('.csf-datetime-settings').data('settings');

            settings = $.extend({}, settings, {
                onReady: function (selectedDates, dateStr, instance) {
                    $(instance.calendarContainer).addClass('csf-flatpickr');
                },
            });

            if ($inputs.length === 2) {
                settings = $.extend({}, settings, {
                    onChange: function (selectedDates, dateStr, instance) {
                        if ($(instance.element).data('type') === 'from') {
                            $inputs.last().get(0)._flatpickr.set('minDate', selectedDates[0]);
                        } else {
                            $inputs.first().get(0)._flatpickr.set('maxDate', selectedDates[0]);
                        }
                    },
                });
            }

            $inputs.each(function () {
                $(this).flatpickr(settings);
            });

        });
    };

    //
    // Field: fieldset
    //
    $.fn.csf_field_fieldset = function () {
        return this.each(function () {
            $(this).find('.csf-fieldset-content').csf_reload_script();
        });
    };

    //
    // Field: gallery
    //
    $.fn.csf_field_gallery = function () {
        return this.each(function () {

            var $this = $(this),
                $edit = $this.find('.csf-edit-gallery'),
                $clear = $this.find('.csf-clear-gallery'),
                $list = $this.find('ul'),
                $input = $this.find('input'),
                $img = $this.find('img'),
                wp_media_frame;

            $this.on('click', '.csf-button, .csf-edit-gallery', function (e) {

                var $el = $(this),
                    ids = $input.val(),
                    what = ($el.hasClass('csf-edit-gallery')) ? 'edit' : 'add',
                    state = (what === 'add' && !ids.length) ? 'gallery' : 'gallery-edit';

                e.preventDefault();

                if (typeof window.wp === 'undefined' || !window.wp.media || !window.wp.media.gallery) {
                    return;
                }

                // Open media with state
                if (state === 'gallery') {

                    wp_media_frame = window.wp.media({
                        library: {
                            type: 'image'
                        },
                        frame: 'post',
                        state: 'gallery',
                        multiple: true
                    });

                    wp_media_frame.open();

                } else {

                    wp_media_frame = window.wp.media.gallery.edit('[gallery ids="' + ids + '"]');

                    if (what === 'add') {
                        wp_media_frame.setState('gallery-library');
                    }

                }

                // Media Update
                wp_media_frame.on('update', function (selection) {

                    $list.empty();

                    var selectedIds = selection.models.map(function (attachment) {

                        var item = attachment.toJSON();
                        var thumb = (item.sizes && item.sizes.thumbnail && item.sizes.thumbnail.url) ? item.sizes.thumbnail.url : item.url;

                        $list.append('<li><img src="' + thumb + '"></li>');

                        return item.id;

                    });

                    $input.val(selectedIds.join(',')).trigger('change');
                    $clear.removeClass('hidden');
                    $edit.removeClass('hidden');

                });

            });

            $clear.on('click', function (e) {
                e.preventDefault();
                $list.empty();
                $input.val('').trigger('change');
                $clear.addClass('hidden');
                $edit.addClass('hidden');
            });

        });

    };

    //
    // Field: group
    //
    $.fn.csf_field_group = function () {
        return this.each(function () {

            var $this = $(this),
                $fieldset = $this.children('.csf-fieldset'),
                $group = $fieldset.length ? $fieldset : $this,
                $wrapper = $group.children('.csf-cloneable-wrapper'),
                $hidden = $group.children('.csf-cloneable-hidden'),
                $max = $group.children('.csf-cloneable-max'),
                $min = $group.children('.csf-cloneable-min'),
                title_by = $wrapper.data('title-by'),
                title_prefix = $wrapper.data('title-by-prefix'),
                field_id = $wrapper.data('field-id'),
                is_number = Boolean(Number($wrapper.data('title-number'))),
                max = parseInt($wrapper.data('max')),
                min = parseInt($wrapper.data('min'));

            // clear accordion arrows if multi-instance
            if ($wrapper.hasClass('ui-accordion')) {
                $wrapper.find('.ui-accordion-header-icon').remove();
            }

            var update_title_numbers = function ($selector) {
                $selector.find('.csf-cloneable-title-number').each(function (index) {
                    $(this).html(($(this).closest('.csf-cloneable-item').index() + 1) + '.');
                });
            };

            $wrapper.accordion({
                header: '> .csf-cloneable-item > .csf-cloneable-title',
                collapsible: true,
                active: false,
                animate: false,
                heightStyle: 'content',
                icons: {
                    'header': 'csf-cloneable-header-icon fas fa-angle-right',
                    'activeHeader': 'csf-cloneable-header-icon fas fa-angle-down'
                },
                activate: function (event, ui) {

                    var $panel = ui.newPanel;
                    var $header = ui.newHeader;

                    if ($panel.length && !$panel.data('opened')) {

                        var $title = $header.find('.csf-cloneable-value');
                        var inputs = [];

                        $.each(title_by, function (key, title_key) {
                            inputs.push($panel.find('[data-depend-id="' + title_key + '"]'));
                        });

                        $.each(inputs, function (key, $input) {

                            $input.on('change keyup csf.keyup', function () {

                                var titles = [];

                                $.each(inputs, function (key, $input) {

                                    var input_value = $input.val();

                                    if (input_value) {
                                        titles.push(input_value);
                                    }

                                });

                                if (titles.length) {
                                    $title.text(titles.join(title_prefix));
                                }

                            }).trigger('csf.keyup');

                        });

                        $panel.csf_reload_script();
                        $panel.data('opened', true);
                        $panel.data('retry', false);

                    } else if ($panel.data('retry')) {

                        $panel.csf_reload_script_retry();
                        $panel.data('retry', false);

                    }

                }
            });

            $wrapper.sortable({
                axis: 'y',
                handle: '.csf-cloneable-title,.csf-cloneable-sort',
                helper: 'original',
                cursor: 'move',
                placeholder: 'widget-placeholder',
                start: function (event, ui) {

                    $wrapper.accordion({active: false});
                    $wrapper.sortable('refreshPositions');
                    ui.item.children('.csf-cloneable-content').data('retry', true);

                },
                update: function (event, ui) {

                    CSF.helper.name_nested_replace($wrapper.children('.csf-cloneable-item'), field_id);
                    $wrapper.csf_customizer_refresh();

                    if (is_number) {
                        update_title_numbers($wrapper);
                    }

                },
            });

            $group.children('.csf-cloneable-add').on('click', function (e) {

                e.preventDefault();

                var count = $wrapper.children('.csf-cloneable-item').length;

                $min.hide();

                if (max && (count + 1) > max) {
                    $max.show();
                    return;
                }

                var $cloned_item = $hidden.csf_clone(true);

                $cloned_item.removeClass('csf-cloneable-hidden');

                $cloned_item.find(':input[name!="_pseudo"]').each(function () {
                    this.name = this.name.replace('___', '').replace(field_id + '[0]', field_id + '[' + count + ']');
                });

                $wrapper.append($cloned_item);
                $wrapper.accordion('refresh');
                $wrapper.accordion({active: count});
                $wrapper.csf_customizer_refresh();
                $wrapper.csf_customizer_listen({closest: true});

                if (is_number) {
                    update_title_numbers($wrapper);
                }

            });

            var event_clone = function (e) {

                e.preventDefault();

                var count = $wrapper.children('.csf-cloneable-item').length;

                $min.hide();

                if (max && (count + 1) > max) {
                    $max.show();
                    return;
                }

                var $this = $(this),
                    $parent = $this.parent().parent(),
                    $cloned_helper = $parent.children('.csf-cloneable-helper').csf_clone(true),
                    $cloned_title = $parent.children('.csf-cloneable-title').csf_clone(),
                    $cloned_content = $parent.children('.csf-cloneable-content').csf_clone(),
                    $cloned_item = $('<div class="csf-cloneable-item" />');

                $cloned_item.append($cloned_helper);
                $cloned_item.append($cloned_title);
                $cloned_item.append($cloned_content);

                $wrapper.children().eq($parent.index()).after($cloned_item);

                CSF.helper.name_nested_replace($wrapper.children('.csf-cloneable-item'), field_id);

                $wrapper.accordion('refresh');
                $wrapper.csf_customizer_refresh();
                $wrapper.csf_customizer_listen({closest: true});

                if (is_number) {
                    update_title_numbers($wrapper);
                }

            };

            $wrapper.children('.csf-cloneable-item').children('.csf-cloneable-helper').on('click', '.csf-cloneable-clone', event_clone);
            $group.children('.csf-cloneable-hidden').children('.csf-cloneable-helper').on('click', '.csf-cloneable-clone', event_clone);

            var event_remove = function (e) {

                e.preventDefault();

                var count = $wrapper.children('.csf-cloneable-item').length;

                $max.hide();
                $min.hide();

                if (min && (count - 1) < min) {
                    $min.show();
                    return;
                }

                $(this).closest('.csf-cloneable-item').remove();

                CSF.helper.name_nested_replace($wrapper.children('.csf-cloneable-item'), field_id);

                $wrapper.csf_customizer_refresh();

                if (is_number) {
                    update_title_numbers($wrapper);
                }

            };

            $wrapper.children('.csf-cloneable-item').children('.csf-cloneable-helper').on('click', '.csf-cloneable-remove', event_remove);
            $group.children('.csf-cloneable-hidden').children('.csf-cloneable-helper').on('click', '.csf-cloneable-remove', event_remove);

        });
    };

    //
    // Field: icon
    //
    $.fn.csf_field_icon = function () {
        return this.each(function () {

            var $this = $(this);

            $this.on('click', '.csf-icon-add', function (e) {

                e.preventDefault();

                var $button = $(this);
                var $modal = $('#csf-modal-icon');

                $modal.removeClass('hidden');

                CSF.vars.$icon_target = $this;

                if (!CSF.vars.icon_modal_loaded) {

                    $modal.find('.csf-modal-loading').show();

                    window.wp.ajax.post('csf-get-icons', {
                        nonce: $button.data('nonce')
                    }).done(function (response) {

                        $modal.find('.csf-modal-loading').hide();

                        CSF.vars.icon_modal_loaded = true;

                        var $load = $modal.find('.csf-modal-load').html(response.content);

                        $load.on('click', 'i', function (e) {

                            e.preventDefault();

                            var icon = $(this).attr('title');

                            CSF.vars.$icon_target.find('.csf-icon-preview i').removeAttr('class').addClass(icon);
                            CSF.vars.$icon_target.find('.csf-icon-preview').removeClass('hidden');
                            CSF.vars.$icon_target.find('.csf-icon-remove').removeClass('hidden');
                            CSF.vars.$icon_target.find('input').val(icon).trigger('change');

                            $modal.addClass('hidden');

                        });

                        $modal.on('change keyup', '.csf-icon-search', function () {

                            var value = $(this).val(),
                                $icons = $load.find('i');

                            $icons.each(function () {

                                var $elem = $(this);

                                if ($elem.attr('title').search(new RegExp(value, 'i')) < 0) {
                                    $elem.hide();
                                } else {
                                    $elem.show();
                                }

                            });

                        });

                        $modal.on('click', '.csf-modal-close, .csf-modal-overlay', function () {
                            $modal.addClass('hidden');
                        });

                    }).fail(function (response) {
                        $modal.find('.csf-modal-loading').hide();
                        $modal.find('.csf-modal-load').html(response.error);
                        $modal.on('click', function () {
                            $modal.addClass('hidden');
                        });
                    });
                }

            });

            $this.on('click', '.csf-icon-remove', function (e) {
                e.preventDefault();
                $this.find('.csf-icon-preview').addClass('hidden');
                $this.find('input').val('').trigger('change');
                $(this).addClass('hidden');
            });

        });
    };

    //
    // Field: map
    //
    $.fn.csf_field_map = function () {
        return this.each(function () {

            if (typeof L === 'undefined') {
                return;
            }

            var $this = $(this),
                $map = $this.find('.csf--map-osm'),
                $search_input = $this.find('.csf--map-search input'),
                $latitude = $this.find('.csf--latitude'),
                $longitude = $this.find('.csf--longitude'),
                $zoom = $this.find('.csf--zoom'),
                map_data = $map.data('map');

            var mapInit = L.map($map.get(0), map_data);

            L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
            }).addTo(mapInit);

            var mapMarker = L.marker(map_data.center, {draggable: true}).addTo(mapInit);

            var update_latlng = function (data) {
                $latitude.val(data.lat);
                $longitude.val(data.lng);
                $zoom.val(mapInit.getZoom());
            };

            mapInit.on('click', function (data) {
                mapMarker.setLatLng(data.latlng);
                update_latlng(data.latlng);
            });

            mapInit.on('zoom', function () {
                update_latlng(mapMarker.getLatLng());
            });

            mapMarker.on('drag', function () {
                update_latlng(mapMarker.getLatLng());
            });

            if (!$search_input.length) {
                $search_input = $('[data-depend-id="' + $this.find('.csf--address-field').data('address-field') + '"]');
            }

            var cache = {};

            $search_input.autocomplete({
                source: function (request, response) {

                    var term = request.term;

                    if (term in cache) {
                        response(cache[term]);
                        return;
                    }

                    $.get('https://nominatim.openstreetmap.org/search', {
                        format: 'json',
                        q: term,
                    }, function (results) {

                        var data;

                        if (results.length) {
                            data = results.map(function (item) {
                                return {
                                    value: item.display_name,
                                    label: item.display_name,
                                    lat: item.lat,
                                    lon: item.lon
                                };
                            }, 'json');
                        } else {
                            data = [{
                                value: 'no-data',
                                label: 'No Results.'
                            }];
                        }

                        cache[term] = data;
                        response(data);

                    });

                },
                select: function (event, ui) {

                    if (ui.item.value === 'no-data') {
                        return false;
                    }

                    var latLng = L.latLng(ui.item.lat, ui.item.lon);

                    mapInit.panTo(latLng);
                    mapMarker.setLatLng(latLng);
                    update_latlng(latLng);

                },
                create: function (event, ui) {
                    $(this).autocomplete('widget').addClass('csf-map-ui-autocomplate');
                }
            });

            var input_update_latlng = function () {

                var latLng = L.latLng($latitude.val(), $longitude.val());

                mapInit.panTo(latLng);
                mapMarker.setLatLng(latLng);

            };

            $latitude.on('change', input_update_latlng);
            $longitude.on('change', input_update_latlng);

        });
    };

    //
    // Field: link
    //
    $.fn.csf_field_link = function () {
        return this.each(function () {

            var $this = $(this),
                $link = $this.find('.csf--link'),
                $add = $this.find('.csf--add'),
                $edit = $this.find('.csf--edit'),
                $remove = $this.find('.csf--remove'),
                $result = $this.find('.csf--result'),
                uniqid = CSF.helper.uid('csf-wplink-textarea-');

            $add.on('click', function (e) {

                e.preventDefault();

                window.wpLink.open(uniqid);

            });

            $edit.on('click', function (e) {

                e.preventDefault();

                $add.trigger('click');

                $('#wp-link-url').val($this.find('.csf--url').val());
                $('#wp-link-text').val($this.find('.csf--text').val());
                $('#wp-link-target').prop('checked', ($this.find('.csf--target').val() === '_blank'));

            });

            $remove.on('click', function (e) {

                e.preventDefault();

                $this.find('.csf--url').val('').trigger('change');
                $this.find('.csf--text').val('');
                $this.find('.csf--target').val('');

                $add.removeClass('hidden');
                $edit.addClass('hidden');
                $remove.addClass('hidden');
                $result.parent().addClass('hidden');

            });

            $link.attr('id', uniqid).on('change', function () {

                var atts = window.wpLink.getAttrs(),
                    href = atts.href,
                    text = $('#wp-link-text').val(),
                    target = (atts.target) ? atts.target : '';

                $this.find('.csf--url').val(href).trigger('change');
                $this.find('.csf--text').val(text);
                $this.find('.csf--target').val(target);

                $result.html('{url:"' + href + '", text:"' + text + '", target:"' + target + '"}');

                $add.addClass('hidden');
                $edit.removeClass('hidden');
                $remove.removeClass('hidden');
                $result.parent().removeClass('hidden');

            });

        });

    };

    //
    // Field: media
    //
    $.fn.csf_field_media = function () {
        return this.each(function () {

            var $this = $(this),
                $upload_button = $this.find('.csf--button'),
                $remove_button = $this.find('.csf--remove'),
                $library = $upload_button.data('library') && $upload_button.data('library').split(',') || '',
                $auto_attributes = ($this.hasClass('csf-assign-field-background')) ? $this.closest('.csf-field-background').find('.csf--auto-attributes') : false,
                wp_media_frame;

            $upload_button.on('click', function (e) {

                e.preventDefault();

                if (typeof window.wp === 'undefined' || !window.wp.media || !window.wp.media.gallery) {
                    return;
                }

                if (wp_media_frame) {
                    wp_media_frame.open();
                    return;
                }

                wp_media_frame = window.wp.media({
                    library: {
                        type: $library
                    }
                });

                wp_media_frame.on('select', function () {

                    var thumbnail;
                    var attributes = wp_media_frame.state().get('selection').first().attributes;
                    var preview_size = $upload_button.data('preview-size') || 'thumbnail';

                    if ($library.length && $library.indexOf(attributes.subtype) === -1 && $library.indexOf(attributes.type) === -1) {
                        return;
                    }

                    $this.find('.csf--id').val(attributes.id);
                    $this.find('.csf--width').val(attributes.width);
                    $this.find('.csf--height').val(attributes.height);
                    $this.find('.csf--alt').val(attributes.alt);
                    $this.find('.csf--title').val(attributes.title);
                    $this.find('.csf--description').val(attributes.description);

                    if (typeof attributes.sizes !== 'undefined' && typeof attributes.sizes.thumbnail !== 'undefined' && preview_size === 'thumbnail') {
                        thumbnail = attributes.sizes.thumbnail.url;
                    } else if (typeof attributes.sizes !== 'undefined' && typeof attributes.sizes.full !== 'undefined') {
                        thumbnail = attributes.sizes.full.url;
                    } else if (attributes.type === 'image') {
                        thumbnail = attributes.url;
                    } else {
                        thumbnail = attributes.icon;
                    }

                    if ($auto_attributes) {
                        $auto_attributes.removeClass('csf--attributes-hidden');
                    }

                    $remove_button.removeClass('hidden');

                    $this.find('.csf--preview').removeClass('hidden');
                    $this.find('.csf--src').attr('src', thumbnail);
                    $this.find('.csf--thumbnail').val(thumbnail);
                    $this.find('.csf--url').val(attributes.url).trigger('change');

                });

                wp_media_frame.open();

            });

            $remove_button.on('click', function (e) {

                e.preventDefault();

                if ($auto_attributes) {
                    $auto_attributes.addClass('csf--attributes-hidden');
                }

                $remove_button.addClass('hidden');
                $this.find('input').val('');
                $this.find('.csf--preview').addClass('hidden');
                $this.find('.csf--url').trigger('change');

            });

        });

    };

    //
    // Field: repeater
    //
    $.fn.csf_field_repeater = function () {
        return this.each(function () {

            var $this = $(this),
                $fieldset = $this.children('.csf-fieldset'),
                $repeater = $fieldset.length ? $fieldset : $this,
                $wrapper = $repeater.children('.csf-repeater-wrapper'),
                $hidden = $repeater.children('.csf-repeater-hidden'),
                $max = $repeater.children('.csf-repeater-max'),
                $min = $repeater.children('.csf-repeater-min'),
                field_id = $wrapper.data('field-id'),
                max = parseInt($wrapper.data('max')),
                min = parseInt($wrapper.data('min'));

            $wrapper.children('.csf-repeater-item').children('.csf-repeater-content').csf_reload_script();

            $wrapper.sortable({
                axis: 'y',
                handle: '.csf-repeater-sort',
                helper: 'original',
                cursor: 'move',
                placeholder: 'widget-placeholder',
                update: function (event, ui) {

                    CSF.helper.name_nested_replace($wrapper.children('.csf-repeater-item'), field_id);
                    $wrapper.csf_customizer_refresh();
                    ui.item.csf_reload_script_retry();

                }
            });

            $repeater.children('.csf-repeater-add').on('click', function (e) {

                e.preventDefault();

                var count = $wrapper.children('.csf-repeater-item').length;

                $min.hide();

                if (max && (count + 1) > max) {
                    $max.show();
                    return;
                }

                var $cloned_item = $hidden.csf_clone(true);

                $cloned_item.removeClass('csf-repeater-hidden');

                $cloned_item.find(':input[name!="_pseudo"]').each(function () {
                    this.name = this.name.replace('___', '').replace(field_id + '[0]', field_id + '[' + count + ']');
                });

                $wrapper.append($cloned_item);
                $cloned_item.children('.csf-repeater-content').csf_reload_script();
                $wrapper.csf_customizer_refresh();
                $wrapper.csf_customizer_listen({closest: true});

            });

            var event_clone = function (e) {

                e.preventDefault();

                var count = $wrapper.children('.csf-repeater-item').length;

                $min.hide();

                if (max && (count + 1) > max) {
                    $max.show();
                    return;
                }

                var $this = $(this),
                    $parent = $this.parent().parent().parent(),
                    $cloned_content = $parent.children('.csf-repeater-content').csf_clone(),
                    $cloned_helper = $parent.children('.csf-repeater-helper').csf_clone(true),
                    $cloned_item = $('<div class="csf-repeater-item" />');

                $cloned_item.append($cloned_content);
                $cloned_item.append($cloned_helper);

                $wrapper.children().eq($parent.index()).after($cloned_item);

                $cloned_item.children('.csf-repeater-content').csf_reload_script();

                CSF.helper.name_nested_replace($wrapper.children('.csf-repeater-item'), field_id);

                $wrapper.csf_customizer_refresh();
                $wrapper.csf_customizer_listen({closest: true});

            };

            $wrapper.children('.csf-repeater-item').children('.csf-repeater-helper').on('click', '.csf-repeater-clone', event_clone);
            $repeater.children('.csf-repeater-hidden').children('.csf-repeater-helper').on('click', '.csf-repeater-clone', event_clone);

            var event_remove = function (e) {

                e.preventDefault();

                var count = $wrapper.children('.csf-repeater-item').length;

                $max.hide();
                $min.hide();

                if (min && (count - 1) < min) {
                    $min.show();
                    return;
                }

                $(this).closest('.csf-repeater-item').remove();

                CSF.helper.name_nested_replace($wrapper.children('.csf-repeater-item'), field_id);

                $wrapper.csf_customizer_refresh();

            };

            $wrapper.children('.csf-repeater-item').children('.csf-repeater-helper').on('click', '.csf-repeater-remove', event_remove);
            $repeater.children('.csf-repeater-hidden').children('.csf-repeater-helper').on('click', '.csf-repeater-remove', event_remove);

        });
    };

    //
    // Field: slider
    //
    $.fn.csf_field_slider = function () {
        return this.each(function () {

            var $this = $(this),
                $input = $this.find('input'),
                $slider = $this.find('.csf-slider-ui'),
                data = $input.data(),
                value = $input.val() || 0;

            if ($slider.hasClass('ui-slider')) {
                $slider.empty();
            }

            $slider.slider({
                range: 'min',
                value: value,
                min: data.min || 0,
                max: data.max || 100,
                step: data.step || 1,
                slide: function (e, o) {
                    $input.val(o.value).trigger('change');
                }
            });

            $input.on('keyup', function () {
                $slider.slider('value', $input.val());
            });

        });
    };

    //
    // Field: sortable
    //
    $.fn.csf_field_sortable = function () {
        return this.each(function () {

            var $sortable = $(this).find('.csf-sortable');

            $sortable.sortable({
                axis: 'y',
                helper: 'original',
                cursor: 'move',
                placeholder: 'widget-placeholder',
                update: function (event, ui) {
                    $sortable.csf_customizer_refresh();
                }
            });

            $sortable.find('.csf-sortable-content').csf_reload_script();

        });
    };

    //
    // Field: sorter
    //
    $.fn.csf_field_sorter = function () {
        return this.each(function () {

            var $this = $(this),
                $enabled = $this.find('.csf-enabled'),
                $has_disabled = $this.find('.csf-disabled'),
                $disabled = ($has_disabled.length) ? $has_disabled : false;

            $enabled.sortable({
                connectWith: $disabled,
                placeholder: 'ui-sortable-placeholder',
                update: function (event, ui) {

                    var $el = ui.item.find('input');

                    if (ui.item.parent().hasClass('csf-enabled')) {
                        $el.attr('name', $el.attr('name').replace('disabled', 'enabled'));
                    } else {
                        $el.attr('name', $el.attr('name').replace('enabled', 'disabled'));
                    }

                    $this.csf_customizer_refresh();

                }
            });

            if ($disabled) {

                $disabled.sortable({
                    connectWith: $enabled,
                    placeholder: 'ui-sortable-placeholder',
                    update: function (event, ui) {
                        $this.csf_customizer_refresh();
                    }
                });

            }

        });
    };

    //
    // Field: spinner
    //
    $.fn.csf_field_spinner = function () {
        return this.each(function () {

            var $this = $(this),
                $input = $this.find('input'),
                $inited = $this.find('.ui-button'),
                data = $input.data();

            if ($inited.length) {
                $inited.remove();
            }

            $input.spinner({
                min: data.min || 0,
                max: data.max || 100,
                step: data.step || 1,
                create: function (event, ui) {
                    if (data.unit) {
                        $input.after('<span class="ui-button csf--unit">' + data.unit + '</span>');
                    }
                },
                spin: function (event, ui) {
                    $input.val(ui.value).trigger('change');
                }
            });

        });
    };

    //
    // Field: switcher
    //
    $.fn.csf_field_switcher = function () {
        return this.each(function () {

            var $switcher = $(this).find('.csf--switcher');

            $switcher.on('click', function () {

                var value = 0;
                var $input = $switcher.find('input');

                if ($switcher.hasClass('csf--active')) {
                    $switcher.removeClass('csf--active');
                } else {
                    value = 1;
                    $switcher.addClass('csf--active');
                }

                $input.val(value).trigger('change');

            });

        });
    };

    //
    // Field: tabbed
    //
    $.fn.csf_field_tabbed = function () {
        return this.each(function () {

            var $this = $(this),
                $links = $this.find('.csf-tabbed-nav a'),
                $contents = $this.find('.csf-tabbed-content');

            $contents.eq(0).csf_reload_script();

            $links.on('click', function (e) {

                e.preventDefault();

                var $link = $(this),
                    index = $link.index(),
                    $content = $contents.eq(index);

                $link.addClass('csf-tabbed-active').siblings().removeClass('csf-tabbed-active');
                $content.csf_reload_script();
                $content.removeClass('hidden').siblings().addClass('hidden');

            });

        });
    };

    //
    // Field: typography
    //
    $.fn.csf_field_typography = function () {
        return this.each(function () {

            var base = this;
            var $this = $(this);
            var loaded_fonts = [];
            var webfonts = csf_typography_json.webfonts;
            var googlestyles = csf_typography_json.googlestyles;
            var defaultstyles = csf_typography_json.defaultstyles;

            //
            //
            // Sanitize google font subset
            base.sanitize_subset = function (subset) {
                subset = subset.replace('-ext', ' Extended');
                subset = subset.charAt(0).toUpperCase() + subset.slice(1);
                return subset;
            };

            //
            //
            // Sanitize google font styles (weight and style)
            base.sanitize_style = function (style) {
                return googlestyles[style] ? googlestyles[style] : style;
            };

            //
            //
            // Load google font
            base.load_google_font = function (font_family, weight, style) {

                if (font_family && typeof WebFont === 'object') {

                    weight = weight ? weight.replace('normal', '') : '';
                    style = style ? style.replace('normal', '') : '';

                    if (weight || style) {
                        font_family = font_family + ':' + weight + style;
                    }

                    if (loaded_fonts.indexOf(font_family) === -1) {
                        WebFont.load({google: {families: [font_family]}});
                    }

                    loaded_fonts.push(font_family);

                }

            };

            //
            //
            // Append select options
            base.append_select_options = function ($select, options, condition, type, is_multi) {

                $select.find('option').not(':first').remove();

                var opts = '';

                $.each(options, function (key, value) {

                    var selected;
                    var name = value;

                    // is_multi
                    if (is_multi) {
                        selected = (condition && condition.indexOf(value) !== -1) ? ' selected' : '';
                    } else {
                        selected = (condition && condition === value) ? ' selected' : '';
                    }

                    if (type === 'subset') {
                        name = base.sanitize_subset(value);
                    } else if (type === 'style') {
                        name = base.sanitize_style(value);
                    }

                    opts += '<option value="' + value + '"' + selected + '>' + name + '</option>';

                });

                $select.append(opts).trigger('csf.change').trigger('chosen:updated');

            };

            base.init = function () {

                //
                //
                // Constants
                var selected_styles = [];
                var $typography = $this.find('.csf--typography');
                var $type = $this.find('.csf--type');
                var $styles = $this.find('.csf--block-font-style');
                var unit = $typography.data('unit');
                var line_height_unit = $typography.data('line-height-unit');
                var exclude_fonts = $typography.data('exclude') ? $typography.data('exclude').split(',') : [];

                //
                //
                // Chosen init
                if ($this.find('.csf--chosen').length) {

                    var $chosen_selects = $this.find('select');

                    $chosen_selects.each(function () {

                        var $chosen_select = $(this),
                            $chosen_inited = $chosen_select.parent().find('.chosen-container');

                        if ($chosen_inited.length) {
                            $chosen_inited.remove();
                        }

                        $chosen_select.chosen({
                            allow_single_deselect: true,
                            disable_search_threshold: 15,
                            width: '100%'
                        });

                    });

                }

                //
                //
                // Font family select
                var $font_family_select = $this.find('.csf--font-family');
                var first_font_family = $font_family_select.val();

                // Clear default font family select options
                $font_family_select.find('option').not(':first-child').remove();

                var opts = '';

                $.each(webfonts, function (type, group) {

                    // Check for exclude fonts
                    if (exclude_fonts && exclude_fonts.indexOf(type) !== -1) {
                        return;
                    }

                    opts += '<optgroup label="' + group.label + '">';

                    $.each(group.fonts, function (key, value) {

                        // use key if value is object
                        value = (typeof value === 'object') ? key : value;
                        var selected = (value === first_font_family) ? ' selected' : '';
                        opts += '<option value="' + value + '" data-type="' + type + '"' + selected + '>' + value + '</option>';

                    });

                    opts += '</optgroup>';

                });

                // Append google font select options
                $font_family_select.append(opts).trigger('chosen:updated');

                //
                //
                // Font style select
                var $font_style_block = $this.find('.csf--block-font-style');

                if ($font_style_block.length) {

                    var $font_style_select = $this.find('.csf--font-style-select');
                    var first_style_value = $font_style_select.val() ? $font_style_select.val().replace(/normal/g, '') : '';

                    //
                    // Font Style on on change listener
                    $font_style_select.on('change csf.change', function (event) {

                        var style_value = $font_style_select.val();

                        // set a default value
                        if (!style_value && selected_styles && selected_styles.indexOf('normal') === -1) {
                            style_value = selected_styles[0];
                        }

                        // set font weight, for eg. replacing 800italic to 800
                        var font_normal = (style_value && style_value !== 'italic' && style_value === 'normal') ? 'normal' : '';
                        var font_weight = (style_value && style_value !== 'italic' && style_value !== 'normal') ? style_value.replace('italic', '') : font_normal;
                        var font_style = (style_value && style_value.substr(-6) === 'italic') ? 'italic' : '';

                        $this.find('.csf--font-weight').val(font_weight);
                        $this.find('.csf--font-style').val(font_style);

                    });

                    //
                    //
                    // Extra font style select
                    var $extra_font_style_block = $this.find('.csf--block-extra-styles');

                    if ($extra_font_style_block.length) {
                        var $extra_font_style_select = $this.find('.csf--extra-styles');
                        var first_extra_style_value = $extra_font_style_select.val();
                    }

                }

                //
                //
                // Subsets select
                var $subset_block = $this.find('.csf--block-subset');
                if ($subset_block.length) {
                    var $subset_select = $this.find('.csf--subset');
                    var first_subset_select_value = $subset_select.val();
                    var subset_multi_select = $subset_select.data('multiple') || false;
                }

                //
                //
                // Backup font family
                var $backup_font_family_block = $this.find('.csf--block-backup-font-family');

                //
                //
                // Font Family on Change Listener
                $font_family_select.on('change csf.change', function (event) {

                    // Hide subsets on change
                    if ($subset_block.length) {
                        $subset_block.addClass('hidden');
                    }

                    // Hide extra font style on change
                    if ($extra_font_style_block.length) {
                        $extra_font_style_block.addClass('hidden');
                    }

                    // Hide backup font family on change
                    if ($backup_font_family_block.length) {
                        $backup_font_family_block.addClass('hidden');
                    }

                    var $selected = $font_family_select.find(':selected');
                    var value = $selected.val();
                    var type = $selected.data('type');

                    if (type && value) {

                        // Show backup fonts if font type google or custom
                        if ((type === 'google' || type === 'custom') && $backup_font_family_block.length) {
                            $backup_font_family_block.removeClass('hidden');
                        }

                        // Appending font style select options
                        if ($font_style_block.length) {

                            // set styles for multi and normal style selectors
                            var styles = defaultstyles;

                            // Custom or gogle font styles
                            if (type === 'google' && webfonts[type].fonts[value][0]) {
                                styles = webfonts[type].fonts[value][0];
                            } else if (type === 'custom' && webfonts[type].fonts[value]) {
                                styles = webfonts[type].fonts[value];
                            }

                            selected_styles = styles;

                            // Set selected style value for avoid load errors
                            var set_auto_style = (styles.indexOf('normal') !== -1) ? 'normal' : styles[0];
                            var set_style_value = (first_style_value && styles.indexOf(first_style_value) !== -1) ? first_style_value : set_auto_style;

                            // Append style select options
                            base.append_select_options($font_style_select, styles, set_style_value, 'style');

                            // Clear first value
                            first_style_value = false;

                            // Show style select after appended
                            $font_style_block.removeClass('hidden');

                            // Appending extra font style select options
                            if (type === 'google' && $extra_font_style_block.length && styles.length > 1) {

                                // Append extra-style select options
                                base.append_select_options($extra_font_style_select, styles, first_extra_style_value, 'style', true);

                                // Clear first value
                                first_extra_style_value = false;

                                // Show style select after appended
                                $extra_font_style_block.removeClass('hidden');

                            }

                        }

                        // Appending google fonts subsets select options
                        if (type === 'google' && $subset_block.length && webfonts[type].fonts[value][1]) {

                            var subsets = webfonts[type].fonts[value][1];
                            var set_auto_subset = (subsets.length < 2 && subsets[0] !== 'latin') ? subsets[0] : '';
                            var set_subset_value = (first_subset_select_value && subsets.indexOf(first_subset_select_value) !== -1) ? first_subset_select_value : set_auto_subset;

                            // check for multiple subset select
                            set_subset_value = (subset_multi_select && first_subset_select_value) ? first_subset_select_value : set_subset_value;

                            base.append_select_options($subset_select, subsets, set_subset_value, 'subset', subset_multi_select);

                            first_subset_select_value = false;

                            $subset_block.removeClass('hidden');

                        }

                    } else {

                        // Clear Styles
                        $styles.find(':input').val('');

                        // Clear subsets options if type and value empty
                        if ($subset_block.length) {
                            $subset_select.find('option').not(':first-child').remove();
                            $subset_select.trigger('chosen:updated');
                        }

                        // Clear font styles options if type and value empty
                        if ($font_style_block.length) {
                            $font_style_select.find('option').not(':first-child').remove();
                            $font_style_select.trigger('chosen:updated');
                        }

                    }

                    // Update font type input value
                    $type.val(type);

                }).trigger('csf.change');

                //
                //
                // Preview
                var $preview_block = $this.find('.csf--block-preview');

                if ($preview_block.length) {

                    var $preview = $this.find('.csf--preview');

                    // Set preview styles on change
                    $this.on('change', CSF.helper.debounce(function (event) {

                        $preview_block.removeClass('hidden');

                        var font_family = $font_family_select.val(),
                            font_weight = $this.find('.csf--font-weight').val(),
                            font_style = $this.find('.csf--font-style').val(),
                            font_size = $this.find('.csf--font-size').val(),
                            font_variant = $this.find('.csf--font-variant').val(),
                            line_height = $this.find('.csf--line-height').val(),
                            text_align = $this.find('.csf--text-align').val(),
                            text_transform = $this.find('.csf--text-transform').val(),
                            text_decoration = $this.find('.csf--text-decoration').val(),
                            text_color = $this.find('.csf--color').val(),
                            word_spacing = $this.find('.csf--word-spacing').val(),
                            letter_spacing = $this.find('.csf--letter-spacing').val(),
                            custom_style = $this.find('.csf--custom-style').val(),
                            type = $this.find('.csf--type').val();

                        if (type === 'google') {
                            base.load_google_font(font_family, font_weight, font_style);
                        }

                        var properties = {};

                        if (font_family) {
                            properties.fontFamily = font_family;
                        }
                        if (font_weight) {
                            properties.fontWeight = font_weight;
                        }
                        if (font_style) {
                            properties.fontStyle = font_style;
                        }
                        if (font_variant) {
                            properties.fontVariant = font_variant;
                        }
                        if (font_size) {
                            properties.fontSize = font_size + unit;
                        }
                        if (line_height) {
                            properties.lineHeight = line_height + line_height_unit;
                        }
                        if (letter_spacing) {
                            properties.letterSpacing = letter_spacing + unit;
                        }
                        if (word_spacing) {
                            properties.wordSpacing = word_spacing + unit;
                        }
                        if (text_align) {
                            properties.textAlign = text_align;
                        }
                        if (text_transform) {
                            properties.textTransform = text_transform;
                        }
                        if (text_decoration) {
                            properties.textDecoration = text_decoration;
                        }
                        if (text_color) {
                            properties.color = text_color;
                        }

                        $preview.removeAttr('style');

                        // Customs style attribute
                        if (custom_style) {
                            $preview.attr('style', custom_style);
                        }

                        $preview.css(properties);

                    }, 100));

                    // Preview black and white backgrounds trigger
                    $preview_block.on('click', function () {

                        $preview.toggleClass('csf--black-background');

                        var $toggle = $preview_block.find('.csf--toggle');

                        if ($toggle.hasClass('fa-toggle-off')) {
                            $toggle.removeClass('fa-toggle-off').addClass('fa-toggle-on');
                        } else {
                            $toggle.removeClass('fa-toggle-on').addClass('fa-toggle-off');
                        }

                    });

                    if (!$preview_block.hasClass('hidden')) {
                        $this.trigger('change');
                    }

                }

            };

            base.init();

        });
    };

    //
    // Field: upload
    //
    $.fn.csf_field_upload = function () {
        return this.each(function () {

            var $this = $(this),
                $input = $this.find('input'),
                $upload_button = $this.find('.csf--button'),
                $remove_button = $this.find('.csf--remove'),
                $preview_wrap = $this.find('.csf--preview'),
                $preview_src = $this.find('.csf--src'),
                $library = $upload_button.data('library') && $upload_button.data('library').split(',') || '',
                wp_media_frame;

            $upload_button.on('click', function (e) {

                e.preventDefault();

                if (typeof window.wp === 'undefined' || !window.wp.media || !window.wp.media.gallery) {
                    return;
                }

                if (wp_media_frame) {
                    wp_media_frame.open();
                    return;
                }

                wp_media_frame = window.wp.media({
                    library: {
                        type: $library
                    },
                });

                wp_media_frame.on('select', function () {

                    var src;
                    var attributes = wp_media_frame.state().get('selection').first().attributes;

                    if ($library.length && $library.indexOf(attributes.subtype) === -1 && $library.indexOf(attributes.type) === -1) {
                        return;
                    }

                    $input.val(attributes.url).trigger('change');

                });

                wp_media_frame.open();

            });

            $remove_button.on('click', function (e) {
                e.preventDefault();
                $input.val('').trigger('change');
            });

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

                var $value = $input.val();

                if ($value) {
                    $remove_button.removeClass('hidden');
                } else {
                    $remove_button.addClass('hidden');
                }

                if ($preview_wrap.length) {

                    if ($.inArray($value.split('.').pop().toLowerCase(), ['jpg', 'jpeg', 'gif', 'png', 'svg', 'webp']) !== -1) {
                        $preview_wrap.removeClass('hidden');
                        $preview_src.attr('src', $value);
                    } else {
                        $preview_wrap.addClass('hidden');
                    }

                }

            });

        });

    };

    //
    // Field: wp_editor
    //
    $.fn.csf_field_wp_editor = function () {
        return this.each(function () {

            if (typeof window.wp.editor === 'undefined' || typeof window.tinyMCEPreInit === 'undefined' || typeof window.tinyMCEPreInit.mceInit.csf_wp_editor === 'undefined') {
                return;
            }

            var $this = $(this),
                $editor = $this.find('.csf-wp-editor'),
                $textarea = $this.find('textarea');

            // If there is wp-editor remove it for avoid dupliated wp-editor conflicts.
            var $has_wp_editor = $this.find('.wp-editor-wrap').length || $this.find('.mce-container').length;

            if ($has_wp_editor) {
                $editor.empty();
                $editor.append($textarea);
                $textarea.css('display', '');
            }

            // Generate a unique id
            var uid = CSF.helper.uid('csf-editor-');

            $textarea.attr('id', uid);

            // Get default editor settings
            var default_editor_settings = {
                tinymce: window.tinyMCEPreInit.mceInit.csf_wp_editor,
                quicktags: window.tinyMCEPreInit.qtInit.csf_wp_editor
            };

            // Get default editor settings
            var field_editor_settings = $editor.data('editor-settings');

            // Callback for old wp editor
            var wpEditor = wp.oldEditor ? wp.oldEditor : wp.editor;

            if (wpEditor && wpEditor.hasOwnProperty('autop')) {
                wp.editor.autop = wpEditor.autop;
                wp.editor.removep = wpEditor.removep;
                wp.editor.initialize = wpEditor.initialize;
            }

            // Add on change event handle
            var editor_on_change = function (editor) {
                editor.on('change keyup', function () {
                    var value = (field_editor_settings.wpautop) ? editor.getContent() : wp.editor.removep(editor.getContent());
                    $textarea.val(value).trigger('change');
                });
            };

            // Extend editor selector and on change event handler
            default_editor_settings.tinymce = $.extend({}, default_editor_settings.tinymce, {
                selector: '#' + uid,
                setup: editor_on_change
            });

            // Override editor tinymce settings
            if (field_editor_settings.tinymce === false) {
                default_editor_settings.tinymce = false;
                $editor.addClass('csf-no-tinymce');
            }

            // Override editor quicktags settings
            if (field_editor_settings.quicktags === false) {
                default_editor_settings.quicktags = false;
                $editor.addClass('csf-no-quicktags');
            }

            // Wait until :visible
            var interval = setInterval(function () {
                if ($this.is(':visible')) {
                    window.wp.editor.initialize(uid, default_editor_settings);
                    clearInterval(interval);
                }
            });

            // Add Media buttons
            if (field_editor_settings.media_buttons && window.csf_media_buttons) {

                var $editor_buttons = $editor.find('.wp-media-buttons');

                if ($editor_buttons.length) {

                    $editor_buttons.find('.csf-shortcode-button').data('editor-id', uid);

                } else {

                    var $media_buttons = $(window.csf_media_buttons);

                    $media_buttons.find('.csf-shortcode-button').data('editor-id', uid);

                    $editor.prepend($media_buttons);

                }

            }

        });

    };

    //
    // Confirm
    //
    $.fn.csf_confirm = function () {
        return this.each(function () {
            $(this).on('click', function (e) {

                var confirm_text = $(this).data('confirm') || window.csf_vars.i18n.confirm;
                var confirm_answer = confirm(confirm_text);

                if (confirm_answer) {
                    CSF.vars.is_confirm = true;
                    CSF.vars.form_modified = false;
                } else {
                    e.preventDefault();
                    return false;
                }

            });
        });
    };

    $.fn.serializeObject = function () {

        var obj = {};

        $.each(this.serializeArray(), function (i, o) {
            var n = o.name,
                v = o.value;

            obj[n] = obj[n] === undefined ? v
                : $.isArray(obj[n]) ? obj[n].concat(v)
                    : [obj[n], v];
        });

        return obj;

    };

    //
    // Options Save
    //
    $.fn.csf_save = function () {
        return this.each(function () {

            var $this = $(this),
                $buttons = $('.csf-save'),
                $panel = $('.csf-options'),
                flooding = false,
                timeout;

            $this.on('click', function (e) {

                if (!flooding) {

                    var $text = $this.data('save'),
                        $value = $this.val();

                    $buttons.attr('value', $text);

                    if ($this.hasClass('csf-save-ajax')) {

                        e.preventDefault();

                        $panel.addClass('csf-saving');
                        $buttons.prop('disabled', true);

                        window.wp.ajax.post('csf_' + $panel.data('unique') + '_ajax_save', {
                            data: $('#csf-form').serializeJSONCSF()
                        })
                            .done(function (response) {

                                // clear errors
                                $('.csf-error').remove();

                                if (Object.keys(response.errors).length) {

                                    var error_icon = '<i class="csf-label-error csf-error">!</i>';

                                    $.each(response.errors, function (key, error_message) {

                                        var $field = $('[data-depend-id="' + key + '"]'),
                                            $link = $('a[href="#tab=' + $field.closest('.csf-section').data('section-id') + '"]'),
                                            $tab = $link.closest('.csf-tab-item');

                                        $field.closest('.csf-fieldset').append('<p class="csf-error csf-error-text">' + error_message + '</p>');

                                        if (!$link.find('.csf-error').length) {
                                            $link.append(error_icon);
                                        }

                                        if (!$tab.find('.csf-arrow .csf-error').length) {
                                            $tab.find('.csf-arrow').append(error_icon);
                                        }

                                    });

                                }

                                $panel.removeClass('csf-saving');
                                $buttons.prop('disabled', false).attr('value', $value);
                                flooding = false;

                                CSF.vars.form_modified = false;
                                CSF.vars.$form_warning.hide();

                                clearTimeout(timeout);

                                var $result_success = $('.csf-form-success');
                                $result_success.empty().append(response.notice).fadeIn('fast', function () {
                                    timeout = setTimeout(function () {
                                        $result_success.fadeOut('fast');
                                    }, 1000);
                                });

                            })
                            .fail(function (response) {
                                alert(response.error);
                            });

                    } else {

                        CSF.vars.form_modified = false;

                    }

                }

                flooding = true;

            });

        });
    };

    //
    // Option Framework
    //
    $.fn.csf_options = function () {
        return this.each(function () {

            var $this = $(this),
                $content = $this.find('.csf-content'),
                $form_success = $this.find('.csf-form-success'),
                $form_warning = $this.find('.csf-form-warning'),
                $save_button = $this.find('.csf-header .csf-save');

            CSF.vars.$form_warning = $form_warning;

            // Shows a message white leaving theme options without saving
            if ($form_warning.length) {

                window.onbeforeunload = function () {
                    return (CSF.vars.form_modified) ? true : undefined;
                };

                $content.on('change keypress', ':input', function () {
                    if (!CSF.vars.form_modified) {
                        $form_success.hide();
                        $form_warning.fadeIn('fast');
                        CSF.vars.form_modified = true;
                    }
                });

            }

            if ($form_success.hasClass('csf-form-show')) {
                setTimeout(function () {
                    $form_success.fadeOut('fast');
                }, 1000);
            }

            $(document).keydown(function (event) {
                if ((event.ctrlKey || event.metaKey) && event.which === 83) {
                    $save_button.trigger('click');
                    event.preventDefault();
                    return false;
                }
            });

        });
    };

    //
    // Taxonomy Framework
    //
    $.fn.csf_taxonomy = function () {
        return this.each(function () {

            var $this = $(this),
                $form = $this.parents('form');

            if ($form.attr('id') === 'addtag') {

                var $submit = $form.find('#submit'),
                    $cloned = $this.children('.csf-field').csf_clone();

                $submit.on('click', function () {

                    if (!$form.find('.form-required').hasClass('form-invalid')) {

                        $this.data('inited', false);

                        $this.empty();

                        $this.html($cloned);

                        $cloned = $cloned.csf_clone();

                        $this.csf_reload_script();

                    }

                });

            }

        });
    };

    //
    // Shortcode Framework
    //
    $.fn.csf_shortcode = function () {

        var base = this;

        base.shortcode_parse = function (serialize, key) {

            var shortcode = '';

            $.each(serialize, function (shortcode_key, shortcode_values) {

                key = (key) ? key : shortcode_key;

                shortcode += '[' + key;

                $.each(shortcode_values, function (shortcode_tag, shortcode_value) {

                    if (shortcode_tag === 'content') {

                        shortcode += ']';
                        shortcode += shortcode_value;
                        shortcode += '[/' + key + '';

                    } else {

                        shortcode += base.shortcode_tags(shortcode_tag, shortcode_value);

                    }

                });

                shortcode += ']';

            });

            return shortcode;

        };

        base.shortcode_tags = function (shortcode_tag, shortcode_value) {

            var shortcode = '';

            if (shortcode_value !== '') {

                if (typeof shortcode_value === 'object' && !$.isArray(shortcode_value)) {

                    $.each(shortcode_value, function (sub_shortcode_tag, sub_shortcode_value) {

                        // sanitize spesific key/value
                        switch (sub_shortcode_tag) {

                            case 'background-image':
                                sub_shortcode_value = (sub_shortcode_value.url) ? sub_shortcode_value.url : '';
                                break;

                        }

                        if (sub_shortcode_value !== '') {
                            shortcode += ' ' + sub_shortcode_tag + '="' + sub_shortcode_value.toString() + '"';
                        }

                    });

                } else {

                    shortcode += ' ' + shortcode_tag + '="' + shortcode_value.toString() + '"';

                }

            }

            return shortcode;

        };

        base.insertAtChars = function (_this, currentValue) {

            var obj = (typeof _this[0].name !== 'undefined') ? _this[0] : _this;

            if (obj.value.length && typeof obj.selectionStart !== 'undefined') {
                obj.focus();
                return obj.value.substring(0, obj.selectionStart) + currentValue + obj.value.substring(obj.selectionEnd, obj.value.length);
            } else {
                obj.focus();
                return currentValue;
            }

        };

        base.send_to_editor = function (html, editor_id) {

            var tinymce_editor;

            if (typeof tinymce !== 'undefined') {
                tinymce_editor = tinymce.get(editor_id);
            }

            if (tinymce_editor && !tinymce_editor.isHidden()) {
                tinymce_editor.execCommand('mceInsertContent', false, html);
            } else {
                var $editor = $('#' + editor_id);
                $editor.val(base.insertAtChars($editor, html)).trigger('change');
            }

        };

        return this.each(function () {

            var $modal = $(this),
                $load = $modal.find('.csf-modal-load'),
                $content = $modal.find('.csf-modal-content'),
                $insert = $modal.find('.csf-modal-insert'),
                $loading = $modal.find('.csf-modal-loading'),
                $select = $modal.find('select'),
                modal_id = $modal.data('modal-id'),
                nonce = $modal.data('nonce'),
                editor_id,
                target_id,
                gutenberg_id,
                sc_key,
                sc_name,
                sc_view,
                sc_group,
                $cloned,
                $button;

            $(document).on('click', '.csf-shortcode-button[data-modal-id="' + modal_id + '"]', function (e) {

                e.preventDefault();

                $button = $(this);
                editor_id = $button.data('editor-id') || false;
                target_id = $button.data('target-id') || false;
                gutenberg_id = $button.data('gutenberg-id') || false;

                $modal.removeClass('hidden');

                // single usage trigger first shortcode
                if ($modal.hasClass('csf-shortcode-single') && sc_name === undefined) {
                    $select.trigger('change');
                }

            });

            $select.on('change', function () {

                var $option = $(this);
                var $selected = $option.find(':selected');

                sc_key = $option.val();
                sc_name = $selected.data('shortcode');
                sc_view = $selected.data('view') || 'normal';
                sc_group = $selected.data('group') || sc_name;

                $load.empty();

                if (sc_key) {

                    $loading.show();

                    window.wp.ajax.post('csf-get-shortcode-' + modal_id, {
                        shortcode_key: sc_key,
                        nonce: nonce
                    })
                        .done(function (response) {

                            $loading.hide();

                            var $appended = $(response.content).appendTo($load);

                            $insert.parent().removeClass('hidden');

                            $cloned = $appended.find('.csf--repeat-shortcode').csf_clone();

                            $appended.csf_reload_script();
                            $appended.find('.csf-fields').csf_reload_script();

                        });

                } else {

                    $insert.parent().addClass('hidden');

                }

            });

            $insert.on('click', function (e) {

                e.preventDefault();

                if ($insert.prop('disabled') || $insert.attr('disabled')) {
                    return;
                }

                var shortcode = '';
                var serialize = $modal.find('.csf-field:not(.csf-depend-on)').find(':input:not(.ignore)').serializeObjectCSF();

                switch (sc_view) {

                    case 'contents':
                        var contentsObj = (sc_name) ? serialize[sc_name] : serialize;
                        $.each(contentsObj, function (sc_key, sc_value) {
                            var sc_tag = (sc_name) ? sc_name : sc_key;
                            shortcode += '[' + sc_tag + ']' + sc_value + '[/' + sc_tag + ']';
                        });
                        break;

                    case 'group':

                        shortcode += '[' + sc_name;
                        $.each(serialize[sc_name], function (sc_key, sc_value) {
                            shortcode += base.shortcode_tags(sc_key, sc_value);
                        });
                        shortcode += ']';
                        shortcode += base.shortcode_parse(serialize[sc_group], sc_group);
                        shortcode += '[/' + sc_name + ']';

                        break;

                    case 'repeater':
                        shortcode += base.shortcode_parse(serialize[sc_group], sc_group);
                        break;

                    default:
                        shortcode += base.shortcode_parse(serialize);
                        break;

                }

                shortcode = (shortcode === '') ? '[' + sc_name + ']' : shortcode;

                if (gutenberg_id) {

                    var content = window.csf_gutenberg_props.attributes.hasOwnProperty('shortcode') ? window.csf_gutenberg_props.attributes.shortcode : '';
                    window.csf_gutenberg_props.setAttributes({shortcode: content + shortcode});

                } else if (editor_id) {

                    base.send_to_editor(shortcode, editor_id);

                } else {

                    var $textarea = (target_id) ? $(target_id) : $button.parent().find('textarea');
                    $textarea.val(base.insertAtChars($textarea, shortcode)).trigger('change');

                }

                $modal.addClass('hidden');

            });

            $modal.on('click', '.csf--repeat-button', function (e) {

                e.preventDefault();

                var $repeatable = $modal.find('.csf--repeatable');
                var $new_clone = $cloned.csf_clone();
                var $remove_btn = $new_clone.find('.csf-repeat-remove');

                var $appended = $new_clone.appendTo($repeatable);

                $new_clone.find('.csf-fields').csf_reload_script();

                CSF.helper.name_nested_replace($modal.find('.csf--repeat-shortcode'), sc_group);

                $remove_btn.on('click', function () {

                    $new_clone.remove();

                    CSF.helper.name_nested_replace($modal.find('.csf--repeat-shortcode'), sc_group);

                });

            });

            $modal.on('click', '.csf-modal-close, .csf-modal-overlay', function () {
                $modal.addClass('hidden');
            });

        });
    };

    //
    // WP Color Picker
    //
    if (typeof Color === 'function') {

        Color.prototype.toString = function () {

            if (this._alpha < 1) {
                return this.toCSS('rgba', this._alpha).replace(/\s+/g, '');
            }

            var hex = parseInt(this._color, 10).toString(16);

            if (this.error) {
                return '';
            }

            if (hex.length < 6) {
                for (var i = 6 - hex.length - 1; i >= 0; i--) {
                    hex = '0' + hex;
                }
            }

            return '#' + hex;

        };

    }

    CSF.funcs.parse_color = function (color) {

        var value = color.replace(/\s+/g, ''),
            trans = (value.indexOf('rgba') !== -1) ? parseFloat(value.replace(/^.*,(.+)\)/, '$1') * 100) : 100,
            rgba = (trans < 100) ? true : false;

        return {value: value, transparent: trans, rgba: rgba};

    };

    $.fn.csf_color = function () {
        return this.each(function () {

            var $input = $(this),
                picker_color = CSF.funcs.parse_color($input.val()),
                palette_color = window.csf_vars.color_palette.length ? window.csf_vars.color_palette : true,
                $container;

            // Destroy and Reinit
            if ($input.hasClass('wp-color-picker')) {
                $input.closest('.wp-picker-container').after($input).remove();
            }

            $input.wpColorPicker({
                palettes: palette_color,
                change: function (event, ui) {

                    var ui_color_value = ui.color.toString();

                    $container.removeClass('csf--transparent-active');
                    $container.find('.csf--transparent-offset').css('background-color', ui_color_value);
                    $input.val(ui_color_value).trigger('change');

                },
                create: function () {

                    $container = $input.closest('.wp-picker-container');

                    var a8cIris = $input.data('a8cIris'),
                        $transparent_wrap = $('<div class="csf--transparent-wrap">' +
                            '<div class="csf--transparent-slider"></div>' +
                            '<div class="csf--transparent-offset"></div>' +
                            '<div class="csf--transparent-text"></div>' +
                            '<div class="csf--transparent-button">transparent <i class="fas fa-toggle-off"></i></div>' +
                            '</div>').appendTo($container.find('.wp-picker-holder')),
                        $transparent_slider = $transparent_wrap.find('.csf--transparent-slider'),
                        $transparent_text = $transparent_wrap.find('.csf--transparent-text'),
                        $transparent_offset = $transparent_wrap.find('.csf--transparent-offset'),
                        $transparent_button = $transparent_wrap.find('.csf--transparent-button');

                    if ($input.val() === 'transparent') {
                        $container.addClass('csf--transparent-active');
                    }

                    $transparent_button.on('click', function () {
                        if ($input.val() !== 'transparent') {
                            $input.val('transparent').trigger('change').removeClass('iris-error');
                            $container.addClass('csf--transparent-active');
                        } else {
                            $input.val(a8cIris._color.toString()).trigger('change');
                            $container.removeClass('csf--transparent-active');
                        }
                    });

                    $transparent_slider.slider({
                        value: picker_color.transparent,
                        step: 1,
                        min: 0,
                        max: 100,
                        slide: function (event, ui) {

                            var slide_value = parseFloat(ui.value / 100);
                            a8cIris._color._alpha = slide_value;
                            $input.wpColorPicker('color', a8cIris._color.toString());
                            $transparent_text.text((slide_value === 1 || slide_value === 0 ? '' : slide_value));

                        },
                        create: function () {

                            var slide_value = parseFloat(picker_color.transparent / 100),
                                text_value = slide_value < 1 ? slide_value : '';

                            $transparent_text.text(text_value);
                            $transparent_offset.css('background-color', picker_color.value);

                            $container.on('click', '.wp-picker-clear', function () {

                                a8cIris._color._alpha = 1;
                                $transparent_text.text('');
                                $transparent_slider.slider('option', 'value', 100);
                                $container.removeClass('csf--transparent-active');
                                $input.trigger('change');

                            });

                            $container.on('click', '.wp-picker-default', function () {

                                var default_color = CSF.funcs.parse_color($input.data('default-color')),
                                    default_value = parseFloat(default_color.transparent / 100),
                                    default_text = default_value < 1 ? default_value : '';

                                a8cIris._color._alpha = default_value;
                                $transparent_text.text(default_text);
                                $transparent_slider.slider('option', 'value', default_color.transparent);

                                if (default_color.value === 'transparent') {
                                    $input.removeClass('iris-error');
                                    $container.addClass('csf--transparent-active');
                                }

                            });

                        }
                    });
                }
            });

        });
    };

    //
    // ChosenJS
    //
    $.fn.csf_chosen = function () {
        return this.each(function () {

            var $this = $(this),
                $inited = $this.parent().find('.chosen-container'),
                is_sortable = $this.hasClass('csf-chosen-sortable') || false,
                is_ajax = $this.hasClass('csf-chosen-ajax') || false,
                is_multiple = $this.attr('multiple') || false,
                set_width = is_multiple ? '100%' : 'auto',
                set_options = $.extend({
                    allow_single_deselect: true,
                    disable_search_threshold: 10,
                    width: set_width,
                    no_results_text: window.csf_vars.i18n.no_results_text,
                }, $this.data('chosen-settings'));

            if ($inited.length) {
                $inited.remove();
            }

            // Chosen ajax
            if (is_ajax) {

                var set_ajax_options = $.extend({
                    data: {
                        type: 'post',
                        nonce: '',
                    },
                    allow_single_deselect: true,
                    disable_search_threshold: -1,
                    width: '100%',
                    min_length: 3,
                    type_delay: 500,
                    typing_text: window.csf_vars.i18n.typing_text,
                    searching_text: window.csf_vars.i18n.searching_text,
                    no_results_text: window.csf_vars.i18n.no_results_text,
                }, $this.data('chosen-settings'));

                $this.CSFAjaxChosen(set_ajax_options);

            } else {

                $this.chosen(set_options);

            }

            // Chosen keep options order
            if (is_multiple) {

                var $hidden_select = $this.parent().find('.csf-hide-select');
                var $hidden_value = $hidden_select.val() || [];

                $this.on('change', function (obj, result) {

                    if (result && result.selected) {
                        $hidden_select.append('<option value="' + result.selected + '" selected="selected">' + result.selected + '</option>');
                    } else if (result && result.deselected) {
                        $hidden_select.find('option[value="' + result.deselected + '"]').remove();
                    }

                    // Force customize refresh
                    if (window.wp.customize !== undefined && $hidden_select.children().length === 0 && $hidden_select.data('customize-setting-link')) {
                        window.wp.customize.control($hidden_select.data('customize-setting-link')).setting.set('');
                    }

                    $hidden_select.trigger('change');

                });

                // Chosen order abstract
                $this.CSFChosenOrder($hidden_value, true);

            }

            // Chosen sortable
            if (is_sortable) {

                var $chosen_container = $this.parent().find('.chosen-container');
                var $chosen_choices = $chosen_container.find('.chosen-choices');

                $chosen_choices.bind('mousedown', function (event) {
                    if ($(event.target).is('span')) {
                        event.stopPropagation();
                    }
                });

                $chosen_choices.sortable({
                    items: 'li:not(.search-field)',
                    helper: 'orginal',
                    cursor: 'move',
                    placeholder: 'search-choice-placeholder',
                    start: function (e, ui) {
                        ui.placeholder.width(ui.item.innerWidth());
                        ui.placeholder.height(ui.item.innerHeight());
                    },
                    update: function (e, ui) {

                        var select_options = '';
                        var chosen_object = $this.data('chosen');
                        var $prev_select = $this.parent().find('.csf-hide-select');

                        $chosen_choices.find('.search-choice-close').each(function () {
                            var option_array_index = $(this).data('option-array-index');
                            $.each(chosen_object.results_data, function (index, data) {
                                if (data.array_index === option_array_index) {
                                    select_options += '<option value="' + data.value + '" selected>' + data.value + '</option>';
                                }
                            });
                        });

                        $prev_select.children().remove();
                        $prev_select.append(select_options);
                        $prev_select.trigger('change');

                    }
                });

            }

        });
    };

    //
    // Helper Checkbox Checker
    //
    $.fn.csf_checkbox = function () {
        return this.each(function () {

            var $this = $(this),
                $input = $this.find('.csf--input'),
                $checkbox = $this.find('.csf--checkbox');

            $checkbox.on('click', function () {
                $input.val(Number($checkbox.prop('checked'))).trigger('change');
            });

        });
    };

    //
    // Helper Check/Uncheck All
    //
    $.fn.csf_checkbox_all = function () {
        return this.each(function () {

            var $this = $(this);

            $this.on('click', function () {

                var $inputs = $this.closest('.csf-field-checkbox').find(':input'),
                    uncheck = false;

                $inputs.each(function () {
                    if (!$(this).prop('checked')) {
                        uncheck = true;
                    }
                });

                if (uncheck) {
                    $inputs.prop('checked', 'checked');
                    $inputs.attr('checked', 'checked');
                } else {
                    $inputs.prop('checked', '');
                    $inputs.removeAttr('checked');
                }

                $inputs.first().trigger('change');

            });

        });
    };

    //
    // Siblings
    //
    $.fn.csf_siblings = function () {
        return this.each(function () {

            var $this = $(this),
                $siblings = $this.find('.csf--sibling'),
                multiple = $this.data('multiple') || false;

            $siblings.on('click', function () {

                var $sibling = $(this);

                if (multiple) {

                    if ($sibling.hasClass('csf--active')) {
                        $sibling.removeClass('csf--active');
                        $sibling.find('input').prop('checked', false).trigger('change');
                    } else {
                        $sibling.addClass('csf--active');
                        $sibling.find('input').prop('checked', true).trigger('change');
                    }

                } else {

                    $this.find('input').prop('checked', false);
                    $sibling.find('input').prop('checked', true).trigger('change');
                    $sibling.addClass('csf--active').siblings().removeClass('csf--active');

                }

            });

        });
    };

    //
    // Help Tooltip
    //
    $.fn.csf_help = function () {
        return this.each(function () {

            var $this = $(this),
                $tooltip,
                offset_left;

            $this.on({
                mouseenter: function () {

                    $tooltip = $('<div class="csf-tooltip"></div>').html($this.find('.csf-help-text').html()).appendTo('body');
                    offset_left = (CSF.vars.is_rtl) ? ($this.offset().left + 24) : ($this.offset().left - $tooltip.outerWidth());

                    $tooltip.css({
                        top: $this.offset().top - (($tooltip.outerHeight() / 2) - 14),
                        left: offset_left,
                    });

                },
                mouseleave: function () {

                    if ($tooltip !== undefined) {
                        $tooltip.remove();
                    }

                }

            });

        });
    };

    //
    // Customize Refresh
    //
    $.fn.csf_customizer_refresh = function () {
        return this.each(function () {

            var $this = $(this),
                $complex = $this.closest('.csf-customize-complex');

            if ($complex.length) {

                var unique_id = $complex.data('unique-id');

                if (unique_id === undefined) {
                    return;
                }

                var $input = $complex.find(':input'),
                    option_id = $complex.data('option-id'),
                    obj = $input.serializeObjectCSF(),
                    data = (!$.isEmptyObject(obj) && obj[unique_id] && obj[unique_id][option_id]) ? obj[unique_id][option_id] : '',
                    control = window.wp.customize.control(unique_id + '[' + option_id + ']');

                // clear the value to force refresh.
                control.setting._value = null;

                control.setting.set(data);

            } else {

                $this.find(':input').first().trigger('change');

            }

            $(document).trigger('csf-customizer-refresh', $this);

        });
    };

    //
    // Customize Listen Form Elements
    //
    $.fn.csf_customizer_listen = function (options) {

        var settings = $.extend({
            closest: false,
        }, options);

        return this.each(function () {

            if (window.wp.customize === undefined) {
                return;
            }

            var $this = (settings.closest) ? $(this).closest('.csf-customize-complex') : $(this),
                $input = $this.find(':input'),
                unique_id = $this.data('unique-id'),
                option_id = $this.data('option-id');

            if (unique_id === undefined) {
                return;
            }

            $input.on('change keyup csf.change', function () {

                var obj = $this.find(':input').serializeObjectCSF();
                var val = (!$.isEmptyObject(obj) && obj[unique_id] && obj[unique_id][option_id]) ? obj[unique_id][option_id] : '';

                window.wp.customize.control(unique_id + '[' + option_id + ']').setting.set(val);

            });

        });
    };

    //
    // Customizer Listener for Reload JS
    //
    $(document).on('expanded', '.control-section', function () {

        var $this = $(this);

        if ($this.hasClass('open') && !$this.data('inited')) {

            var $fields = $this.find('.csf-customize-field');
            var $complex = $this.find('.csf-customize-complex');

            if ($fields.length) {
                $this.csf_dependency();
                $fields.csf_reload_script({dependency: false});
                $complex.csf_customizer_listen();
            }

            $this.data('inited', true);

        }

    });

    //
    // Window on resize
    //
    CSF.vars.$window.on('resize csf.resize', CSF.helper.debounce(function (event) {

        var window_width = navigator.userAgent.indexOf('AppleWebKit/') > -1 ? CSF.vars.$window.width() : window.innerWidth;

        if (window_width <= 782 && !CSF.vars.onloaded) {
            $('.csf-section').csf_reload_script();
            CSF.vars.onloaded = true;
        }

    }, 200)).trigger('csf.resize');

    //
    // Widgets Framework
    //
    $.fn.csf_widgets = function () {
        return this.each(function () {

            $(document).on('widget-added widget-updated', function (event, $widget) {

                var $fields = $widget.find('.csf-fields');

                if ($fields.length) {
                    $fields.csf_reload_script();
                }

            });

            $(document).on('click', '.widget-top', function (event) {

                var $fields = $(this).parent().find('.csf-fields');

                if ($fields.length) {
                    $fields.csf_reload_script();
                }

            });

            $('.widgets-sortables, .control-section-sidebar').on('sortstop', function (event, ui) {
                ui.item.find('.csf-fields').csf_reload_script_retry();
            });

        });
    };

    //
    // Nav Menu Options Framework
    //
    $.fn.csf_nav_menu = function () {
        return this.each(function () {

            var $navmenu = $(this);

            $navmenu.on('click', 'a.item-edit', function () {
                $(this).closest('li.menu-item').find('.csf-fields').csf_reload_script();
            });

            $navmenu.on('sortstop', function (event, ui) {
                ui.item.find('.csf-fields').csf_reload_script_retry();
            });

        });
    };

    //
    // Retry Plugins
    //
    $.fn.csf_reload_script_retry = function () {
        return this.each(function () {

            var $this = $(this);

            if ($this.data('inited')) {
                $this.children('.csf-field-wp_editor').csf_field_wp_editor();
            }

        });
    };

    //
    // Reload Plugins
    //
    $.fn.csf_reload_script = function (options) {

        var settings = $.extend({
            dependency: true,
        }, options);

        return this.each(function () {

            var $this = $(this);

            // Avoid for conflicts
            if (!$this.data('inited')) {

                // Field plugins
                $this.children('.csf-field-accordion').csf_field_accordion();
                $this.children('.csf-field-backup').csf_field_backup();
                $this.children('.csf-field-background').csf_field_background();
                $this.children('.csf-field-code_editor').csf_field_code_editor();
                $this.children('.csf-field-date').csf_field_date();
                $this.children('.csf-field-datetime').csf_field_datetime();
                $this.children('.csf-field-fieldset').csf_field_fieldset();
                $this.children('.csf-field-gallery').csf_field_gallery();
                $this.children('.csf-field-group').csf_field_group();
                $this.children('.csf-field-icon').csf_field_icon();
                $this.children('.csf-field-link').csf_field_link();
                $this.children('.csf-field-media').csf_field_media();
                $this.children('.csf-field-map').csf_field_map();
                $this.children('.csf-field-repeater').csf_field_repeater();
                $this.children('.csf-field-slider').csf_field_slider();
                $this.children('.csf-field-sortable').csf_field_sortable();
                $this.children('.csf-field-sorter').csf_field_sorter();
                $this.children('.csf-field-spinner').csf_field_spinner();
                $this.children('.csf-field-switcher').csf_field_switcher();
                $this.children('.csf-field-tabbed').csf_field_tabbed();
                $this.children('.csf-field-typography').csf_field_typography();
                $this.children('.csf-field-upload').csf_field_upload();
                $this.children('.csf-field-wp_editor').csf_field_wp_editor();

                // Field colors
                $this.children('.csf-field-border').find('.csf-color').csf_color();
                $this.children('.csf-field-background').find('.csf-color').csf_color();
                $this.children('.csf-field-color').find('.csf-color').csf_color();
                $this.children('.csf-field-color_group').find('.csf-color').csf_color();
                $this.children('.csf-field-link_color').find('.csf-color').csf_color();
                $this.children('.csf-field-typography').find('.csf-color').csf_color();

                // Field chosenjs
                $this.children('.csf-field-select').find('.csf-chosen').csf_chosen();

                // Field Checkbox
                $this.children('.csf-field-checkbox').find('.csf-checkbox').csf_checkbox();
                $this.children('.csf-field-checkbox').find('.csf-checkbox-all').csf_checkbox_all();

                // Field Siblings
                $this.children('.csf-field-button_set').find('.csf-siblings').csf_siblings();
                $this.children('.csf-field-image_select').find('.csf-siblings').csf_siblings();
                $this.children('.csf-field-palette').find('.csf-siblings').csf_siblings();

                // Help Tooptip
                $this.children('.csf-field').find('.csf-help').csf_help();

                if (settings.dependency) {
                    $this.csf_dependency();
                }

                $this.data('inited', true);

                $(document).trigger('csf-reload-script', $this);

            }

        });
    };

    //
    // Document ready and run scripts
    //
    $(document).ready(function () {

        $('.csf-save').csf_save();
        $('.csf-options').csf_options();
        $('.csf-sticky-header').csf_sticky();
        $('.csf-nav-options').csf_nav_options();
        $('.csf-nav-metabox').csf_nav_metabox();
        $('.csf-taxonomy').csf_taxonomy();
        $('.csf-page-templates').csf_page_templates();
        $('.csf-post-formats').csf_post_formats();
        $('.csf-shortcode').csf_shortcode();
        $('.csf-search').csf_search();
        $('.csf-confirm').csf_confirm();
        $('.csf-expand-all').csf_expand_all();
        $('.csf-onload').csf_reload_script();
        $('#widgets-editor').csf_widgets();
        $('#widgets-right').csf_widgets();
        $('#menu-to-edit').csf_nav_menu();

    });

})(jQuery, window, document);
