(function($){
    "use strict";

    const { __, _x, sprintf } = wp.i18n;

    $.pixeInputOptions = {
        'aria-hidden': {
            'title': 'Aria Hidden',
            'type': 'checkbox',
            'tip-text': 'Hide decorative elements from screen readers',
            'default': 'yes',
            'width': '1-2'
        },
        'aria-label': {
            'title': 'Aria Label',
            'type': 'text',
            'tip-text': 'Use this to provide an accessible name for buttons or links without visible text',
            'width': '1-1'
        },
        'url-parameters': {
            'title': 'URL Parameters',
            'type': 'text',
            'width': '1-1',
            'tip-text': 'Eg. key=value&key2=value2',
            // 'condition': {'link-to': ['!popup', '!image-lb', '!video-custom-lb', '!image-custom-lb']}
        },
    };

    // get input based on settings
    $.pixeGetInput = function(slug, value, option, container){
        var resetButton = option['hide-reset']? '': $.pixeResetValue(option['reset-siblings']);
        var input;

        switch( option.type ){
            case 'html':
                var html = (typeof(option.html) == 'function')? option.html(): option.html;
                input = $('<div class="pixe-input-html" >' + html + '</div>');
                if( option.class ){
                    input.addClass(option.class);
                }
                container.append(input);
                break;
            case 'heading':
                input = $('<div class="pixe-input-heading" >' + option.heading + '</div>');
                if( option.class ){
                    input.addClass(option.class);
                }
                container.append(input);
                break;
            case 'description':
                var description = (typeof(option.description) == 'function')? option.description(): option.description;
                input = $('<div class="pixe-input-description" >' + description + '</div>');
                if( option.class ){
                    input.addClass(option.class);
                }
                container.append(input);
                break;
            case 'icon':
                input = $.pixeIconSelector({
                    title: option.title,
                    slug: slug,
                    value: value,
                    withNone: option['with-none']
                });
                container.append(input);
                break;
            case 'divider':
                input = $('<div class="pixe-divider" ></div>');
                container.append(input);
                break;
            case 'bullet-preset-combobox':
            case 'navigation-preset-combobox':
            case 'touch-navigation-preset-combobox':
            case 'pagination-preset-combobox':
                var comboboxOptions;
                if( option.type == 'bullet-preset-combobox' ){
                    comboboxOptions = $.pixeComboboxOption.bulletPreset();
                }else if( option.type == 'navigation-preset-combobox' ){
                    comboboxOptions = $.pixeComboboxOption.navigationPreset();
                }else if( option.type == 'touch-navigation-preset-combobox' ){
                    comboboxOptions = $.pixeComboboxOption.touchNavigationPreset();
                }else if( option.type == 'pagination-preset-combobox' ){
                    comboboxOptions = $.pixeComboboxOption.paginationPreset();
                }

                input = $.pixeInputWrap({
                    title: option.title? option.title + resetButton: '',
                    width: option.width,
                    content: $.pixeCombobox({
                        slug: slug,
                        value: value,
                        class: 'pixe-' + option.type,
                        options: comboboxOptions,
                        bottom: $.pixeComboboxBottom('Open Preset')
                    })
                });
                input.pixeResetValue();
                input.pixeCombobox({
                    contentFilter: $.pixeControlComboboxFilter,
                    defaultFilter: true,
                });
                container.append(input);
                break;
            case 'typo-preset-combobox':
                input = $.pixeInputWrap({
                    title: option.title + resetButton,
                    width: option.width,
                    descriptionTop: option['description-top'],
                    callback: option.callback,
                    content: $.pixeCombobox({
                        slug: slug,
                        value: value,
                        class: 'pixe-typo-preset-combobox',
                        options: $.pixeComboboxOption.typoPreset(),
                        bottom: $.pixeComboboxBottom('New Preset', undefined, 'folder-plus')
                    })
                });
                input.pixeResetValue();
                input.pixeCombobox({
                    selector: '.pixe-typo-preset-combobox',
                    contentFilter: $.pixeTypoComboboxFilter,
                    defaultFilter: true
                });
                container.append(input);
                break;
            case 'font-family':
                var comboboxBottom = '<div class="pixe-combobox-tab-bottom pixe-no-user-select" >';
                    comboboxBottom += $.pixeComboboxBottom('Variable Manager', undefined, undefined, 'variable');
                    comboboxBottom += '</div>';

                input = $.pixeInputWrap({
                    title: option.title? option.title + resetButton: '',
                    width: option.width,
                    descriptionTop: option['description-top'],
                    callback: option.callback,
                    content: $.pixeCombobox({
                        slug: slug,
                        value: value,
                        class: 'pixe-font-family-combobox',
                        top: $.pixeComboboxTab({
                            custom: 'Custom Value',
                            variable: 'Variables'
                        }),
                        bottom: comboboxBottom,
                        options: $.pixeComboboxOption.fontFamilyTabs(),
                        popupClass: 'pixe-font-family-combobox-popup',
                        search: option.search
                    })
                });
                input.pixeResetValue();
                input.pixeCombobox({
                    selector: '.pixe-font-family-combobox',
                    contentFilter: $.pixeFontFamilyComboboxFilter,
                    defaultFilter: true
                });
                container.append(input);
                break;
            case 'font-weight':
                var comboboxBottom = '<div class="pixe-combobox-tab-bottom pixe-no-user-select" >';
                    comboboxBottom += $.pixeComboboxBottom('Variable Manager', undefined, undefined, 'variable');
                    comboboxBottom += '</div>';

                input = $.pixeInputWrap({
                    title: option.title? option.title + resetButton: '',
                    width: option.width,
                    descriptionTop: option['description-top'],
                    callback: option.callback,
                    content: $.pixeCombobox({
                        slug: slug,
                        value: value,
                        class: 'pixe-font-weight-combobox',
                        top: $.pixeComboboxTab({
                            custom: 'Custom Value',
                            variable: 'Variables'
                        }),
                        bottom: comboboxBottom,
                        options: $.pixeComboboxOption.fontWeightTabs(),
                        popupClass: 'pixe-font-weight-combobox-popup',
                        search: option.search
                    })
                });
                input.pixeResetValue();
                input.pixeCombobox({
                    selector: '.pixe-font-weight-combobox',
                    contentFilter: $.pixeFontWeightComboboxFilter,
                    defaultFilter: true
                });
                container.append(input);
                break;
            case 'shadow':
                var comboboxBottom = '<div class="pixe-combobox-tab-bottom pixe-no-user-select" >';
                    comboboxBottom += $.pixeComboboxBottom('Variable Manager');
                    comboboxBottom += '</div>';

                input = $.pixeInputWrap({
                    title: option.title? option.title + resetButton: '',
                    width: option.width,
                    descriptionTop: option['description-top'],
                    callback: option.callback,
                    content: $.pixeCombobox({
                        slug: slug,
                        value: value,
                        class: 'pixe-shadow-combobox',
                        placeholder: 'None',
                        options: '<div class="pixe-option-vary" data-type="shadow" ></div>',
                        bottom: comboboxBottom,
                        popupClass: 'pixe-shadow-combobox-popup',
                        search: option.search
                    })
                });
                input.pixeResetValue();
                input.pixeCombobox({
                    selector: '.pixe-shadow-combobox',
                    contentFilter: $.pixeShadowComboboxFilter,
                    defaultFilter: true
                });
                container.append(input);
                break;
            case 'button-preset-combobox':
                var comboboxBottom;
                if( option.updatePreset ){
                    comboboxBottom = $.pixeComboboxBottom('New Preset', undefined, 'button');
                }else{
                    comboboxBottom = $.pixeComboboxBottom('Open Preset');
                }

                input = $.pixeInputWrap({
                    title: option.title? option.title + resetButton: '',
                    width: option.width,
                    content: $.pixeCombobox({
                        slug: slug,
                        value: value,
                        class: 'pixe-button-preset-combobox',
                        options: $.pixeComboboxOption.buttonPreset(),
                        bottom: comboboxBottom
                    })
                });
                input.pixeResetValue();
                input.pixeCombobox({
                    selector: '.pixe-button-preset-combobox',
                    contentFilter: $.pixeButtonComboboxFilter,
                    defaultFilter: true
                });
                container.append(input);
                break;
            case 'template':
                var options = {};
                switch( option['template-type'] ){
                    case 'template':
                        options = $.pixeComboboxOption.template();
                        break;
                    case 'header':
                        options = $.pixeComboboxOption.headerTemplate();
                        break;
                    case 'header-mobile':
                        options = $.pixeComboboxOption.headerTemplateMobile();
                        break;
                    case 'footer':
                        options = $.pixeComboboxOption.footerTemplate();
                        break;
                    case 'popup':
                        options = $.pixeComboboxOption.popupTemplate();
                        break;
                }

                input = $.pixeInputWrap({
                    title: option.title? option.title + resetButton: '',
                    width: option.width,
                    content: $.pixeCombobox({
                        slug: slug,
                        type: (option['combobox-type'] == 'multi-combobox')? 'multiple': '',
                        value: value,
                        options: options,
                        default: option.default,
                        bottom: $.pixeComboboxBottom('Open Template Manager')
                    })
                });
                input.pixeResetValue();
                input.pixeCombobox({
                    contentFilter: $.pixeTemplateComboboxFilter,
                    defaultFilter: true
                });
                container.append(input);

                break;
            case 'multi-combobox':
            case 'combobox':
                var options = {};
                var callbackDefault;

                // combobox option
                if( typeof(option.options) == 'string' ){
                    if( $.pixeComboboxOption[option.options] ){
                        options = $.pixeComboboxOption[option.options]();
                    }else{
                        options = option.options;
                    }
                }else{
                    var withDefault = option['with-default'];
                    if( option['with-default'] == undefined ) withDefault = true;

                    options = $.pixeComboboxOption.object(option.options, withDefault);
                }

                // callback settings
                if( option.callback ){
                    callbackDefault = option['with-default'];
                    if( option['with-default'] == undefined ) callbackDefault = true;
                }
                
                input = $.pixeInputWrap({
                    title: option.title? option.title + resetButton: '',
                    tipText: option['tip-text'],
                    width: option.width,
                    class: option.class,
                    placeholder: option.placeholder,
                    descriptionTop: option['description-top'],
                    descriptionBottom: option['description-bottom'],
                    callback: option.callback,
                    'callback-data': option['callback-data'],
                    'callback-default': callbackDefault,
                    content: $.pixeCombobox({
                        slug: slug,
                        type: (option.type == 'multi-combobox')? 'multiple': '',
                        value: value,
                        options: options,
                        popupClass: option['popup-class'],
                        default: option.default,
                        bottom: option['bottom'],
                        search: option.search
                    })
                });
                input.pixeResetValue();
                input.pixeCombobox();
                container.append(input);
                break;
            case 'post-filter':
                input = $.pixeInputWrap({
                    width: '1-1',
                    callback: option.callback,
                    content: $.pixePostFilter({
                        slug: slug,
                        value: value,
                        taxonomy: option.taxonomy
                    })
                });
                container.append(input);
                break;
            case 'range-input':
                input = $.pixeInputWrap({
                    title: option.title + resetButton,
                    width: option.width,
                    class: option.class,
                    descriptionTop: option['description-top'],
                    descriptionBottom: option['description-bottom'],
                    callback: option.callback,
                    content: $.pixeRangeInput({ 
                        slug: slug,
                        min: option.min,
                        max: option.max,
                        decimal: option.decimal,
                        range: option.range,
                        width: option['input-width'],
                        group: option['input-group'],
                        suffix: option.suffix,
                        suffixText: option['suffix-text'],
                        filter: option.filter,
                        value: value,
                        placeholder: option['placeholder'],
                        variableType: option['variable-type']
                    })
                });
                input.pixeResetValue();
                input.pixeRangeInput();
                input.pixeCombobox();
                container.append(input);
                break;
            case 'text-group':
                input = $.pixeInputWrap({
                    title: option.title,
                    width: '1-1',
                    content: $.pixeTextGroupInput({
                        slug: slug,
                        options: option.options,
                        value: value
                    })
                });
                container.append(input);
                break;
            case 'tab':
                input = $.pixeInputWrap({
                    title: option.title,
                    width: '1-1',
                    content: $.pixeTabInput({
                        slug: slug,
                        options: option.options,
                        value: value
                    })
                });
                container.append(input);
                break;
            case 'text-ratio':
                input = $.pixeInputWrap({
                    title: option.title + resetButton,
                    width: option.width,
                    descriptionTop: option['description-top'],
                    callback: option.callback,
                    content: $.pixeTextRatio({ 
                        slug: slug,
                        value: value
                    })
                });
                input.pixeResetValue();
                container.append(input);
                break;
            case 'datepicker':
                input = $.pixeInputWrap({
                    title: option.title? option.title + resetButton: '',
                    width: option.width,
                    descriptionTop: option['description-top'],
                    callback: option.callback,
                    content: $.pixeInput({ 
                        slug: slug,
                        type: 'date',
                        value: value,
                    })
                });
                input.pixeResetValue();
                container.append(input);
                break;
            case 'timepicker':
                input = $.pixeInputWrap({
                    title: option.title? option.title + resetButton: '',
                    width: option.width,
                    descriptionTop: option['description-top'],
                    callback: option.callback,
                    content: $.pixeInput({ 
                        slug: slug,
                        value: value,
                        type: 'time'
                    })
                });
                input.pixeResetValue();
                container.append(input);
                break;
            case 'text':
                input = $.pixeInputWrap({
                    class: option.class,
                    title: option.title? option.title + resetButton: '',
                    width: option.width,
                    tipText: option['tip-text'],
                    descriptionTop: option['description-top'],
                    descriptionBottom: option['description-bottom'],
                    callback: option.callback,
                    content: $.pixeInput({ 
                        slug: slug,
                        value: value,
                        width: option['input-width'],
                        info: option['input-info'],
                        group: option['input-group'],
                        placeholder: option['placeholder']
                    })
                });
                input.pixeResetValue();
                container.append(input);
                break;
            case 'textarea':
                input = $.pixeInputWrap({
                    title: option.title? option.title + resetButton: '',
                    class: option.class,
                    width: option.width,
                    descriptionTop: option['description-top'],
                    callback: option.callback,
                    content: $.pixeTextarea({ 
                        slug: slug,
                        value: value
                    })
                });
                input.pixeResetValue();
                container.append(input);
                break;
            case 'upload': 
                input = $.pixeInputWrap({
                    title: option.title,
                    class: 'pixe-upload-input-wrap ' + (option.class? option.class: ''),
                    width: option.width,
                    descriptionTop: option['description-top'],
                    callback: option.callback,
                    content: $.pixeUploadArea({
                        slug: slug,
                        value: value,
                        title: option['input-title'],
                        mediaType: option['media-type'],
                        convertSvg: option['convert-svg'],
                        multiple: option.multiple
                    })
                });
                input.pixeUploadArea();
                container.append(input);
                break;
            case 'ssdisplay':
                var ssDisplay = $('<div class="pixe-ss-display pixe-svg-preset" ></div>');
                ssDisplay.attr('data-slug', slug);
                ssDisplay.data('value', value);
                ssDisplay.addClass(option['ss-icon']);

                var input = $.pixeInputWrap({
                    title: option.title,
                    class: option.class,
                    width: option.width,
                    content: ssDisplay,
                    callback: option.callback,
                    descriptionTop: option['description-top'],
                });
                container.append(input);

                ssDisplay.on('click', function(){
                    new $.pixeStyleSelector({
                        obj: { '': ssDisplay.data('value') },
                        target: $(this),
                        title: option['ss-title'],
                        type: option['ss-type'],
                        hidePreset: option['hidePreset'],
                        onChange: function(v){
                            if(v){
                                ssDisplay.data('value', v).trigger('change');
                            }else{
                                ssDisplay.removeData('value').trigger('change');
                            }
                        }
                    })
                });
                break;
            case 'colordisplay':
                var colorType = option['color-type']? option['color-type']: 'color';
                var colorInput = $('<div class="pixe-color-display-wrap" ></div>');
                var colorDisplay = $('<div class="pixe-color-display" ></div>');
                colorDisplay.attr('data-slug', slug);
                colorDisplay.data('value', value);
                colorDisplay.appendTo(colorInput);

                var input = $.pixeInputWrap({
                    title: option.title,
                    class: option.class,
                    width: option.width,
                    content: colorInput,
                    callback: option.callback,
                    descriptionTop: option['description-top'],
                });
                container.append(input);
                
                var ssValue;
                if( colorType == 'color' || colorType == 'plain-color' || colorType == 'edit-color' ){
                    ssValue = { color: value }
                }else{
                    ssValue = value;
                }
                $.pixeSetColorDisplay(colorInput, ssValue);

                // bind colorpicker
                colorInput.on('click', function(){
                    new $.pixeStyleSelector({
                        obj: {'': ssValue},
                        target: $(this),
                        type: colorType,
                        onChange: function(v){
                            if( colorType == 'color' || colorType == 'plain-color' || colorType == 'edit-color' ){
                                if( v && v.color ){
                                    colorDisplay.data('value', v.color).trigger('change');
                                }else{
                                    colorDisplay.removeData('value').trigger('change');
                                }
                            }else{
                                if(v){
                                    colorDisplay.data('value', v).trigger('change');
                                }else{
                                    colorDisplay.removeData('value').trigger('change');
                                }
                            }

                            // set color
                            $.pixeSetColorDisplay(colorInput, v);
                        }
                    })
                });
                break;
            case 'colorpicker':
                var ss = new $.pixeStyleSelector({
                    display: 'html'
                });
                input = $.pixeInputWrap({
                    title: option.title,
                    width: option.width,
                    callback: option.callback,
                });
                input.append(ss.colorpicker(slug, value, option.gradient, option.preset));
                container.append(input);
                break;
            case 'tmce':
                var textarea = $.pixeTmce('pixe-admin-editor-' + slug, {height: 310});
                textarea.attr('data-slug', slug);
                if( value ){ textarea.val(value); } 

                var tmce = $('<div class="pixe-tmce-wrap" ></div>');
                tmce.append(textarea);
                tmce.appendTo(document.body);
                tmce.pixeTmce();
                container.append(tmce);
                break;
            case 'border-width':
                input = $.pixeBorderInput({
                    slug: slug,
                    value: value,
                    title: option.title + resetButton
                });
                input.pixeResetValue();
                container.append(input);
                break;
            case 'border-radius':
                input = $.pixeRadiusInput({
                    slug: slug,
                    value: value,
                    title: option.title + resetButton
                });
                input.pixeResetValue();
                container.append(input);
                break;
            case 'padding':
                input = $.pixeSizeInput({
                    slug: slug,
                    title: option.title + resetButton,
                    class: option.class,
                    type: 'padding',
                    tbType: option.tbType,
                    value: value,
                    enableSync: option['enable-sync']
                });
                input.pixeResetValue();
                input.appendTo(container);
                break;
            case 'margin':
                input = $.pixeSizeInput({
                    slug: slug,
                    title: option.title + resetButton,
                    class: option.class,
                    descriptionTop: option['description-top'],
                    type: 'margin',
                    value: value,
                    enableSync: option['enable-sync']
                });
                input.pixeResetValue();
                input.appendTo(container);
                break;
            case 'hide-on-devices':
                input = $.pixeInputWrap({
                    title: option.title,
                    width: option.width,
                    descriptionTop: option['description-top'],
                    content: $.pixeHideOnDevices({
                        slug: slug,
                        value: value
                    })
                });
                container.append(input);
                break;
            case 'checkbox-multiple-raw':
                input = $.pixeInputWrap({
                    title: option.title? option.title + resetButton: '',
                    class: option.class,
                    width: option.width,
                    descriptionTop: option['description-top'],
                    callback: option.callback,
                    content: $.pixeMultiCheckboxRaw({ 
                        slug: slug,
                        value: value,
                        options: option.options,
                        defaultValue: option.default,
                        extraClass: option['extra-class']
                    })
                });
                input.pixeMultiCheckbox();
                input.pixeResetValue();
                container.append(input);
                break;
            case 'checkbox': 
                input = $.pixeInputWrap({
                    title: option.title? option.title + resetButton: '',
                    class: option.class,
                    width: option.width,
                    descriptionTop: option['description-top'],
                    descriptionBottom: option['description-bottom'],
                    tipText: option['tip-text'],
                    callback: option.callback,
                    content: $.pixeCheckbox({ 
                        slug: slug,
                        value: value,
                        defaultValue: option.default,
                        activeValue: option['active-value'],
                        inActiveValue: option['inactive-value']
                    })
                });
                input.pixeResetValue();
                container.append(input);
                break;
            case 'radioicon':
                input = $.pixeInputWrap({
                    title: option.title? option.title + resetButton: '',
                    class: option.class,
                    width: option.width,
                    descriptionTop: option['description-top'],
                    callback: option.callback,
                    content: $.pixeRadioIcon({ 
                        slug: slug,
                        value: value,
                        options: option.options,
                        iconType: option['icon-type'],
                        style: option['style']
                    })
                });
                input.pixeRadioIcon();
                input.pixeResetValue();
                container.append(input);
                break;
            case 'save-block':
                var html  = '<div class="pixe-save-block-wrap" >';
                html += '<input type="text" />';
                html += '<div class="pixe-save-block-button" data-type="block" placeholder="Enter block name..." >';
                html += $.pixeGetAdminIcon('bookmark');
                html += 'Save as Custom Block';
                html += '</div>'; // pixe-save-block-button
                html += '<div class="pixe-export-block-button" data-type="download-block" >';
                html += $.pixeGetAdminIcon('download-file');
                html += 'Export Block (.json)';
                html += '</div>';
                html += '<div class="pixe-description" >Open Block Manager</div>';
                html += '</div>'; // pixe-save-block-wrap

                input = $.pixeInputWrap({
                    title: option.title,
                    width: option.width,
                    content: html
                });
                container.append(input);
                container.pixeSaveBlock();
                break
            case 'button':
                var buttonText = option['button-text']? option['button-text']: '';
                var button = $('<div class="pixe-button-callback" >' + buttonText + '</div>');
                if( option.icon ){
                    button.prepend($.pixeGetAdminIcon(option.icon));
                }
                if( option['button-class'] ){
                    button.addClass(option['button-class']);
                }
                if( option['button-callback'] ){
                    button.attr('data-button-callback', option['button-callback']);
                }

                input = $.pixeInputWrap({
                    class: option.class,
                    title: option.title,
                    width: option.width,
                    content: button
                });
                container.append(input);
                break;
        }

        // conditional
        if( input && option.condition ){
            input.attr('data-condition', '');
            input.data('condition', option.condition);
        }

        // custom events
        if( input && option.event ){
            option.event(input);
        }

        return input;
    }

    // text group input
    $.pixeTextGroupInput = function(settings){
        settings = $.extend({
            slug: '',
            options: {},
            value: undefined
        }, settings);

        var input = $('<div class="pixe-text-group-input" ></div>');
        input.attr('data-slug', settings.slug);
        input.data('value', settings.value);

        var value = settings.value? settings.value: {};
        for( var slug in settings.options ){
            var option = settings.options[slug];
            switch(option.type){
                case 'text':
                    input.append($.pixeInputWrap({
                        title: option.title,
                        content: $.pixeInput({
                            innerSlug: slug,
                            value: value[slug]
                        }),
                        width: option.width
                    }));
                    break;
            }
        }

        input.on('change', '[data-inner-slug]', function(e){
            e.preventDefault();
            e.stopPropagation();

            var data = {};
            input.find('[data-inner-slug]').each(function(){
                var input = $(this);
                $.pixeSetData(data, input.attr('data-inner-slug'), $.pixeGetInputVal(input));
            });

            input.data('value', data).trigger('change');
        });

        return input;
    }

    // builder input tab
    $.pixeTabInput = function(settings){
        settings = $.extend({
            slug: '',
            options: {},
            value: undefined
        }, settings);

        var tab = $('<div class="pixe-tab-input" ></div>');
        tab.attr('data-slug', settings.slug);
        tab.data('value', settings.value);

        var tabContent = $('<div class="pixe-tab-input-area" ></div>');
        tabContent.appendTo(tab);

        var addNew = $('<div class="pixe-tab-input-new" >Add New</div>');
        addNew.appendTo(tab);

        function updateData(){
            var data = [];

            tabContent.children('.pixe-tab-input-item').each(function(){
                var tabItem = $(this);
                var value = {};

                tabItem.find('[data-inner-slug]').each(function(){
                    var input = $(this);
                    $.pixeSetData(value, input.attr('data-inner-slug'), $.pixeGetInputVal(input));
                });

                tabItem.find('.pixe-tab-input-title').html(value.title? value.title: 'Tab');
                data.push(value);
            });

            tab.data('value', data).trigger('change');
        }

        // get item
        function setTabTitle(tabTitle, value){
            if( value ){
                tabTitle.html(value);
            }else{
                tabTitle.html('Tab');
            }
            tabTitle.append($.pixeGetAdminIcon('remove', {class: 'pixe-remove'}));
        }
        function getTabItem(value){
            var tabItem = $('<div class="pixe-tab-input-item" ></div>');
            var tabTitle = $('<div class="pixe-tab-input-title" ></div>');
            tabTitle.appendTo(tabItem);
            setTabTitle(tabTitle, value.title);

            var tabContent = $('<div class="pixe-tab-input-content" ></div>');
            tabContent.appendTo(tabItem);

            for( var slug in settings.options ){
                var option = settings.options[slug];
                switch(option.type){
                    case 'text':
                        tabContent.append($.pixeInputWrap({
                            title: option.title,
                            content: $.pixeInput({
                                innerSlug: slug,
                                value: value[slug]
                            }),
                            width: '1-1'
                        }));
                        break;
                    case 'textarea':
                        tabContent.append($.pixeInputWrap({
                            title: option.title,
                            content: $.pixeTextarea({
                                innerSlug: slug,
                                value: value[slug]
                            }),
                            width: '1-1'
                        }));
                        break;
                    case 'upload':
                        tabContent.append($.pixeInputWrap({
                            title: option.title,
                            content: $.pixeUploadArea({
                                innerSlug: slug,
                                value: value[slug]
                            }),
                            width: '1-1'
                        }));
                        break;
                    case 'checkbox': 
                        tabContent.append($.pixeInputWrap({
                            title: option.title,
                            content: $.pixeCheckbox({ 
                                innerSlug: slug,
                                value: value[slug],
                                defaultValue: option.default,
                                activeValue: option['active-value'],
                                inActiveValue: option['inactive-value']
                            }),
                            width: '1-1',
                        }));
                        break;
                }
            }

            return tabItem;
        }

        // initialize value
        if( settings.value ){
            for( var i in settings.value ){
                tabContent.append(getTabItem(settings.value[i]));
            }
        }

        // events
        tab.on('click', '.pixe-tab-input-title', function(){
            var tabItem = $(this).closest('.pixe-tab-input-item');
            
            if( tabItem.hasClass('pixe-active') ){
                tabItem.removeClass('pixe-active');
            }else{
                tabItem.addClass('pixe-active').siblings().removeClass('pixe-active');
            }
        });
        tab.on('click', '.pixe-remove', function(e){
            e.preventDefault();
            e.stopPropagation();

            var tabItem = $(this).closest('.pixe-tab-input-item');
            tabItem.remove();
            updateData();
        });
        addNew.on('click', function(){
            var tabItem = getTabItem({});
            tabContent.append(tabItem);
            tabItem.addClass('pixe-active').siblings().removeClass('pixe-active');
            updateData();
        });


        // update
        tab.on('change', '[data-inner-slug]', function(e){
            e.preventDefault();
            e.stopPropagation();

            updateData();

            // if title is changed, update title
            if( $(this).attr('data-inner-slug') == 'title' ){
                var tabItem = $(this).closest('.pixe-tab-input-item');
                var tabTitle = tabItem.children('.pixe-tab-input-title');
                setTabTitle(tabTitle, $(this).val());
            }
        });

        return tab;
    }

    
    // bind save block
    $.fn.pixeSaveBlock = function(){

        $(this).on('click', '.pixe-save-block-button, .pixe-export-block-button', function(){
            if( $(this).hasClass('pixe-loading') ) return;

            var button = $(this);
            var title = button.siblings('input').val();
            var type = button.attr('data-type');
            var id = $.pixeSettingsEdit.activeData._id;

            if( !title ){
                $.pixeConfirmationBox({
                    title: 'Name Missing',
                    message: 'Please fill the custom block name.',
                    cancelText: ''
                });
            }else if( !id ){
                $.pixeConfirmationBox({
                    title: 'A Problem Occurred',
                    message: 'Please refresh the page and try this again.',
                    cancelText: ''
                });
            }else{
                $.pixeBuilder.setIframeStatus({
                    event: 'add-block',
                    type: type,
                    title: title,
                    id: id
                });

                button.addClass('pixe-loading');

                if( $(this).hasClass('pixe-export-block-button') ){
                    button.siblings('input').val('');
                    button.removeClass('pixe-loading');
                }else{
                    setTimeout(function(){
                        button.siblings('input').val('');
                        button.removeClass('pixe-loading');
                    }, 4000);
                }
                
            }
        });

        $(this).on('click', '.pixe-save-block-wrap > .pixe-description', function(){
            $.pixeBlockSettings.init({ activeTab: 'custom-blocks' });
        });
        
    }

    // input filter
    $.pixeInputFilter = {
        'item-width': function(value, type, e, input){
            if( type == 'col' ){
                if( e.type == 'input' ){
                    return value;
                }else{
                    if( $.pixeColumnSize.column.indexOf(value) >= 0 ){
                        return value;
                    }else if( $.pixeColumnSize.columnAlt[value] ){
                        input.val($.pixeColumnSize.columnAlt[value]);
                        return $.pixeColumnSize.columnAlt[value];
                    }else{
                        input.val('1/1');
                        return '1/1';
                    }
                }
            }else if( type == 'auto' || type == 'none' ){
                input.val('-');
                
                return type;
            }
            
            return value + type;
        },
        'position': function(value, type, e, input){
            if( type == 'auto' || type == 'none' ){
                input.val('-');
                
                return type;
            }
            
            return value + type;
        }
    }

    // column size
    $.pixeColumnSize = {
        minSize: 8, // percent
        percent: [
            8.33, 10, 12.5, 16.66, 20, 
            25, 30, 33.33, 37.5, 40, 
            41.66, 50, 58.33, 60, 62.5, 
            66.66, 70, 75, 80, 83.33, 
            87.5, 90, 91.66, 100
        ],
        column: [
            '1/12', '1/10', '1/8', '1/6', '1/5', 
            '1/4', '3/10', '1/3', '3/8', '2/5', 
            '5/12', '1/2', '7/12', '3/5', '5/8', 
            '2/3', '7/10', '3/4', '4/5', '5/6', 
            '7/8', '9/10', '11/12', '1/1'
        ],
        columnAlt: {
            // 12
            '2/12': '1/6', '3/12': '1/4', '4/12': '1/3', '6/12': '1/2',
            '8/12': '2/3', '9/12': '3/4', '10/12': '5/6', '12/12': '1/1',
            // 10
            '2/10': '1/5', '4/10': '2/5', '6/10': '3/5', '8/10': '4/5',
            // 8
            '2/8': '1/4', '4/8': '1/2', '6/8': '3/4',
            // 6
            '2/6': '1/3', '4/6': '2/3',
            // 4
            '2/4': '1/2'
        }

    };

    // update input data & appearance
    $.pixeGetInputVal = function(input){
        var value;
        
        // checkbox
        if( input.is('input[type="checkbox"]') ){
            if( input.prop('checked') ){
                value = input.val();
            }

        // normal input
        }else if( input.is('input, select, textarea') ){

            // tmce
            if( input.hasClass('wp-editor-area') ){
                value = wp.editor.autop(wp.editor.getContent(input.attr('id')));

            // normal input
            }else{
                value = input.val();
            }
            
        }else{
            value = input.data('value');
        }

        return value;
    }
    $.fn.pixeInputUpdate = function(value, triggerChange){
        $(this).each(function(){
            if( $(this).is('input[type="checkbox"]') ){
                if( value ){
                    $(this).prop('checked', true);
                }else{
                    $(this).prop('checked', false);
                }
            }else if( $(this).is('input, select, textarea') ){
                if( $(this).attr('type') == 'hidden' ){
                    $(this).val(value).trigger('initvalue');
                }else{
                    $(this).val(value);
                }
            }else{
                // update value
                if( value ){
                    $(this).data('value', value);
                }else{
                    $(this).removeAttr('data-value').removeData('value');
                }

                // input type
                if( $(this).hasClass('pixe-size-input') ){
                    $(this).trigger('initvalue2');

                // combobox, rangeinput, textratio, radioicons
                }else{
                    $(this).trigger('initvalue');
                }
            }

            if( triggerChange ){
                $(this).trigger('change');
            }
        });

        return this;
    }

    // set colordisplay
    $.pixeSetColorDisplay = function(container, value){
        var colorDisplay = container.find('.pixe-color-display');
        var colorText = 'None';

        if( value && value.color ){
            var colorBg = $.pixeGetColor(value.color);
            colorText = colorBg.type == 'color'? colorBg.css: colorBg.type;
            colorDisplay.css('background', colorBg.css);
        }else{
            colorDisplay.css('background', '');
        }

        if( $.pixeColorDisplayText ){
            colorDisplay.parent('.pixe-color-display-wrap').addClass('pixe-with-text');

            var textHtml = colorDisplay.siblings('.pixe-text');
            if( !textHtml.length ){
                textHtml = $('<span class="pixe-text" ></span>');
                textHtml.insertAfter(colorDisplay);
            }
            textHtml.html(colorText);
        }
    }

    // hide input on specfic condition
    $.fn.pixeInputCondition = function(value, device, pointer, group){
        var input = $(this);
        var conditions = $(this).data('condition');
        
        // check condition
        var display = true;
        for( var key in conditions ){

            // if ignore device
            var deviceData = device;
            var pointerData = pointer;
            if( Array.isArray(conditions[key]) && conditions[key].indexOf('ignore-device') >= 0 ){
                deviceData = '';
            }
            if( Array.isArray(conditions[key]) && conditions[key].indexOf('ignore-state') >= 0 ){
                pointerData = '';
            }
            
            // get value
            var currentValue = $.pixeGetStateValue(value, key, deviceData, pointerData, group);
            if( !currentValue ) currentValue = '';

            // match multiple value
            if( Array.isArray(conditions[key]) ){
                display = display && conditions[key].indexOf(currentValue) >= 0;

            // callback function
            }else if( conditions[key] == 'pixe-callback' ){
                var callback = input.data('callback');
                var callbackData = input.data('callback-data');
                if( typeof(callback) == 'function' ){
                    display = display && callback(input, currentValue);
                }else if( callbackData ){
                    display = display && $.pixeComboboxCallback(callback, input, callbackData);
                }else{
                    display = display && $.pixeComboboxCallback(callback, input, currentValue);
                }

            // match single value
            }else{
                if( conditions[key].charAt(0) == '!' ){
                    var conditionVal = conditions[key].substring(1);
                    if( conditionVal.indexOf('&') >= 0 ){
                        conditionVal = conditionVal.split('&');
                        display = display && conditionVal.indexOf(currentValue) < 0;
                        console.log(key, conditionVal, display, currentValue);
                    }else{
                        display = display && conditionVal != currentValue;
                    }
                }else{
                    display = display && conditions[key] == currentValue;
                }
                
            }
        }

        // switch css
        if( display ){
            input.show();
        }else{
            input.hide();
        }
    }

    // device selector
    $.pixeHideOnDevices = function(settings){
        settings = $.extend({
            slug: '',
            value: undefined
        }, settings);

        var item = $($.pixeDeviceSelector('', 'pixe-hide-on-devices'));
        if( settings.slug ){ item.attr('data-slug', settings.slug); }
        item.children().addClass('pixe-active');
        
        // init data
        var value = settings.value? settings.value: [];
        if( value.length ){
            item.data('value', value);

            for( var i in value ){
                item.children('[data-device="' + value[i] + '"]').removeClass('pixe-active');
            }
        }

        // event
        item.on('click', '[data-device]', function(){
            var device = $(this).attr('data-device');

            var index = value.indexOf(device);
            if( index >= 0 ){
                $(this).addClass('pixe-active');
                value.splice(index, 1);
            }else{
                if( value.length >= 2 ){ return; }
                $(this).removeClass('pixe-active');
                value.push(device);
            }

            if( value.length ){
                item.data('value', value).trigger('change');
            }else{
                item.removeData('value').trigger('change');
            }
        });

        return item;
    }

    // icon selector
    $.pixeIconSelector = function(settings){
        settings = $.extend({
            slug: '',
            value: undefined
        }, settings);

        // get data
        var iconType, iconData;
        if( settings.value ){
            if( settings.value == 'none' ){
                iconType = 'none';
            }else{
                iconType = settings.value.type;
                iconData = settings.value;
            }
        }

        var resetButton = ''; // $.pixeResetValue();
        var container = $('<div class="pixe-icon-selector" ></div>');
        var input = $('<div class="pixe-hidden-input" ></div>');
        input.attr('data-slug', settings.slug);
        input.data('value', settings.value);
        input.appendTo(container);
        
        // type
        var typeSelect = $.pixeInputWrap({
            title: (settings.title? settings.title: 'Type') + resetButton,
            width: '1-1',
            content: $.pixeCombobox({
                value: iconType,
                class: 'pixe-icon-preset-combobox',
                options: $.pixeComboboxOption.iconPreset(settings.withNone),
                bottom: $.pixeComboboxBottom('Open Preset')
            })
        });
        container.append(typeSelect);

        // image
        var imageUpload = $.pixeInputWrap({
            width: '1-1',
            content: $.pixeUploadArea({
                value: (iconType == 'image')? iconData.value: undefined,
                convertSvg: true
            })
        });
        var uploadArea = imageUpload.find('.pixe-upload-area');
        container.append(imageUpload);

        // button
        var iconDisplay = $('<div class="pixe-icon-display" ></div>');
        var selectButton = $('<div class="pixe-icon-select" >Change Icon</div>');
        container.append(iconDisplay);
        container.append(selectButton);

        // initialize and set data
        function setIconState(icon){
            iconDisplay.empty();
            if( typeof(icon) == 'object' && icon.type != 'image' ){
                iconDisplay.append($.pixeGetIcon(icon));
                container.addClass('pixe-icon-active');
            }else{
                container.removeClass('pixe-icon-active');
                selectButton.html('Choose Icon');
            }
        }
        function setDisplayState(type){
            if( !type || type == 'none' ){
                imageUpload.hide();
                selectButton.hide();
                iconDisplay.hide();
            }else if( type == 'image' || type == 'image-raw' ){
                imageUpload.show();
                selectButton.hide();
                iconDisplay.hide();

                if( type == 'image' ){
                    uploadArea.attr('data-convert-svg', 1);
                }else if( type == 'image-raw' ){
                    uploadArea.removeAttr('data-convert-svg');
                }
            }else{
                imageUpload.hide();
                selectButton.show();

                if( container.hasClass('pixe-icon-active') ){
                    iconDisplay.css('display', 'flex');
                }else{
                    iconDisplay.css('display', '');
                }
            }
        }

        // init & bind
        setIconState(iconData);
        setDisplayState(iconType);
        container.pixeUploadArea();
        container.pixeCombobox({
            contentFilter: $.pixeIconComboboxFilter,
            defaultFilter: true,
        });
        container.pixeResetValue();

        typeSelect.on('change', '.pixe-combobox', function(){
            var value = $(this).data('value');

            if( !value || value == 'none' ){
                setIconState();
                input.data('value', value).trigger('change');
            }
            setDisplayState(value);
        });
        selectButton.on('click', function(){
            var type = typeSelect.find('.pixe-combobox').data('value');
            var targetPos = $(this);
            if( container.hasClass('pixe-icon-active') ){
                targetPos = iconDisplay;
            }

            $.pixeIconSelect.open({
                type: type,
                target: targetPos,
                width: typeSelect.outerWidth(),
                onChange: function(value){
                    iconData = { type: type, value: value };
                    input.data('value', iconData).trigger('change');
                    setIconState(iconData);
                    setDisplayState(type);
                }
            });
        });
        imageUpload.on('change', '.pixe-upload-area', function(){
            var value = $(this).data('value');
            if( value ){
                iconData = {
                    type: 'image',
                    value: value
                };
            }else{
                iconData = undefined;
            }
            input.data('value', iconData).trigger('change');
            setIconState(iconData);
        });

        return container;
    }

    // radio
    $.pixeRadioIconData = {
        'alignment': {
            'left': '<svg width="18" height="18" viewBox="0 0 18 18" ><path d="M2.25 5.25C2.25 4.83579 2.58579 4.5 3 4.5H15C15.4142 4.5 15.75 4.83579 15.75 5.25C15.75 5.66421 15.4142 6 15 6H3C2.58579 6 2.25 5.66421 2.25 5.25Z" /><path d="M3 8C2.58579 8 2.25 8.33577 2.25 8.75C2.25 9.16415 2.58579 9.5 3 9.5H9.75C10.1642 9.5 10.5 9.16415 10.5 8.75C10.5 8.33577 10.1642 8 9.75 8H3Z" /><path d="M2.25 12.25C2.25 11.8358 2.58579 11.5 3 11.5H12C12.4142 11.5 12.75 11.8358 12.75 12.25C12.75 12.6642 12.4142 13 12 13H3C2.58579 13 2.25 12.6642 2.25 12.25Z" /></svg>',
            'center': '<svg width="18" height="18" viewBox="0 0 18 18" ><path d="M2.25 5.25C2.25 4.83579 2.58579 4.5 3 4.5H15C15.4142 4.5 15.75 4.83579 15.75 5.25C15.75 5.66421 15.4142 6 15 6H3C2.58579 6 2.25 5.66421 2.25 5.25Z" /><path d="M5.625 8.25C5.21079 8.25 4.875 8.58577 4.875 9C4.875 9.41415 5.21079 9.75 5.625 9.75H12.375C12.7892 9.75 13.125 9.41415 13.125 9C13.125 8.58577 12.7892 8.25 12.375 8.25H5.625Z" /><path d="M3.75 12.75C3.75 12.3358 4.08579 12 4.5 12H13.5C13.9142 12 14.25 12.3358 14.25 12.75C14.25 13.1642 13.9142 13.5 13.5 13.5H4.5C4.08579 13.5 3.75 13.1642 3.75 12.75Z" /></svg>',
            'right': '<svg width="18" height="18" viewBox="0 0 18 18"><path d="M2.25 5.25C2.25 4.83579 2.58579 4.5 3 4.5H15C15.4142 4.5 15.75 4.83579 15.75 5.25C15.75 5.66421 15.4142 6 15 6H3C2.58579 6 2.25 5.66421 2.25 5.25Z" /><path d="M8.25 8.25C7.83578 8.25 7.5 8.58577 7.5 9C7.5 9.41415 7.83578 9.75 8.25 9.75H15C15.4142 9.75 15.75 9.41415 15.75 9C15.75 8.58577 15.4142 8.25 15 8.25H8.25Z" /><path d="M5.25 12.75C5.25 12.3358 5.58579 12 6 12H15C15.4142 12 15.75 12.3358 15.75 12.75C15.75 13.1642 15.4142 13.5 15 13.5H6C5.58579 13.5 5.25 13.1642 5.25 12.75Z" /></svg>'
        }, 
        'v-alignment': {    
            'top': '<svg width="15" height="14" viewBox="0 0 15 14" ><path d="M3.88461 13.8821V2.84132H5.77401V13.8821H3.88461ZM8.97595 9.38213V2.84132H10.8654V9.38213H8.97595ZM0.25 1.12496V0H14.5V1.12496H0.25Z" /></svg>',
            'center': '<svg width="15" height="14" viewBox="0 0 15 14" ><path d="M3.59856 13.375V7.56246H0V6.4375H3.59856V0.625H5.48796V6.4375H8.76201V2.875H10.6514V6.4375H14.25V7.56246H10.6514V11.125H8.76201V7.56246H5.48796V13.375H3.59856Z" /></svg>',
            'bottom': '<svg width="13" height="14" viewBox="0 0 13 14" ><path d="M0.166504 13.1668V12.1668H12.8331V13.1668H0.166504ZM3.39727 10.6412V0.827148H5.07674V10.6412H3.39727ZM7.9229 10.6412V4.82715H9.60237V10.6412H7.9229Z" /></svg>',
        },
        'h-alignment': {
            'space-between': '<svg width="16" height="16" viewBox="0 0 16 16" ><path d="M14 15.5V0.5H15.5V15.5H14ZM0.5 15.5V0.5H2V15.5H0.5ZM10.25 11.75V4.25H12.5V11.75H10.25ZM3.5 11.75V4.25H5.75V11.75H3.5Z" /></svg>',
            'left': '<svg width="14" height="14" viewBox="0 0 14 14" ><path d="M0 13.88V0H1.388V13.88H0ZM2.776 10.41V8.328H9.716V10.41H2.776ZM2.776 5.552V3.47H13.88V5.552H2.776Z" /></svg>',
            'center': '<svg width="9" height="14" viewBox="0 0 9 14" ><path d="M3.86231 13.375V0.625H5.13731V13.375H3.86231ZM6.4123 10.1875V3.8125H8.32481V10.1875H6.4123ZM0.674805 10.1875V3.8125H2.5873V10.1875H0.674805Z" /></svg>',
            'right': '<svg width="14" height="13" viewBox="0 0 14 13" ><path d="M11.9949 12.35V0H13.2299V12.35H11.9949ZM4.58488 9.2625V7.41H10.7599V9.2625H4.58488ZM0.879883 4.94V3.0875H10.7599V4.94H0.879883Z" /></svg>'
        }
    }
    $.pixeRadioIcon = function(settings){
        settings = $.extend({
            slug: '',
            value: '',
            options: {},
            iconType: 'svg',
            style: 1
        }, settings);

        var options = settings.options;
        if( typeof(options) == 'string' ){
            options = $.pixeRadioIconData[options];
        }

        var html  = '<div class="pixe-radio-icons pixe-style-' + settings.style + '" ';
            html += settings.slug? 'data-slug="' + settings.slug + '" ': '';
            html += settings.value? 'data-value="' + settings.value + '" ': '';
            html += ' >';

        if( options ){
            if( settings.style == 'text' ){
                for( var slug in options ){
                    html += '<label>';
                    html += '<input type="radio" name="pixe-radioicon-' + settings.slug + '" value="' + slug + '" ' + (settings.value == slug? 'checked': '') + ' />';
                    html += '<div class="pixe-text" >' + options[slug] + '</div>';
                    html += '</label>';
                }
            }else if( settings.iconType == 'svg' ){
                for( var slug in options ){
                    html += '<label>';
                    html += '<input type="radio" name="pixe-radioicon-' + settings.slug + '" value="' + slug + '" ' + (settings.value == slug? 'checked': '') + ' />';
                    html += '<div class="pixe-icon" >' + options[slug] + '</div>';
                    html += '</label>';
                }
            }else{
                for( var slug in options ){
                    html += '<label>';
                    html += '<input type="radio" name="pixe-radioicon-' + settings.slug + '" value="' + slug + '" ' + (settings.value == slug? 'checked': '') + ' />';
                    html += '<div class="pixe-icon pixe-svg-preset ' + options[slug] + '" ></div>';
                    html += '</label>';
                }
            }
            
        }

        html += '</div>';

        return html;
    }
    $.fn.pixeRadioIcon = function(){

        function setState(radio, value){
            if( value ){
                radio.removeClass('pixe-empty');
            }else{
                radio.addClass('pixe-empty');
            }
        }

        // change events
        $(this).find('.pixe-radio-icons').each(function(){
            var radio = $(this);

            $(this).find('input[type="radio"]').on('change', function(){
                if( $(this).prop('checked') ){
                    radio.data('value', $(this).val());
                    setState(radio, $(this).val());
                }
            });

            // init state
            setState(radio, $(this).data('value'));
        });

        // update input value
        $(this).on('initvalue', '.pixe-radio-icons', function(){
            var radio = $(this);
            var value = radio.val();

            radio.find('input[type="radio"]').each(function(){
                if( $(this).val() == value ){
                    $(this).prop('checked', true);
                }else{
                    $(this).prop('checked', false);
                }
            });

            // state
            setState(radio, value);
        });
    }

    // multi checkbox
    $.pixeUpdateMultiCheckboxOptions = function(input, options){
        var checkbox = input.find('.pixe-multi-checkbox, .pixe-multi-checkbox2');
        if( !checkbox.length ){ checkbox = input.filter('.pixe-multi-checkbox, .pixe-multi-checkbox2'); }
        checkbox.empty();

        var value = checkbox.data('value');
        var html;
        for(var slug in options){
            html  = '<label>';
            html += '<input type="checkbox" value="' + $.pixeEscAttr(slug) + '" ';
            if( value && value.indexOf(slug) >= 0 ){
                html += 'checked ';
            }
            html += ' />';
            html += '<span>' + options[slug] + '</span>';
            html += '</label>';
            
            checkbox.append(html);
        }
    }
    $.pixeMultiCheckboxRaw = function(settings){
        settings = $.extend({
            slug: '',
            innerSlug: '',
            value: '',
            options: {},
            extraClass: ''
        }, settings);

        var value = settings.value;
        if( typeof(value) == 'object' ){
            value = JSON.stringify(value);
        }

        var html = '<div class="pixe-multi-checkbox2 ' + $.pixeEscAttr(settings.extraClass) + '" ';
        html += settings.slug? 'data-slug="' + $.pixeEscAttr(settings.slug) + '" ': '';
        html += settings.innerSlug? 'data-inner-slug="' + $.pixeEscAttr(settings.innerSlug) + '" ': '';
        html += value? 'data-value="' + $.pixeEscAttr(value) + '" ': '';
        html += ' >';
        if( settings.options ){
            for( var slug in settings.options ){
                html += '<label>';
                html += '<input type="checkbox" value="' + $.pixeEscAttr(slug) + '" ';
                if( settings.value && settings.value.indexOf(slug) >= 0 ){
                    html += 'checked ';
                }
                html += ' />';
                html += '<span>' + settings.options[slug] + '</span>';
                html += '</label>';
            }
        }
        html += '</div>';

        return html;
    }
    $.pixeMultiCheckbox = function(settings){
        settings = $.extend({
            slug: '',
            innerSlug: '',
            value: '',
            options: {}
        }, settings);

        var value = settings.value;
        if( typeof(value) == 'object' ){
            value = JSON.stringify(value);
        }

        var html = '<div class="pixe-multi-checkbox" ';
        html += settings.slug? 'data-slug="' + $.pixeEscAttr(settings.slug) + '" ': '';
        html += settings.innerSlug? 'data-inner-slug="' + $.pixeEscAttr(settings.innerSlug) + '" ': '';
        html += value? 'data-value="' + $.pixeEscAttr(value) + '" ': '';
        html += ' >';
        if( settings.options ){
            for( var slug in settings.options ){
                html += '<label>';
                html += '<input type="checkbox" value="' + $.pixeEscAttr(slug) + '" ';
                if( settings.value && settings.value.indexOf(slug) >= 0 ){
                    html += 'checked ';
                }
                html += ' />';
                html += '<span>' + settings.options[slug] + '</span>';
                html += '</label>';
            }
        }
        html += '</div>';

        return html;
    }
    $.fn.pixeMultiCheckbox = function(){
        $(this).on('change', '.pixe-multi-checkbox, .pixe-multi-checkbox2', function(){
            var data = [];

            $(this).find('input:checked').each(function(){
                data.push($(this).attr('value'));
            });
            $(this).data('value', data);
        });

        $(this).on('initvalue', '.pixe-multi-checkbox, .pixe-multi-checkbox2', function(){
            var data = $(this).data('value');

            $(this).find('input[type="checkbox"]').each(function(){
                if( data && data.indexOf($(this).val) >= 0 ){
                    $(this).prop('checked', true);
                }else{
                    $(this).prop('checked', false);
                }
            });
        });
    }

    // checkbox
    $.pixeCheckbox = function(settings){
        settings = $.extend({
            slug: '',
            value: '',
            defaultValue: 'no',
            activeValue: 'yes',
            inActiveValue: 'no'
        }, settings);

        var html = '';
        if( settings.defaultValue == settings.activeValue ){
            html += '<div class="pixe-checkbox pixe-default-yes" >';
            html += '<label>';
            html += '<input type="checkbox" value="' + $.pixeEscAttr(settings.inActiveValue) + '" ';
            html += settings.slug? 'data-slug="' + $.pixeEscAttr(settings.slug) + '" ': '';
            html += settings.innerSlug? 'data-inner-slug="' + $.pixeEscAttr(settings.innerSlug) + '" ': '';
            html += settings.value == settings.inActiveValue? 'checked': '';
            html += ' />';
            html += '<span></span>';
            html += '</label>';
            html += '</div>';
        }else{
            html += '<div class="pixe-checkbox pixe-default-no" >';
            html += '<label>';
            html += '<input type="checkbox" value="' + $.pixeEscAttr(settings.activeValue) + '" ';
            html += settings.slug? 'data-slug="' + $.pixeEscAttr(settings.slug) + '" ': '';
            html += settings.innerSlug? 'data-inner-slug="' + $.pixeEscAttr(settings.innerSlug) + '" ': '';
            html += settings.value == settings.activeValue? 'checked': '';
            html += ' />';
            html += '<span></span>';
            html += '</label>';
            html += '</div>';
        }

        return html;
    }

    // tmce
    $.fn.pixeTmce = function(){
        $(this).find('.wp-editor-area').each(function(){
            if( $(this).hasClass('pixe-init') ) return;
            $(this).addClass('pixe-init');

            var textarea = $(this);
            var id = $(this).attr('id');
            var tmceInit = $.pixeClone(tinyMCEPreInit.mceInit['pixe-tmce']);
            
            tmceInit.setup = function(editor){
                editor.on('change', function(){
                    textarea.trigger('change');
                })
            };
            if( textarea.attr('data-height') ){
                tmceInit.height = textarea.attr('data-height');
            }
            
            wp.editor.remove(id);

            // delay to remove editor out
            setTimeout(function(){
                wp.editor.initialize(id, {
                    tinymce: tmceInit,
                    quicktags: tinyMCEPreInit.qtInit['pixe-tmce'],
                    mediaButtons: true
                });
            }, 1);
            
        });
    }
    $.pixeTmce = function(id = 'pixe-tmce', settings){
        settings = $.extend({
            height: ''
        }, settings);

        var tmce = $('<textarea class="wp-editor-area" ></textarea>');
        tmce.attr('id', id);

        if( settings.height ){
            tmce.attr('data-height', settings.height);
        }

        return tmce;
    }

    // width as col
    $.pixeInputWrap = function(settings){
        settings = $.extend({
            width: '',
            class: '',
            title: '',
            titleTip: '',
            isPro: false,
            content: '',
            callback: undefined
        }, settings);

        var wrap = $('<div class="pixe-input-wrap" ></div>');
        if( settings.class ){
            wrap.addClass(settings.class);
        }
        if( settings.width ){
            if( typeof(settings.width) == 'number' ){
                wrap.css('width', settings.width);
            }else if( settings.width.match(/^(\d+\-\d+)$/) ){
                wrap.attr('data-width', settings.width);
            }else{
                wrap.css('width', settings.width);
            }
        }

        var headWrap = $('<div class="pixe-head-wrap" ></div>');
        if( settings.title ){
            var label = $('<label>' + settings.title + '</label>');
            if( settings.tipText ){
                var tip = $('<div class="pixe-svg-preset pixe-svg-info" ></div>');
                    tip.attr('data-tip-text', settings.tipText);
                label.append(tip);
            }
            if( settings.isPro ){
                label.append($.pixeProBadge());
            }
            headWrap.append(label);
        }
        if( settings.isPro && (typeof(pixePP) === 'undefined' || !pixePP.active) ){
            headWrap.addClass('pixe-pro-content-restrict');
        }
        if( settings.descriptionTop ){
            headWrap.append('<div class="pixe-description pixe-top" >' + settings.descriptionTop + '</div>');
        }
        if( headWrap.children().length ){
            wrap.append(headWrap);
        }

        if( settings.content ){
            wrap.append(settings.content);
        }
        if( settings.descriptionBottom ){
            wrap.append('<div class="pixe-description pixe-bottom" >' + settings.descriptionBottom + '</div>');
        }
        
        // callback module
        if( settings.callback ){
            wrap.data('callback', settings.callback);
        }
        // default callback data
        if( settings['callback-data'] ){
            wrap.data('callback-data', settings['callback-data']);
        }
        // allow default combobox options in callback
        if( settings['callback-default'] ){
            wrap.data('callback-default', settings['callback-default']);
        }

        return wrap;
    }

    // use keyboard to control number input
    $.fn.pixeNumberInput = function(){
        if( !$(this).is('input[type="text"]') ) return;

        $(this).on('keydown', function(e){
            var input = $(this);

            // key up or down
            var diff = 0;
            if( e.keyCode == 38 ){
                diff = 1;
            }else if( e.keyCode == 40 ){
                diff = -1;
            }
            if( e.shiftKey ){
                diff *= 10;
            }
            if( diff == 0 ) return;

            // get value
            var data = input.val();
            var value = data? parseFloat(data): 0;
            var match = data.match(/[^\.\-0-9]+/);
            var suffix = match && match[0]? match[0]: '';
            if( isNaN(value) ) return;
            
            input.val((value + diff) + suffix).trigger('change');
        });
    }

    // inputbox
    $.pixeRangeData = {
        'column': {
            'col': $.pixeColumnSize.column,
            '%': {min: $.pixeColumnSize.min, max: 100},
            'px': {min: 100, max: 1000},
            'auto': 'none'
        },
        'item-width': {
            'px': {min: 100, max: 1400},
            '%': {min: 10, max: 100},
            'vw': {min: 0, max: 100},
            'auto': 'none'
        },
        'width': {
            '%': {min: 10, max: 100},
            'px': {min: 100, max: 1400},
            'vw': {min: 0, max: 100}
        },
        'width2': {
            'px': {min: 100, max: 1400},
            '%': {min: 10, max: 100},
            'vw': {min: 0, max: 100}
        },
        'image-width': {
            'px': {min: 100, max: 1400},
            '%': {min: 10, max: 100},
            'vw': {min: 0, max: 100}
        },
        'box-width': {
            'px': {min: 900, max: 1800},
            '%': {min: 80, max: 100},
            'vw': {min: 80, max: 100}
        },
        'content-width': {
            'px': {min: 900, max: 1400},
        },
        'input-width': {
            'px': {min: 40, max: 500},
            '%': {min: 10, max: 100},
            'em': {min: 0, max: 5, decimal: 1},
        },
        'input-height': {
            'px': {min: 20, max: 80},
            '%': {min: 0, max: 100},
            'em': {min: 1, max: 5},
        },
        'height': {
            'px': {min: 0, max: 1000},
            'vh': {min: 0, max: 100},
            '%': {min: 0, max: 100}
        },
        'image-height-px': {
            'px': {min: 100, max: 500}
        },
        'height-offset': {
            'px': {min: 0, max: 300},
            'vh': {min: 0, max: 50}
        },
        'font-size': {
            'px': {min: 8, max: 120},
            'em': {min: 10, max: 120, decimal: 1},
            'rem': {min: 10, max: 120, decimal: 1},
            'vw': {min: 0, max: 100, decimal: 1},
        },
        'padding': {
            'px': {min: 0, max: 200},
            '%': {min: 0, max: 100},
            'em': {min: 0, max: 30},
            'rem': {min: 0, max: 30},
            'vw': {min: 0, max: 100}
        },
        'padding-px': {
            'px': {min: 0, max: 200}
        },
        'margin': {
            'px': {min: -200, max: 200},
            '%': {min: -100, max: 100},
            'em': {min: -30, max: 30},
            'rem': {min: -30, max: 30},
            'vw': {min: -100, max: 100}
        },
        'margin-positive': {
            'px': {min: 0, max: 200},
            '%': {min: 0, max: 100},
            'em': {min: 0, max: 30},
            'rem': {min: 0, max: 30},
            'vw': {min: 0, max: 100}
        },
        'position': {
            'px': {min: -1000, max: 1000},
            '%': {min: -100, max: 100},
            'em': {min: -10, max: 10},
            'rem': {min: -10, max: 10},
            'auto': 'none'
        },
        'transform': {
            'px': {min: -1000, max: 1000},
            '%': {min: -100, max: 100},
            'em': {min: -10, max: 10},
            'rem': {min: -10, max: 10},
        },
        'transform-offset': {
            'px': {min: -800, max: 800},
            '%': {min: -100, max: 100},
            'em': {min: -10, max: 10},
            'rem': {min: -10, max: 10},
        },
        'transform-small': {
            'px': {min: -50, max: 50},
            '%': {min: -100, max: 100},
            'em': {min: -5, max: 5},
            'rem': {min: -5, max: 5},
        },
        'transform-p': {
            'px': {min: -1000, max: 1000},
            '%': {min: -100, max: 100},
        },
        'background': {
            '%': {min: -200, max: 200},
            'px': {min: -300, max: 300},
            'em': {min: -20, max: 20},
            'rem': {min: -20, max: 20},
            'vw': {min: -20, max: 20}
        },
        'background-width': {
            'px': {min: 50, max: 500},
            '%': {min: 30, max: 200},
            'em': {min: 5, max: 50},
            'rem': {min: 5, max: 50},
            'vw': {min: 5, max: 50}
        },
        'button-width': {
            'px': {min: 20, max: 300},
            '%': {min: 0, max: 100},
            'em': {min: 5, max: 20},
        },
        'bar-width': {
            'px': {min: 0, max: 80},
            '%': {min: 0, max: 100},
        },
        'bar-height': {
            'px': {min: 0, max: 30},
        },
        'border': {
            'px': {min: 0, max: 20},
            'em': {min: 0, max: 5},
            'rem': {min: 0, max: 5},
        },
        'menu-divider': {
            'px': {min: 0, max: 50},
            'em': {min: 0, max: 5},
            'rem': {min: 0, max: 5},
            '%': {min: 0, max: 100},
        },
        'radius': {
            'px': {min: 0, max: 50},
            'em': {min: 0, max: 10},
            'rem': {min: 0, max: 10},
            '%': {min: 0, max: 100},
        },
        'gap': {
            'px': {min: 0, max: 60},
            '%': {min: 0, max: 60},
            'em': {min: 0, max: 6},
            'rem': {min: 0, max: 6},
        },
        'gap-px': {
            'px': {min: 0, max: 60},
        },
        'gap-minus': {
            'px': {min: -40, max: 40},
            '%': {min: -40, max: 40},
            'em': {min: -5, max: 5},
            'rem': {min: -5, max: 5},
        },
        'controls': {
            'px': {min: 0, max: 40},
            'em': {min: 0, max: 4, decimal: 1},
            'rem': {min: 0, max: 4, decimal: 1},
        },
        'controls-l': {
            'px': {min: 0, max: 100},
            'em': {min: 0, max: 10, decimal: 1},
            'rem': {min: 0, max: 10, decimal: 1},
        },
        'avatar': {
            'px': {min: 30, max: 150},
            '%': {min: 10, max: 60},
        },
        'scroll-posx': {
            'px': {min: -600, max: 600},
            '%': {min: -200, max: 200},
            'vw': {min: -200, max: 200},
        },
        'scroll-posy': {
            'px': {min: -600, max: 600},
            '%': {min: -200, max: 200},
            'vh': {min: -200, max: 200},
        },
        'scroll-width': {
            'px': {min: 0, max: 1920},
            '%': {min: -200, max: 200},
            'vw': {min: -200, max: 200},
            'vh': {min: -200, max: 200},
        },
        'scroll-blur': {
            'px': {min: 0, max: 40},
        },
        'variable': {
            'px': {min: -100, max: 100},
            '%': {min: -100, max: 100},
            'em': {min: -10, max: 10},
            'rem': {min: -10, max: 10},
            'vw': {min: -100, max: 100},
            'dvh': {min: -100, max: 100},
        },
        'viewport': {
            'px': {min: -100, max: 100},
            '%': {min: -100, max: 100},
            'em': {min: -10, max: 10},
            'rem': {min: -10, max: 10},
            'vw': {min: -100, max: 100},
            'dvh': {min: -100, max: 100},
        },
    };
    $.pixeGetRangePopup = function(settings){
        settings = $.extend({
            rangeInput: '',
            style: 'pixe-range-input-popup'
        }, settings);

        var popupContent = $('<div class="pixe-range-variable-content" ></div>');
        var rangeInput = settings.rangeInput;
        var input = rangeInput.find('input[type="text"]');
        var typeInput = input.siblings('.pixe-combobox');
        var hiddenInput = input.siblings('input[type="hidden"]');
        var variableType = rangeInput.attr('data-variable-type') || 'number';
        var hasVariable = variableType != 'none';
        
        var value = hiddenInput.val() || '';
        var variable = $.pixeGetVariable(value);
        var variableTab = $();
        var rangeSettings;

        if( hasVariable ){
            // popup tab header
            var tabHead = $($.pixeComboboxTab({
                custom: 'Custom Value',
                variable: 'Variables'
            }));
            popupContent.append(tabHead);

            tabHead.on('click', '[data-tab]', function(){
                var tabSlug = $(this).attr('data-tab');
                popupContent.find('[data-tab="' + tabSlug + '"]').addClass('pixe-active').siblings().removeClass('pixe-active');
                $.pixeSetPopupPosition(popup.settings, popup.popupBox);
            });
        }

        // custom tab content
        var customTab = $('<div class="pixe-options pixe-active" data-tab="custom" ></div>');
        popupContent.append(customTab);

        // sycned range input
        var syncedInput;
        if( hasVariable ){
            var syncedRangeInput = rangeInput.clone();
            var syncedInput = syncedRangeInput.find('input[type="text"]');
            var syncedTypeInput = syncedRangeInput.find('.pixe-combobox');

            syncedRangeInput.removeClass('pixe-input-focus');
            syncedRangeInput.find('input[type="hidden"]').remove();
            syncedTypeInput.data('value', typeInput.data('value')).removeClass('pixe-init');
            customTab.append(syncedRangeInput);

            // bind events
            syncedInput.pixeNumberInput();
            syncedRangeInput.pixeCombobox();
            syncedRangeInput.on('input change', 'input[type="text"], .pixe-combobox', function(e){
                if( $(this).is('input[type="text"]') ){
                    input.val($(this).val()).trigger('slidechange');
                    if( e.type == 'change' ){
                        syncedInput.val(input.val());
                    }
                }else if( $(this).hasClass('pixe-combobox') ){
                    typeInput.data('value', $(this).data('value')).trigger('initvalue');
                    typeInput.trigger('change');
                    updateRangeSettings($(this).data('value'));
                }

                variableTab.find('.pixe-option').removeClass('pixe-active');
            });
        }

        var range = $('<input class="pixe-range-selector" type="range" />');
        customTab.append(range);

        function getRangeSettings(typeData){
            var data = {
                min: input.attr('data-min') || 0,
                max: input.attr('data-max') || 100,
                decimal: parseInt(input.attr('data-decimal')) || 0,
                defaultValue: input.attr('data-default') || '',
                start: 0
            };
            var rangeData = input.data('range');

            // get preset range data
            if( rangeData ){
                rangeData = (typeof(rangeData) == 'string')? $.pixeRangeData[rangeData]: rangeData;

                if( rangeData && rangeData[typeData] && !Array.isArray(rangeData[typeData]) && rangeData[typeData] != 'none' ){
                    data.min = rangeData[typeData].min || data.min;
                    data.max = rangeData[typeData].max || data.max;
                    data.decimal = rangeData[typeData].decimal || 0;
                }
            }
            
            // range start value
            if( variable || data.defaultValue ){
                data.start = parseInt(data.defaultValue);
            }else if( input.val() ){
                data.start = parseFloat(input.val()) * (10 ** data.decimal);
            }
            if( isNaN(data.start) ){
                data.start = 0;
            }

            return data;
        }
        function setRangeStyle(value){
            range.css({
                '--pixe--progress': ((value - rangeSettings.min) / (rangeSettings.max - rangeSettings.min)) * 100 + '%'
            });
        }
        function updateRangeSettings(typeData){
            rangeSettings = getRangeSettings(typeData);

            range.attr('min', rangeSettings.min);
            range.attr('max', rangeSettings.max);
            range.val(rangeSettings.start);

            if( syncedInput ){
                syncedInput.attr({
                    'data-min': rangeSettings.min,
                    'data-max': rangeSettings.max,
                    'data-decimal': rangeSettings.decimal
                });
            }
            setRangeStyle(rangeSettings.start);
        }
        updateRangeSettings(typeInput.data('value'));

        // on select range
        range.on('input', function(e){
            e.preventDefault();

            setRangeStyle($(this).val());
            input.val(parseFloat($(this).val()) / (10 ** rangeSettings.decimal)).trigger('slidechange');

            // synced input
            if( syncedInput ){
                syncedInput.val(input.val());
                if( syncedTypeInput.length && syncedTypeInput.data('value') == 'variable' ){
                    syncedTypeInput.data('value', typeInput.data('value')).trigger('initvalue');
                }
            }

            variableTab.find('.pixe-option').removeClass('pixe-active');
        });

        // variable tab content
        if( hasVariable ){
            variableTab = $('<div class="pixe-options" data-tab="variable" ></div>');
            variableTab.append($.pixeComboboxOption.rangeVariable(variableType));
            popupContent.append(variableTab);

            // variable events
            variableTab.on('click', '.pixe-option', function(){
                var variableName = $(this).data('value');
                input.val(variableName).trigger('slidechange');
                popup.close();
            });

            // bottom section
            var bottom = $('<div class="pixe-combobox-tab-bottom pixe-no-user-select" ></div>');
            bottom.append('<span data-tab="custom" style="display:none;" ></span>');
            bottom.append($.pixeComboboxBottom('Variable Manager', undefined, undefined, 'variable'));
            popupContent.append(bottom);

            bottom.on('click', '[data-tab="variable"]', function(e){
                e.stopPropagation();
                if( $.pixeVariableSettings ){
                    $.pixeVariableSettings.init({
                        activeTab: variableType
                    });
                }else if( $.pixeEditor ){
                    $.pixeEditor.setParentStatus({
                        event: 'variables',
                        action: 'edit',
                        activeTab: variableType
                    });
                }
                popup.close();
            });
        }

        // initial state
        if( hasVariable && variable ){
            popupContent.find('[data-tab="variable"]').addClass('pixe-active').siblings().removeClass('pixe-active');
            variableTab.find('.pixe-option[data-value="' + variable + '"]').addClass('pixe-active').siblings().removeClass('pixe-active');
        }

        // create popup
        var popup = new $.pixePopup({
            content: popupContent,
            target: input,
            targetFocus: rangeInput,
            style: settings.style + ' pixe-combobox-popup'
        });

        return popup;
    };

    $.fn.pixeRangeInput = function(){

        $(this).find('.pixe-range-input').each(function(){
            if( $(this).hasClass('pixe-init') ) return;
            $(this).addClass('pixe-init');
            
            var rangeInput = $(this);
            var input = rangeInput.find('input[type="text"]');
            var typeInput = input.siblings('.pixe-combobox');
            var hiddenInput = input.siblings('input[type="hidden"]');
            var filterInput = rangeInput.attr('data-filter')? $.pixeInputFilter[rangeInput.attr('data-filter')]: undefined;
            
            rangeInput.on('click', 'input[type="text"]', function(){
                if( $(this).hasClass('pixe-target-close') ){
                    $(this).removeClass('pixe-target-close');
                    return;
                }

                var inputType = 'range';
                var inputOptions = [];

                // input with preset range
                if( input.data('range') ){
                    var rangeData = input.data('range');
                    rangeData = (typeof(rangeData) == 'string')? $.pixeRangeData[rangeData]: rangeData;

                    var dataType = input.siblings('.pixe-combobox').data('value');
                    if( rangeData && rangeData[dataType] ){
                        if( Array.isArray(rangeData[dataType]) ){
                            inputType = 'combobox';
                            inputOptions = rangeData[dataType];
                        }else if(rangeData[dataType] == 'none'){
                            inputType = 'none';
                        }
                    }
                } 

                // create range input
                if( inputType == 'range' ){
                    $.pixeGetRangePopup({
                        rangeInput: rangeInput
                    });
                
                // combobox input
                }else if( inputType == 'combobox' ){
                    var content = $('<div class="pixe-options pixe-active pixe-scrollbar" ></div>');
                    content.append($.pixeComboboxOption.arrayObject(inputOptions));

                    var popup = new $.pixePopup({
                        content: content,
                        target: input,
                        targetFocus: rangeInput,
                        style: 'pixe-combobox-popup'
                    });

                    content.on('click', '.pixe-option', function(){
                        input.val($(this).html()).trigger('change');
                        popup.close();
                    });
                }
                
            });

            // focus class
            rangeInput.on('focus', 'input[type="text"]', function(){
                rangeInput.addClass('pixe-input-focus');
            }).on('blur', 'input[type="text"]', function(){
                rangeInput.removeClass('pixe-input-focus');
            });
            rangeInput.on('pixe-focus', '.pixe-combobox', function(){
                rangeInput.addClass('pixe-input-focus');
            }).on('pixe-blur', '.pixe-combobox', function(){
                rangeInput.removeClass('pixe-input-focus');  
            });

            // bind number input
            input.pixeNumberInput();

            // range input with suffix
            if( input.attr('data-suffix') ){

                rangeInput.on('input change slidechange', 'input[type="text"]', function(e){
                    var value = $(this).val();

                    // auto fill suffix
                    if( value && !isNaN(value) ){
                        
                        if( e.type != 'input' ){
                            var suffix = $(this).attr('data-suffix');
                            input.val(value + suffix);
                            hiddenInput.val(value + suffix).trigger('change');
                        }

                    // allow custom value with suffix
                    }else{
                        var variable = $.pixeGetVariable(value);
                        if( variable ){
                            input.val(variable);
                            hiddenInput.val('var(' + variable + ')').trigger('change');
                        }else{
                            hiddenInput.val(value).trigger('change');
                        }
                    }
                });
                rangeInput.on('initvalue', 'input[type="hidden"]', function(){
                    var value = $(this).val() || '';
                    var variable = $.pixeGetVariable(value);

                    if( variable ){
                        input.val(variable);
                    }else{
                        input.val(value);
                    }
                });

            // range input with preset range
            }else{

                function updateHiddenInput(e){
                    var value = input.val() || '';
                    var variable = $.pixeGetVariable(value);
                    var typeData = typeInput.data('value') || '';

                    if( filterInput ){ 
                        hiddenInput.val(filterInput(input.val(), typeData, e, input));
                    }else if( variable ){
                        hiddenInput.val('var(' + variable + ')');

                        if( typeData != 'variable' ){
                            typeInput.data('value', 'variable').trigger('initvalue');
                        }
                    }else if( value ){
                        if( typeInput.length && typeData == 'variable' ){
                            typeData = typeInput.find('.pixe-option').first().data('value') || '';
                            typeInput.data('value', typeData).trigger('initvalue');
                        }

                        hiddenInput.val(value + typeData);        
                    }else{
                        hiddenInput.val('');
                    }

                    hiddenInput.trigger('change');
                }

                rangeInput.on('input change slidechange', 'input[type="text"]', function(e){
                    e.stopPropagation();
                    updateHiddenInput(e);
                });
                rangeInput.on('change', '.pixe-combobox', function(e){
                    e.stopPropagation();
                    updateHiddenInput(e);
                });
                rangeInput.on('initvalue', 'input[type="hidden"]', function(){
                    var value = $(this).val() || '';
                    var type = '';

                    if( value ){
                        type = $.pixeGetUnit(value);
                        if( type == 'variable' ){
                            value = $.pixeGetVariable(value);
                        }else{
                            value = parseFloat(value);
                        }
                    }

                    input.val(value);
                    typeInput.data('value', type).trigger('initvalue');
                });
            }
        });

    }
    $.pixeRangeInput = function(settings){
        settings = $.extend({
            slug: '',
            slugInner: '',
            value: '',
            min: 0,
            max: 100,
            decimal: 0,
            width: '',
            wrapSize: '',
            suffix: '',
            suffixText: '',
            contentClass: '',
            placeholder: '',
            filter: '',
            class: '',
            variableType: 'number'
        }, settings);

        var html  = '<div class="pixe-range-input ' + $.pixeEscAttr(settings.class) + '" ';
            html += (settings.width? 'style="max-width: ' + $.pixeSizeFormat(settings.width) + '"': '');
            html += (settings.filter? 'data-filter="' + $.pixeEscAttr(settings.filter) + '"': '');
            html += 'data-variable-type="' + $.pixeEscAttr(settings.variableType) + '" ';
            html += ' >';

        if( settings.range ){
            var value = settings.value? settings.value: '';
            var type = (value)? $.pixeGetUnit(value): '';
            var variable = $.pixeGetVariable(value);
            if( variable ){
                value = variable;
            }else if( type == 'auto' || type == 'none' ){
                value = '-';
            }else if( type != 'col' ){
                value = parseFloat(value);
            }

            html += '<input type="text" ';
            html += (settings.value? 'value="' + $.pixeEscAttr(value) + '" ': '');
            html += (settings.placeholder? 'placeholder="' + $.pixeEscAttr(settings.placeholder) + '"': '')
            html += 'data-min="' + $.pixeEscAttr(settings.min) + '" ';
            html += 'data-max="' + $.pixeEscAttr(settings.max) + '" ';
            html += 'data-decimal="' + $.pixeEscAttr(settings.decimal) + '" ';
            html += 'data-range=\'' + (typeof(settings.range) == 'string'? $.pixeEscAttr(settings.range): JSON.stringify(settings.range)) + '\' ';
            html += '/>';
            html += '<input type="hidden" ';
            html += (settings.value? 'value="' + $.pixeEscAttr(settings.value) + '" ': '');
            html += (settings.slug? 'data-slug= "' + $.pixeEscAttr(settings.slug) + '" ': '');
            html += (settings.slugInner? 'data-slug-inner= "' + $.pixeEscAttr(settings.slugInner) + '" ': '');
            html += (settings.group? 'data-input-group= "' + $.pixeEscAttr(settings.group) + '" ': '');
            html += ' />';

            var range = (typeof(settings.range) == 'string')? $.pixeRangeData[settings.range]: settings.range;
            var comboboxOptions = $.pixeComboboxOption.arrayObject(Object.keys(range));
            html += $.pixeCombobox({
                value: type,
                class: 'pixe-borderless',
                popupClass: 'pixe-small pixe-combobox-popup-unit',
                options: comboboxOptions
            });
        }else{
            html += '<input type="text" ';
            html += (settings.placeholder? 'placeholder="' + $.pixeEscAttr(settings.placeholder) + '"': '')
            html += (settings.value? 'value="' + $.pixeEscAttr(settings.value) + '" ': '');
            html += 'data-min="' + $.pixeEscAttr(settings.min) + '" ';
            html += 'data-max="' + $.pixeEscAttr(settings.max) + '" ';
            html += 'data-decimal="' + $.pixeEscAttr(settings.decimal) + '" ';
            html += 'data-suffix="' + $.pixeEscAttr(settings.suffix) + '" ';
            if( settings.default ){
                html += 'data-default="' + $.pixeEscAttr(settings.default) + '" ';
                html += 'placeholder="' + $.pixeEscAttr(settings.default + settings.suffix) + '" ';
            }
            html += (settings.width? 'style="width: ' + $.pixeSizeFormat(settings.width) + '"': '');
            html += '/>';
            html += '<input type="hidden" ';
            html += (settings.value? 'value="' + $.pixeEscAttr(settings.value) + '" ': '');
            html += (settings.slug? 'data-slug= "' + $.pixeEscAttr(settings.slug) + '" ': '');
            html += (settings.slugInner? 'data-slug-inner= "' + $.pixeEscAttr(settings.slugInner) + '" ': '');
            html += ' />';

            if( settings.suffixText ){
                html += '<span class="pixe-suffix-text">' + settings.suffixText + '</span>';
            }
        }
        html += '</div>'; // pixe-range-input

        return html;
    }

    // ratio text
    $.pixeTextRatio = function(settings){
        settings = $.extend({
            slug: '',
            value: ''
        }, settings);

        // create input
        var input = $('<div class="pixe-text-ratio" ></div>');
        input.attr('data-slug', settings.slug);
        input.data('value', settings.value);
        
        var inputW = $($.pixeInput({
            placeholder: 'W',
            value: settings.value? settings.value.w: ''
        }));
        var inputH = $($.pixeInput({
            placeholder: 'H',
            value: settings.value? settings.value.h: ''
        }));

        input.append(inputW);
        input.append('<div class="pixe-separator" >:</div>')
        input.append(inputH);
        
        // bind
        input.find('input[type="text"]').pixeNumberInput();
        input.on('input, change', 'input', function(){
            var w = inputW.find('input').val();
            var h = inputH.find('input').val();
            input.data('value', {w: w, h: h});
        });
        input.on('initvalue', function(){
            var value = input.data('value');
            if( !value ) value = {};
            inputW.find('input').val(value.w);
            inputH.find('input').val(value.h);
        });

        return input;
    }

    // normal input box
    $.pixeInput = function(settings){
        settings = $.extend({
            class: '',
            slug: '',
            type: 'text',
            value: '',
            width: '',
            placeholder: '',
        }, settings);

        var html  = '<div class="pixe-input ' + $.pixeEscAttr(settings.class? settings.class: '') + '" ';
            html += (settings.type? 'data-type="' + $.pixeEscAttr(settings.type) + '" ': '');
            html += (settings.width? 'style="width: ' + $.pixeSizeFormat(settings.width) + '"': '');
            html += ' >';
            html += '<input type="' + $.pixeEscAttr(settings.type) + '" ';
            html += (settings.value? 'value="' + $.pixeEscAttr(settings.value) + '" ': '');
            html += (settings.slug? 'data-slug= "' + $.pixeEscAttr(settings.slug) + '" ': '');
            html += (settings.innerSlug? 'data-inner-slug= "' + $.pixeEscAttr(settings.innerSlug) + '" ': '');
            html += (settings.group? 'data-input-group= "' + $.pixeEscAttr(settings.group) + '" ': '');
            html += (settings.placeholder? 'placeholder="' + $.pixeEscAttr(settings.placeholder) + '"': '')
            html += ' />';
            if( settings['info'] ){
                html += settings['info'];
            }
            html += '</div>'; // pixe-input

        return html;
    }   

    // textarea
    $.pixeTextarea = function(settings){
        settings = $.extend({
            class: '',
            slug: '',
            innerSlug: '',
            value: '',
            placeholder: '',
        }, settings);

        var html  = '<textarea class="pixe-textarea ' + $.pixeEscAttr(settings.class? settings.class: '') + '" ';
            html += (settings.slug? 'data-slug= "' + $.pixeEscAttr(settings.slug) + '" ': '');
            html += (settings.innerSlug? 'data-inner-slug= "' + $.pixeEscAttr(settings.innerSlug) + '" ': '');
            html += (settings.placeholder? 'placeholder="' + $.pixeEscAttr(settings.placeholder) + '"': '')
            html += ' >';
            html += $.pixeEscTextarea(settings.value? settings.value: '');
            html += '</textarea>'; // pixe-input

        return html;
    }

    // padding & margin & border size input
    $.pixeSizeInput = function(settings){
        settings = $.extend({
            slug: '',
            title: '',
            value: {},
            type: '', // padding, margin
            tbType: '', // px or empty string
            enableSync: true
        }, settings);
        
        // html
        var html  = '<div class="pixe-size-input pixe-synced ' + $.pixeEscAttr(settings.class? settings.class: '') + '" ';
            html += (settings.slug? 'data-slug="' + $.pixeEscAttr(settings.slug) + '" ': '');
            html += ' >';

            html += '<div class="pixe-head-wrap" >';
            html += '<label>' + settings.title + '</label>';
            if( settings.descriptionTop ){
                html += '<div class="pixe-description pixe-top" >' + settings.descriptionTop + '</div>';
            }
            html += '</div>';

            html += '<div class="pixe-content" >';

            // sync
            if( settings.enableSync ){
                html += '<div class="pixe-row pixe-space-sync" >';
                html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="13" width="3" height="16" fill="#DCE4EC"/><rect width="3" height="16" fill="#DCE4EC"/><rect y="16" width="3" height="16" transform="rotate(-90 0 16)" fill="#92A2B1"/><rect y="3" width="3" height="16" transform="rotate(-90 0 3)" fill="#92A2B1"/></svg>';
                html += $.pixeRangeInput({
                    slugInner: 'top-bottom',
                    range: (settings.tbType)? settings.tbType: settings.type,
                    variableType: 'spacing',
                    value: (settings.value.top == settings.value.bottom)? settings.value.top: ''
                });
                html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect y="16" width="3" height="16" transform="rotate(-90 0 16)" fill="#DCE4EC"/><rect y="3" width="3" height="15" transform="rotate(-90 0 3)" fill="#DCE4EC"/><rect x="13" width="3" height="16" fill="#92A2B1"/><rect width="3" height="16" fill="#92A2B1"/></svg>';
                html += $.pixeRangeInput({
                    slugInner: 'left-right',
                    range: settings.type,
                    variableType: 'spacing',
                    value: (settings.value.left == settings.value.right)? settings.value.left: ''
                });
                html += '<div class="pixe-action-unsync" >';
                html += '<svg width="16" height="8" viewBox="0 0 16 8" fill="none" ><path d="M6.66667 0.666667C6.66667 1.03486 6.36819 1.33333 6 1.33333H4C2.52724 1.33333 1.33333 2.52724 1.33333 4C1.33333 5.47273 2.52724 6.66667 4 6.66667H6C6.36819 6.66667 6.66667 6.96513 6.66667 7.33333C6.66667 7.70153 6.36819 8 6 8H4C1.79086 8 0 6.20913 0 4C0 1.79086 1.79086 0 4 0H6C6.36819 0 6.66667 0.29848 6.66667 0.666667Z" fill="#383C49"/><path d="M9.99992 1.33333C9.63172 1.33333 9.33325 1.03486 9.33325 0.666667C9.33325 0.29848 9.63172 0 9.99992 0H11.9999C14.2091 0 15.9999 1.79086 15.9999 4C15.9999 6.20913 14.2091 8 11.9999 8H9.99992C9.63172 8 9.33325 7.70153 9.33325 7.33333C9.33325 6.96513 9.63172 6.66667 9.99992 6.66667H11.9999C13.4727 6.66667 14.6666 5.47273 14.6666 4C14.6666 2.52724 13.4727 1.33333 11.9999 1.33333H9.99992Z" fill="#383C49"/><path d="M12 3.99992C12 4.36812 11.7015 4.66659 11.3333 4.66659H4.66667C4.29848 4.66659 4 4.36812 4 3.99992C4 3.63172 4.29848 3.33325 4.66667 3.33325H11.3333C11.7015 3.33325 12 3.63172 12 3.99992Z" fill="#383C49"/></svg>';
                html += '</div>';
                html += '</div>';
            }

            // unsync
            html += '<div class="pixe-row pixe-space-unsync" >';
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="13" width="3" height="16" fill="#DCE4EC"/><rect width="3" height="16" fill="#DCE4EC"/><rect y="16" width="3" height="16" transform="rotate(-90 0 16)" fill="#DCE4EC"/><rect y="3" width="3" height="16" transform="rotate(-90 0 3)" fill="#92A2B1"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'top',
                range: (settings.tbType)? settings.tbType: settings.type,
                variableType: 'spacing',
                value: settings.value.top
            });
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect y="16" width="3" height="16" transform="rotate(-90 0 16)" fill="#DCE4EC"/><rect y="3" width="3" height="15" transform="rotate(-90 0 3)" fill="#DCE4EC"/><rect x="13" width="3" height="16" fill="#DCE4EC"/><rect width="3" height="16" fill="#92A2B1"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'left',
                range: settings.type,
                variableType: 'spacing',
                value: settings.value.left
            });

            if( settings.enableSync ){
                html += '<div class="pixe-action-sync" >';
                html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" ><path d="M8.70692 3.52158C8.44659 3.78193 8.02466 3.78213 7.76432 3.52179C7.50399 3.26143 7.50399 2.83933 7.76432 2.57897L7.99972 2.3432C9.56179 0.781108 12.0945 0.781108 13.6566 2.3432C15.2187 3.9053 15.2187 6.43796 13.6566 8.00008L12.0067 9.64995C10.4446 11.212 7.91206 11.2121 6.34995 9.65015C6.08964 9.38981 6.08977 8.96755 6.35011 8.70721C6.61046 8.44688 7.03259 8.44688 7.29292 8.70721C8.33432 9.74841 10.0225 9.74848 11.0639 8.70715L12.7137 7.05728C13.7551 6.01585 13.7551 4.32741 12.7137 3.28601C11.6723 2.24461 9.98392 2.24461 8.94252 3.28601L8.70692 3.52158Z" fill="#383C49"/><path d="M8.23538 13.4209L7.99958 13.6567C6.43747 15.2188 3.90481 15.2188 2.34272 13.6567C0.780618 12.0946 0.780618 9.56197 2.34272 7.99991L3.99263 6.34996C5.55472 4.78787 8.08752 4.78802 9.64965 6.35012C9.90998 6.61047 9.91018 7.03251 9.64978 7.29284C9.38945 7.55317 8.96705 7.55311 8.70665 7.29277C7.66525 6.25137 5.97684 6.25137 4.93544 7.29277L3.28552 8.94271C2.24412 9.98411 2.24412 11.6725 3.28552 12.7139C4.32692 13.7553 6.01536 13.7553 7.05678 12.7139L7.29278 12.4783C7.55312 12.218 7.97525 12.218 8.23558 12.4783C8.49592 12.7386 8.49572 13.1606 8.23538 13.4209Z" fill="#383C49"/></svg>';
                html += '</div>';
            }
            
            html += '</div>';
            html += '<div class="pixe-row pixe-space-unsync" >';
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="13" width="3" height="16" fill="#DCE4EC"/><rect width="3" height="16" fill="#DCE4EC"/><rect y="16" width="3" height="16" transform="rotate(-90 0 16)" fill="#92A2B1"/><rect y="3" width="3" height="16" transform="rotate(-90 0 3)" fill="#DCE4EC"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'bottom',
                range: (settings.tbType)? settings.tbType: settings.type,
                variableType: 'spacing',
                value: settings.value.bottom
            });
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect y="16" width="3" height="16" transform="rotate(-90 0 16)" fill="#DCE4EC"/><rect y="3" width="3" height="15" transform="rotate(-90 0 3)" fill="#DCE4EC"/><rect x="13" width="3" height="16" fill="#92A2B1"/><path d="M0 0H3V16H0V0Z" fill="#DCE4EC"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'right',
                range: settings.type,
                variableType: 'spacing',
                value: settings.value.right
            });
            html += '</div>';
            html += '</div>'; // pixe-size-input-content
            html += '</div>'; // pixe-size-input

        // init object
        var container = $(html);
        container.pixeCombobox();
        container.pixeRangeInput();
        if( Object.keys(settings.value).length ){
            container.data('value', settings.value);
        }
        if( settings.enableSync && settings.value.top == settings.value.bottom && settings.value.left == settings.value.right ){
            container.addClass('pixe-synced');
        }else{
            container.removeClass('pixe-synced');
        }

        // sync & unsync button
        container.on('click', '.pixe-action-sync', function(){
            container.addClass('pixe-synced');
        });
        container.on('click', '.pixe-action-unsync', function(){
            container.removeClass('pixe-synced');
        });

        // initvalue
        container.on('initvalue2', function(){
            var value = $(this).data('value');
            if( value && value['top'] && value['top'] == value['bottom'] ){
                container.find('input[data-slug-inner="top-bottom"]').val(value['top']).trigger('initvalue')
            }else{
                container.find('input[data-slug-inner="top-bottom"]').val('').trigger('initvalue');
            }
            if( value && value['left'] && value['left'] == value['right'] ){
                container.find('input[data-slug-inner="left-right"]').val(value['left']).trigger('initvalue')
            }else{
                container.find('input[data-slug-inner="left-right"]').val('').trigger('initvalue');
            }
            container.find('input[data-slug-inner="top"]').val((value && value['top'])? value['top']:'').trigger('initvalue')
            container.find('input[data-slug-inner="right"]').val((value && value['right'])? value['right']:'').trigger('initvalue');
            container.find('input[data-slug-inner="bottom"]').val((value && value['bottom'])? value['bottom']:'').trigger('initvalue');
            container.find('input[data-slug-inner="left"]').val((value && value['left'])? value['left']:'').trigger('initvalue');
        });

        // value change
        container.on('change', '[data-slug-inner]', function(){
            var slug = $(this).attr('data-slug-inner');
            var value = container.data('value');
            if( !value ){ value = {} };

            switch(slug){
                case 'left-right':
                    container.find('input[data-slug-inner="left"], input[data-slug-inner="right"]').val($(this).val()).trigger('initvalue');
                    if( $(this).val() ){
                        value.left = $(this).val();
                        value.right = $(this).val();
                    }else{
                        delete value.left;
                        delete value.right;
                    }
                    break;
                case 'top-bottom':
                    container.find('input[data-slug-inner="top"], input[data-slug-inner="bottom"]').val($(this).val()).trigger('initvalue');
                    if( $(this).val() ){
                        value.top = $(this).val();
                        value.bottom = $(this).val();
                    }else{
                        delete value.top;
                        delete value.bottom;
                    }
                    break;
                case 'top':
                    var bottom = container.find('input[data-slug-inner="bottom"]');
                    if( $(this).val() == bottom.val() ){
                        container.find('input[data-slug-inner="top-bottom"]').val($(this).val()).trigger('initvalue');
                    }else{
                        container.find('input[data-slug-inner="top-bottom"]').val('').trigger('initvalue');
                    }
                    if( $(this).val() ){
                        value.top = $(this).val();
                    }else{
                        delete value.top;
                    }
                    break;
                case 'bottom':
                    var top = container.find('input[data-slug-inner="top"]');
                    if( $(this).val() == top.val() ){
                        container.find('input[data-slug-inner="top-bottom"]').val($(this).val()).trigger('initvalue');
                    }else{
                        container.find('input[data-slug-inner="top-bottom"]').val('').trigger('initvalue');
                    }
                    if( $(this).val() ){
                        value.bottom = $(this).val();
                    }else{
                        delete value.bottom;
                    }
                    break;
                case 'left':
                    var right = container.find('input[data-slug-inner="right"]');
                    if( $(this).val() == right.val() ){
                        container.find('input[data-slug-inner="left-right"]').val($(this).val()).trigger('initvalue');
                    }else{
                        container.find('input[data-slug-inner="left-right"]').val('').trigger('initvalue');
                    }
                    if( $(this).val() ){
                        value.left = $(this).val();
                    }else{
                        delete value.left;
                    }
                    break;
                case 'right':
                    var left = container.find('input[data-slug-inner="left"]');
                    if( $(this).val() == left.val() ){
                        container.find('input[data-slug-inner="left-right"]').val($(this).val()).trigger('initvalue');
                    }else{
                        container.find('input[data-slug-inner="left-right"]').val('').trigger('initvalue');
                    }
                    if( $(this).val() ){
                        value.right = $(this).val();
                    }else{
                        delete value.right;
                    }
                    break;
            }

            if( Object.keys(value).length ){
                container.data('value', value);
            }else{
                container.removeData('value');
            }
        });
        
        return container;
    }

    // border input
    $.pixeBorderInput = function(settings){
        settings = $.extend({
            slug: '',
            title: '',
            value: {},
            min: undefined,
            max: undefined
        }, settings);

        var isSynced = (settings.value['top'] == settings.value['right'] && 
                        settings.value['top'] == settings.value['bottom'] && 
                        settings.value['top'] == settings.value['left']);
        
        // html
        var html  = '<div class="pixe-size-input pixe-synced" ';
            html += (settings.slug? 'data-slug="' + $.pixeEscAttr(settings.slug) + '" ': '');
            html += ' >';
            html += '<label>' + settings.title + '</label>';
            html += '<div class="pixe-content" >';

            // sync
            html += '<div class="pixe-row pixe-space-sync pixe-half" >';
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect y="16" width="3" height="16" transform="rotate(-90 0 16)" fill="#92A2B1"/><rect y="3" width="3" height="15" transform="rotate(-90 0 3)" fill="#92A2B1"/><rect x="13" width="3" height="16" fill="#92A2B1"/><rect width="3" height="16" fill="#92A2B1"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'all',
                range: 'border',
                value: isSynced? settings.value['top']: ''
            });
            html += '<div class="pixe-action-unsync" >';
            html += '<svg width="16" height="8" viewBox="0 0 16 8" fill="none" ><path d="M6.66667 0.666667C6.66667 1.03486 6.36819 1.33333 6 1.33333H4C2.52724 1.33333 1.33333 2.52724 1.33333 4C1.33333 5.47273 2.52724 6.66667 4 6.66667H6C6.36819 6.66667 6.66667 6.96513 6.66667 7.33333C6.66667 7.70153 6.36819 8 6 8H4C1.79086 8 0 6.20913 0 4C0 1.79086 1.79086 0 4 0H6C6.36819 0 6.66667 0.29848 6.66667 0.666667Z" fill="#383C49"/><path d="M9.99992 1.33333C9.63172 1.33333 9.33325 1.03486 9.33325 0.666667C9.33325 0.29848 9.63172 0 9.99992 0H11.9999C14.2091 0 15.9999 1.79086 15.9999 4C15.9999 6.20913 14.2091 8 11.9999 8H9.99992C9.63172 8 9.33325 7.70153 9.33325 7.33333C9.33325 6.96513 9.63172 6.66667 9.99992 6.66667H11.9999C13.4727 6.66667 14.6666 5.47273 14.6666 4C14.6666 2.52724 13.4727 1.33333 11.9999 1.33333H9.99992Z" fill="#383C49"/><path d="M12 3.99992C12 4.36812 11.7015 4.66659 11.3333 4.66659H4.66667C4.29848 4.66659 4 4.36812 4 3.99992C4 3.63172 4.29848 3.33325 4.66667 3.33325H11.3333C11.7015 3.33325 12 3.63172 12 3.99992Z" fill="#383C49"/></svg>';
            html += '</div>';
            html += '</div>';

            // unsync
            html += '<div class="pixe-row pixe-space-unsync" >';
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect y="16" width="3" height="16" transform="rotate(-90 0 16)" fill="#DCE4EC"/><rect y="3" width="3" height="15" transform="rotate(-90 0 3)" fill="#DCE4EC"/><rect x="13" width="3" height="16" fill="#DCE4EC"/><rect width="3" height="16" fill="#92A2B1"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'left',
                range: 'border',
                value: settings.value.left
            });
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="13" width="3" height="16" fill="#DCE4EC"/><rect width="3" height="16" fill="#DCE4EC"/><rect y="16" width="3" height="16" transform="rotate(-90 0 16)" fill="#DCE4EC"/><rect y="3" width="3" height="16" transform="rotate(-90 0 3)" fill="#92A2B1"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'top',
                range: 'border',
                value: settings.value.top
            });
            html += '<div class="pixe-action-sync" >';
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" ><path d="M8.70692 3.52158C8.44659 3.78193 8.02466 3.78213 7.76432 3.52179C7.50399 3.26143 7.50399 2.83933 7.76432 2.57897L7.99972 2.3432C9.56179 0.781108 12.0945 0.781108 13.6566 2.3432C15.2187 3.9053 15.2187 6.43796 13.6566 8.00008L12.0067 9.64995C10.4446 11.212 7.91206 11.2121 6.34995 9.65015C6.08964 9.38981 6.08977 8.96755 6.35011 8.70721C6.61046 8.44688 7.03259 8.44688 7.29292 8.70721C8.33432 9.74841 10.0225 9.74848 11.0639 8.70715L12.7137 7.05728C13.7551 6.01585 13.7551 4.32741 12.7137 3.28601C11.6723 2.24461 9.98392 2.24461 8.94252 3.28601L8.70692 3.52158Z" fill="#383C49"/><path d="M8.23538 13.4209L7.99958 13.6567C6.43747 15.2188 3.90481 15.2188 2.34272 13.6567C0.780618 12.0946 0.780618 9.56197 2.34272 7.99991L3.99263 6.34996C5.55472 4.78787 8.08752 4.78802 9.64965 6.35012C9.90998 6.61047 9.91018 7.03251 9.64978 7.29284C9.38945 7.55317 8.96705 7.55311 8.70665 7.29277C7.66525 6.25137 5.97684 6.25137 4.93544 7.29277L3.28552 8.94271C2.24412 9.98411 2.24412 11.6725 3.28552 12.7139C4.32692 13.7553 6.01536 13.7553 7.05678 12.7139L7.29278 12.4783C7.55312 12.218 7.97525 12.218 8.23558 12.4783C8.49592 12.7386 8.49572 13.1606 8.23538 13.4209Z" fill="#383C49"/></svg>';
            html += '</div>';
            html += '</div>';
            html += '<div class="pixe-row pixe-space-unsync" >';
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect y="16" width="3" height="16" transform="rotate(-90 0 16)" fill="#DCE4EC"/><rect y="3" width="3" height="15" transform="rotate(-90 0 3)" fill="#DCE4EC"/><rect x="13" width="3" height="16" fill="#92A2B1"/><path d="M0 0H3V16H0V0Z" fill="#DCE4EC"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'right',
                range: 'border',
                value: settings.value.right
            });
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="13" width="3" height="16" fill="#DCE4EC"/><rect width="3" height="16" fill="#DCE4EC"/><rect y="16" width="3" height="16" transform="rotate(-90 0 16)" fill="#92A2B1"/><rect y="3" width="3" height="16" transform="rotate(-90 0 3)" fill="#DCE4EC"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'bottom',
                range: 'border',
                value: settings.value.bottom
            });
            html += '</div>';

            html += '</div>'; // pixe-size-input-content
            html += '</div>'; // pixe-size-input

        // init object
        var container = $(html);
        container.pixeCombobox();
        container.pixeRangeInput();
        if( Object.keys(settings.value).length ){
            container.data('value', settings.value);
        }
        if( isSynced ){
            container.addClass('pixe-synced');
        }else{
            container.removeClass('pixe-synced');
        }

        // sync & unsync button
        container.on('click', '.pixe-action-sync', function(){
            container.addClass('pixe-synced');
        });
        container.on('click', '.pixe-action-unsync', function(){
            container.removeClass('pixe-synced');
        });

        // initvalue
        container.on('initvalue2', function(){
            var value = $(this).data('value');
            if( value && value['top'] && value['top'] == value['right'] && value['top'] == value['bottom'] && value['top'] == value['left'] ){
                container.find('input[data-slug-inner="all"]').val(value['top']).trigger('initvalue')
            }else{
                container.find('input[data-slug-inner="all"]').val('').trigger('initvalue');
            }
            container.find('input[data-slug-inner="top"]').val((value && value['top'])? value['top']:'').trigger('initvalue')
            container.find('input[data-slug-inner="right"]').val((value && value['right'])? value['right']:'').trigger('initvalue');
            container.find('input[data-slug-inner="bottom"]').val((value && value['bottom'])? value['bottom']:'').trigger('initvalue');
            container.find('input[data-slug-inner="left"]').val((value && value['left'])? value['left']:'').trigger('initvalue');
        });

        // value change
        container.on('change', '[data-slug-inner]', function(){
            var slug = $(this).attr('data-slug-inner');
            var value = container.data('value');
            if( !value ){ value = {} };
            
            switch(slug){
                case 'all':
                    var val = $(this).val();
                    container.find('input[data-slug-inner="top"], input[data-slug-inner="right"], input[data-slug-inner="bottom"], input[data-slug-inner="left"]').val($(this).val()).trigger('initvalue');
                    if( val ){
                        value['top'] = val;
                        value['right'] = val;
                        value['bottom'] = val;
                        value['left'] = val;
                    }else{
                        delete value['top'];
                        delete value['right'];
                        delete value['bottom'];
                        delete value['left'];
                    }
                    break;
                case 'top':
                case 'right':
                case 'bottom':
                case 'left':
                    var top = container.find('input[data-slug-inner="top"]').val();
                    var right = container.find('input[data-slug-inner="right"]').val();
                    var bottom = container.find('input[data-slug-inner="bottom"]').val();
                    var left = container.find('input[data-slug-inner="left"]').val();

                    if( top == right && top == bottom && top == left ){
                        container.find('input[data-slug-inner="all"]').val(top).trigger('initvalue');
                    }else{
                        container.find('input[data-slug-inner="all"]').val('').trigger('initvalue');
                    }
                    if( $(this).val() ){
                        value[slug] = $(this).val();
                    }else{
                        delete value[slug];
                    }
                    break;
            }

            if( Object.keys(value).length ){
                container.data('value', value);
            }else{
                container.removeData('value');
            }
        });
        
        return container;
    }

    // border radius
    $.pixeRadiusInput = function(settings){
        settings = $.extend({
            slug: '',
            title: '',
            value: {}
        }, settings);

        var isSynced = (settings.value['top-left'] == settings.value['top-right'] && 
                        settings.value['top-left'] == settings.value['bottom-left'] && 
                        settings.value['top-left'] == settings.value['bottom-right']);
        
        // html
        var html  = '<div class="pixe-size-input pixe-synced" ';
            html += (settings.slug? 'data-slug="' + $.pixeEscAttr(settings.slug) + '" ': '');
            html += ' >';
            html += '<label>' + settings.title + '</label>';
            html += '<div class="pixe-content" >';

            // sync
            html += '<div class="pixe-row pixe-space-sync pixe-half" >';
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="1.5" y="1.5" width="13" height="13" rx="3.5" stroke="#92A2B1" stroke-width="3"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'all',
                range: 'radius',
                value: isSynced? settings.value['top-left']: '',
                variableType: 'radius'
            });
            html += '<div class="pixe-action-unsync" >';
            html += '<svg width="16" height="8" viewBox="0 0 16 8" fill="none" ><path d="M6.66667 0.666667C6.66667 1.03486 6.36819 1.33333 6 1.33333H4C2.52724 1.33333 1.33333 2.52724 1.33333 4C1.33333 5.47273 2.52724 6.66667 4 6.66667H6C6.36819 6.66667 6.66667 6.96513 6.66667 7.33333C6.66667 7.70153 6.36819 8 6 8H4C1.79086 8 0 6.20913 0 4C0 1.79086 1.79086 0 4 0H6C6.36819 0 6.66667 0.29848 6.66667 0.666667Z" fill="#383C49"/><path d="M9.99992 1.33333C9.63172 1.33333 9.33325 1.03486 9.33325 0.666667C9.33325 0.29848 9.63172 0 9.99992 0H11.9999C14.2091 0 15.9999 1.79086 15.9999 4C15.9999 6.20913 14.2091 8 11.9999 8H9.99992C9.63172 8 9.33325 7.70153 9.33325 7.33333C9.33325 6.96513 9.63172 6.66667 9.99992 6.66667H11.9999C13.4727 6.66667 14.6666 5.47273 14.6666 4C14.6666 2.52724 13.4727 1.33333 11.9999 1.33333H9.99992Z" fill="#383C49"/><path d="M12 3.99992C12 4.36812 11.7015 4.66659 11.3333 4.66659H4.66667C4.29848 4.66659 4 4.36812 4 3.99992C4 3.63172 4.29848 3.33325 4.66667 3.33325H11.3333C11.7015 3.33325 12 3.63172 12 3.99992Z" fill="#383C49"/></svg>';
            html += '</div>';
            html += '</div>';

            // unsync
            html += '<div class="pixe-row pixe-space-unsync" >';
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect y="16" width="3" height="16" transform="rotate(-90 0 16)" fill="#DCDCDC"/><rect x="13" width="3" height="16" fill="#DCDCDC"/><mask id="path-3-inside-1_18030_31426" fill="white"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 6.50305C0 2.9132 2.91015 0.00305176 6.5 0.00305176H16V3.00305H6.5C4.567 3.00305 3 4.57006 3 6.50305V15.9996H0V6.50305Z"/></mask><path fill-rule="evenodd" clip-rule="evenodd" d="M0 6.50305C0 2.9132 2.91015 0.00305176 6.5 0.00305176H16V3.00305H6.5C4.567 3.00305 3 4.57006 3 6.50305V15.9996H0V6.50305Z" fill="#848484"/><path d="M16 0.00305176H19V-2.99695H16V0.00305176ZM16 3.00305V6.00305H19V3.00305H16ZM3 15.9996V18.9996H6V15.9996H3ZM0 15.9996H-3V18.9996H0V15.9996ZM6.5 0.00305176V-2.99695C1.2533 -2.99695 -3 1.25635 -3 6.50305H0H3C3 4.57006 4.567 3.00305 6.5 3.00305V0.00305176ZM16 0.00305176V-2.99695H6.5V0.00305176V3.00305H16V0.00305176ZM16 3.00305H19V0.00305176H16H13V3.00305H16ZM6.5 3.00305V6.00305H16V3.00305V0.00305176H6.5V3.00305ZM3 6.50305H6C6 6.22691 6.22386 6.00305 6.5 6.00305V3.00305V0.00305176C2.91015 0.00305176 0 2.9132 0 6.50305H3ZM3 15.9996H6V6.50305H3H0V15.9996H3ZM0 15.9996V18.9996H3V15.9996V12.9996H0V15.9996ZM0 6.50305H-3V15.9996H0H3V6.50305H0Z" fill="#92A2B1" mask="url(#path-3-inside-1_18030_31426)"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'top-left',
                range: 'radius',
                value: settings.value['top-left'],
                variableType: 'radius'
            });
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect y="0.00164795" width="3" height="16" fill="#DCDCDC"/><rect y="16.0016" width="3" height="16" transform="rotate(-90 0 16.0016)" fill="#DCDCDC"/><mask id="path-3-inside-1_18030_31437" fill="white"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.49805 7.75117e-08C13.0879 3.47032e-08 15.998 2.91015 15.998 6.5L15.998 16L12.998 16L12.998 6.5C12.998 4.567 11.431 3 9.49805 3L0.00146488 3L0.00146484 1.90757e-07L9.49805 7.75117e-08Z"/></mask><path fill-rule="evenodd" clip-rule="evenodd" d="M9.49805 7.75117e-08C13.0879 3.47032e-08 15.998 2.91015 15.998 6.5L15.998 16L12.998 16L12.998 6.5C12.998 4.567 11.431 3 9.49805 3L0.00146488 3L0.00146484 1.90757e-07L9.49805 7.75117e-08Z" fill="#848484"/><path d="M15.998 16L15.998 19L18.998 19L18.998 16L15.998 16ZM12.998 16L9.99805 16L9.99805 19L12.998 19L12.998 16ZM0.00146488 3L-2.99854 3L-2.99854 6L0.00146492 6L0.00146488 3ZM0.00146484 1.90757e-07L0.00146481 -3L-2.99854 -3L-2.99854 2.26532e-07L0.00146484 1.90757e-07ZM15.998 6.5L18.998 6.5C18.998 1.2533 14.7448 -3 9.49805 -3L9.49805 7.75117e-08L9.49805 3C11.431 3 12.998 4.567 12.998 6.5L15.998 6.5ZM15.998 16L18.998 16L18.998 6.5L15.998 6.5L12.998 6.5L12.998 16L15.998 16ZM12.998 16L12.998 19L15.998 19L15.998 16L15.998 13L12.998 13L12.998 16ZM12.998 6.5L9.99805 6.5L9.99805 16L12.998 16L15.998 16L15.998 6.5L12.998 6.5ZM9.49805 3L9.49805 6C9.77419 6 9.99805 6.22386 9.99805 6.5L12.998 6.5L15.998 6.5C15.998 2.91015 13.0879 3.47032e-08 9.49805 7.75117e-08L9.49805 3ZM0.00146488 3L0.00146492 6L9.49805 6L9.49805 3L9.49805 7.75117e-08L0.00146484 1.90757e-07L0.00146488 3ZM0.00146484 1.90757e-07L-2.99854 2.26532e-07L-2.99854 3L0.00146488 3L3.00146 3L3.00146 1.54983e-07L0.00146484 1.90757e-07ZM9.49805 7.75117e-08L9.49805 -3L0.00146481 -3L0.00146484 1.90757e-07L0.00146488 3L9.49805 3L9.49805 7.75117e-08Z" fill="#92A2B1" mask="url(#path-3-inside-1_18030_31437)"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'top-right',
                range: 'radius',
                value: settings.value['top-right'],
                variableType: 'radius'
            });
            html += '<div class="pixe-action-sync" >';
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" ><path d="M8.70692 3.52158C8.44659 3.78193 8.02466 3.78213 7.76432 3.52179C7.50399 3.26143 7.50399 2.83933 7.76432 2.57897L7.99972 2.3432C9.56179 0.781108 12.0945 0.781108 13.6566 2.3432C15.2187 3.9053 15.2187 6.43796 13.6566 8.00008L12.0067 9.64995C10.4446 11.212 7.91206 11.2121 6.34995 9.65015C6.08964 9.38981 6.08977 8.96755 6.35011 8.70721C6.61046 8.44688 7.03259 8.44688 7.29292 8.70721C8.33432 9.74841 10.0225 9.74848 11.0639 8.70715L12.7137 7.05728C13.7551 6.01585 13.7551 4.32741 12.7137 3.28601C11.6723 2.24461 9.98392 2.24461 8.94252 3.28601L8.70692 3.52158Z" fill="#383C49"/><path d="M8.23538 13.4209L7.99958 13.6567C6.43747 15.2188 3.90481 15.2188 2.34272 13.6567C0.780618 12.0946 0.780618 9.56197 2.34272 7.99991L3.99263 6.34996C5.55472 4.78787 8.08752 4.78802 9.64965 6.35012C9.90998 6.61047 9.91018 7.03251 9.64978 7.29284C9.38945 7.55317 8.96705 7.55311 8.70665 7.29277C7.66525 6.25137 5.97684 6.25137 4.93544 7.29277L3.28552 8.94271C2.24412 9.98411 2.24412 11.6725 3.28552 12.7139C4.32692 13.7553 6.01536 13.7553 7.05678 12.7139L7.29278 12.4783C7.55312 12.218 7.97525 12.218 8.23558 12.4783C8.49592 12.7386 8.49572 13.1606 8.23538 13.4209Z" fill="#383C49"/></svg>';
            html += '</div>';
            html += '</div>';
            html += '<div class="pixe-row pixe-space-unsync" >';
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect y="3" width="3" height="15" transform="rotate(-90 0 3)" fill="#DCDCDC"/><path d="M13 0H16V16H13V0Z" fill="#DCDCDC"/><mask id="path-3-inside-1_18030_31449" fill="white"><path fill-rule="evenodd" clip-rule="evenodd" d="M6.50195 16.0018C2.9121 16.0018 0.001953 13.0917 0.00195284 9.50183L0.00195243 0.00183105L3.00195 0.00183092L3.00195 9.50183C3.00195 11.4348 4.56896 13.0018 6.50195 13.0018L15.9985 13.0018L15.9985 16.0018L6.50195 16.0018Z"/></mask><path fill-rule="evenodd" clip-rule="evenodd" d="M6.50195 16.0018C2.9121 16.0018 0.001953 13.0917 0.00195284 9.50183L0.00195243 0.00183105L3.00195 0.00183092L3.00195 9.50183C3.00195 11.4348 4.56896 13.0018 6.50195 13.0018L15.9985 13.0018L15.9985 16.0018L6.50195 16.0018Z" fill="#848484"/><path d="M0.00195243 0.00183105L0.00195229 -2.99817L-2.99805 -2.99817L-2.99805 0.00183119L0.00195243 0.00183105ZM3.00195 0.00183092L6.00195 0.00183079L6.00195 -2.99817L3.00195 -2.99817L3.00195 0.00183092ZM15.9985 13.0018L18.9985 13.0018L18.9985 10.0018L15.9985 10.0018L15.9985 13.0018ZM15.9985 16.0018L15.9985 19.0018L18.9985 19.0018L18.9985 16.0018L15.9985 16.0018ZM0.00195284 9.50183L-2.99805 9.50183C-2.99805 14.7485 1.25525 19.0018 6.50195 19.0018L6.50195 16.0018L6.50195 13.0018C4.56896 13.0018 3.00195 11.4348 3.00195 9.50183L0.00195284 9.50183ZM0.00195243 0.00183105L-2.99805 0.00183119L-2.99805 9.50183L0.00195284 9.50183L3.00195 9.50183L3.00195 0.00183092L0.00195243 0.00183105ZM3.00195 0.00183092L3.00195 -2.99817L0.00195229 -2.99817L0.00195243 0.00183105L0.00195256 3.00183L3.00195 3.00183L3.00195 0.00183092ZM3.00195 9.50183L6.00195 9.50183L6.00195 0.00183079L3.00195 0.00183092L0.00195243 0.00183105L0.00195284 9.50183L3.00195 9.50183ZM6.50195 13.0018L6.50195 10.0018C6.22581 10.0018 6.00195 9.77797 6.00195 9.50183L3.00195 9.50183L0.00195284 9.50183C0.001953 13.0917 2.9121 16.0018 6.50195 16.0018L6.50195 13.0018ZM15.9985 13.0018L15.9985 10.0018L6.50195 10.0018L6.50195 13.0018L6.50195 16.0018L15.9985 16.0018L15.9985 13.0018ZM15.9985 16.0018L18.9985 16.0018L18.9985 13.0018L15.9985 13.0018L12.9985 13.0018L12.9985 16.0018L15.9985 16.0018ZM6.50195 16.0018L6.50195 19.0018L15.9985 19.0018L15.9985 16.0018L15.9985 13.0018L6.50195 13.0018L6.50195 16.0018Z" fill="#92A2B1" mask="url(#path-3-inside-1_18030_31449)"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'bottom-left',
                range: 'radius',
                value: settings.value['bottom-left'],
                variableType: 'radius'
            });
            html += '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect width="3" height="16" fill="#DCDCDC"/><rect y="3" width="3" height="16" transform="rotate(-90 0 3)" fill="#DCDCDC"/><mask id="path-3-inside-1_18030_31460" fill="white"><path fill-rule="evenodd" clip-rule="evenodd" d="M16 9.49994C16 13.0898 13.0899 15.9999 9.5 15.9999L0 15.9999L2.62268e-07 12.9999L9.5 12.9999C11.433 12.9999 13 11.4329 13 9.49994L13 0.00335667L16 0.00335693L16 9.49994Z"/></mask><path fill-rule="evenodd" clip-rule="evenodd" d="M16 9.49994C16 13.0898 13.0899 15.9999 9.5 15.9999L0 15.9999L2.62268e-07 12.9999L9.5 12.9999C11.433 12.9999 13 11.4329 13 9.49994L13 0.00335667L16 0.00335693L16 9.49994Z" fill="#848484"/><path d="M0 15.9999L-3 15.9999L-3 18.9999L-2.62268e-07 18.9999L0 15.9999ZM2.62268e-07 12.9999L5.24537e-07 9.99994L-3 9.99994L-3 12.9999L2.62268e-07 12.9999ZM13 0.00335667L13 -2.99664L10 -2.99664L10 0.00335641L13 0.00335667ZM16 0.00335693L19 0.0033572L19 -2.99664L16 -2.99664L16 0.00335693ZM9.5 15.9999L9.5 18.9999C14.7467 18.9999 19 14.7466 19 9.49994L16 9.49994L13 9.49994C13 11.4329 11.433 12.9999 9.5 12.9999L9.5 15.9999ZM0 15.9999L-2.62268e-07 18.9999L9.5 18.9999L9.5 15.9999L9.5 12.9999L2.62268e-07 12.9999L0 15.9999ZM2.62268e-07 12.9999L-3 12.9999L-3 15.9999L0 15.9999L3 15.9999L3 12.9999L2.62268e-07 12.9999ZM9.5 12.9999L9.5 9.99994L5.24537e-07 9.99994L2.62268e-07 12.9999L0 15.9999L9.5 15.9999L9.5 12.9999ZM13 9.49994L10 9.49994C10 9.77608 9.77614 9.99994 9.5 9.99994L9.5 12.9999L9.5 15.9999C13.0899 15.9999 16 13.0898 16 9.49994L13 9.49994ZM13 0.00335667L10 0.00335641L10 9.49994L13 9.49994L16 9.49994L16 0.00335693L13 0.00335667ZM16 0.00335693L16 -2.99664L13 -2.99664L13 0.00335667L13 3.00336L16 3.00336L16 0.00335693ZM16 9.49994L19 9.49994L19 0.0033572L16 0.00335693L13 0.00335667L13 9.49994L16 9.49994Z" fill="#92A2B1" mask="url(#path-3-inside-1_18030_31460)"/></svg>';
            html += $.pixeRangeInput({
                slugInner: 'bottom-right',
                range: 'radius',
                value: settings.value['bottom-right'],
                variableType: 'radius'
            });
            html += '</div>';

            html += '</div>'; // pixe-size-input-content
            html += '</div>'; // pixe-size-input

        // init object
        var container = $(html);
        container.pixeCombobox();
        container.pixeRangeInput();
        if( Object.keys(settings.value).length ){
            container.data('value', settings.value);
        }
        if( isSynced ){
            container.addClass('pixe-synced');
        }else{
            container.removeClass('pixe-synced');
        }

        // sync & unsync button
        container.on('click', '.pixe-action-sync', function(){
            container.addClass('pixe-synced');
        });
        container.on('click', '.pixe-action-unsync', function(){
            container.removeClass('pixe-synced');
        });

        // initvalue
        container.on('initvalue2', function(){
            var value = $(this).data('value');
            if( value && value['top-left'] && value['top-left'] == value['top-right'] && value['top-left'] == value['bottom-left'] && value['top-left'] == value['bottom-right'] ){
                container.find('input[data-slug-inner="all"]').val(value['top-left']).trigger('initvalue')
            }else{
                container.find('input[data-slug-inner="all"]').val('').trigger('initvalue');
            }
            container.find('input[data-slug-inner="top-left"]').val((value && value['top-left'])? value['top-left']:'').trigger('initvalue')
            container.find('input[data-slug-inner="top-right"]').val((value && value['top-right'])? value['top-right']:'').trigger('initvalue');
            container.find('input[data-slug-inner="bottom-left"]').val((value && value['bottom-left'])? value['bottom-left']:'').trigger('initvalue');
            container.find('input[data-slug-inner="bottom-right"]').val((value && value['bottom-right'])? value['bottom-right']:'').trigger('initvalue');
        });

        // value change
        container.on('change', '[data-slug-inner]', function(){
            var slug = $(this).attr('data-slug-inner');
            var value = container.data('value');
            if( !value ){ value = {} };
            
            switch(slug){
                case 'all':
                    var val = $(this).val();
                    container.find('input[data-slug-inner="top-left"], input[data-slug-inner="top-right"], input[data-slug-inner="bottom-left"], input[data-slug-inner="bottom-right"]').val($(this).val()).trigger('initvalue');
                    if( val ){
                        value['top-left'] = val;
                        value['top-right'] = val;
                        value['bottom-left'] = val;
                        value['bottom-right'] = val;
                    }else{
                        delete value['top-left'];
                        delete value['top-right'];
                        delete value['bottom-left'];
                        delete value['bottom-right'];
                    }
                    break;
                case 'top-left':
                case 'top-right':
                case 'bottom-left':
                case 'bottom-right':
                    var tl = container.find('input[data-slug-inner="top-left"]').val();
                    var tr = container.find('input[data-slug-inner="top-right"]').val();
                    var bl = container.find('input[data-slug-inner="bottom-left"]').val();
                    var br = container.find('input[data-slug-inner="bottom-right"]').val();

                    if( tl == tr && tl == bl && tl == br ){
                        container.find('input[data-slug-inner="all"]').val(tl).trigger('initvalue');
                    }else{
                        container.find('input[data-slug-inner="all"]').val('').trigger('initvalue');
                    }
                    if( $(this).val() ){
                        value[slug] = $(this).val();
                    }else{
                        delete value[slug];
                    }
                    break;
            }

            if( Object.keys(value).length ){
                container.data('value', value);
            }else{
                container.removeData('value');
            }
        });
        
        return container;
    }

    // uploadarea
    $.pixeSetUploadSelection = function(item, selections){
        var isMultiple = item.attr('data-multiple');
        var convertSvg = item.attr('data-convert-svg');
        
        var images = [];
        var asyncRequests = 0;

        function setData(){
            if( isMultiple ){
                item.data('value', images);
            }else{
                item.data('value', images[0]);
            }
            item.trigger('change');
        }
        function getSvg(image){
            $.ajax({
                url: image.url,
                dataType: 'html',
                type: 'GET',
                success: function(html){
                    // create new svg icon
                    asyncRequests--;
                    var svgIcon = {
                        type: 'svg',
                        svg: $.pixeCleanSvg(html)
                    };
                    images.push(svgIcon);

                    // update data
                    if( asyncRequests == 0 ){  setData(); }
                },
                error: function(jqXHR, textStatus, errorThrown){
                    console.log(jqXHR, textStatus, errorThrown);

                    // push data normally if cannot get svg
                    asyncRequests--;
                    images.push(image);

                    // update data
                    if( asyncRequests == 0 ){  setData(); }
                }
            });
        }
        function getImage(selection){
            var image = {
                type: 'attachment',
                id: selection.id,
                url: selection.url,
                width: selection.width,
                height: selection.height
            };

            if( selection.mime == 'image/svg+xml' && convertSvg ){
                asyncRequests++;
                getSvg(image);
            }else{
                images.push(image);
            }

            return image;
        }

        // get image
        for( var i in selections ){
            getImage(selections[i]);
        }

        // trigger change event
        if( asyncRequests == 0 ){
            setData();
        }
    }
    $.fn.pixeUploadArea = function(){

        function setMedia(item){
            var data = item.data('value');
            var bg = item.children('.pixe-upload-background');
            bg.children('video, svg').remove();
            bg.css('background-image', '');

            if( data && data.url ){
                var type = $.pixeGetMediaType(data.url);
                if( type == 'image' ){
                    bg.css('background-image', 'url("' + data.url + '")'); 
                }else if( type == 'video' ){
                    bg.prepend($.pixeGetHtml5Video(data.url));
                }
                  
                item.addClass('pixe-active'); 
            }else if( data && data.type == 'svg' ){
                bg.append(data.svg);
                item.addClass('pixe-active');
            }else{
                item.removeClass('pixe-active'); 
            }
        }
        
        $(this).find('.pixe-upload-area').each(function(){
            if( $(this).hasClass('pixe-init') ) return;
            $(this).addClass('pixe-init');

            var uploadArea = $(this);
            setMedia(uploadArea);

            uploadArea.on('click', function(e){
                if( $(e.target).closest('.pixe-upload-remove').length ) return;

                // get media type if exists
                var library = {};
                var type = [];
                if( uploadArea.attr('data-media-type') ){
                    var mediaType = uploadArea.attr('data-media-type').split(',');
                    for( var i in mediaType ){
                        switch(mediaType[i]){
                            case 'svg':
                                type.push('image/svg+xml');
                                break;
                            case 'png':
                                type.push('image/png');
                                break;
                            case 'json':
                                type.push('application/json');
                                break;
                            case 'font':
                                type.push('font/woff2');
                                type.push('font/woff');
                                type.push('font/ttf');
                                type.push('font/otf');
                                break;
                        }
                    }
                }
                if( type.length ){
                    library.type = type;
                }

                // open frame
                $(document.body).trigger('uploadframeopen');
                var isMultiple = uploadArea.attr('data-multiple');
                var frame = wp.media({ 
                    title: 'Upload Image',
                    multiple: isMultiple? 'add': false,
                    library: library
                }).open().on('select', function(){
                    var selections = frame.state().get('selection').toJSON();
                    $.pixeSetUploadSelection(uploadArea, selections);
                }).on('close', function(){
                    $(document.body).trigger('uploadframeclose');
                });
            });
            uploadArea.on('change', function(){
                setMedia(uploadArea);
            });
            uploadArea.on('click', '.pixe-upload-remove', function(e){
                uploadArea.removeData('value').removeAttr('data-value');
                uploadArea.trigger('change');
            });
        });

    }
    $.pixeUploadArea = function(settings){
        settings = $.extend({
            class: '',
            slug: '',
            innerSlug: '',
            value: '',
            title: 'Select from Media Library',
            caption: 'Choose or upload your media',
            multiple: false,
            mediaType: '',
            convertSvg: false
        }, settings);

        var html  = '<div class="pixe-upload-area ' + $.pixeEscAttr(settings.class) + '" ';
            html += settings.slug? ' data-slug="' + $.pixeEscAttr(settings.slug) + '" ': '';
            html += settings.innerSlug? ' data-inner-slug="' + $.pixeEscAttr(settings.innerSlug) + '" ': '';
            html += settings.value? ' data-value="' + $.pixeEscAttr(JSON.stringify(settings.value)) + '" ': '';
            html += settings.multiple? ' data-multiple="1" ': '';
            html += settings.mediaType? ' data-media-type="' + $.pixeEscAttr(settings.mediaType) + '" ': '';
            html += settings.convertSvg? ' data-convert-svg="1" ': '';
            html += ' >';
            html += $.pixeGetAdminIcon('upload', {class: 'pixe-upload-icon'});
            html += '<div class="pixe-head" >';
            html += '<label>' + settings.title + '</label>';
            html += '<div class="pixe-caption">' + settings.caption + '</div>';
            html += '</div>';
            html += '<div class="pixe-upload-background" >';
            html += '<div class="pixe-upload-edit" >';
            html += '<svg width="16" height="15" viewBox="0 0 16 15" fill="none" ><path fill-rule="evenodd" clip-rule="evenodd" d="M5.30256 7.44774C5.07335 7.67691 4.94458 7.98778 4.94458 8.31198V9.94462C4.94458 10.2821 5.21819 10.5557 5.55569 10.5557H7.18834C7.51247 10.5557 7.82334 10.4269 8.05257 10.1977L13.8581 4.39216C14.3354 3.91485 14.3354 3.14098 13.8581 2.66368L12.8366 1.64216C12.3593 1.16485 11.5854 1.16485 11.1081 1.64216L5.30256 7.44774ZM7.18834 9.33351H6.1668V8.31198L11.9724 2.5064L12.9939 3.52792L7.18834 9.33351Z" fill="#383C49"/><path d="M6.77781 2.61111C6.77781 2.94862 6.5042 3.22223 6.16669 3.22223H3.11114V12.3889H12.2778V9.33337C12.2778 8.99585 12.5514 8.72226 12.8889 8.72226C13.2264 8.72226 13.5 8.99585 13.5 9.33337V12.3889C13.5 13.0639 12.9528 13.6111 12.2778 13.6111H3.11114C2.43612 13.6111 1.88892 13.0639 1.88892 12.3889V3.22223C1.88892 2.54721 2.43612 2 3.11114 2H6.16669C6.5042 2 6.77781 2.27361 6.77781 2.61111Z" fill="#383C49"/></svg>';
            html += '</div>';
            html += '<div class="pixe-upload-remove" >';
            html += '<svg width="8" height="8" viewBox="0 0 8 8" fill="none" ><path d="M7.07274 0.159096C7.28485 -0.0530293 7.6288 -0.0530348 7.84091 0.159096C8.05303 0.371222 8.05303 0.715151 7.84091 0.927277L4.76816 4.00004L7.84091 7.07274C8.05303 7.28485 8.05303 7.6288 7.84091 7.84091C7.6288 8.05303 7.28485 8.05303 7.07274 7.84091L3.99998 4.76821L0.927285 7.84091C0.923966 7.84423 0.92062 7.84749 0.917241 7.85069C0.704437 8.05298 0.36791 8.04972 0.159098 7.84091C4.06325e-06 7.68181 -0.0397737 7.44857 0.0397761 7.25243C0.0662891 7.18703 0.106067 7.12575 0.159098 7.07274L3.23181 4.00004L0.159098 0.927304C-0.0530327 0.715179 -0.0530327 0.371249 0.159098 0.159123C0.371224 -0.0530078 0.715154 -0.0530078 0.927279 0.159123L3.99998 3.23181L7.07274 0.159096Z" fill="#383C49"/></svg>';
            html += '</div>';
            html += '</div>';
            html += '</div>';
        
        return html;
    }

    // post filter
    $.pixePostFilter = function(settings){
        settings = $.extend({
            slug: '',
            value: '',
            taxonomy: false,
        }, settings);

        var input = $('<div class="pixe-post-filter" ></div>');
        input.attr('data-slug', settings.slug);
        input.data('value', settings.value);

        if( settings.taxonomy ){
            input.addClass('pixe-type-taxonomy');
        }

        // bind
        input.on('change', function(){
            var data = {};

            $(this).find('[data-inner-slug]').each(function(){
                var slug = $(this).attr('data-inner-slug');
                var value = $(this).data('value');
                data[slug] = value;
            });

            $(this).data('value', data);
        });

        return input;
    }
    $.pixePostFilterCallback = function(input, postType){
        if( !postType ) postType = 'post';

        var postOptions = {};
        var postFilter = input.find('.pixe-post-filter');
    
        if( postFilter.attr('data-post-type') != postType ){

            // post filter
            postFilter.attr('data-post-type', postType);
            postFilter.empty();
            
            // init filter
            var filterVal = postFilter.data('value')? postFilter.data('value'): {};
            var filter = $.pixeInputWrap({
                title: 'Filter',
                width: '1-1',
                content: $.pixeMultiCheckbox({ 
                    innerSlug: 'filter',
                    value: filterVal.filter
                })
            });
            filter.pixeMultiCheckbox();
            filter.appendTo(postFilter);

            // set filter option & value
            function setFilter(){
                postOptions = {};

                if( input.hasClass('pixe-type-taxonomy') ){
                    postOptions['post'] = 'Manual';
                }
                
                postOptions = $.extend(postOptions, pixeData.postTaxonomy[postType]);
                $.pixeUpdateMultiCheckboxOptions(filter, postOptions);
            }

            // create taxonomy
            function setFilterType(){
                var filterVal = postFilter.find('.pixe-multi-checkbox').data('value');
                var filterData = postFilter.data('value')? postFilter.data('value'): {};
                filter.siblings().remove();

                if( filterVal ){
                    for(var i in filterVal){
                        var type = filterVal[i];
                        if( !postOptions[type] ) continue;

                        var filterType = $.pixeInputWrap({
                            title: postOptions[type],
                            width: '1-1',
                            content: $.pixeCombobox({
                                type: 'multiple',
                                innerSlug: type,
                                value: filterData[type],
                            })
                        });
                        postFilter.append(filterType);

                        if( type == 'post' ){
                            $.pixeComboboxCallback('post', filterType, postType);
                        }else if( type == 'user-role' ){
                            $.pixeComboboxCallback('user-role', filterType);
                        }else{
                            $.pixeComboboxCallback('category', filterType, type);
                        }
                        
                    }
                }
                
                postFilter.pixeCombobox();
            }

            // retrieve taxonomy data if not present
            if( pixeData.postTaxonomy[postType] ){
                setFilter();
                setFilterType();
            }else{
                $.pixeComboboxCallback('taxonomy', filter, postType);
                filter.on('callbackready', function(){
                    setFilter();
                    setFilterType();
                });
            }

            // bind events
            filter.on('change', function(){
                setFilterType();
            });
        }

        return true;
    }
    
    // init combobox objects
    $(document).ready(function(){
        if( typeof(pixeData) == 'undefined' ){ return; }
        if( !pixeData.posts ) pixeData.posts = {};
        if( !pixeData.postTaxonomy ) pixeData.postTaxonomy = {};
        if( !pixeData.postCategory ) pixeData.postCategory = {};
    });

    // post combobox callback
    $.pixeComboboxCallbackQueue = $();
    $.pixeComboboxCallback = function(type, input, value){
        if( type == 'post' && !pixeData.postTypes[value] ){ return false; }
        if( type == 'taxonomy' && value && !pixeData.postTypes[value] ){ return false; }

        // check if value is the same
        var dataType = input.attr('data-input-type');
        var dataValue = input.attr('data-input-value');
        if( dataType == type && dataValue == value ){ return true; }
     
        input.attr('data-input-type', type);
        input.attr('data-input-value', value);

        // set combobox options content base on type
        function updateInput(inputOptions, placeholder){

            // check for combobox
            var combobox = input.find('.pixe-combobox');
            if( !combobox.length ){ combobox = input.filter('.pixe-combobox'); }

            if( combobox.length ){
                var withDefault = input.data('callback-default')? true: false;
                
                combobox.attr('data-placeholder', placeholder);
                $.pixeUpdateCombobox(combobox, {
                    options: inputOptions,
                    'with-default': withDefault
                });
                
                return;
            }
            
            // multiple checkbox
            var checkbox = input.find('.pixe-multi-checkbox, .pixe-multi-checkbox2');
            if( !checkbox.length ){ checkbox = input.filter('.pixe-multi-checkbox, .pixe-multi-checkbox2'); }

            if( checkbox.length ){
                $.pixeUpdateMultiCheckboxOptions(checkbox, inputOptions);
                return;
            }
        }
        function setContent(){
            switch(type){
                case 'menu': 
                    if( pixeData.menus ){ 
                        updateInput(pixeData.menus, 'Select Menu');
                        return true;
                    }
                    break;
                case 'user-role':
                    if( pixeData.userRoles ){ 
                        updateInput(pixeData.userRoles, 'Select Role');
                        return true;
                    }
                    break;
                case 'widget':
                    if( pixeData.widgetArea ){ 
                        updateInput(pixeData.widgetArea, 'Select Widget');
                        return true;
                    }
                    break;
                case 'post':
                    if( pixeData.posts[value] ){ 
                        updateInput(pixeData.posts[value], 'Select Post');
                        return true;
                    }
                    break;
                case 'taxonomy':
                    if( !value ){ value = 'post'; }
                    if( pixeData.postTaxonomy[value] ){ 
                        updateInput(pixeData.postTaxonomy[value], 'Select Taxonomy');
                        return true;
                    }
                    break;
                case 'category':
                    if( !value ){ value = 'category'; }
                    if( pixeData.postCategory[value] ){ 
                        updateInput(pixeData.postCategory[value], 'Select Category');
                        return true;
                    }
                    break;
            }

            return false;
        }

        if( setContent() ) return true;

        // if no data, prepare to get
        input.addClass('pixe-loading');
        $.pixeComboboxCallbackQueue = $.pixeComboboxCallbackQueue.add(input);

        // on update combobox
        input.on('callbackready', function(){
            if( setContent() ){
                $(this).off('callbackready');
                $(this).removeClass('pixe-loading');
                $.pixeComboboxCallbackQueue = $.pixeComboboxCallbackQueue.not($(this));
            }
        });

        // ajax request to get data
        var ajaxData = $.pixeGetAjaxData({
            action: 'pixe_get_combobox_list',
            type: type,
            value: value
        });
        $.pixeAjax({
            ajaxData: ajaxData,
            onSuccess: function(data){
                if( typeof(data) != 'object' ) return;

                // update data 
                switch(type){
                    case 'menu': pixeData.menus = data; break;
                    case 'user-role': pixeData.userRoles = data; break;
                    case 'post': pixeData.posts[value] = data; break;
                    case 'widget': pixeData.widgetArea = data; break;
                    case 'taxonomy': pixeData.postTaxonomy[value] = data; break;
                    case 'category': pixeData.postCategory[value] = data; break;
                }

                // update post combobox ( if any )
                $.pixeComboboxCallbackQueue.trigger('callbackready');
            }
        });

        return true;
    }

    // combobox
    $.fn.pixeMultiCombobox = function(){
        if( $(this).hasClass('pixe-init') ) return;
        $(this).addClass('pixe-init');

        var combobox = $(this);
        var text = combobox.children('.pixe-text');
        var options = combobox.children('.pixe-content').children('.pixe-options');

        function addItem(slug, label){
            if( !slug || !label ) return; 
            if( !text.children('[data-item-slug="' + slug + '"]').length ){
                var item = $('<span data-value="" ></span>');
                item.attr('data-item-slug', slug);
                item.append(label);
                item.append('<span class="pixe-svg-preset pixe-svg-sx pixe-svg-hover pixe-remove" ></span>');
                text.append(item);
            }
        }
        function updateVal(){
            var values = [];
            text.children('[data-item-slug]').each(function(){
                values.push($(this).attr('data-item-slug'));
            });
            
            if( values.length ){
                combobox.data('value', values);
            }else{
                combobox.removeData('value').removeAttr('data-value');
            }

            combobox.trigger('change');
        }

        // remove option with empty slug
        options.children().each(function(){
            if( !$(this).attr('data-value') ) $(this).remove();
        });

        // remove data
        text.on('click', '.pixe-remove', function(){
            var item = $(this).closest('[data-item-slug]');
            var slug = item.attr('data-item-slug');

            item.remove();
            updateVal();

            var selectedOption = options.find('.pixe-option[data-value="' + slug + '"]');
            selectedOption.removeClass('pixe-multi-selected');
        });

        // initialize value
        combobox.on('initvalue', function(){
            text.empty();
            options.children().removeClass('pixe-multi-selected');

            var values = combobox.data('value');
            if( typeof(values) == 'string' ) values = [values];

            for( var i in values ){
                var selectedOption = options.find('.pixe-option[data-value="' + values[i] + '"]');
                if( selectedOption.length ){
                    selectedOption.addClass('pixe-multi-selected');
                    var slug = selectedOption.data('value');
                    var label = selectedOption.html();
                    addItem(slug, label);
                }
            }
        });
        combobox.trigger('initvalue');

        // dropdown option
        combobox.on('click', function(e){
            if( $(this).hasClass('pixe-target-close') || $(e.target).hasClass('pixe-remove') ){
                $(this).removeClass('pixe-target-close');
                return;
            }
            
            var content = combobox.children('.pixe-content').clone();
            var extraClass = combobox.attr('data-popup-class')? combobox.attr('data-popup-class'): '';
            var popup = new $.pixePopup({
                content: content,
                target: combobox,
                style: 'pixe-combobox-popup ' + extraClass
            });

            // event
            content.on('click', '.pixe-option', function(){
                var slug = $(this).data('value');
                var label = $(this).html();
                addItem(slug, label);
                updateVal();

                var selectedOption = options.find('.pixe-option[data-value="' + slug + '"]');
                selectedOption.addClass('pixe-multi-selected');

                popup.close();
            });
        });
        
    }
    $.fn.pixeCombobox = function(settings){
        settings = $.extend({
            selector: '.pixe-combobox',
        }, settings);

        // bind
        $(this).find(settings.selector).each(function(){
            if( $(this).hasClass('pixe-type-multiple') ){
                return $(this).pixeMultiCombobox(settings);
            }

            if( $(this).hasClass('pixe-init') ) return;
            $(this).addClass('pixe-init');

            var combobox = $(this);
            var text = combobox.children('.pixe-text');

            // initialize value
            combobox.on('initvalue', function(){
                var options = combobox.find('.pixe-option');
                var selectedOption;
                var selectedValue = combobox.data('value');
                var selectedVariable = $.pixeGetVariable(selectedValue);

                if( selectedValue ){
                    selectedOption = options.filter(function(){
                        var optionValue = $(this).data('value');
                        if( selectedVariable ){
                            return optionValue == selectedVariable;
                        }else{
                            return optionValue == selectedValue;
                        }
                    }).first();
                }else if( !combobox.attr('data-placeholder') ){
                    selectedOption = options.first();
                    combobox.data('value', selectedOption.data('value'));
                }
                if( selectedOption && selectedOption.length ){
                    text.html(selectedOption.html());
                }else if( combobox.attr('data-placeholder') ){
                    text.html(combobox.attr('data-placeholder'))
                }else{
                    text.html('');
                }

                // add class for 1 input
                if( options.length == 1 ){
                    combobox.addClass('pixe-1');
                }
                
            });
            combobox.trigger('initvalue');

            // dropdown option
            combobox.on('click', function(){
                if( $(this).hasClass('pixe-target-close') ){
                    $(this).removeClass('pixe-target-close');
                    return;
                }

                var content = combobox.children('.pixe-content').clone();
                content.find('.pixe-option-vary').each(function(){
                    var type = $(this).attr('data-type');
                    if( type == 'range' ){
                        $(this).replaceWith($.pixeComboboxOption.rangeVariable($(this).attr('data-variable')));
                    }else if( type == 'font-family' ){
                        $(this).replaceWith($.pixeComboboxOption.fontFamilyVariable());
                    }else if( type == 'shadow' ){
                        $(this).replaceWith($.pixeComboboxOption.shadowVariable());
                    }
                });

                var extraClass = combobox.attr('data-popup-class')? combobox.attr('data-popup-class'): '';
                var popup = new $.pixePopup({
                    content: content,
                    target: combobox,
                    targetArea: combobox,
                    targetAreaPos: ['top'],
                    targetFocus: combobox,
                    ignoreParentPos: true,
                    style: 'pixe-combobox-popup ' + extraClass,
                    onClose: settings.onClose
                });
                if( settings.onShow ){ settings.onShow(); }

                // check scrollbar
                var options = content.children('.pixe-options');
                if( options.prop('scrollHeight') > options.innerHeight() ){
                    options.addClass('pixe-scrollbar');
                }

                var value = combobox.data('value') || '';
                var variable = $.pixeGetVariable(value);
                var currentOption = content.find('.pixe-option').filter(function(){
                    var optionValue = $(this).data('value');
                    if( variable ){
                        return optionValue == variable;
                    }else{
                        return optionValue == value;
                    }
                }).first();

                // tab filter
                var tabHead = content.find('.pixe-combobox-tab');
                var tabBottom = content.find('.pixe-combobox-tab-bottom');
                if( tabHead.length ){
                    if( settings.tabFilter ){
                        settings.tabFilter(content, combobox, popup);
                    }else{
                        // events
                        tabHead.on('click', '[data-tab]', function(){
                            var tabSlug = $(this).attr('data-tab');
                            content.find('[data-tab="' + tabSlug + '"]').addClass('pixe-active').siblings().removeClass('pixe-active');
                            content.find('[data-tab="' + tabSlug + '"]').addClass('pixe-active').siblings().removeClass('pixe-active');
                            $.pixeSetPopupPosition(popup.settings, popup.popupBox);
                        }); 

                        // initial tab by value
                        if( currentOption.length ){
                            var currentOptions = currentOption.closest('.pixe-options');
                            var tabSlug = currentOptions.attr('data-tab');

                            tabHead.find('[data-tab="' + tabSlug + '"]').addClass('pixe-active').siblings().removeClass('pixe-active');
                            tabBottom.find('[data-tab="' + tabSlug + '"]').addClass('pixe-active').siblings().removeClass('pixe-active');
                            currentOptions.addClass('pixe-active').siblings().removeClass('pixe-active');
                            $.pixeSetPopupPosition(popup.settings, popup.popupBox);
                        }
                    }
                }

                // set scroll position
                if( currentOption.length ){
                    options.scrollTop(currentOption.position().top - 8);
                    currentOption.addClass('pixe-active');
                }

                // set min width
                if( popup.popupBox.outerWidth() < combobox.outerWidth() ){
                    popup.popupBox.css('min-width', combobox.outerWidth());
                }

                // event
                if( settings.contentFilter ){
                    settings.contentFilter(content, combobox, popup);
                }
                
                if( !settings.contentFilter || settings.defaultFilter ){
                    content.on('click', '.pixe-option', function(){
                        var optionValue = $(this).data('value');
                        var variable = $.pixeGetVariable(optionValue);
                        if( variable ){
                            optionValue = 'var(' + variable + ')';
                        }

                        // set text
                        if( !optionValue && combobox.attr('data-placeholder') ){
                            text.html(combobox.attr('data-placeholder'));
                        }else{
                            text.html($(this).html());
                        }

                        // update data
                        combobox.data('value', optionValue);
                        combobox.trigger('change');
    
                        popup.close();
                    });
                }

                // search input
                content.on('input change', '.pixe-combobox-search input[type="text"]', function(){
                    var text = $(this).val().toLowerCase();

                    if( !text.length ){
                        content.find('.pixe-option, .pixe-option-title').removeClass('pixe-hidden');
                    }else{
                        content.find('.pixe-option-title').addClass('pixe-hidden');
                        content.find('.pixe-option').each(function(){
                            if( $(this).text().toLowerCase().includes(text) ){
                                $(this).removeClass('pixe-hidden');
                            }else{
                                $(this).addClass('pixe-hidden');
                            }
                        });
                    }

                    
                });
                
            });
        });

    }
    $.pixeComboboxTab = function(options){
        var active = false;
        var html = '<div class="pixe-combobox-tab pixe-no-user-select" >';
            for( var i in options ){
                html += '<span ';
                html += !active? 'class="pixe-active" ': '';
                html += 'data-tab="' + $.pixeEscAttr(i) + '" >' + options[i] + '</span>';
                active = true;
            }
            html += '</div>';

        return html;
    }
    $.pixeComboboxBottom = function(text, icon = 'option', newIcon, tab){

        var html  = '<div class="pixe-combobox-bottom-option" ';
            html += (tab? 'data-tab="' + $.pixeEscAttr(tab) + '" ': '');
            html += '>';

        if( newIcon ){
            html += '<div class="pixe-combobox-bottom-new" >';
            html += $.pixeGetAdminIcon(newIcon) + text;
            html += '</div>';

            html += '<div class="pixe-combobox-bottom-settings" >';
            html += $.pixeGetAdminIcon(icon);
            html += '</div>';
        }else{
            html += '<div class="pixe-combobox-bottom-settings pixe-full" >';
            html += $.pixeGetAdminIcon(icon) + text;
            html += '</div>';
        }

        html += '</div>';
        
        return html;
    }
    $.pixeCombobox = function(settings){
        settings = $.extend({
            slug: '',
            innserSlug: '',
            type: '',
            value: '',
            class: '',
            options: '',
            top: '',
            bottom: '',
            width: '',
            contentClass: '',
            placeholder: '',
            default: ''
        }, settings);

        var value = settings.value? settings.value: (settings.default? settings.default: '');
        if( typeof(value) == 'object' ){
            value = JSON.stringify(value);
        }
        if( settings.type ){
            settings.class += 'pixe-type-' + settings.type;
        }

        var html  = '<div class="pixe-combobox ' + $.pixeEscAttr(settings.class.trim()) + '" ';
            html += (value? 'data-value="' + $.pixeEscAttr(value) + '" ': '');
            html += (settings.width? 'style="width: ' + $.pixeSizeFormat(settings.width) + '"': '');
            html += (settings.slug? 'data-slug="' + $.pixeEscAttr(settings.slug) + '" ': '');
            html += (settings.innerSlug? 'data-inner-slug="' + $.pixeEscAttr(settings.innerSlug) + '" ': '');
            html += (settings.default? 'data-default="' + $.pixeEscAttr(settings.default) + '" ': '');
            html += (settings.popupClass? 'data-popup-class="' + $.pixeEscAttr(settings.popupClass) +  '" ': '');
            html += (settings.placeholder? 'data-placeholder="' + $.pixeEscAttr(settings.placeholder) + '" ': '');
            html += ' >';
            html += '<div class="pixe-text" ></div>';
            html += '<div class="pixe-content ' + $.pixeEscAttr(settings.contentClass) + '" >';
            if( settings.search ){
                html += '<div class="pixe-combobox-search" >';
                html += '<input type="text" placeholder="Search" />';
                html += '</div>';
            }
            if( settings.top ){
                if( typeof(settings.top) == 'function' ){
                    html += settings.top();
                }else{
                    html += settings.top;
                }
            }
            if( typeof(settings.options) == 'object' ){
                var active = false;
                for( var i in settings.options){
                    var options = settings.options[i];
                    html += '<div class="pixe-options' + (!active? ' pixe-active': '') + '" data-tab="' + $.pixeEscAttr(i) + '" >';
                    html += options;
                    html += '</div>'; // pixe-options
                    active = true;
                }
            }else{
                html += '<div class="pixe-options pixe-active" >';
                html += settings.options;
                html += '</div>'; // pixe-options
            }
            
            if( settings.bottom ){
                if( typeof(settings.bottom) == 'function' ){
                    html += settings.bottom();
                }else{
                    html += settings.bottom;
                }
            }
            html += '</div>'; // pixe-content
            html += '</div>'; // pixe-combobox

        return html;
    }
    $.pixeUpdateCombobox = function(target, settings){
        settings = $.extend({
            selector: '',
            options: '',
            'with-default': true,
        }, settings);

        // combobox option
        var options = '';
        if( typeof(settings.options) == 'string' ){
            if( $.pixeComboboxOption[settings.options] ){
                options = $.pixeComboboxOption[settings.options]();
            }else{
                options = settings.options;
            }
        }else{
            options = $.pixeComboboxOption.object(settings.options, settings['with-default']);
        }
        
        // update
        target.find(settings.selector + ' .pixe-options').each(function(){
            var tab = $(this).attr('data-tab');

            if( typeof(options) == 'object' && options[tab] ){
                $(this).empty().append(options[tab]);
                $(this).closest('.pixe-combobox').trigger('initvalue');
            }else if( typeof(options) == 'string' ){
                $(this).empty().append(options);
                $(this).closest('.pixe-combobox').trigger('initvalue');
            }
        });
    }
    $.pixeComboboxOption = {
        range: function(min = 1, max = 100){
            var html  = ''
            for( var i = min; i <= max; i++ ){
                html += '<div class="pixe-option" data-value="' + i + '" >' + i + '</div>';
            }
            return html;
        },
        object: function(options, withDefault = false){
            var html  = '';
            if( withDefault ){
                if( typeof(withDefault) == 'string' ){
                    html += '<div class="pixe-option" data-value="" >' + withDefault + '</div>';
                }else{
                    html += '<div class="pixe-option" data-value="" >Default</div>';
                }
            }
            for( var key in options ){
                if( !options[key] ) continue;

                if( typeof(options[key]) == 'string' ){
                    if( options[key].match(/^\*.*\*$/) ){
                        html += '<div class="pixe-option-title" >' + options[key].slice(1).slice(0, -1) + '</div>';
                    }else{
                        html += '<div class="pixe-option" data-value="' + key + '" >' + options[key] + '</div>';
                    }
                }else{
                    html += $.pixeComboboxOption.gridObject(options[key]);
                }
                
            }
            return html;
        },
        gridObject: function(settings){
            var html  = '<div class="pixe-grid-option" ' + (settings.width? 'style="max-width: ' + settings.width + '"': '') + ' >';
            for( var key in settings.options ){
                html += '<div class="pixe-option" data-value="' + key + '" >' + settings.options[key] + '</div>';
            }
            html += '</div>';
            return html;
        },
        arrayObject: function(options, withDefault = false){
            var html  = '';
            if( withDefault ){
                html += '<div class="pixe-option" data-value="" >Default</div>';
            }
            for( var key in options ){
                html += '<div class="pixe-option" data-value="' + options[key] + '" >' + options[key] + '</div>';
            }
            return html;
        },
        iconPreset: function(withNone = true){
            var html  = '<div class="pixe-option" data-value="" >Default</div>';
            if( withNone ){
                html += '<div class="pixe-option" data-value="none" >None</div>';
            }
            html += '<div class="pixe-option" data-value="image" >Image / Svg</div>';
            html += '<div class="pixe-option" data-value="image-raw" >Raw Svg</div>';
            html += '<div class="pixe-option-title" >Icon Type</div>';
            html += '<div class="pixe-option" data-value="font-awesome" >- Font Awesome</div>';
            html += '<div class="pixe-option" data-value="lucide" >- Lucide</div>';
            html += '<div class="pixe-option" data-value="material-symbols" >- Material Symbols</div>';
            
            if( pixeData.iconPreset ){
                for( var slug in pixeData.iconPreset ){
                    html += '<div class="pixe-option" data-value="' + slug + '" >- ' + pixeData.iconPreset[slug].label + '</div>';
                }
            }

            return html;
        },
        paginationPreset: function(){
            var options = {};
            if( pixeData.controlPreset && pixeData.controlPreset.pagination ){
                for( var slug in pixeData.controlPreset.pagination ){
                    if( pixeData.controlPreset.pagination[slug].label ){
                        options[slug] = pixeData.controlPreset.pagination[slug].label;
                    }
                }
            }

            return this.object(options, true);
        },
        navigationPreset: function(){
            var options = {};
            if( pixeData.controlPreset && pixeData.controlPreset.navigation ){
                for( var slug in pixeData.controlPreset.navigation ){
                    if( pixeData.controlPreset.navigation[slug].label ){
                        options[slug] = pixeData.controlPreset.navigation[slug].label;
                    }
                }
            }

            return this.object(options, true);
        },
        touchNavigationPreset: function(){
            var options = {};
            if( pixeData.controlPreset && pixeData.controlPreset.touch ){
                for( var slug in pixeData.controlPreset.touch ){
                    if( pixeData.controlPreset.touch[slug].label ){
                        options[slug] = pixeData.controlPreset.touch[slug].label;
                    }
                }
            }

            return this.object(options, true);
        },
        bulletPreset: function(){
            var options = {};
            if( pixeData.controlPreset && pixeData.controlPreset.bullet ){
                for( var slug in pixeData.controlPreset.bullet ){
                    if( pixeData.controlPreset.bullet[slug].label ){
                        options[slug] = pixeData.controlPreset.bullet[slug].label;
                    }
                }
            }

            return this.object(options, true);
        },
        buttonPreset: function(){
            var options = {};
            if( pixeData.buttonPreset && pixeData.buttonPreset.preset && !Array.isArray(pixeData.buttonPreset.preset) ){
                for( var slug in pixeData.buttonPreset.preset ){
                    if( pixeData.buttonPreset.preset[slug].label ){
                        options[slug] = pixeData.buttonPreset.preset[slug].label;
                    }
                }
            }

            return this.object(options, 'Custom');
        },
        typoPreset: function(){
            var html  = '<div class="pixe-option" data-value="" >Custom</div>';
            var resetButton = '<div class="pixe-typo-settings-reset" >' + $.pixeGetAdminIcon('reset') + '</div>';
            
            // system
            for( var slug in $.pixeTypoStyle.systemTypo ){
                html += '<div class="pixe-option" data-value="' + slug + '" >' + $.pixeTypoStyle.systemTypo[slug] + resetButton + '</div>';
            }

            // custom
            if( pixeData.typoPreset && pixeData.typoPreset.presetOrder ){
                for( var i = 0; i < pixeData.typoPreset.presetOrder.length; i++ ){
                    var slug = pixeData.typoPreset.presetOrder[i];
                    if( pixeData.typoPreset.preset[slug].label ){
                        html += '<div class="pixe-option" data-value="' + slug + '" >' + pixeData.typoPreset.preset[slug].label + resetButton + '</div>';
                    }
                }
            }
            return html;
        },
        colorPreset: function(){

            // preset color
            var activePreset = $.pixeColorStyle.getActivePreset();
            
            function getColorInfo(value){
                if( typeof(value) == 'object' && (value.type == 'gradient' || value.type == 'radial') ){
                    return 'gradient';
                }else if( typeof(value) == 'string' ){
                    return $.pixeRGBToHex(value);
                }
                return '';
            }
            function getItem(slug, label){
                var colorInfo = activePreset && activePreset.value? getColorInfo(activePreset.value[slug]): '';
                var html = '<div class="pixe-color-display" data-color="' + slug + '" ></div>';
                    html += $.pixeEscHtml(label);
                    if( colorInfo ){
                        html += ' <span class="pixe-color-code" >' + $.pixeEscHtml(colorInfo) + '</span>';
                    }
                return html;
            }
            function getVariableItem(slug, data){
                var colorValue = data? (data.light || data.dark): '';
                var colorInfo = getColorInfo(colorValue);
                var color = colorValue? $.pixeGetColor(colorValue): false;
                var html = '<div class="pixe-color-display pixe-type-variable" style="' + (color && color.css? 'background:' + $.pixeEscAttr(color.css): '') + '" ></div>';
                    html += $.pixeEscHtml(slug);
                    if( colorInfo ){
                        html += ' <span class="pixe-color-code" >' + $.pixeEscHtml(colorInfo) + '</span>';
                    }
                return html;
            }

            // system
            var preset  = '<div class="pixe-option" data-value="" >Custom Color</div>';
                preset += '<div class="pixe-option-title" >System Colors</div>';
            for( var slug in $.pixeColorStyle.systemColor ){
                preset += '<div class="pixe-option pixe-option-color" data-value="' + slug + '" >' + getItem(slug, $.pixeColorStyle.systemColor[slug]) + '</div>'; 
            }

            // custom
            if( activePreset && activePreset.customColor && activePreset.customColorOrder && activePreset.customColorOrder.length ){
                preset += '<div class="pixe-option-title" >Custom\'s Colors</div>';

                for( var i in activePreset.customColorOrder ){
                    var slug = activePreset.customColorOrder[i];
                    var label = activePreset.customColor[slug];

                    if( slug && label ){
                        preset += '<div class="pixe-option pixe-option-color" data-value="' + slug + '" >' + getItem(slug, label) + '</div>'; 
                    }
                }
            } 

            // variable color
            var variable = '';
            if( pixeData.variablePreset && pixeData.variablePreset.color ){
                for( var slug in pixeData.variablePreset.color ){
                    variable += '<div class="pixe-option pixe-option-color" data-value="' + $.pixeEscAttr(slug) + '" >';
                    variable += getVariableItem(slug, pixeData.variablePreset.color[slug]);
                    variable += '</div>';
                }
            }
            if( !variable ){
                variable = '<div class="pixe-option-title" >No color variables found.</div>';
            }

            return { preset: preset, variable: variable };
        },
        rangeVariable: function(type){
            var html = '';
            type = type || 'number';

            var variables = pixeData.variablePreset? pixeData.variablePreset[type]: false;
            if( variables ){
                for( var slug in variables ){
                    var meta = $.pixeVariableUtil.getOptionMetaValue(type, variables[slug]);

                    html += '<div class="pixe-option pixe-option-range-variable" data-value="' + $.pixeEscAttr(slug) + '" >';
                    html += '<span class="pixe-variable-name">' + $.pixeEscHtml(slug) + '</span>';
                    html += '<span class="pixe-variable-meta-value">' + $.pixeEscHtml(meta) + '</span>';
                    html += '</div>';
                }
            }

            if( !html ){
                html = '<div class="pixe-option-title" >No variables found.</div>';
            }

            return html;
        },
        getFontFamilyOptions: function(webSafeFonts){
            var html = '';
            if( Object.keys(pixeData.typoPreset.customFont).length ){
                html += '<div class="pixe-head" >Custom Fonts</div>';
                for( var key in pixeData.typoPreset.customFont ){
                    html += '<div class="pixe-option" data-value="' + $.pixeEscAttr(key) + '" >' + $.pixeEscHtml(key) + '</div>';
                }
            }
            if( Object.keys(pixeData.typoPreset.googleFont).length ){
                html += '<div class="pixe-head" >Google Fonts</div>';
                for( var fontName in pixeData.typoPreset.googleFont ){
                    html += '<div class="pixe-option" data-value="' + $.pixeEscAttr(fontName) + '" >' + $.pixeEscHtml(fontName) + '</div>';
                }
            }
            if( Object.keys(webSafeFonts).length ){
                html += '<div class="pixe-head" >Web Safe Fonts</div>';
                if( Array.isArray(webSafeFonts) ){
                    for( var i = 0; i < webSafeFonts.length; i++ ){
                        html += '<div class="pixe-option" data-value="' + $.pixeEscAttr(webSafeFonts[i]) + '" >' + $.pixeEscHtml(webSafeFonts[i]) + '</div>';
                    }
                }else{
                    for( var key in webSafeFonts ){
                        html += '<div class="pixe-option" data-value="' + $.pixeEscAttr(key) + '" >' + $.pixeEscHtml(webSafeFonts[key]) + '</div>';
                    }
                }
            }

            return html;
        },
        fontFamily: function(){
            var webSafeFonts = [
                'Georgia, serif',
                '"Palatino Linotype", "Book Antiqua", Palatino, serif',
                '"Times New Roman", Times, serif',
                'Helvetica, sans-serif',
                'Arial, Helvetica, sans-serif',
                '"Arial Black", Gadget, sans-serif',
                '"Comic Sans MS", cursive, sans-serif',
                'Impact, Charcoal, sans-serif',
                '"Lucida Sans Unicode", "Lucida Grande", sans-serif',
                'Tahoma, Geneva, sans-serif',
                '"Trebuchet MS", Helvetica, sans-serif',
                'Verdana, Geneva, sans-serif',
                '"Courier New", Courier, monospace',
                '"Lucida Console", Monaco, monospace'
            ];

            var html  = '<div class="pixe-option" data-value="" >Default</div>';
                html += this.getFontFamilyOptions(webSafeFonts);

            return html;
        },
        fontFamilyTabs: function(){
            var custom  = '<div class="pixe-option" data-value="" >Default</div>';
                custom += this.getFontFamilyOptions(this.getWebSafeFontFamily());

            return { 
                custom: custom,
                variable: '<div class="pixe-option-vary" data-type="font-family" ></div>' 
            };
        },
        getWebSafeFontFamily: function(){
            return [
                'Georgia, serif',
                '"Palatino Linotype", "Book Antiqua", Palatino, serif',
                '"Times New Roman", Times, serif',
                'Helvetica, sans-serif',
                'Arial, Helvetica, sans-serif',
                '"Arial Black", Gadget, sans-serif',
                '"Comic Sans MS", cursive, sans-serif',
                'Impact, Charcoal, sans-serif',
                '"Lucida Sans Unicode", "Lucida Grande", sans-serif',
                'Tahoma, Geneva, sans-serif',
                '"Trebuchet MS", Helvetica, sans-serif',
                'Verdana, Geneva, sans-serif',
                '"Courier New", Courier, monospace',
                '"Lucida Console", Monaco, monospace'
            ];
        },
        fontFamilyVariable: function(){
            var html = '';
            var variables = pixeData.variablePreset? pixeData.variablePreset['font-family']: false;

            if( variables ){
                for( var slug in variables ){
                    html += '<div class="pixe-option pixe-option-font-family-variable" data-value="' + $.pixeEscAttr(slug) + '" >';
                    html += '<span class="pixe-variable-name">' + $.pixeEscHtml(slug) + '</span>';
                    html += $.pixeVariableUtil.fontFamilyMeta(variables[slug], true);
                    html += '</div>';
                }
            }

            if( !html ){
                html = '<div class="pixe-option-title" >No font family variables found.</div>';
            }

            return html;
        },
        fontFamilySingle: function(){
            var webSafeFonts = [
                'system-ui',
                '-apple-system',
                '"Segoe UI"',
                'Roboto',
                'Arial',
                'sans-serif',
                'Georgia',
                '"Times New Roman"',
                'serif',
                'ui-monospace',
                'Consolas',
                '"Courier New"',
                'monospace'
            ];
            var html  = '<div class="pixe-option" data-value="" >None</div>';
                html += this.getFontFamilyOptions(webSafeFonts);

            return html;
        },
        linkTarget: function(){
            return this.object({
                '': 'Same Window',
                '_blank': 'New Window'
            }, false);
        },
        shadowStyle: function(){
            return this.object({
                'inset': 'Inset',
            }, true);
        },
        shadowVariable: function(){
            var html = '';
            var variables = pixeData.variablePreset? pixeData.variablePreset.shadow: false;

            function getShadowMeta(data){
                if( typeof(data) != 'object' || Array.isArray(data) ){
                    return '-';
                }

                return ['x', 'y', 'blur', 'spread'].map(function(key){
                    return data[key] !== undefined && data[key] !== null && data[key] !== ''? data[key]: 0;
                }).join(' ');
            }
            function getShadowPreviewColor(data){
                var color = data && typeof(data) == 'object'? $.pixeGetColor(data.color): false;

                if( color && color.css ){
                    return '<span class="pixe-preview-color" style="background: ' + color.css + ';" ></span>';
                }else{
                    return '';
                }
            }

            if( variables ){
                for( var slug in variables ){
                    html += '<div class="pixe-option pixe-option-range-variable pixe-option-shadow-variable" data-value="' + $.pixeEscAttr(slug) + '" >';
                    html += '<span class="pixe-variable-name">' + $.pixeEscHtml(slug) + '</span>';
                    html += '<span class="pixe-variable-meta-value">';
                    html += getShadowPreviewColor(variables[slug]);
                    html += getShadowMeta(variables[slug]);
                    html += '</span>';
                    html += '</div>';
                }
            }

            if( !html ){
                html = '<div class="pixe-option-title" >No shadow variables found.</div>';
            }

            return html;
        },
        borderStyle: function(){
            return this.object({
                'solid': 'Solid',
                'dotted': 'Dotted',
                'dashed': 'Dashed',
                'double': 'Double',
                'groove': 'Groove',
                'ridge': 'Ridge',
                'inset': 'Inset',
                'outset': 'Outset',
                'initial': 'Initial',
                'inherit': 'Inherit'
            }, true);
        },
        backgroundPosition: function(){
            return this.object({
                'center': 'Center', 
                'center-left': 'Center Left', 
                'center-right': 'Center Right', 
                'top-center': 'Top Center', 
                'top-left': 'Top Left', 
                'top-right': 'Top Right', 
                'bottom-center': 'Bottom Center', 
                'bottom-left': 'Bottom Left', 
                'bottom-right': 'Bottom Right', 
                'custom': 'Custom'
            }, true);
        },
        objectFit: function(){
            return this.object({
                'fill': 'Fill',
                'cover': 'Cover',
                'contain': 'Contain',
                'none': 'None',
                'scale-down': 'Scale Down'
            }, true);
        },
        backgroundSize: function(){
            return this.object({
                'auto': 'Auto',
                'cover': 'Cover',
                'contain': 'Contain',
                'custom': 'Custom'
            }, true);
        },
        backgroundRepeat: function(){
            return this.object({
                'no-repeat': 'No Repeat',
                'repeat': 'Repeat',
                'repeat-x': 'Repeat X',
                'repeat-y': 'Repeat Y'
            }, true);
        },
        backgroundAttachment: function(){
            return this.object({
                'parallax': 'Parallax',
                'fixed': 'Fixed',
                'none': 'None'
            }, true);
        },
        backgroundMask: function(){
            return this.object({
                'none': 'None',
                'custom': 'Custom (Image, SVG)',
                'grid': {
                    width: '230px',
                    options: {
                        'circle': $.pixeSvgBackground('circle', true),
                        'triangle': $.pixeSvgBackground('triangle', true),
                        'pentagon': $.pixeSvgBackground('pentagon', true),
                        'hexagon': $.pixeSvgBackground('hexagon', true),
                        'octagon': $.pixeSvgBackground('octagon', true),
                        'sketch-1': $.pixeSvgBackground('sketch-1', true),
                        'sketch-2': $.pixeSvgBackground('sketch-2', true),
                        'sketch-3': $.pixeSvgBackground('sketch-3', true),
                        'sketch-4': $.pixeSvgBackground('sketch-4', true),
                        'sketch-5': $.pixeSvgBackground('sketch-5', true),
                        'sketch-6': $.pixeSvgBackground('sketch-6', true),
                        'blub-1': $.pixeSvgBackground('blub-1', true),
                        'blub-2': $.pixeSvgBackground('blub-2', true),
                        'blub-3': $.pixeSvgBackground('blub-3', true),
                        'blub-4': $.pixeSvgBackground('blub-4', true),
                        'blub-5': $.pixeSvgBackground('blub-5', true)
                    }
                }
            }, true);
        },
        imageBlend: function(){
            return this.object({
                '': 'None',
                'multiply': 'Multiply',
                'screen': 'Screen',
                'overlay': 'Overlay',
                'darken': 'Darken',
                'lighten': 'Lighten',
                'color-dodge': 'Color Dodge',
                'color-burn': 'Color Burn',
                'difference': 'Difference',
                'exclusion': 'Exclusion',
                'hue': 'Hue',
                'saturation': 'Saturation',
                'color': 'Color',
            }, false);
        },
        imageFilter: function(){
            return this.object({
                'blur': 'Blur',
                'brightness': 'Brightness',
                'contrast': 'Contrast',
                'grayscale': 'Grayscale',
                'hue-rotate': 'Hue Rotate',
                'invert': 'Invert',
                'opacity': 'Opacity',
                'saturate': 'Saturate',
                'sepia': 'Sepia'
            }, true);
        },
        headingTag: function(){
            return this.object({
                'h1': 'Heading 1',
                'h2': 'Heading 2',
                'h3': 'Heading 3',
                'h4': 'Heading 4',
                'h5': 'Heading 5',
                'h6': 'Heading 6',
                'div': 'div',
                'span': 'span',
            }, true)
        },
        fontWeightObject: function(){
            return {
                '100': '100 - Thin',
                '200': '200 - Extra Light',
                '300': '300 - Light',
                '400': '400 - Normal',
                '500': '500 - Medium',
                '600': '600 - Semi Bold',
                '700': '700 - Bold',
                '800': '800 - Extra Bold',
                '900': '900 - Black',
                '950': '950 - Extra Black',
            };
        },
        fontWeightTabs: function(){
            return {
                custom: this.fontWeight(),
                variable: '<div class="pixe-option-vary" data-type="range" data-variable="font-weight" ></div>'
            };
        },
        fontWeight: function(allowNone = true){
            return this.object(this.fontWeightObject(), allowNone);
        },
        fontStyle: function(allowNone = true){
            return this.object({
                'normal': 'Normal', 
                'italic': 'Italic',
                'oblique': 'Oblique',
            }, allowNone);
        },
        textTransform: function(){
            return this.object({
                'none': 'None', 
                'capitalize': 'Capitalize',
                'uppercase': 'Uppercase',
                'lowercase': 'Lowercase',
            }, true);
        },
        textDecoration: function(){
            return this.object({
                'none': 'None', 
                'line-through': 'Line Through', 
                'overline': 'Overline', 
                'underline': 'Underline', 
                'underline overline': 'Underline & Overline', 
            }, true);
        },
        overflow: function(){
            return this.object({
                'visible': 'Visible',
                'hidden': 'Hidden'
            }, true);
        },
        postType: function(){
            return this.object(pixeData.postTypes, false);
        },
        siteLink: function(){
            return this.object({
                '': 'None',
                'custom': 'Custom URL',
            }, false) + this.object(pixeData.postTypes);
        },
        postLink: function(){
            return this.object({
                '--title': '*Standard*',
                '': 'Default (Single Post)',
                'none': 'None',
                'custom': 'Custom URL',
                'home': 'Home Page',
                '--title2': '*Wordpress Content*',
                'image-custom-lb': 'Custom Image Lightbox',
                'video-lb': 'Video Lightbox (Youtube/Vimeo/File URL)',
                'video-custom-lb': 'Video Lightbox (Self Hosted)',
                'popup': 'Popup',
                '--title3': '*Woocommerce*',
                'wc-cart': 'Cart Page',
                'wc-checkout': 'Checkout Page',
                'wc-account': 'Account Page',
                'wc-shop': 'Shop Page',
            }, false);
        },
        buttonLink: function(){
            return this.object({
                '--title': '*Standard*',
                '': 'Custom URL',
                'home': 'Home Page',
                '--title2': '*Wordpress Content*',
                'query': 'Single Post',
                'archive-post': 'Archive Post Type',
                'archive-tax': 'Archive Taxonomy',
                '--title3': '*Media & Popups*',
                'image-custom-lb': 'Custom Image Lightbox',
                'video-lb': 'Video Lightbox (Youtube/Vimeo/File URL)',
                'video-custom-lb': 'Video Lightbox (Self Hosted)',
                'popup': 'Popup',
                '--title4': '*Single Post*',
                'prev-post': 'Previous Post',
                'next-post': 'Next Post',
            }, false) + this.object(pixeData.postTypes) + this.object({
                '--title5': '*Woocommerce*',
                'wc-cart': 'Cart Page',
                'wc-checkout': 'Checkout Page',
                'wc-account': 'Account Page',
                'wc-shop': 'Shop Page',
            });
        },
        imageLink: function(){
            return this.object({
                '--title': '*Standard*',
                'none': 'None',
                'file': 'File',
                'custom': 'Custom URL',
                'home': 'Home Page',
                'title2': '*Wordpress Content*',
                'query': 'Single Post',
                'archive-post': 'Archive Post Type',
                'archive-tax': 'Archive Taxonomy',
                '--title3': '*Media & Popups*',
                'image-lb': 'Image Lightbox',
                'image-custom-lb': 'Custom Image Lightbox',
                'video-lb': 'Video Lightbox (Youtube/Vimeo/File URL)',
                'video-custom-lb': 'Video Lightbox (Self Hosted)',
                'popup': 'Popup',
                '--title4': '*Single Post*',
                'prev-post': 'Previous Post',
                'next-post': 'Next Post',
            }, true) + this.object(pixeData.postTypes) + this.object({
                '--title5': '*Woocommerce*',
                'wc-cart': 'Cart Page',
                'wc-checkout': 'Checkout Page',
                'wc-account': 'Account Page',
                'wc-shop': 'Shop Page',
            });
        },
        imageRatio: function(){
            return this.object({
                '1/1': '1:1',
                '5/4': '5:4',
                '4/3': '4:3',
                '3/2': '3:2',
                '16/9': '16:9',
                '4/5': '4:5',
                '3/4': '3:4',
                '2/3': '2:3',
                '9/16': '9:16',
                'custom': 'Custom'
            }, true);
        },
        thumbnailSizes: function(){
            return '<div class="pixe-option" data-value="" >Full</div>' + this.object(pixeData.thumbnailSizes);
        },
        separatorType: function(){
            return this.object({
                '': 'Comma',
                'divider': 'Divider',
                'dot': 'Dot',
                'none': 'None'
            });
        },
        textAnimationEffects: function(){
            return this.object({
                'none': 'None',
                'show-on-hover': '*Show On Hover*',
                'fade-in': 'Fade In',
                'zoom-in-show': 'Zoom In',
                'zoom-out-show': 'Zoom Out',
                'slide-in-up': 'Slide In Up',
                'slide-in-down': 'Slide In Down',
                'slide-in-left': 'Slide In Left',
                'slide-in-right': 'Slide In Right',
                'leave-on-hover': '*Leave On Hover*',
                'fade-out': 'Fade Out',
                'zoom-in-hide': 'Zoom In',
                'zoom-out-hide': 'Zoom Out',
                'slide-out-up': 'Slide Out Up',
                'slide-out-down': 'Slide Out Down',
                'slide-out-left': 'Slide Out Left',
                'slide-out-right': 'Slide Out Right',
            }, true);
        },
        transEffectsIn: function(){
            return this.object({
                'none': 'None',
                'fade-in': 'Fade In',
                'zoom-in-show': 'Zoom In',
                'zoom-out-show': 'Zoom Out',
                'slide-in-up-full': 'Slide In Up',
                'slide-in-down-full': 'Slide In Down',
                'slide-in-left-full': 'Slide In Left',
                'slide-in-right-full': 'Slide In Right',
            }, true);
        },
        transEffectsOut: function(){
            return this.object({
                'none': 'None',
                'fade-out': 'Fade Out',
                'zoom-in-hide': 'Zoom In',
                'zoom-out-hide': 'Zoom Out',
                'slide-out-up-full': 'Slide Out Up',
                'slide-out-down-full': 'Slide Out Down',
                'slide-out-left-full': 'Slide Out Left',
                'slide-out-right-full': 'Slide Out Right',
            }, true);
        },
        slderEffectsIn: function(){
            return this.object({
                'none': 'None',
                'fade-in': 'Fade In',
                'zoom-in-show': 'Zoom In',
                'zoom-out-show': 'Zoom Out',
                'slide-in-up': 'Slide In Up',
                'slide-in-down': 'Slide In Down',
                'slide-in-left': 'Slide In Left',
                'slide-in-right': 'Slide In Right',
            }, true);
        },
        sliderEffectsOut: function(){
            return this.object({
                'none': 'None',
                'fade-out': 'Fade Out',
                'zoom-in-hide': 'Zoom In',
                'zoom-out-hide': 'Zoom Out',
                'slide-out-up': 'Slide Out Up',
                'slide-out-down': 'Slide Out Down',
                'slide-out-left': 'Slide Out Left',
                'slide-out-right': 'Slide Out Right',
            }, true);
        },
        animationEffects: function(){
            return this.object({
                'none': 'None',
                'fade-in': 'Fade In',
                'fade-in-up': 'Fade In Up',
                'fade-in-down': 'Fade In Down',
                'fade-in-left': 'Fade In Left',
                'fade-in-right': 'Fade In Right',
                'slide-in-up': 'Slide In Up',
                'slide-in-down': 'Slide In Down',
                'slide-in-left': 'Slide In Left',
                'slide-in-right': 'Slide In Right',
                'zoom-in': 'Zoom In',
                'zoom-in-up': 'Zoom In Up',
                'zoom-in-down': 'Zoom In Down',
                'zoom-in-left': 'Zoom In Left',
                'zoom-in-right': 'Zoom In Right',
                'rotate-in': 'Rotate In',
                'rotate-in-up-left': 'Rotate In Up Left',
                'rotate-in-up-right': 'Rotate In Up Right',
                'rotate-in-down-left': 'Rotate In Down Left',
                'rotate-in-down-right': 'Rotate In Down Right',
                'bounce': 'Bounce',
                'bounce-in': 'Bounce In',
                'bounce-in-up': 'Bounce In Up',
                'bounce-in-down': 'Bounce In Down',
                'bounce-in-left': 'Bounce In Left',
                'bounce-in-right': 'Bounce In Right',
                'flip-in-x': 'Flip In X',
                'flip-in-y': 'Flip In Y',
                'flash': 'Flash',
                'jack-in-the-box': 'Jack In The Box',
                'jello': 'Jello',
                'light-speed-in-left': 'Light Speed In Left',
                'light-speed-in-right': 'Light Speed In Right',
                'roll-in': 'Roll In',
                'pulse': 'Pulse',
                'rubber-band': 'Rubber Band',
                'shake-x': 'Shake X',
                'shake-y': 'Shake Y',
                'swing': 'Swing',
                'tada': 'Tada',
                'wobble': 'Wobble'
            }, true);
        },
        alignment: function(){
            return this.object({
                'center': 'Center',
                'left': 'Left',
                'right': 'Right'
            }, true);
        },
        template: function(){
            var templateList = {};
            if( pixeData.template ){
                for( var i in pixeData.template ){
                    var template = pixeData.template[i];
                    templateList[template.id] = template.title;
                }
            }
            templateList.none = 'None';

            return this.object(templateList, true);
        },
        templateParts: function(){
            var types = {
                'headerTemplate': 'Header',
                'footerTemplate': 'Footer',
                'postTemplate': 'Post Template',
                'headerTemplate': 'Taxonomy Template',
                'popupTemplate': 'Popup Template',
            };
            var templateList = {};

            for( var slug in types ){
                if( pixeData[slug] ){
                    for( var i in pixeData[slug] ){
                        var template = pixeData[slug][i];
                        templateList[template.id] = types[slug] + ':' + template.title;
                    }
                }
            }

            return this.object(templateList, true);
        },
        headerTemplate: function(){
            var headerList = {};
            if( pixeData.headerTemplate ){
                for( var i in pixeData.headerTemplate ){
                    var template = pixeData.headerTemplate[i];
                    headerList[template.id] = template.title;
                }
            }
            headerList.none = 'None';

            return this.object(headerList, true);
        },
        headerTemplateMobile: function(){
            var headerList = {};
            if( pixeData.headerTemplate ){
                for( var i in pixeData.headerTemplate ){
                    var template = pixeData.headerTemplate[i];
                    if( template.type == 'left' || template.type == 'right' ) continue;
                    headerList[template.id] = template.title;
                }
            }
            headerList.none = 'None';

            return this.object(headerList, true);
        },
        footerTemplate: function(){
            var footerList = {};
            if( pixeData.footerTemplate ){
                for( var i in pixeData.footerTemplate ){
                    var template = pixeData.footerTemplate[i];
                    footerList[template.id] = template.title;
                }
            }
            footerList.none = 'None';

            return this.object(footerList, true);
        },
        postTemplate: function(){
            var templateList = {
                0: '*Post Template*'
            };
            if( pixeData.postTemplate ){
                for( var i in pixeData.postTemplate ){
                    var template = pixeData.postTemplate[i];
                    templateList[template.id] = template.title;
                }
            }
            if( pixeData.customPostTemplate ){
                templateList['--title2'] = '*Custom Template*'
                for( var i in pixeData.customPostTemplate ){
                    templateList[i] = pixeData.customPostTemplate[i];
                }
            }

            return this.object(templateList, true);
        },
        taxonomyTemplate: function(){
            var templateList = {};
            if( pixeData.taxonomyTemplate ){
                for( var i in pixeData.taxonomyTemplate ){
                    var template = pixeData.taxonomyTemplate[i];
                    templateList[template.id] = template.title;
                }
            }

            return this.object(templateList, true);
        },
        popupTemplate: function(){
            var popupList = {};
            if( pixeData.popupTemplate ){
                for( var i in pixeData.popupTemplate ){
                    var template = pixeData.popupTemplate[i];
                    popupList[template.id] = template.title;
                }
            }
            popupList.none = 'None';

            return this.object(popupList, true);
        },
        dateFormat: function(){
            const date = new Date();
            const months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
            const m = date.getMonth().toString().padStart(2, '0');
            const d = date.getDate().toString().padStart(2, '0')

            return this.object({
                'F j, Y': months[date.getMonth()] + ' ' + date.getDate() + ', ' + date.getFullYear(),
                'Y-m-d': date.getFullYear() + '-' + m + '-' + d,
                'd/m/Y': d + '/' + m + '/' + date.getFullYear(),
                'm/d/Y': m + '/' + d + '/' + date.getFullYear(),
                'custom': 'Custom'
            }, true);
        },
        timeFormat: function(){
            const date = new Date();
            const period = date.getHours() <= 12? 'am': 'pm';
            const g = date.getHours() > 12? date.getHours() - 12: date.getHours();
            const m = date.getMinutes().toString().padStart(2, '0');
            const h = date.getHours().toString().padStart(2, '0');

            return this.object({
                'g:i a': g + ':' + m + ' ' + period,
                'g:i A': g + ':' + m + ' ' + period.toUpperCase(),
                'H:i': h + ':' + m,
                'custom': 'Custom'
            }, true);
        },
        alignContent: function(){
            return this.object({
                'start': 'Start',
                'end': 'End',
                'center': 'Center',
                'flex-start': 'Flex Start',
                'flex-end': 'Flex End',
                'space-between': 'Space Between',
                'space-around': 'Space Around',
                'stretch': 'Stretch',
            }, true);
        },
        queryOrder: function(){
            return this.object({
                'asc': 'Ascending',
                'desc': 'Descending'
            }, true);
        },
        postOrderby: function(){
            return this.object({
                'none': 'None',
                'name': 'Name',
                'author': 'Author',
                'date': 'Date',
                'title': 'Title',
                'modified': 'Modified',
                'menu_order': 'Menu Order',
                'parent': 'Parent',
                'ID': 'ID',
                'rand': 'Rand',
                'relevance': 'Relevance',
            }, true);
        },
        taxOrderby: function(){
            return this.object({
                'name': 'Name', 
                'slug': 'Slug', 
                'term_group': 'Term Group', 
                'term_id': 'Term ID', 
                'id': 'ID', 
                'description': 'Description', 
                'parent': 'Parent', 
                'term_order': 'Term Order',
                'count': 'Count',
                'include': 'Include'
            }, true);
        },
        preloadIcon: function(){
            var list = [
                'bouncy-arc', 'bouncy', 'cardio', 'chaotic-orbit',
                'dot-pulse', 'dot-spinner', 'dot-stream', 'dot-wave',
                'grid', 'hatch', 'helix', 'hourglasses',
                'infinity', 'jelly-triangle', 'jelly', 'line-wobble',
                'mirage', 'miyagi', 'momentum', 'orbit',
                'pin-wheel', 'ping', 'pulsar', 'quantum',
                'reuleaux', 'ring', 'ring2', 'spiral', 'square', 'squircle',
                'tail-chase', 'tailspin', 'trefoil', 'trio', 'waveform', 'wobber', 'zoomies'
            ];
            var obj = {};
            for( var i in list ){
                var slug = list[i];
                obj[slug] = $.pixePreloadScript(slug)
            }

            return this.object(obj, true);
        },
        shapeDivider: function(){
            return this.object({
                'none': 'None',
                'custom': 'Custom',
                'book': $.pixeShapeDivider('book'),
                'book-negative': $.pixeShapeDivider('book-negative'),
                'curve': $.pixeShapeDivider('curve'),
                'curve-negative': $.pixeShapeDivider('curve-negative'),
                'curve-asymmetrical': $.pixeShapeDivider('curve-asymmetrical'),
                'curve-asymmetrical-negative': $.pixeShapeDivider('curve-asymmetrical-negative'),
                'fan-opacity': $.pixeShapeDivider('fan-opacity'),
                'mountains': $.pixeShapeDivider('mountains'),
                'pyramids': $.pixeShapeDivider('pyramids'),
                'pyramids-negative': $.pixeShapeDivider('pyramids-asymmetrical'),
                'tilt': $.pixeShapeDivider('tilt'),
                'tilt-opacity': $.pixeShapeDivider('tilt-opacity'),
                'triangle': $.pixeShapeDivider('triangle'),
                'triangle-negative': $.pixeShapeDivider('triangle-negative'),
                'triangle-asymmetrical': $.pixeShapeDivider('triangle-asymmetrical'),
                'triangle-asymmetrical-negative': $.pixeShapeDivider('triangle-asymmetrical-negative'),
                'waves': $.pixeShapeDivider('waves'),
                'waves-negative': $.pixeShapeDivider('waves-negative'),
                'waves-pattern': $.pixeShapeDivider('waves-pattern'),
                'zigzag': $.pixeShapeDivider('zigzag')
            }, true);
        }
    };

})(jQuery);	
