(function($){
    "use strict";

    // inline content item
    $.pixeInlineContent = {
        
        // use for create a text edit area
        get: function(settings){
            settings = $.extend({
                slug: 'content',
                type: 'content',
                item: undefined,
                value: undefined,
                defaultTag: 'h3',
                textContent: ''
            }, settings);
            
            var t = this;
            var value = settings.item.data('settings');
            var slug = settings.slug;
            var tag = value[slug + '-tag']? value[slug + '-tag']: settings.defaultTag;
            var content;

            // title type
            if( settings.type == 'title' ){
                if( value[slug] && typeof(value[slug]) == 'string' ){
                    content = value[slug];
                }else{
                    content = 'Add your heading text here';
                }
                content = '<span class="pixe-inline-target" >' + content + '</span>';

            // text type
            }else if( settings.type == 'plain-text' ){
                if( value[slug] && typeof(value[slug]) == 'string' ){
                    content = value[slug];
                }else{
                    content = settings.textContent;
                }
                
            // content type
            }else{
                tag = 'div';

                // content
                if( value[slug] && typeof(value[slug]) == 'string' ){
                    content = value[slug];
                }else{
                    content = '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>';
                }
            }

            // create item
            var inlineItem = $(document.createElement(tag));
            inlineItem.addClass('pixe-inline');
            inlineItem.data('onchange', settings.onChange);
            inlineItem.append(content);   
            if( settings.type ){
                inlineItem.attr('data-inline', settings.slug);
                inlineItem.attr('data-inline-type', settings.type);
            }

            // event
            if( settings.type != 'plain-text2' ){
                t.setStyle(inlineItem, settings.item);
            }
            
            inlineItem.on('input', function(){
                t.setVal(inlineItem, 'content');
            });
            return inlineItem;
        },
        
        replaceTag: function(oldTarget, newTag){
            var t = this;
            
            if( oldTarget.get(0).tagName.toLowerCase() != newTag ){
                var inlineType = oldTarget.attr('data-inline-type');
                var newHtml = $(document.createElement(newTag))
                newHtml.addClass('pixe-inline');
                newHtml.attr('data-inline', oldTarget.attr('data-inline'));
                newHtml.attr('data-inline-type', inlineType);
                newHtml.attr('data-typo-preset', oldTarget.attr('data-typo-preset'));
                newHtml.append(oldTarget.contents());
                newHtml.children('.pixe-inline-target').removeAttr('contentEditable');
                oldTarget.replaceWith(newHtml);

                // event 
                newHtml.on('input', function(){
                    t.setVal(newHtml, 'content');
                });
                
                return newHtml;
            }
            return false;
        },

        // get value from item container
        getVal: function(inlineItem, type){
            var item = inlineItem.closest('.pixe-item');
            var settings = item.data('settings');

            return settings[inlineItem.attr('data-inline') + '-' + type];
        },

        // set value to parent item
        setVal: function(inlineItem, type, value){
            var t = this;
            var item = inlineItem.closest('.pixe-item');
            var settings = item.data('settings');

            // init history
            if( !t.editTarget || !t.editTarget.is(item) ){
                t.editTarget = item;
                t.editHistory = new $.pixeEditHistory(item, {
                    debounceTime: 500
                });
            }

            // get item slug
            var slug;
            if( type == 'content' ){
                slug = inlineItem.attr('data-inline');
                if( inlineItem.children('.pixe-inline-target').length ){
                    value = inlineItem.children('.pixe-inline-target').html();
                }else{
                    value = inlineItem.html();
                }
            }else{
                slug = inlineItem.attr('data-inline') + '-' + type
            }

            if( type == 'content' ){
                value = $.pixeContentRGBAToHex(value);
            }

            // set value
            $.pixeSetData(settings, slug, value);

            // update item style
            if( type != 'content' ){
                t.setStyle(inlineItem, item, type);
            }

            // on change event
            if( typeof(inlineItem.data('onchange')) == 'function' ){
                inlineItem.data('onchange')(slug);
            }

            // add to history
            t.editHistory.onChange(slug);
        },

        // text style
        setStyle: function(inlineItem, item, type){
            var slug = inlineItem.attr('data-inline');
            var settings = item.data('settings');
            var id = '[data-id="' + settings._id + '"]';
            var css = '', tabletCss = '', mobileCss = '';

            // assign icon
            var iconDeps = [];
            var icon = settings[slug + '-icon']? settings[slug + '-icon']: {};
            var iconHtml = $($.pixeGetIcon(icon.icon, {'icon-class': 'pixe-inline-icon'}));
            $.pixeResponsiveClass(iconHtml, icon['icon-hide-on']);
            
            inlineItem.children('.pixe-inline-icon').remove();
            if( iconHtml.length ){
                if( icon['position'] == 'right' || icon['position'] == 'right-block' || icon['position'] == 'right-stretch' ){
                    inlineItem.append(iconHtml);
                }else{
                    inlineItem.prepend(iconHtml);
                }
            }
            iconDeps.push(icon.icon);
                
            $.pixeAddIconDependency(item, iconDeps);

            // style
            function getCss(device = ''){
                var ret = '';

                ret += $.pixeSetInlineIconCss({
                    selector: id + ' .pixe-inline',
                    iconSelector: id + ' .pixe-inline-icon',
                    icon: icon,
                    textAlign: settings[device + slug + '-text-align'],
                    selectorCustom: $.pixeGetTextColorCss(settings[device + slug + '-color'])
                }, device);

                // hover color
                ret += $.pixeSetCss($.pixeGetHoverSelector(id + ' .pixe-inline-icon:hover', item), {
                    color: icon[device + 'color-hover']
                });
                ret += $.pixeSetCss($.pixeGetHoverSelector(id + ' .pixe-inline:hover', item), {
                    custom: $.pixeGetTextColorCss(settings[device + slug + '-color'], undefined, '-hover')
                });
                
                return ret;
            }

            css += getCss();
            tabletCss += getCss('tablet-');
            mobileCss += getCss('mobile-');

            $.pixeAddCss(item, slug + '-style',  css);
            $.pixeAddCss(item, slug + '-style',  tabletCss, 'tablet');
            $.pixeAddCss(item, slug + '-style',  mobileCss, 'mobile');
            
            // typo preset
            var typoSlug = slug + '-typo';
            if( !type || type == 'typo' ){
                // preview preset
                $.pixeTypoStyle.setPresetData(inlineItem, settings[typoSlug]);

                // typo custom css
                $.pixeAddCss(item, typoSlug,  $.pixeSetCss(id + ' .pixe-inline', {'custom': $.pixeTypoStyle.getPresetCss(settings[typoSlug])}));
                $.pixeAddCss(item, typoSlug,  $.pixeSetCss(id + ' .pixe-inline', {'custom': $.pixeTypoStyle.getPresetCss(settings[typoSlug], 'tablet-')}), 'tablet');
                $.pixeAddCss(item, typoSlug,  $.pixeSetCss(id + ' .pixe-inline', {'custom': $.pixeTypoStyle.getPresetCss(settings[typoSlug], 'mobile-')}), 'mobile');
            }
            $.pixeAddTypoDependency(item, [settings[typoSlug]]);

            $.pixeItem.renderCss(item);
        },

    }

    // range control
    $.pixeRange = {

        isHighlight: function(){
            let selection = window.getSelection().toString();

            if( selection.length > 0 ){
                return true;
            }
            return false; 
        },

        // save & return cursor selection
        current: false,

        saveSelection: function(e){
            if( window.getSelection().rangeCount <= 0 ) return;

            var range = window.getSelection().getRangeAt(0);
            $.pixeRange.current = {
                startContainer: range.startContainer,
                startOffset: range.startOffset,
                endContainer: range.endContainer,
                endOffset: range.endOffset
            }
        },
        returnSelection: function(){
            $.pixeRange.set($.pixeRange.current);
        },

        // set range
        set: function(range){
            var selection = window.getSelection();
            selection.removeAllRanges();
            selection.addRange($.pixeRange.create(range));
        },
        setBefore: function(node){
            $.pixeRange.set({
                startContainer: node,
                startOffset: 0,
                endContainer: node,
                endOffset: 0
            });
        },
        setAfter: function(node){
            while( node.lastChild ){ node = node.lastChild; }
            $.pixeRange.set({
                startContainer: node,
                startOffset: node.length,
                endContainer: node,
                endOffset: node.length
            });
        },

        // create new range from range object
        create: function(range){
            var newRange = document.createRange();
            newRange.setStart(range.startContainer, range.startOffset);
            newRange.setEnd(range.endContainer, range.endOffset);
            return newRange;
        },

        // is single point range
        isSinglePoint: function(range){
            if( !range.startContainer.isSameNode(range.endContainer) || range.startOffset != range.endOffset ){
                return false;
            }
            return true;
        },

        // is last element
        isLast: function(html){
            var isLast = true;
            var nextNode = html.nextSibling;
            while( isLast && nextNode ){
                if( nextNode.nodeType == Node.ELEMENT_NODE || (nextNode.nodeType == Node.TEXT_NODE && nextNode.length > 0) ){
                    isLast = false;
                }
                nextNode = nextNode.nextSibling;
            }

            return isLast;
        },

        // delete selection out
        deleteSelection: function(range){
            if( !$.pixeRange.isSinglePoint(range) ){
                range.extractContents();
            }
        }

    };

    ////////////////////
    // inline toolbar //
    ////////////////////
    $.pixeInlineToolbar = {
        elem: false,        // toolbar object
        type: 'content',    // content / title
        target: false,      // editarea
        state: {},

        init: function(){
            var t = this;

            var toolbar  = '<div class="pixe-inline-toolbar pixe-box-sizing" >';
            toolbar += '<div class="pixe-inline-toolbar1">';
            toolbar += '<div class="pixe-input-wrap" ><label>' + $.pixeEscAttr(pixei18n.preset.typo) + '</label>';
            toolbar += $.pixeCombobox({
                slug: 'preset',
                class: 'pixe-typo-preset-combobox',
                width: 136,
                options: $.pixeComboboxOption.typoPreset(),
                bottom: $.pixeComboboxBottom('New Preset', undefined, 'folder-plus')
            });
            toolbar += '</div>'; // typo preset
            toolbar += '<div class="pixe-divider" ></div>';
            toolbar += $.pixeGetAdminIcon('option-typo', { class: 'pixe-action', data: 'data-action="family"' });
            toolbar += $.pixeGetAdminIcon('option-tag', { class: 'pixe-action', data: 'data-action="title-tag"' });
            toolbar += '<div class="pixe-input-wrap" style="width: 114px" ><label>Size</label>';
            toolbar += $.pixeRangeInput({
                slug: 'font-size',
                range: 'font-size',
                variableType: 'font-size'
            });
            toolbar += '</div>'; // font size
            toolbar += '<div class="pixe-input-wrap" style="width: 75px"><label>Lt.Sp.</label>';
            toolbar += $.pixeRangeInput({
                slug: 'letter-spacing',
                min: -50,
                max: 150,
                decimal: 1,
                suffix: 'px',
                variableType: 'letter-spacing'
            });
            toolbar += '</div>'; // Lt.Sp.
            toolbar += '<div class="pixe-input-wrap" style="width: 75px" ><label>Ln.Ht.</label>';
            toolbar += $.pixeRangeInput({
                slug: 'line-height',
                min: 10, 
                max: 50,
                decimal: 1,
                variableType: 'line-height'
            });
            toolbar += '</div>'; // Lt.Sp.
            toolbar += '<div class="pixe-input-wrap" style="width: 107px" ><label>Weight</label>';
            toolbar += $.pixeCombobox({
                slug: 'font-weight',
                class: 'pixe-font-weight-combobox',
                top: $.pixeComboboxTab({
                    custom: 'Custom Value',
                    variable: 'Variables'
                }),
                bottom: '<div class="pixe-combobox-tab-bottom pixe-no-user-select" >' + $.pixeComboboxBottom('Variable Manager', undefined, undefined, 'variable') + '</div>',
                options: $.pixeComboboxOption.fontWeightTabs(),
                popupClass: 'pixe-font-weight-combobox-popup'
            });
            toolbar += '</div>'; // weight
            toolbar += '<div class="pixe-action" data-action="settings" ><svg width="18" height="18" viewBox="0 0 18 18" fill="none" ><path fill-rule="evenodd" clip-rule="evenodd" d="M8.99998 12C10.6569 12 12 10.6568 12 9C12 7.34314 10.6569 6 8.99998 6C7.34315 6 6 7.34314 6 9C6 10.6568 7.34315 12 8.99998 12ZM8.99998 10.5C9.82843 10.5 10.5 9.82845 10.5 9C10.5 8.17155 9.82843 7.5 8.99998 7.5C8.1716 7.5 7.49998 8.17155 7.49998 9C7.49998 9.82845 8.1716 10.5 8.99998 10.5Z" fill="#99ADBF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M11.3384 1.39867L11.64 3.61055C11.8854 3.73098 12.1213 3.86768 12.3465 4.01924L14.4136 3.17417C14.7608 3.03225 15.1594 3.1686 15.347 3.4934L16.9423 6.2566C17.1298 6.58141 17.0486 6.9948 16.7521 7.22449L14.9863 8.59245C14.9953 8.72715 14.9999 8.86305 14.9999 9C14.9999 9.13695 14.9953 9.27285 14.9863 9.40755L16.7521 10.7755C17.0486 11.0052 17.1298 11.4186 16.9423 11.7434L15.347 14.5066C15.1594 14.8314 14.7608 14.9677 14.4136 14.8258L12.3465 13.9808C12.1213 14.1323 11.8854 14.269 11.64 14.3894L11.3384 16.6013C11.2877 16.9729 10.9703 17.25 10.5952 17.25H7.4046C7.02955 17.25 6.71216 16.9729 6.66148 16.6013L6.35986 14.3894C6.11447 14.269 5.87852 14.1323 5.65339 13.9808L3.58622 14.8258C3.23906 14.9677 2.84042 14.8314 2.65289 14.5066L1.05757 11.7434C0.87004 11.4186 0.951272 11.0052 1.24776 10.7755L3.01356 9.40755C3.00452 9.27285 2.99994 9.13695 2.99994 9C2.99994 8.86305 3.00452 8.72715 3.01356 8.59245L1.24776 7.22449C0.951272 6.9948 0.87004 6.58141 1.05756 6.2566L2.65289 3.4934C2.84042 3.1686 3.23905 3.03225 3.58622 3.17417L5.65339 4.01924C5.87852 3.86768 6.11447 3.73098 6.35986 3.61055L6.66148 1.39867C6.71216 1.02705 7.02955 0.75 7.4046 0.75H10.5952C10.9703 0.75 11.2877 1.02705 11.3384 1.39867ZM10.2617 4.60503L10.9792 4.95711C11.1629 5.04731 11.3398 5.14979 11.5088 5.26354L12.173 5.71067L14.3753 4.81036L15.316 6.43964L13.4362 7.89585L13.4897 8.69287C13.4965 8.79412 13.4999 8.89657 13.4999 9C13.4999 9.10343 13.4965 9.20588 13.4897 9.30713L13.4362 10.1042L15.316 11.5604L14.3753 13.1897L12.173 12.2893L11.5088 12.7365C11.3398 12.8502 11.1629 12.9526 10.9792 13.0429L10.2617 13.395L9.94063 15.75H8.05925L7.7381 13.395L7.02074 13.0429C6.83695 12.9526 6.66003 12.8502 6.49108 12.7365L5.82691 12.2893L3.6246 13.1897L2.68394 11.5604L4.56365 10.1042L4.51019 9.30713C4.50341 9.20588 4.49993 9.10343 4.49993 9C4.49993 8.89657 4.50341 8.79412 4.51019 8.69287L4.56365 7.89585L2.68394 6.43964L3.62459 4.81036L5.8269 5.71067L6.49108 5.26354C6.66003 5.14979 6.83694 5.04732 7.02074 4.95712L7.7381 4.60503L8.05925 2.25H9.94063L10.2617 4.60503Z" fill="#99ADBF"/></svg></div>';
            toolbar += '<div class="pixe-action" data-action="remove" ><svg width="18" height="18" viewBox="0 0 18 18" ><path d="M7.5 7.49997C7.91422 7.49997 8.25 7.83576 8.25 8.24998V12C8.25 12.4142 7.91422 12.75 7.5 12.75C7.08579 12.75 6.75 12.4142 6.75 12V8.24998C6.75 7.83576 7.08579 7.49997 7.5 7.49997Z" fill="#99ADBF"/><path d="M10.5 7.49997C10.9142 7.49997 11.25 7.83576 11.25 8.24998V12C11.25 12.4142 10.9142 12.75 10.5 12.75C10.0858 12.75 9.75 12.4142 9.75 12V8.24998C9.75 7.83576 10.0858 7.49997 10.5 7.49997Z" fill="#99ADBF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M6.75 0.75C5.92157 0.75 5.25 1.42157 5.25 2.25V3.75H2.25C1.83579 3.75 1.5 4.08578 1.5 4.5C1.5 4.91421 1.83579 5.25 2.25 5.25H3.08824L3.66694 15.0881C3.71359 15.881 4.37014 16.5 5.16436 16.5H12.8356C13.6298 16.5 14.2864 15.881 14.333 15.0881L14.9118 5.25H15.75C16.1642 5.25 16.5 4.91421 16.5 4.5C16.5 4.08578 16.1642 3.75 15.75 3.75H12.75V2.25C12.75 1.42157 12.0784 0.75 11.25 0.75H6.75ZM4.59083 5.25L5.16436 15H12.8356L13.4092 5.25H4.59083ZM6.75 2.25H11.25V3.75H6.75V2.25Z" fill="#99ADBF"/></svg></div>'; 

            toolbar += '</div>'; // pixe-top-section
            toolbar += '<div class="pixe-inline-toolbar2">';
            toolbar += '<div class="pixe-action" data-action="icon" >' + $.pixeGetAdminIcon('icon') + '</div>';
            toolbar += '<div class="pixe-divider pixe-icon-divider" ></div>';
            toolbar += '<div class="pixe-action" data-action="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></div>';
            toolbar += '<div class="pixe-action" data-action="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></div>';
            toolbar += '<div class="pixe-action" data-action="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></div>';
            toolbar += '<div class="pixe-divider" ></div>';
            toolbar += '<div class="pixe-action" data-action="bold" ><svg width="8" height="12" viewBox="0 0 8 12" ><path d="M1.28125 11.25C0.96875 11.25 0.703125 11.1406 0.484375 10.9219C0.265625 10.7031 0.15625 10.4375 0.15625 10.125V1.875C0.15625 1.5625 0.265625 1.29687 0.484375 1.07812C0.703125 0.859375 0.96875 0.75 1.28125 0.75H4.43125C5.25625 0.75 5.97188 1.0125 6.57813 1.5375C7.18438 2.0625 7.4875 2.725 7.4875 3.525C7.4875 4 7.35625 4.4375 7.09375 4.8375C6.83125 5.2375 6.48125 5.54375 6.04375 5.75625V5.86875C6.58125 6.04375 7.01563 6.35625 7.34688 6.80625C7.67813 7.25625 7.84375 7.7625 7.84375 8.325C7.84375 9.175 7.51563 9.875 6.85938 10.425C6.20313 10.975 5.4375 11.25 4.5625 11.25H1.28125ZM1.76875 9.825H4.46875C4.94375 9.825 5.35625 9.66875 5.70625 9.35625C6.05625 9.04375 6.23125 8.65 6.23125 8.175C6.23125 7.7125 6.05625 7.325 5.70625 7.0125C5.35625 6.7 4.94375 6.54375 4.46875 6.54375H1.76875V9.825ZM1.76875 5.19375H4.31875C4.75625 5.19375 5.13438 5.05 5.45313 4.7625C5.77188 4.475 5.93125 4.1125 5.93125 3.675C5.93125 3.2375 5.77188 2.87187 5.45313 2.57812C5.13438 2.28437 4.75625 2.1375 4.31875 2.1375H1.76875V5.19375Z" /></svg></div>';
            toolbar += '<div class="pixe-action" data-action="italic" ><svg width="10" height="12" viewBox="0 0 10 12" ><path d="M0.949951 11.2687C0.739951 11.2687 0.562451 11.196 0.417451 11.0505C0.272451 10.9049 0.199951 10.7268 0.199951 10.5161C0.199951 10.3053 0.272451 10.1281 0.417451 9.98435C0.562451 9.8406 0.739951 9.76872 0.949951 9.76872H2.71245L5.3187 2.09998H3.08745C2.87745 2.09998 2.69995 2.02722 2.55495 1.88171C2.40995 1.73619 2.33745 1.55807 2.33745 1.34733C2.33745 1.13659 2.40995 0.95935 2.55495 0.815601C2.69995 0.671851 2.87745 0.599976 3.08745 0.599976H8.71245C8.92245 0.599976 9.09995 0.672732 9.24495 0.818244C9.38995 0.963757 9.46245 1.14188 9.46245 1.35262C9.46245 1.56336 9.38995 1.7406 9.24495 1.88435C9.09995 2.0281 8.92245 2.09998 8.71245 2.09998H6.94995L4.3437 9.76872H6.57495C6.78495 9.76872 6.96245 9.84148 7.10745 9.98699C7.25245 10.1325 7.32495 10.3106 7.32495 10.5214C7.32495 10.7321 7.25245 10.9093 7.10745 11.0531C6.96245 11.1968 6.78495 11.2687 6.57495 11.2687H0.949951Z" /></svg></div>';
            toolbar += '<div class="pixe-action" data-action="underline" ><svg width="12" height="14" viewBox="0 0 12 14" ><path d="M1.3125 13.375C1.15312 13.375 1.01953 13.3208 0.911719 13.2123C0.803906 13.1039 0.75 12.9695 0.75 12.8092C0.75 12.6489 0.803906 12.5156 0.911719 12.4094C1.01953 12.3031 1.15312 12.25 1.3125 12.25H10.6875C10.8469 12.25 10.9805 12.3042 11.0883 12.4127C11.1961 12.5211 11.25 12.6555 11.25 12.8158C11.25 12.9761 11.1961 13.1094 11.0883 13.2156C10.9805 13.3219 10.8469 13.375 10.6875 13.375H1.3125ZM6 10.75C4.75 10.75 3.77187 10.3844 3.06562 9.65313C2.35937 8.92188 2.00625 7.93125 2.00625 6.68125V1.01875C2.00625 0.807725 2.08454 0.626844 2.24113 0.476107C2.39773 0.325369 2.58211 0.25 2.79426 0.25C3.00642 0.25 3.1875 0.325369 3.3375 0.476107C3.4875 0.626844 3.5625 0.807725 3.5625 1.01875V6.68125C3.5625 7.46875 3.775 8.1 4.2 8.575C4.625 9.05 5.225 9.2875 6 9.2875C6.775 9.2875 7.375 9.05 7.8 8.575C8.225 8.1 8.4375 7.46875 8.4375 6.68125V1.01875C8.4375 0.807725 8.51579 0.626844 8.67238 0.476107C8.82898 0.325369 9.01335 0.25 9.2255 0.25C9.43767 0.25 9.61875 0.325369 9.76875 0.476107C9.91875 0.626844 9.99375 0.807725 9.99375 1.01875V6.68125C9.99375 7.93125 9.64062 8.92188 8.93437 9.65313C8.22812 10.3844 7.25 10.75 6 10.75Z" /></svg></div>';
            toolbar += '<div class="pixe-action" data-action="strikeThrough" ><svg width="16" height="12" viewBox="0 0 16 12" ><path d="M1.0625 7.3125C0.903125 7.3125 0.769531 7.25828 0.661719 7.14984C0.553906 7.04139 0.5 6.90702 0.5 6.74672C0.5 6.58641 0.553906 6.45312 0.661719 6.34687C0.769531 6.24062 0.903125 6.1875 1.0625 6.1875H14.9375C15.0969 6.1875 15.2305 6.24172 15.3383 6.35016C15.4461 6.45861 15.5 6.59298 15.5 6.75328C15.5 6.91359 15.4461 7.04687 15.3383 7.15312C15.2305 7.25937 15.0969 7.3125 14.9375 7.3125H1.0625ZM7.0625 5.0625V1.875H3.6875C3.42709 1.875 3.20573 1.78364 3.02343 1.60091C2.84114 1.4182 2.75 1.19633 2.75 0.935288C2.75 0.674263 2.84114 0.453125 3.02343 0.271875C3.20573 0.090625 3.42709 0 3.6875 0H12.3125C12.5729 0 12.7943 0.0913621 12.9766 0.274087C13.1589 0.4568 13.25 0.678675 13.25 0.939712C13.25 1.20074 13.1589 1.42187 12.9766 1.60312C12.7943 1.78437 12.5729 1.875 12.3125 1.875H8.9375V5.0625H7.0625ZM7.99779 12C7.73676 12 7.51563 11.9089 7.33438 11.7266C7.15313 11.5443 7.0625 11.3229 7.0625 11.0625V8.4375H8.9375V11.0625C8.9375 11.3229 8.84614 11.5443 8.66341 11.7266C8.4807 11.9089 8.25883 12 7.99779 12Z" /></svg></div>';
            toolbar += '<div class="pixe-action" data-action="quote" ><svg width="14" height="10" viewBox="0 0 14 10" ><path d="M9.08325 4.58333H12.4166V1.25H9.08325V4.58333ZM1.58325 4.58333H4.91659V1.25H1.58325V4.58333ZM11.5208 9.16667C11.1735 9.16667 10.9131 9.02431 10.7395 8.73958C10.5659 8.45486 10.5555 8.15972 10.7083 7.85417L11.7083 5.83333H9.08325C8.73603 5.83333 8.44089 5.71181 8.19784 5.46875C7.95478 5.22569 7.83325 4.93056 7.83325 4.58333V1.25C7.83325 0.902778 7.95478 0.607639 8.19784 0.364583C8.44089 0.121528 8.73603 0 9.08325 0H12.4166C12.7638 0 13.0589 0.121528 13.302 0.364583C13.5451 0.607639 13.6666 0.902778 13.6666 1.25V5.70833C13.6666 5.80556 13.6562 5.90278 13.6353 6C13.6145 6.09722 13.5833 6.1875 13.5416 6.27083L12.3333 8.66667C12.2638 8.81944 12.1562 8.94097 12.0103 9.03125C11.8645 9.12153 11.7013 9.16667 11.5208 9.16667ZM4.02075 9.16667C3.67353 9.16667 3.41311 9.02431 3.2395 8.73958C3.06589 8.45486 3.05547 8.15972 3.20825 7.85417L4.20825 5.83333H1.58325C1.23603 5.83333 0.940891 5.71181 0.697835 5.46875C0.45478 5.22569 0.333252 4.93056 0.333252 4.58333V1.25C0.333252 0.902778 0.45478 0.607639 0.697835 0.364583C0.940891 0.121528 1.23603 0 1.58325 0H4.91659C5.26381 0 5.55895 0.121528 5.802 0.364583C6.04506 0.607639 6.16659 0.902778 6.16659 1.25V5.70833C6.16659 5.80556 6.15617 5.90278 6.13534 6C6.1145 6.09722 6.08325 6.1875 6.04159 6.27083L4.83325 8.66667C4.76381 8.81944 4.65617 8.94097 4.51034 9.03125C4.3645 9.12153 4.20131 9.16667 4.02075 9.16667Z" /></svg></div>';
            toolbar += '<div class="pixe-action" data-action="ul" ><svg width="16" height="14" viewBox="0 0 16 14" ><path d="M6.47909 12.875C6.302 12.875 6.15356 12.8148 6.03377 12.6943C5.91398 12.5738 5.85409 12.4245 5.85409 12.2464C5.85409 12.0683 5.91398 11.9202 6.03377 11.8021C6.15356 11.6841 6.302 11.625 6.47909 11.625H14.8749C15.052 11.625 15.2004 11.6853 15.3202 11.8058C15.44 11.9263 15.4999 12.0756 15.4999 12.2537C15.4999 12.4318 15.44 12.5799 15.3202 12.698C15.2004 12.816 15.052 12.875 14.8749 12.875H6.47909ZM6.47909 7.62504C6.302 7.62504 6.15356 7.5648 6.03377 7.44431C5.91398 7.32381 5.85409 7.17451 5.85409 6.9964C5.85409 6.81827 5.91398 6.67018 6.03377 6.55212C6.15356 6.43407 6.302 6.37504 6.47909 6.37504H14.8749C15.052 6.37504 15.2004 6.43528 15.3202 6.55577C15.44 6.67627 15.4999 6.82558 15.4999 7.00369C15.4999 7.18181 15.44 7.3299 15.3202 7.44796C15.2004 7.56601 15.052 7.62504 14.8749 7.62504H6.47909ZM6.47909 2.35421C6.302 2.35421 6.15356 2.29396 6.03377 2.17348C5.91398 2.05298 5.85409 1.90367 5.85409 1.72556C5.85409 1.54744 5.91398 1.39935 6.03377 1.28129C6.15356 1.16324 6.302 1.10421 6.47909 1.10421H14.8749C15.052 1.10421 15.2004 1.16445 15.3202 1.28494C15.44 1.40544 15.4999 1.55474 15.4999 1.73285C15.4999 1.91098 15.44 2.05907 15.3202 2.17712C15.2004 2.29518 15.052 2.35421 14.8749 2.35421H6.47909ZM1.93742 13.6459C1.54784 13.6459 1.21433 13.5139 0.936898 13.25C0.659467 12.9862 0.520752 12.6563 0.520752 12.2605C0.520752 11.8646 0.656169 11.5313 0.927002 11.2605C1.19784 10.9896 1.53117 10.8542 1.927 10.8542C2.32284 10.8542 2.6527 10.9929 2.91659 11.2704C3.18047 11.5478 3.31242 11.8813 3.31242 12.2709C3.31242 12.649 3.17779 12.9727 2.90852 13.242C2.63925 13.5112 2.31554 13.6459 1.93742 13.6459ZM1.93742 8.39587C1.54784 8.39587 1.21433 8.2592 0.936898 7.98585C0.659467 7.71251 0.520752 7.3839 0.520752 7.00004C0.520752 6.61618 0.659467 6.28758 0.936898 6.01423C1.21433 5.74088 1.54784 5.60421 1.93742 5.60421C2.31554 5.60421 2.63925 5.74088 2.90852 6.01423C3.17779 6.28758 3.31242 6.61618 3.31242 7.00004C3.31242 7.3839 3.17779 7.71251 2.90852 7.98585C2.63925 8.2592 2.31554 8.39587 1.93742 8.39587ZM1.91659 3.12504C1.53274 3.12504 1.20413 2.98837 0.930773 2.71502C0.657426 2.44167 0.520752 2.11307 0.520752 1.72921C0.520752 1.34535 0.657426 1.01674 0.930773 0.743396C1.20413 0.470048 1.53274 0.333374 1.91659 0.333374C2.30043 0.333374 2.62904 0.470048 2.9024 0.743396C3.17575 1.01674 3.31242 1.34535 3.31242 1.72921C3.31242 2.11307 3.17575 2.44167 2.9024 2.71502C2.62904 2.98837 2.30043 3.12504 1.91659 3.12504Z" /></svg></div>';
            toolbar += '<div class="pixe-action" data-action="ol" ><svg width="16" height="16" viewBox="0 0 16 16" ><path d="M6.16663 12.5833H15.3333M0.666626 11.3782V11.2083C0.666626 10.449 1.28223 9.83332 2.04163 9.83332H2.07879C2.81766 9.83332 3.41682 10.4323 3.41682 11.1712C3.41682 11.4928 3.31231 11.8059 3.11933 12.0632L0.666626 15.3335L3.41663 15.3333M6.16663 7.99999H15.3333M6.16663 3.41666H15.3333M0.666626 1.58332L2.49996 0.666656V6.16666" stroke="#383C49" stroke-width="1.1" stroke-linecap="round" stroke-linejoin="round"/></svg></div>';
            toolbar += '<div class="pixe-action" data-action="link" ><svg width="16" height="16" viewBox="0 0 16 16" ><path d="M8.70644 3.52149C8.4461 3.78184 8.02417 3.78204 7.76384 3.5217C7.5035 3.26134 7.5035 2.83924 7.76384 2.57888L7.99924 2.34311C9.5613 0.781016 12.094 0.781016 13.6561 2.34311C15.2182 3.90521 15.2182 6.43787 13.6561 7.99999L12.0062 9.64986C10.4441 11.2119 7.91157 11.212 6.34946 9.65005C6.08915 9.38972 6.08928 8.96746 6.34962 8.70712C6.60997 8.44679 7.0321 8.44679 7.29243 8.70712C8.33384 9.74832 10.022 9.74839 11.0634 8.70706L12.7132 7.05719C13.7546 6.01576 13.7546 4.32732 12.7132 3.28592C11.6718 2.24452 9.98344 2.24452 8.94204 3.28592L8.70644 3.52149Z" /><path d="M8.23612 13.421L8.00032 13.6568C6.4382 15.2189 3.90554 15.2189 2.34345 13.6568C0.78135 12.0947 0.78135 9.56206 2.34345 8L3.99336 6.35005C5.55546 4.78796 8.08825 4.78811 9.65038 6.35021C9.91072 6.61056 9.91092 7.0326 9.65052 7.29293C9.39018 7.55326 8.96778 7.5532 8.70738 7.29286C7.66598 6.25146 5.97757 6.25146 4.93617 7.29286L3.28626 8.9428C2.24486 9.9842 2.24486 11.6726 3.28626 12.714C4.32766 13.7554 6.0161 13.7554 7.05752 12.714L7.29352 12.4784C7.55385 12.2181 7.97598 12.2181 8.23632 12.4784C8.49665 12.7387 8.49645 13.1607 8.23612 13.421Z" /></svg></div>';
            toolbar += '<div class="pixe-action" data-action="tag" ><svg width="15" height="9" viewBox="0 0 15 9" ><path d="M5.55 7.95L2.1 4.5L5.55 1.05L4.5 0L0 4.5L4.5 9L5.55 7.95ZM9.45 7.95L12.9 4.5L9.45 1.05L10.5 0L15 4.5L10.5 9L9.45 7.95Z" /></svg></div>';
            toolbar += '<div class="pixe-action" data-action="color" ><span class="pixe-color-display" ></span></div>';
            toolbar += $.pixeCombobox({
                class: 'pixe-action-transform',
                options: $.pixeComboboxOption.textTransform(),
                width: 107
            });
            toolbar += '<div class="pixe-divider pixe-editor-divider" ></div>';
            toolbar += '<div class="pixe-action" data-action="editor" ><svg width="12" height="14" viewBox="0 0 12 14" ><path d="M5.32961 13.6667C5.15148 13.6667 5.00339 13.6068 4.88533 13.487C4.76728 13.3672 4.70825 13.2188 4.70825 13.0417V8.25004H4.29158C3.19645 8.25004 2.26294 7.86389 1.49106 7.09158C0.719189 6.31928 0.333252 5.38525 0.333252 4.2895C0.333252 3.19375 0.719189 2.26046 1.49106 1.48962C2.26294 0.718791 3.19645 0.333374 4.29158 0.333374H11.3749C11.552 0.333374 11.7004 0.393617 11.8202 0.514103C11.94 0.634603 11.9999 0.783909 11.9999 0.96202C11.9999 1.14014 11.94 1.28824 11.8202 1.40629C11.7004 1.52435 11.552 1.58337 11.3749 1.58337H10.1249V13.0417C10.1249 13.2188 10.0647 13.3672 9.94419 13.487C9.82369 13.6068 9.67438 13.6667 9.49627 13.6667C9.31815 13.6667 9.17006 13.6068 9.052 13.487C8.93394 13.3672 8.87492 13.2188 8.87492 13.0417V1.58337H5.95825V13.0417C5.95825 13.2188 5.89801 13.3672 5.77752 13.487C5.65702 13.6068 5.50772 13.6667 5.32961 13.6667Z" /></svg></div>';
            toolbar += '<div class="pixe-action" data-action="edit-typo" ><svg width="16" height="16" viewBox="0 0 16 16" ><path fill-rule="evenodd" clip-rule="evenodd" d="M8.00014 10.6667C9.47294 10.6667 10.6668 9.47277 10.6668 8.00004C10.6668 6.52728 9.47294 5.33337 8.00014 5.33337C6.5274 5.33337 5.3335 6.52728 5.3335 8.00004C5.3335 9.47277 6.5274 10.6667 8.00014 10.6667ZM8.00014 9.33337C8.73654 9.33337 9.33348 8.73644 9.33348 8.00004C9.33348 7.26364 8.73654 6.66671 8.00014 6.66671C7.26381 6.66671 6.66681 7.26364 6.66681 8.00004C6.66681 8.73644 7.26381 9.33337 8.00014 9.33337Z" /><path fill-rule="evenodd" clip-rule="evenodd" d="M10.079 1.24322L10.347 3.20933C10.5652 3.31639 10.7749 3.43789 10.975 3.57261L12.8125 2.82145C13.1211 2.69529 13.4754 2.81649 13.6422 3.10521L15.0602 5.56138C15.2269 5.8501 15.1547 6.21756 14.8912 6.42173L13.3216 7.63769C13.3296 7.75743 13.3336 7.87823 13.3336 7.99996C13.3336 8.12169 13.3296 8.24249 13.3216 8.36223L14.8912 9.57816C15.1547 9.78236 15.2269 10.1498 15.0602 10.4386L13.6422 12.8947C13.4754 13.1834 13.1211 13.3046 12.8125 13.1785L10.975 12.4273C10.7749 12.562 10.5652 12.6836 10.347 12.7906L10.079 14.7567C10.0339 15.087 9.75176 15.3333 9.41836 15.3333H6.58225C6.24887 15.3333 5.96674 15.087 5.9217 14.7567L5.65359 12.7906C5.43547 12.6836 5.22573 12.562 5.02561 12.4273L3.18813 13.1785C2.87954 13.3046 2.5252 13.1834 2.35851 12.8947L0.940442 10.4386C0.773748 10.1498 0.845955 9.78236 1.1095 9.57816L2.6791 8.36223C2.67107 8.24249 2.66699 8.12169 2.66699 7.99996C2.66699 7.87823 2.67107 7.75743 2.6791 7.63769L1.1095 6.42173C0.845955 6.21756 0.773748 5.8501 0.940435 5.56138L2.35851 3.10521C2.5252 2.81649 2.87953 2.69529 3.18813 2.82145L5.02561 3.57261C5.22573 3.43789 5.43547 3.31639 5.65359 3.20933L5.9217 1.24322C5.96674 0.912893 6.24887 0.666626 6.58225 0.666626H9.41836C9.75176 0.666626 10.0339 0.912893 10.079 1.24322ZM9.12189 4.09332L9.75963 4.40628C9.92296 4.48646 10.0802 4.57755 10.2304 4.67866L10.8208 5.07611L12.7784 4.27584L13.6146 5.72409L11.9437 7.01849L11.9912 7.72696C11.9972 7.81696 12.0003 7.90803 12.0003 7.99996C12.0003 8.09189 11.9972 8.18296 11.9912 8.27296L11.9437 8.98143L13.6146 10.2758L12.7784 11.7241L10.8208 10.9238L10.2304 11.3213C10.0802 11.4224 9.92296 11.5134 9.75963 11.5936L9.12189 11.9066L8.83649 14H7.16416L6.87869 11.9066L6.24103 11.5936C6.07767 11.5134 5.92041 11.4224 5.77023 11.3213L5.17985 10.9238L3.22225 11.7241L2.3861 10.2758L4.05696 8.98143L4.00944 8.27296C4.00341 8.18296 4.00032 8.09189 4.00032 7.99996C4.00032 7.90803 4.00341 7.81696 4.00944 7.72696L4.05696 7.01849L2.3861 5.72409L3.22224 4.27584L5.17985 5.07611L5.77023 4.67866C5.92041 4.57755 6.07766 4.48647 6.24103 4.40629L6.87869 4.09332L7.16416 1.99996H8.83649L9.12189 4.09332Z" /></svg></div>';
            toolbar += '<div class="pixe-action" data-action="ai" ><svg width="17" height="18" viewBox="0 0 17 18" ><path d="M14.2162 12.7185L16.635 13.8113L14.2162 14.9032L13.125 17.3213L12.033 14.904L9.615 13.8113L12.033 12.7193L13.125 10.3012L14.2162 12.7185ZM15.6863 4.43625L5.0955 15.0263C4.88659 15.2354 4.6385 15.4014 4.36543 15.5146C4.09235 15.6279 3.79963 15.6862 3.504 15.6863H0L0.000750035 12.1823C0.000678543 11.5857 0.237539 11.0135 0.65925 10.5915L11.25 0L15.6863 4.43625ZM3.43275 1.75125L5.058 2.56125L3.43275 3.36975L2.625 4.99425L1.8165 3.36975L0.192 2.56125L1.8165 1.75125L2.625 0.12825L3.43275 1.75125ZM1.5 14.1863H3.504C3.60254 14.1861 3.70008 14.1666 3.79107 14.1288C3.88205 14.0909 3.96468 14.0355 4.03425 13.9657L5.3145 12.6863L3 10.3717L1.7205 11.6513C1.57984 11.7919 1.50079 11.9826 1.50075 12.1815L1.5 14.1863Z" /></svg></div>';
            toolbar += '</div>'; // pixe-top-section

            toolbar += '<div class="pixe-inline-toolbar-pointer" ></div>';
            toolbar += '</div>';

            t.elem = $(toolbar);
            t.elem.appendTo($(document.body));
            t.elem.pixeCombobox({
                selector: '.pixe-typo-preset-combobox',
                contentFilter: $.pixeTypoComboboxFilter,
                defaultFilter: true
            });
            t.elem.pixeCombobox({
                selector: '.pixe-font-weight-combobox',
                contentFilter: $.pixeFontWeightComboboxFilter,
                defaultFilter: true
            });
            t.elem.pixeCombobox();
            t.elem.pixeRangeInput();
            t.elem.pixeDraggable({
                handlerClass: '.pixe-inline-toolbar',
                frameSelector: '.pixe-inline-toolbar'
            });
            t.bindToolbar();
        },

        typoChange: function(slug, value){
            var t = this;
            var typo = $.pixeInlineContent.getVal(t.target, 'typo');
            if( !typo ){ 
                typo = {}; 
            }else{
                typo = $.pixeClone(typo);
            }

            $.pixeSetData(typo, slug, value);
            $.pixeInlineContent.setVal(t.target, 'typo', typo);
            t.elem.find('.pixe-inline-toolbar1 [data-slug="preset"]').data('typo', typo);
        },
        
        bindToolbar: function(){
            var t = this;

            // reset input
            t.elem.on('cleartypo', '.pixe-typo-preset-combobox', function(){
                var typo = $(this).data('typo');
                if( typo.preset ){
                    typo = { preset: typo.preset };
                }
                
                $.pixeInlineContent.setVal(t.target, 'typo', typo);
                $(this).data('typo', typo);
                t.updateTypoToolbar();
            });

            // update typo
            t.elem.on('change', '.pixe-inline-toolbar1 [data-slug]', function(){
                var slug = $(this).attr('data-slug');
                var value = $.pixeGetInputVal($(this));

                t.typoChange(slug, value);
            });

            // update length
            t.elem.on('change', '.pixe-inline-toolbar2 [data-slug]', function(){
                var slug = $(this).attr('data-slug');
                var value = $.pixeGetInputVal($(this));
                
                $.pixeInlineContent.setVal(t.target, slug, value);
            });
            
            function doAction(action, button){
                switch( action ){
                    case 'ai':
                        $.pixeCallback['ai-text-option'](button, undefined, t.target.closest('.pixe-item'));
                        break;
                    case 'remove':
                        $(window).trigger('closeinline');
                        $.pixeItem.remove(t.target.closest('.pixe-item'));
                        break;
                    case 'edit-typo':
                    case 'settings':
                        pixeData.hideBuilderPanel = false;
                        $.pixeEditor.setEditTarget(t.target.closest('.pixe-item'), ['style', 'content-typo']);
                        break;
                    case 'family':
                        // get typo data
                        var typo = $.pixeInlineContent.getVal(t.target, 'typo');
                        if( !typo ){ typo = {}; }

                        var inlinePopup = new $.pixeInlinePopup({
                            target: button,
                            width: 340,
                            options: {
                                'font-family': {
                                    'title': 'Font Family',
                                    'width': '1-2',
                                    'type': 'font-family'
                                },
                                'font-style': {
                                    'title': 'Font Style',
                                    'width': '1-2',
                                    'type': 'combobox',
                                    'options': 'fontStyle'
                                },
                                'text-transform': {
                                    'title': 'Text Transform',
                                    'width': '1-2',
                                    'type': 'combobox',
                                    'options': 'textTransform'
                                },
                                'text-decoration': {
                                    'title': 'Text Decoration',
                                    'width': '1-2',
                                    'type': 'combobox',
                                    'options': 'textDecoration'
                                },
                            },
                            values: typo
                        });
                        if( inlinePopup.content ){
                            inlinePopup.content.on('change', '[data-slug]', function(){
                                t.typoChange($(this).attr('data-slug'), $(this).data('value'));
                            });
                        }
                        break;
                    
                    case 'editor':
                        if( t.type == 'title' ) return;
                        var editorId = 'pixe-tmce';
                        var editor = $.pixeTmce(editorId, {height: 280});
                        editor.val(t.target.html());

                        var editorSave = $('<div class="pixe-save-change">Save Changes</div>');
                        var editorWrap = $('<div class="pixe-lb-editor-content" ></div>');
                        editorWrap.append(editor);
                        editorWrap.append(editorSave);

                        // create lightbox
                        var lb = new $.pixeLightboxPopup({
                            class: 'pixe-lb-editor',
                            title: 'Classic Editor',
                            content: editorWrap
                        });
                        
                        // bind event
                        editor.on('change', function(e){
                            editorSave.addClass('pixe-active');
                            $(this).off(e);
                        });
                        editorSave.on('click', function(){
                            var content = wp.editor.autop(wp.editor.getContent('pixe-tmce'));
                            t.target.html(content);
                            lb.close();

                            // update data
                            $.pixeInlineContent.setVal(t.target, 'content');
                        });
                        break;
                    case 'left':
                    case 'center':
                    case 'right':
                        if( t.type == 'title' ){
                            var oldAlign = $.pixeInlineContent.getVal(t.target, 'text-align');
                            if( action == oldAlign ){
                                $.pixeInlineContent.setVal(t.target, 'text-align', '');
                            }else{
                                $.pixeInlineContent.setVal(t.target, 'text-align', action);
                            }
                        }else{
                            var parent = t.getSelectionParent(t.target, false);
                            parent.each(function(){
                                // unset alignment
                                if( t.state.align == action ){
                                    $(this).css('text-align', '');
                                }else{
                                    $(this).css('text-align', action);
                                }
    
                                if( !$(this).attr('style') ){
                                    $(this).removeAttr('style');
                                }
                            });
                            $.pixeInlineContent.setVal(t.target, 'content');
                        }
                        
                        // reapply state
                        $.pixeInlineToolbar.readState();
                        break;

                    case 'bold':
                        t.toggleTag('strong');
                        $.pixeInlineContent.setVal(t.target, 'content');
                        
                        // reapply state
                        $.pixeInlineToolbar.readState();
                        break;
                    case 'italic':                        
                        t.toggleTag('em');
                        $.pixeInlineContent.setVal(t.target, 'content');
                        
                        // reapply state
                        $.pixeInlineToolbar.readState();
                        break;
                    case 'underline':
                        t.toggleTag('u');
                        $.pixeInlineContent.setVal(t.target, 'content');
                        
                        // reapply state
                        $.pixeInlineToolbar.readState();
                        break
                    case 'strikeThrough':
                        t.toggleTag('del');
                        $.pixeInlineContent.setVal(t.target, 'content');
                        
                        // reapply state
                        $.pixeInlineToolbar.readState();
                        break;
                    case 'icon': 
                        if( t.type == 'content' ) return;
                        var iconData = $.pixeInlineContent.getVal(t.target, 'icon');
                        new $.pixeStyleSelector({
                            target: button,
                            type: 'inline-icon',
                            obj: {'': $.pixeClone(iconData)},
                            onChange: function(value){
                                $.pixeInlineContent.setVal(t.target, 'icon', value);
                            }
                        });
                        break;
                    case 'title-tag':
                        if( t.type == 'content' ) return;

                        var allowTag = 'h1, h2, h3, h4, h5, h6, div';
                        var currentTag = t.target.get(0).tagName.toLowerCase();
                        var inlinePopup = new $.pixeInlinePopup({
                            popupPosition: 'top-center',
                            target: button,
                            options: 'inline-tag',
                            values: { 'tag': currentTag },
                            onChange: function(slug, value){
                                // replace element
                                var newTag = value;
                                var newHtml = $.pixeInlineContent.replaceTag(t.target, newTag);
                                if( newHtml ){ t.target = newHtml; }

                                // update value
                                $.pixeInlineContent.setVal(t.target, 'tag', newTag);
                            }
                        });
                        if( inlinePopup.content ){
                            inlinePopup.content.on('click', function(){
                                $.pixeRange.returnSelection();
                            });
                        }
                        break;
                    case 'tag':
                        if( t.type == 'title' ) return;

                        var allowTag = 'p, div, h1, h2, h3, h4, h5, h6, pre';
                        var parents = t.getSelectionParent(t.target, false);
                        var currentTag;

                        // for normal tag
                        if( parents.is(allowTag) ){
                            parents = parents.not('ul, ol');
                            currentTag = parents.first().get(0).tagName.toLowerCase();

                        // for list tag
                        }else{
                            var nodes = t.getSelectionElements();
                            var liNodes = nodes.filter('li');
                            liNodes = liNodes.add(nodes.first().closest('li'));

                            parents = $();

                            // find node in list
                            liNodes.each(function(){
                                if( $(this).contents().length > 1 || !$(this).children().is(allowTag) ){
                                    parents = parents.add($(this));
                                }else{
                                    parents = parents.add($(this).children());
                                }
                            });
                            
                            if( parents.first().length ){
                                currentTag = parents.first().get(0).tagName.toLowerCase();
                            }
                            if( currentTag == 'li' ){
                                currentTag = 'p'; 
                            }
                        }

                        var inlinePopup = new $.pixeInlinePopup({
                            popupPosition: 'top-center',
                            target: button,
                            options: {
                                'tag': {
                                    'title': 'Tag',
                                    'type': 'combobox',
                                    'width': '1-1',
                                    'with-default': false,
                                    'options': {
                                        'p': 'Paragraph',
                                        'div': 'Div',
                                        'h1': 'Heading 1',
                                        'h2': 'Heading 2',
                                        'h3': 'Heading 3',
                                        'h4': 'Heading 4',
                                        'h5': 'Heading 5',
                                        'h6': 'Heading 6',
                                        'pre': 'Preformatted'
                                    }
                                },
                            },
                            values: {
                                'tag': currentTag
                            }
                        });
                        if( inlinePopup.content ){
                            inlinePopup.content.on('click', function(){
                                $.pixeRange.returnSelection();
                            });
                            inlinePopup.content.on('change', '.pixe-combobox', function(){
                                var newTag = $(this).data('value');
                                var newParent = $();

                                parents.each(function(){
                                    if( $(this).is('li') ){
                                        var newElement = $(document.createElement(newTag));
                                        newElement.append($(this).contents());
                                        newElement.appendTo($(this));
                                        newParent = newParent.add(newElement);
                                    }else{
                                        newParent = newParent.add($.pixeInlineEdit.replaceTag($(this), 'p, h1, h2, h3, h4, h5, h6, pre', newTag));
                                    }
                                });
                                parents = newParent;

                                // update data
                                $.pixeInlineContent.setVal(t.target, 'content');

                                // return cursor
                                $.pixeRange.returnSelection();
                            });
                        }
                        break;
                    case 'link':
                        // selection link
                        var nodes = t.getSelectionElements();
                        var linkTag;

                        // if link tag exists
                        if( nodes.is('a') ){
                            linkTag = nodes.filter('a').first();
                        }else if( nodes.first().closest('a').length ){
                            linkTag = nodes.first().closest('a');

                        // link tag not exists
                        }else{
                            var range = $.pixeRange.current;
                            linkTag = document.createElement('a');
                            
                            // range is single point
                            if( $.pixeRange.isSinglePoint(range) ){
                                var startArea = range.startContainer;
                                while( startArea.firstChild ){ startArea = startArea.firstChild; }

                                // find first & last space
                                var startNode = startArea;
                                var startOffset = startNode.nodeValue.lastIndexOf(' ', range.startOffset - 1);
                                while( startOffset == -1 && startNode.previousSibling && startNode.previousSibling.nodeType == Node.TEXT_NODE ){
                                    startNode = startNode.previousSibling;
                                    startOffset = startNode.nodeValue.lastIndexOf(' ');
                                }
                                if( startOffset == -1 ){ 
                                    startOffset = 0; 
                                }else{
                                    startOffset++;
                                }

                                var endNode = startArea;
                                var endOffset = endNode.nodeValue.indexOf(' ', range.endOffset);
                                while( endOffset == -1 && endNode.nextSibling && endNode.nextSibling.nodeType == Node.TEXT_NODE ){
                                    endNode = endNode.nextSibling;
                                    endOffset = endNode.nodeValue.indexOf(' ');
                                }
                                if( endOffset == -1 ){ 
                                    endOffset = endNode.length; 
                                }

                                var linkRange = $.pixeRange.create({
                                    startContainer: startNode,
                                    startOffset: startOffset,
                                    endContainer: endNode,
                                    endOffset: endOffset
                                });
                                linkRange.surroundContents(linkTag);

                            // range is highlight
                            }else{ 
                                // find end node & offset
                                var endNode = range.startContainer;
                                var endOffset;
                                while( endNode != range.endContainer && endNode.nextSibling && endNode.nextSibling.nodeType == Node.TEXT_NODE ){
                                    endNode = endNode.nextSibling;
                                }
                                if( endNode == range.endContainer ){
                                    endOffset = range.endOffset;
                                }else{
                                    endOffset = endNode.length;
                                }

                                // create and surround content
                                var linkRange = $.pixeRange.create({
                                    startContainer: range.startContainer,
                                    startOffset: range.startOffset,
                                    endContainer: endNode,
                                    endOffset: endOffset
                                });
                                linkRange.surroundContents(linkTag);
                            }

                            linkTag = $(linkTag);
                        }

                        // create style selector
                        if( linkTag ){
                            $.pixeRange.setAfter(linkTag.get(0));
                            $.pixeRange.saveSelection();
                            linkTag.addClass('pixe-link-editing');

                            new $.pixeStyleSelector({
                                popupPosition: 'top-center',
                                type: 'inline-link',
                                target: button,
                                obj: {'': {
                                    'custom-url': linkTag.attr('href'),
                                    target: linkTag.attr('target'),
                                    rel: linkTag.attr('rel'),
                                }},
                                onChange: function(value){

                                    function removeLink(){
                                        linkTag.removeAttr('href');
                                        linkTag.removeAttr('target');
                                        linkTag.removeAttr('rel');
                                        linkTag.removeAttr('class');
                                    }
                                    removeLink();

                                    if( !value['link-to'] ){
                                        if( value['custom-url'] ){
                                            linkTag.attr('href', value['custom-url']);
                                            if( value.target ){ linkTag.attr('target', value.target); }
                                            if( value.rel ){ linkTag.attr('rel', value.rel ); }
                                        }else{
                                            removeLink();
                                        }
                                    }
                                },
                                onClose: function(){
                                    button.removeClass('pixe-active');

                                    if( linkTag.attr('href') ){
                                        $(linkTag).removeClass('pixe-link-editing');
                                    }else{
                                        $(linkTag).contents().unwrap();
                                    }
                                    
                                    // update data
                                    $.pixeInlineContent.setVal(t.target, 'content');
                                }
                            });
                        }else{
                            button.removeClass('pixe-active');
                        }
                        break;

                    case 'color':
                        var ssType = 'inline-color';
                        var tagName = 'span';
                        var styleName = ['color', 'text-shadow', 'background', 'text-stroke'];
                        var colorButton = t.elem.find('[data-action="color"]').children('span');
                        
                        // init variables
                        var isInline = true;
                        var nodes = t.getSelectionElements();
                        var dataNode = t.getSelectionNodeFirst(nodes, tagName, styleName);
                        var colorTag = $();

                        if( $.pixeRange.isSinglePoint($.pixeRange.current) ){
                            ssType = 'link-color';
                            if( dataNode.length ){
                                colorTag = dataNode;
                            }else{
                                isInline = false;
                                colorTag = t.target;
                                dataNode = t.target;
                            }
                        }
                        
                        // read previous style
                        var style;
                        if( isInline ){
                            style = t.readTextColorStyle(dataNode);
                        }else{
                            style = $.pixeInlineContent.getVal(dataNode, 'color');
                            if( !style ){ 
                                style = {};
                            }else{
                                style = $.pixeClone(style);
                            }
                        }

                        // popup
                        new $.pixeStyleSelector({
                            type: ssType,
                            target: button,
                            obj: {'': style},
                            onChange: function(value){

                                // button color
                                if( value.color ){
                                    var color = $.pixeGetColor(value.color);
                                    colorButton.css({ background: color.css });
                                }

                                // get color tag
                                if( !colorTag.length ){ 
                                    t.unwrapSelection(nodes, tagName, styleName);
                                    colorTag = colorTag.add(t.wrapSelectionTexts('span'));

                                    // return cursor
                                    $.pixeRange.returnSelection();
                                }

                                // update value
                                if( isInline ){
                                    $.pixeSetTextColor(colorTag, value);
                                    t.cleanHtml();
                                    $.pixeInlineContent.setVal(t.target, 'content');
                                }else{
                                    $.pixeInlineContent.setVal(t.target, 'color', value);
                                }
                            },
                            onClose: function(){

                                // remove empty span tag out
                                colorTag.each(function(){
                                    if( $(this).is('span') && !$.pixeHasStyle($(this), ['color', 'text-shadow', 'background', 'text-stroke']) ){
                                        $(this).contents().unwrap();
                                    }
                                });
                            }
                        });
                        break;

                    case 'quote':
                        if( t.type == 'title' ) return;
                        var nodes = t.getSelectionParent(t.target);

                        // remove old quote out
                        if( nodes.is('blockquote') ){
                            nodes.contents().unwrap('blockquote');
                        
                        // wrap quote on unactive state
                        }else{
                            nodes.wrapAll('<blockquote></blockquote>');
                        }

                        // return cursor
                        $.pixeRange.returnSelection();
                        
                        // update data
                        $.pixeInlineContent.setVal(t.target, 'content');

                        // reapply state
                        $.pixeInlineToolbar.readState();
                        break;

                    case 'ul':
                    case 'ol':  
                        if( t.type == 'title' ) return;
                        var nodes = t.getSelectionParent(t.target, false);

                        // if list exists remove ul element out
                        if( nodes.is('ul, ol') ){

                            nodes = nodes.filter('ul, ol');
                            if( nodes.is(action) ){
                                nodes = nodes.filter(action);

                                var liNodes = nodes.children('li');
                                liNodes.unwrap(action);
                                liNodes.each(function(){
                                    if( $(this).contents().length > 1 || !$(this).children().is('p, h1, h2, h3, h4, h5, h6, pre, div') ){
                                        $.pixeInlineEdit.replaceTag($(this), 'li', 'p');
                                    }else{
                                        $(this).children().unwrap();
                                    }
                                });
                            }else{
                                $.pixeInlineEdit.replaceTag(nodes, 'ul, ol', action);
                            }
                        
                        // if not exists add new element
                        }else{

                            // change p & heading tag to li
                            var liElements = $.pixeInlineEdit.replaceTag(nodes, 'p, h1, h2, h3, h4, h5, h6, pre, div', 'li');

                            // merge if connect to another list element
                            if( liElements.first().prev(action).length ){
                                liElements.first().prev(action).append(liElements);
                            }else if( liElements.last().next(action).length ){
                                liElements.last().next(action).prepend(liElements);
                            }else{
                                liElements.wrapAll($('<' + action + '></' + action + '>'));
                            }
                        }

                        // return cursor
                        $.pixeRange.returnSelection();
                        
                        // update data
                        $.pixeInlineContent.setVal(t.target, 'content');

                        // reapply state
                        $.pixeInlineToolbar.readState();
                        break;
                }
            }

            // retain & save selection while clicking in toolbar area
            t.elem.on('mousedown', function(e){
                if( !$(e.target).closest('.pixe-input, .pixe-range-input').length ){
                    e.preventDefault();
                }
            });
            
            // on click target
            t.elem.on('click', '.pixe-action', function(e){

                var button = $(this);
                var action = $(this).attr('data-action');

                // wait for save selection event
                setTimeout(function(){
                    doAction(action, button);
                }, 1);
                
            });

            // transform action
            t.elem.on('change', '.pixe-action-transform', function(){
                if( t.type == 'title' ) return;

                var value = $(this).data('value');
                var nodes = t.getSelectionElements();

                // single point
                if( $.pixeRange.isSinglePoint($.pixeRange.current) ){
                    var dataNode = t.getSelectionNodeFirst(nodes, 'span', 'text-transform');
                    
                    // change current tag
                    if( dataNode.length ){
                        if( value ){
                            dataNode.css('text-transform', value);
                        }else{
                            dataNode.contents().unwrap();
                        }
                    }else{
                        dataNode = t.getSelectionParent(t.target, false);
                        dataNode.css('text-transform', value);

                        if( !dataNode.attr('style') ){
                            dataNode.removeAttr('style');
                        }
                    }
                    
                    $.pixeInlineContent.setVal(t.target, 'content');

                // highlight - unwrap then wrap again
                }else{
                    t.unwrapSelection(nodes, 'span', 'text-transform');
                    if( value ){
                        t.wrapSelectionTexts('span', 'text-transform', value);
                    }
                    $.pixeInlineContent.setVal(t.target, 'content');
                }

                // return cursor
                $.pixeRange.returnSelection();
            });
        },
        

        cleanHtml: function(){
            var t = this;
            if( !t.target ) return;

            function elemMatch(elem1, elem2){
                if( elem1.attributes.length == elem2.attributes.length ){
                    for( var i = 0; i < elem1.attributes.length; i++ ){
                        var name = elem1.attributes[i].name;
                        if( elem1.getAttribute(name) != elem2.getAttribute(name) ){
                            return false;
                        }
                    }
                }
                return true;
            }

            t.target.find('span').each(function(){
                if( !this.isConnected ) return;

                // clean empty span
                if( !this.attributes.length ){
                    $(this).contents().unwrap();
                }

                // clean next span with the same attributes
                var next = this.nextElementSibling;
                if( next && next.tagName === 'SPAN' ){
                    if( elemMatch(this, next) ){
                        $(this).append($(next).contents());
                        next.remove();
                    }
                }
            });
        },

        // read text color
        readTextColorStyle: function(dataNode){
            var style = {};

            // get existed data
            if( dataNode.length && dataNode.get(0).style ){
                var dataStyle = dataNode.get(0).style;

                // text stroke
                if( dataStyle.webkitTextStrokeWidth ){
                    style.stroke = {};
                    style.stroke.size = dataStyle.webkitTextStrokeWidth;
                    if( dataStyle.webkitTextStrokeColor != 'initial' && dataStyle.webkitTextStrokeColor != 'currentColor' ){
                        style.stroke.color = dataStyle.webkitTextStrokeColor;
                    }
                }

                // text shadow
                if( dataStyle.textShadow ){
                    style.shadow = {};
                    var textShadow = dataStyle.textShadow;
                    var colorMatch = textShadow.match(/rgba?\(.*\)/);
                    var sizeMatch;
                    if( colorMatch && colorMatch[0] ){ 
                        style.shadow.color = colorMatch[0]; 
                        sizeMatch = textShadow.replace(colorMatch[0], '').trim().split(' ');
                    }else{
                        sizeMatch = textShadow.trim().split(' ');
                    }
                    if( sizeMatch[0] ){ style.shadow.x = sizeMatch[0]; }
                    if( sizeMatch[1] ){ style.shadow.y = sizeMatch[1]; }
                    if( sizeMatch[2] ){ style.shadow.blur = sizeMatch[2]; }
                }
                
                // color
                if( dataStyle.color ){
                    style.color = dataStyle.color;

                    // check if preset
                    if( style.color.indexOf('var(--pixe--color--') >= 0 ){
                        var presetName = style.color.replace('var(--pixe--color--', '').replace(')', '');
                        style.color = {
                            type: 'preset',
                            name: presetName
                        }
                    }
                }

                // gradient & background
                if( dataStyle.backgroundImage ){
                    var bgText = dataStyle.backgroundImage;
                    var bgType = 'image';

                    // gradient section
                    if( bgText.indexOf('url(') != -1 ){
                        var url = bgText.replace('url("', '').replace('")', '');
                        style.mask = {
                            image: {url: url}
                        };

                        if( dataStyle.backgroundPosition && dataStyle.backgroundPosition != 'initial' ){
                            if( dataStyle.backgroundPosition == 'center center' ){
                                style.mask.position = 'center';
                            }else{
                                if( isNaN(parseFloat(dataStyle.backgroundPositionX)) || isNaN(parseFloat(dataStyle.backgroundPositionY)) ){
                                    style.mask.position = dataStyle.backgroundPositionY + '-' + dataStyle.backgroundPositionX;
                                }else{
                                    style.mask.position = 'custom';
                                    style.mask['pos-x'] = dataStyle.backgroundPositionX;
                                    style.mask['pos-y'] = dataStyle.backgroundPositionY;
                                }
                            }
                        }
                        if( dataStyle.backgroundRepeat && dataStyle.backgroundRepeat != 'initial' ){
                            style.mask.repeat = dataStyle.backgroundRepeat;
                        }
                        if( dataStyle.backgroundSize && dataStyle.backgroundSize != 'initial' ){
                            if( isNaN(parseFloat(dataStyle.backgroundSize)) ){
                                style.mask.size = dataStyle.backgroundSize;
                            }else{
                                style.mask.size = 'custom';
                                style.mask.scale = dataStyle.backgroundSize;
                            }
                            
                        }

                    }else if( bgText.indexOf('radial-gradient(circle') != -1 ){
                        style.color = { type: 'radial' };
                        bgType = 'gradient';
                    }else if( bgText.indexOf('linear-gradient(') != -1 ){
                        style.color = {};
                        bgType = 'gradient';
                        
                        // find angle
                        var angleMatch = bgText.match(/(\d+)deg/);
                        if( angleMatch && angleMatch[1] && angleMatch[1] != '90' ){
                            style.color.angle = angleMatch[1];
                        }
                    }
                    if( bgType == 'gradient' ){
                        var colorMatch = bgText.match(/(rgba?\([^\)]*\) \d+%)/g);
                        if( colorMatch ){
                            for( var i in colorMatch ){
                                var gradientMatch = colorMatch[i].match(/(rgba?\(.*\)) (\d+)%/);
                                if( gradientMatch && gradientMatch[1] && gradientMatch[2] ){
                                    style.color[gradientMatch[2]] = gradientMatch[1];
                                }
                            }
                        }
                    }

                    // image section
                }
            }

            return style;
        },

        // if range is in target element
        isRangeInEditor: function(){
            var t = this;

            if( t.target ){
                var range = $.pixeRange.current;
                if( t.target.has(range.startContainer).length && t.target.has(range.endContainer).length ){
                    return true;
                }
            }

            return false;
        },

        // for checking selection status
        getSelectionNodeFirst: function(nodes, tagName, styleName){
            var target = nodes.first().pixeClosestWithStyle(tagName, styleName);
            
            if( !target.length ){
                nodes.each(function(i){
                    if( i == 0 || !$(this).is(tagName) ) return;

                    if( $.pixeHasStyle($(this), styleName) ){
                        target = target.add($(this));
                        return false;
                    }
                });
            }

            return target;
        },
        isSelectionTagActive: function(nodes, tagName){
            return (nodes.is(tagName) || nodes.first().closest(tagName).length);
        },

        // get all elements node in selection
        getSelectionElements: function(){
            
            var range = $.pixeRange.current;
            var startNode = range.startContainer;
            var endNode = range.endContainer;
            
            var nodes = $();
            
            // add parent for text node & add element for element node
            if( startNode.nodeType == Node.TEXT_NODE ){
                nodes = nodes.add(startNode.parentElement);
            }

            // find next node and add element along the way to "nodes"
            var tNodes = $();
            while( startNode != endNode ){
                if( startNode.firstChild ){
                    tNodes = tNodes.add(startNode);
                    startNode = startNode.firstChild;
                }else if( startNode.nextSibling ){
                    startNode = startNode.nextSibling;
                }else{
                    while( !startNode.nextSibling ){
                        startNode = startNode.parentElement;
                    }
                    startNode = startNode.nextSibling;
                }

                if( tNodes.length && startNode.nodeType == Node.TEXT_NODE && startNode.length > 0 ){
                    nodes = nodes.add(tNodes);
                    tNodes = $();
                }
            }

            return nodes;
        },
        getSelectionParent: function(container, withQuote = true){

            var t = this;
            var nodes = t.getSelectionElements();

            var parents = container.children().filter(function(){
                if( $(this).is(nodes) || $(this).has(nodes).length ){
                    return true;
                }
                return false;
            });

            // without quote
            if( !withQuote ){

                // inside blockquote case
                if( parents.length == 1 && parents.is('blockquote') ){
                    parents = t.getSelectionParent(parents);

                // ignore element in blockquote
                }else{
                    parents = parents.not('blockquote');
                }
            }
            
            return parents;
        },

        // unset tag for specific range
        unwrapTag: function(range, tagName, styleName = ''){

            var start = range.startContainer.parentElement;
            var tag;
            if( styleName.length ){
                tag = $(start).pixeClosestWithStyle(tagName, styleName);
            }else{
                tag = $(start).closest(tagName);
            } 
            if( !tag.length ) return false;

            // ensure front and back element exists
            var textBefore = document.createTextNode(' ');
            var textAfter = document.createTextNode(' ');
            $(textBefore).insertBefore(tag);
            $(textAfter).insertAfter(tag);

            // split back content
            var bRange = document.createRange();
            bRange.setStart(range.endContainer, range.endOffset);
            bRange.setEnd(textAfter, 0);

            var bContent = bRange.extractContents();
            if( bContent.textContent.trim().length > 0 ){
                bRange.insertNode(bContent);
            }

            // split front content
            var fRange = document.createRange();
            fRange.setStart(textBefore, 1);
            fRange.setEnd(range.startContainer, range.startOffset);

            var fContent = fRange.extractContents();
            if( fContent.textContent.trim().length > 0 ){
                fRange.insertNode(fContent);
            }

            // unwrap
            var content;
            content = tag.contents().unwrap(tagName);

            // remove positional text out
            textBefore.remove();
            textAfter.remove();
            
            return content;
        },
        unwrapSelection: function(nodes, tagName, styleName = ''){
            
            var t = this;
            var range = $.pixeRange.current;
            
            // use for returning the selection
            var focusContent = false;
            var startContent = false;
            var endContent = range.endContainer;
            var endContentOffset = range.endOffset;

            // unwrap first node, if exists & set new focus
            focusContent = t.unwrapTag(range, tagName, styleName);
            if( focusContent !== false ){
                var startContent = focusContent.get(0);
                while( startContent.firstChild ){ startContent = startContent.firstChild; }
                range.startContainer = startContent;
                range.startOffset = 0;
            }

            // check later nodes
            nodes.each(function(i){
                if( i == 0 || !$(this).is(tagName) ) return;
                if( styleName.length && !$.pixeHasStyle($(this), styleName) ) return;

                var startNode = $(this).get(0);
                while( startNode.firstChild ){ startNode = startNode.firstChild; }

                // if end node
                if( $(this).is(range.endContainer) || $(this).has(range.endContainer).length ){
                    var tRange = document.createRange();
                    tRange.setStart(startNode, 0);
                    tRange.setEnd(range.endContainer, range.endOffset);

                    focusContent = t.unwrapTag(tRange, tagName);

                    if( focusContent !== false ){
                        var endContent = focusContent.last().get(0);
                        while( endContent.lastChild ){ endContent = endContent.lastChild; }
                        endContentOffset = endContent.length;
                    }
                
                // middle node
                }else{
                    $(this).contents().unwrap();
                }
                
            });

            if( endContentOffset > endContent.length ){
                endContentOffset = endContent.length;
            }
            range.endContainer = endContent;
            range.endOffset = endContentOffset;

        },

        // wrap all text node in selection
        wrapSelectionTexts: function(tagName, styleName = false, value = false){

            var range = $.pixeRange.current;
            var startNode = range.startContainer;
            var endNode = range.endContainer;

            var tRange;
            var tContent;

            var nodes = $();

            // only 1 node
            if( startNode == endNode ){

                if( startNode.nodeType == Node.TEXT_NODE && startNode.nodeValue.trim() != "" ){
                    tRange = document.createRange();
                    tRange.setStart(startNode, range.startOffset);
                    tRange.setEnd(endNode, range.endOffset);
                    tContent = document.createElement(tagName);
                    if( styleName && value ){ tContent.style[styleName] = value; }
                    tContent.append(tRange.extractContents());
                    tRange.insertNode(tContent);
                    nodes = nodes.add(tContent);

                    range.startContainer = tContent.firstChild;
                    range.startOffset = 0;
                    range.endContainer = tContent.firstChild;
                    range.endOffset = tContent.firstChild.length;
                }

            // multiple nodes
            }else{

                var iNode = startNode;
                var lastLap = false;
                tRange = document.createRange();

                // middle & end node
                while( true ){
                    if( iNode.nodeType == Node.TEXT_NODE && iNode.nodeValue.trim() != "" ){
                        
                        // for adjacent text node
                        var previousSibling = iNode.previousSibling;
                        while( previousSibling && previousSibling.nodeType == Node.TEXT_NODE && previousSibling.length == 0 ){
                            previousSibling = previousSibling.previousSibling;
                        }

                        var usePrevContent = $(tContent).is(previousSibling);

                        if( !usePrevContent ){
                            tContent = document.createElement(tagName);
                            if( styleName && value ){ tContent.style[styleName] = value; }
                        }
                        
                        if( iNode == startNode ){
                            tRange.setStart(iNode, range.startOffset);
                            tRange.setEnd(iNode, iNode.length);
                            tContent.append(tRange.extractContents());
                        }else if( iNode == endNode ){
                            tRange.setStart(iNode, 0);
                            tRange.setEnd(iNode, range.endOffset);
                            tContent.append(tRange.extractContents());
                        }else{
                            tRange.setStart(iNode, 0);
                            tRange.setEnd(iNode, 0);
                            tContent.append(iNode);
                        }
                        
                        if( !usePrevContent ){
                            tRange.insertNode(tContent);
                            nodes = nodes.add(tContent);
                        }

                        if( iNode == startNode ){
                            iNode = tContent.firstChild; // prevent tag adding duplication
                            range.startContainer = tContent.firstChild;
                            range.startOffset = 0;
                        }else if( iNode == endNode ){
                            range.endContainer = tContent.lastChild;
                            range.endOffset = tContent.lastChild.length;
                        }
                    }

                    if( iNode.firstChild ){
                        iNode = iNode.firstChild;
                    }else if( iNode.nextSibling ){
                        iNode = iNode.nextSibling;
                    }else{
                        while( !iNode.nextSibling ){
                            iNode = iNode.parentElement;
                        }
                        iNode = iNode.nextSibling;
                    }

                    if( lastLap ){ break; }
                    if( iNode == endNode ){ lastLap = true; }
                }

            }

            return nodes;

        },
        
        // toggle tag on/off
        toggleTag: function(tagName){
            var t = this;
            var nodes = t.getSelectionElements();
            var isActive = t.isSelectionTagActive(nodes, tagName);

            // unwrap
            if( isActive ){

                // single point
                if( $.pixeRange.isSinglePoint($.pixeRange.current) ){
                    var range = $.pixeRange.current;
                    var tagHtml = range.startContainer.nodeType == Node.TEXT_NODE? range.startContainer.parentElement.closest(tagName): range.startContainer.closest(tagName);
                    var lastElem = tagHtml.lastChild;
                    while( lastElem.lastChild ){ lastElem = tagHtml.lastChild; }
                    
                    // if last child
                    if( lastElem.isSameNode(range.startContainer) && range.startOffset == lastElem.length ){
                        var blankText = document.createTextNode(String.fromCharCode(8203));
                        $(blankText).insertAfter(tagHtml);
                        $.pixeRange.setAfter(blankText);
                        $.pixeRange.saveSelection();

                        // on any action remove blank character or tag out
                        function removeBlankText(e){
                            
                            // remove blank text
                            blankText.nodeValue = blankText.nodeValue.replace(/\u200B/g, '');
                            if( !blankText.nodeValue ){ 
                                blankText.remove(); 
                            }
                            $.pixeRange.saveSelection();
                            
                            // unbind events
                            $(document).off('mousedown', removeBlankText);
                        }
                        $(document).on('mousedown', removeBlankText);
                    
                    // remove whole tag out
                    }else{
                        $(tagHtml).contents().unwrap();
                        $.pixeRange.returnSelection();
                    }

                // multi point
                }else{
                    t.unwrapSelection(nodes, tagName);
                    $.pixeRange.returnSelection();
                }

            // wrap
            }else{

                // single point
                if( $.pixeRange.isSinglePoint($.pixeRange.current) ){

                    // create tag with blank text
                    var blankText = String.fromCharCode(8203);
                    var html = document.createElement(tagName);
                    html.append(blankText);

                    // add tag to cursor
                    var range = $.pixeRange.create($.pixeRange.current);
                    range.insertNode(html);

                    // set cursor to target
                    $.pixeRange.setAfter(html);
                    $.pixeRange.saveSelection();

                    // on any action remove blank character or tag out
                    function removeBlankText(e){

                        // remove blank text out and return selection to the same area
                        html.firstChild.nodeValue = html.firstChild.nodeValue.replace(/\u200B/g, '');
                        if( !html.innerHTML ){ 
                            html.remove();
                            $.pixeRange.saveSelection();
                        }else{
                            $.pixeRange.current.startContainer.isSameNode(html.firstChild);
                            $.pixeRange.current.startOffset = html.firstChild.length;
                            $.pixeRange.current.endOffset = html.firstChild.length;
                            $.pixeRange.returnSelection();
                        }

                        // unbind events
                        $(document).off('mousedown', removeBlankText);
                    }
                    $(document).on('mousedown', removeBlankText);
                
                // area selection
                }else{
                    t.wrapSelectionTexts(tagName);
                    $.pixeRange.returnSelection();
                }
            }
            
        },

        readState: function(){
            var t = $.pixeInlineToolbar;
            if( t.elem.css('display') == 'none' || !t.isRangeInEditor() ) return;
            
            // read state
            t.state = {
                align: ''
            };

            var nodes = t.getSelectionElements();
            t.state.bold = t.isSelectionTagActive(nodes, 'strong');
            t.state.italic = t.isSelectionTagActive(nodes, 'em');
            t.state.underline = t.isSelectionTagActive(nodes, 'u');
            t.state.strikeThrough = t.isSelectionTagActive(nodes, 'del');
            t.state.link = t.isSelectionTagActive(nodes, 'a');
            
            // blockquote
            var bqParent = t.getSelectionParent(t.target); 
            t.state.quote = bqParent.is('blockquote');

            // parent without blockquote
            var parent = t.getSelectionParent(t.target, false); 
            t.state.ul = parent.is('ul');
            t.state.ol = parent.is('ol');

            // align
            if( t.type == 'title' ){
                t.state.align = $.pixeInlineContent.getVal(t.target, 'text-align');
            }else{
                parent.each(function(){
                    var align = $.pixeHasStyle($(this), 'text-align');
                    if( align ){
                        t.state.align = align; 
                        return false;
                    }
                });
            }

            // length
            t.state.length = $.pixeInlineContent.getVal(t.target, 'length');

            // color
            var colorNode = t.getSelectionNodeFirst(nodes, 'span', ['color', 'background']);
            if( !colorNode.length ){
                colorNode = t.target;
            }
            var computedStyle = window.getComputedStyle(colorNode.get(0));
            if( computedStyle.backgroundClip == 'text' ){
                t.state.color = computedStyle.backgroundImage;
            }else{
                t.state.color = computedStyle.color;
            }
            
            // text transform
            var transformNode = t.getSelectionNodeFirst(nodes, 'span', 'text-transform');
            if( !transformNode.length ){
                transformNode = t.getSelectionParent(t.target, false);
            }
            t.state.transform = $.pixeHasStyle(transformNode, 'text-transform');

            // apply state
            t.elem.find('[data-action]').each(function(){
                
                var action = $(this).attr('data-action');

                switch( action ){
                    case 'left':
                    case 'center':
                    case 'right':
                        if( t.state.align == action ){
                            $(this).addClass('pixe-active');
                        }else{
                            $(this).removeClass('pixe-active');
                        }
                        break;
                    case 'bold':
                    case 'italic':
                    case 'underline':
                    case 'strikeThrough':
                    case 'quote':
                    case 'ul':
                    case 'ol':
                    case 'link':
                        if( t.state[action] ){
                            $(this).addClass('pixe-active');
                        }else{
                            $(this).removeClass('pixe-active');
                        }
                        break;
                    case 'color':
                        if( t.state.color ){
                            $(this).children().css({
                                'background': t.state.color
                            });
                        }else{
                            $(this).children().css({'background': ''});
                        }

                }

            });
            t.elem.find('.pixe-action-transform').pixeInputUpdate(t.state.transform, false);
            t.elem.find('[data-slug="length"]').val(t.state.length);
        },

        showToolbar: function(editarea, type){
            var t = this;
            t.type = type;

            if( type == 'plain-text' ){
                t.elem.hide();
                return;
            }else{
                t.elem.attr('data-type', type);
            }

            t.elem.show();
            t.target = editarea;
            t.updateTypoToolbar();
            t.setToolbarPosition();
        },

        setToolbarPosition: function(){
            var t = this;
            
            // position the toolbar
            var screenOffset = 20;
            var screenWidth = window.innerWidth;
            var width = t.elem.outerWidth();
            var height = t.elem.outerHeight();
            var pointerLeftMargin = 0;

            t.elem.removeClass('pixe-bottom');

            // top bottom position
            var topPos = t.target.offset().top - height - 20;
            if( topPos < 0 ){
                topPos = t.target.offset().top + t.target.outerHeight() + 20;
                t.elem.addClass('pixe-bottom');
            }

            // left right position
            var leftPos = t.target.offset().left + (t.target.outerWidth() / 2) - (width / 2);
            if( leftPos <= screenOffset ){ 
                pointerLeftMargin = leftPos - screenOffset;
                leftPos = screenOffset; 
            }else if( leftPos + width >= screenWidth - screenOffset ){
                pointerLeftMargin = leftPos + width - (screenWidth - screenOffset);
                leftPos = screenWidth - screenOffset - width;
            }

            t.elem.css({ top: topPos, left: leftPos });
            t.elem.children('.pixe-inline-toolbar-pointer').css({ 'margin-left': pointerLeftMargin });
        },

        // update typo value for toolbar 1
        updateTypoToolbar: function(){
            var t = this;
            if( !t.target ) return;

            var typo = $.pixeInlineContent.getVal(t.target, 'typo');
            if( !typo ){ typo = {}; }
            
            t.elem.find('.pixe-inline-toolbar1 [data-slug]').each(function(){
                var slug = $(this).attr('data-slug');          

                if( slug == 'preset' ){
                    $(this).pixeInputUpdate(typo['preset'], false);
                    $(this).data('typo', typo);
                }else{
                    $(this).pixeInputUpdate(typo[slug], false);
                }
            });
        },
    };

    ///////////////////
    // inline editor //
    ///////////////////
    $.pixeInlineEdit = {

        // editarea selection change event 
        // delay 5 ms to wait for browser range data
        selectionChange: function(e){
            if( e && e.target && $(e.target).closest('.pixe-popup, .pixe-inline-toolbar, .media-modal').length ) return;
            
            setTimeout(function(){ 
                $.pixeRange.saveSelection();
                $.pixeInlineToolbar.readState();
            }, 5);
        },

        // bind the editable action
        bindElement: function(editarea, type){

            // save selection on change
            $.pixeInlineEdit.selectionChange();
            $(editarea).on('keyup', $.pixeInlineEdit.selectionChange);
            $(document.body).on('mouseup', $.pixeInlineEdit.selectionChange);

            // prevent p tag creation & save selection on change
            if( !type || type == 'content' ){
                editarea.on('keyup', $.pixeInlineEdit.contentKeyUp);
                editarea.on('keydown', $.pixeInlineEdit.contentKeyDown);
                editarea.on('paste', $.pixeInlineEdit.contentPaste);
            }else{
                editarea.on('keydown', $.pixeInlineEdit.titleKeyDown);
                editarea.on('paste', $.pixeInlineEdit.titlePaste);
            }

        },

        // unbind editable action
        unbindElement: function(editarea, type){

            // unbind events
            $(editarea).off('keyup', $.pixeInlineEdit.selectionChange);
            $(document.body).off('mouseup', $.pixeInlineEdit.selectionChange);
            
            if( !type || type == 'content' ){
                editarea.off('keyup', $.pixeInlineEdit.contentKeyUp);
                editarea.off('keydown', $.pixeInlineEdit.contentKeyDown);
                editarea.off('paste', $.pixeInlineEdit.contentPaste);
            }else{
                editarea.off('keydown', $.pixeInlineEdit.titleKeyDown);
                editarea.off('paste', $.pixeInlineEdit.titlePaste);
            }
        },

        // inline title event
        titleKeyDown: function(e){

            // prevent enter from creating new element
            if( e.keyCode == 13 && !e.shiftKey ){
                e.preventDefault();

                var range = $.pixeRange.current;

                if( $.pixeRange.isSinglePoint(range) ){
                    if( range.endOffset == range.endContainer.length ){
                        if( !range.endContainer.nextSibling ){
                            document.execCommand("insertHTML", false, '<br><br>');
                        }else if( range.endContainer.nextSibling.tagName == 'BR' && !range.endContainer.nextSibling.nextSibling ){
                            $.pixeRange.setAfter(range.endContainer.nextSibling);
                            document.execCommand("insertHTML", false, '<br><br>');
                        }else{
                            document.execCommand("insertHTML", false, '<br>');
                        }
                    }else{
                        document.execCommand("insertHTML", false, '<br>');
                    }
                }else{
                    document.execCommand("insertHTML", false, '<br>');
                }
            }
        },
        titlePaste: function(e){
            
            // get text clipboard data
            var text = '';
            var clipboard = e.clipboardData;
            if( !clipboard ){ clipboard = e.originalEvent.clipboardData; }
            if( clipboard ){ 
                text = clipboard.getData('text/plain');    
            }else if( window.clipboardData ){
                text = window.clipboardData.getData('Text');
            }

            // insert text manually
            if( text ){
                e.preventDefault();
                document.execCommand("insertText", false, text);
            }

        },

        // inline content event
        contentKeyUp: function(e){
            var editarea = $(this);

            // replace div with paragraph on enter key
            if( e.keyCode == 13 && !e.shiftKey ){
                var isChanged = false;

                editarea.find('div').each(function(){
                    var pTag = $('<p></p>');
                    pTag.append($(this).contents());
                    $(this).replaceWith(pTag);

                    isChanged = true;
                });

                // update the value
                if( isChanged ){
                    $.pixeInlineContent.setVal(editarea, 'content');
                } 
            }
        },
        contentKeyDown: function(e){
            
            // backspace - prevent removing all html tags
            if( e.keyCode == 8 ){
                var editarea = $(this);
                if( editarea.children().length == 1 ){
                    if( editarea.children().html() == '<br>' ){
                        e.preventDefault();
                    }
                }else{
                    var range = $.pixeRange.current;
                    
                    // for removing to previous blank tag
                    if( $.pixeRange.isSinglePoint(range) && range.startOffset == 0 && !range.startContainer.previousSibling ){
                        console.log(range);
                    }
                }
            }
        },
        contentPaste: function(e){
            
            // get text clipboard data
            var text = '';
            var clipboard = e.clipboardData;
            if( !clipboard ){ clipboard = e.originalEvent.clipboardData; }
            if( clipboard ){
                text = clipboard.getData('text/plain');    
            }else if( window.clipboardData ){
                text = window.clipboardData.getData('Text');
            }
            
            // format html
            // insert text manually
            if( text ){
                e.preventDefault();
                document.execCommand("insertText", false, text);
            }
        },

        // replace html tag
        replaceTag: function(content, from, to){
            
            var newElements = $(); 
            
            $(content).each(function(){
                var wrapElement = $('<' + to + '></' + to + '>');
                wrapElement.insertBefore($(this));
                $(this).appendTo(wrapElement).contents().unwrap(from);

                newElements = newElements.add(wrapElement);
            });

            return newElements;
        }

    };
    $.fn.pixeInlineEdit = function(){

        // init toolbar object
        $.pixeInlineToolbar.init();

        // bind inline editor
        $(this).on('click', '[data-inline-type]', function(){

            // check if there're inner inline target
            function getInlineTarget(ea){
                var inlineTarget = ea.children('.pixe-inline-target');
                if( !inlineTarget.length ){  inlineTarget = ea; }
                return inlineTarget;
            }

            var editarea = $(this);
            var inlineTarget = getInlineTarget(editarea);
            
            // prevent duplicate event
            if( inlineTarget.attr('contentEditable') == 'true' ){ return; }  

            var item = editarea.closest('.pixe-item');
            var type = editarea.attr('data-inline-type');

            // make area editable
            $(document.body).addClass('pixe-inline-editing');
            inlineTarget.attr('contentEditable', 'true').focus();
            editarea.trigger('pixe-inline-init');
            item.addClass('pixe-focus');

            // bind element
            $.pixeInlineToolbar.showToolbar(editarea, type);
            $.pixeInlineEdit.bindElement(editarea, type);
            
            // set mousedown click target ( in case it's different element )
            var mouseDownTarget = null;
            function setInlineTarget(e){ mouseDownTarget = $(e.target); }
            $(document.body).on('mousedown', setInlineTarget);

            // click outside div to unbind edit area
            function closeInlineEvent(){
                $(window).trigger('closeinline');
            }
            function closeInline(e){
                var target = $(e.target);

                // do nothing if click on edit area / inline toolbar / popup
                if( mouseDownTarget && mouseDownTarget.closest(editarea).length ) return;
                if( target.closest(editarea).length ) return;
                if( target.closest('.pixe-inline-toolbar, .pixe-popup').length ) return;
                if( target.closest('.pixe-lb, .supports-drag-drop, .pixe-confirmation').length ) return;

                // unbind editor
                item.removeClass('pixe-focus');
                inlineTarget = getInlineTarget(editarea);
                inlineTarget.removeAttr('contentEditable');
                $.pixeInlineEdit.unbindElement(editarea, type);

                // if not click on another inline area
                if( !target.closest('[data-inline-type]').length ){
                    $(document.body).removeClass('pixe-inline-editing');
                    $.pixeInlineToolbar.elem.hide(); 
                }

                // unbind event
                $(document.body).off('mousedown', setInlineTarget);
                $(window).off('mousedown closeinline', closeInline);
                $(window).off('resize', closeInlineEvent);
            }
			$(window).on('mousedown closeinline',  closeInline);
            $(window).on('resize', closeInlineEvent);

        });

    }

    ////////////////////////////////////////////
    // inline tab
    ////////////////////////////////////////////

    $.pixeInlineTab = {

        getInput: function(type, slug, value, tag = 'div', extraClass){
            
            switch(type){
                case 'text': 
                    var text = $('<' + tag + '></' + tag + '>');
                    text.attr('data-tab-slug', slug);
                    text.attr('data-tab-type', 'text');
                    text.attr('data-inline-type', 'plain-text');
                    text.attr('data-inline-target', 'self');
                    if( value ){ text.append(value); }
                    if( extraClass ){ text.addClass(extraClass); }

                    // event
                    text.on('pixe-inline-init', function(){
                        $.pixeInlineTab.getVal($(this));
                    });
                    text.on('input', function(){
                        $.pixeInlineTab.setVal($(this), slug);
                    });
                    return text;

                case 'data':
                    var data = $('<div></div>');
                    data.attr('data-tab-slug', slug);
                    data.attr('data-tab-type', 'data');
                    data.addClass('pixe-tab-data');
                    if( value ){ data.data('value', value); }
                    if( extraClass ){ data.addClass(extraClass); }

                    // event
                    data.on('beforechange', function(){
                        $.pixeInlineTab.getVal($(this));
                    });
                    data.on('change', function(){
                        $.pixeInlineTab.setVal($(this), slug);
                    });
                    return data;
    
                case 'container':
                    var content = $('<div></div>');
                    content.attr('data-tab-slug', slug);
                    content.attr('data-tab-type', 'container');
                    content.addClass('pixe-tab-container');
                    if( value && value.length ){ 
                        $.pixeEditor.render(value, undefined, undefined, content); 
                    }
                    if( extraClass ){ content.addClass(extraClass); }
                    $.pixeItem.setTabContainerStatus(content);
                    return content;
            }

        },

        updateTabData: function(item){
            var settings = item.data('settings');
            var tabData = {};

            // get tab data
            item.find('[data-tab-slug]').each(function(){
                if( !$(this).closest('.pixe-item').is(item) ) return; // for tab inside tab case

                var slug = $(this).attr('data-tab-slug');
                var type = $(this).attr('data-tab-type');
                if( type == 'text' ){
                    if( !tabData[slug] ){ tabData[slug] = []; }
                    tabData[slug].push($(this).html());
                }else if( type == 'data' ){
                    if( !tabData[slug] ){ tabData[slug] = []; }
                    tabData[slug].push($(this).data('value'));
                }
            });

            // format tab data
            var tab = [];
            var firstKey = Object.keys(tabData)[0];
            if( firstKey ){
                var length = tabData[firstKey].length;
                for(var i = 0; i < length; i++){
                    var t = {};
                    for(var s in tabData){
                        if( tabData[s][i] ){
                            t[s] = tabData[s][i]
                        }
                    }
    
                    tab.push(t);
                }
            }
            settings._tab = tab;
        },

        // update tab data (excluding container) before editing
        getVal: function(tabInput){
            var t = this;
            var item = tabInput.closest('.pixe-item');

            t.updateTabData(item);
            t.editTarget = item;
            t.editHistory = new $.pixeEditHistory(item, {
                debounceTime: 500
            });
        },
        setVal: function(tabInput, type){
            var t = this;
            var item = tabInput.closest('.pixe-item');

            // init history
            if( !t.editTarget || !t.editTarget.is(item) ){
                if( $.pixeDebug ){ console.log("error: cannot add tab data to history"); }
            }else{
                t.updateTabData(item);
                t.editHistory.onChange('_tab', type + ' Edited');
            }

        }

    };

})(jQuery);
