File: //var/www/mussarq_bak/wp-content/plugins/us-header-builder/admin/js/header-builder.js
if (window.$ushb === undefined) window.$ushb = {};
$ushb.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
!function($){
	if (window.$ushb.mixins === undefined) window.$ushb.mixins = {};
	// TODO: replace AJAX URL;
	$ushb.ajaxUrl = $('.us-bld').data('ajaxurl');
	/**
	 * $ushb.Tabs class
	 *
	 * Boundable events: beforeShow, afterShow, beforeHide, afterHide
	 *
	 * @param container
	 * @constructor
	 */
	$ushb.Tabs = function(container){
		this.$container = $(container);
		this.$list = this.$container.find('.usof-tabs-list:first');
		this.$items = this.$list.children('.usof-tabs-item');
		this.$sections = this.$container.find('.usof-tabs-section');
		this.items = this.$items.toArray().map($);
		this.sections = this.$sections.toArray().map($);
		this.active = 0;
		this.items.forEach(function($elm, index){
			$elm.on('click', this.open.bind(this, index));
		}.bind(this));
	};
	$.extend($ushb.Tabs.prototype, $usof.mixins.Events, {
		open: function(index){
			if (index == this.active || this.sections[index] == undefined) return;
			if (this.sections[this.active] !== undefined) {
				this.trigger('beforeHide', this.active, this.sections[this.active], this.items[this.active]);
				this.sections[this.active].hide();
				this.items[this.active].removeClass('active');
				this.trigger('afterHide', this.active, this.sections[this.active], this.items[this.active]);
			}
			this.trigger('beforeShow', index, this.sections[index], this.items[index]);
			this.sections[index].show();
			this.items[index].addClass('active');
			this.trigger('afterShow', index, this.sections[index], this.items[index]);
			this.active = index;
		}
	});
	/**
	 * $ushb.EForm class
	 * @param container
	 * @constructor
	 */
	$ushb.EForm = function(container){
		this.$container = $(container);
		this.$tabs = this.$container.find('.usof-tabs');
		if (this.$tabs.length) {
			this.tabs = new $ushb.Tabs(this.$tabs);
		}
		this.initFields(this.$container);
	};
	$.extend($ushb.EForm.prototype, $usof.mixins.Fieldset);
	/**
	 * $ushb.Elist class: A popup with elements list to choose from. Behaves as a singleton.
	 * Boundable events: beforeShow, afterShow, beforeHide, afterHide, select
	 * @constructor
	 */
	$ushb.EList = function(){
		if ($ushb.elist !== undefined) return $ushb.elist;
		this.$container = $('.us-bld-window.for_adding');
		if (this.$container.length > 0) {
			this.$container.appendTo($(document.body));
			this.init();
		}
	};
	$.extend($ushb.EList.prototype, $usof.mixins.Events, {
		init: function(){
			this.$closer = this.$container.find('.us-bld-window-closer');
			this.$list = this.$container.find('.us-bld-window-list');
			this._events = {
				select: function(event){
					var $item = $(event.target).closest('.us-bld-window-item');
					this.hide();
					this.trigger('select', $item.data('name'));
				}.bind(this),
				hide: this.hide.bind(this)
			};
			this.$closer.on('click', this._events.hide);
			this.$list.on('click', '.us-bld-window-item', this._events.select);
		},
		show: function(){
			if (this.$container.length == 0) {
				// Loading elements list html via ajax
				$.ajax({
					type: 'post',
					url: $ushb.ajaxUrl,
					data: {
						action: 'ushb_get_elist_html'
					},
					success: function(html){
						this.$container = $(html).css('display', 'none').appendTo($(document.body));
						this.init();
						this.show();
					}.bind(this)
				});
				return;
			}
			this.trigger('beforeShow');
			this.$container.css('display', 'block');
			this.trigger('afterShow');
		},
		hide: function(){
			this.trigger('beforeHide');
			this.$container.css('display', 'none');
			this.trigger('afterHide');
		}
	});
	// Singleton instance
	$ushb.elist = new $ushb.EList;
	/**
	 * $ushb.EBuilder class: A popup with loadable elements forms
	 * Boundable events: beforeShow, afterShow, beforeHide, afterHide, save
	 * @constructor
	 */
	$ushb.EBuilder = function(){
		this.$container = $('.us-bld-window.for_editing');
		this.loaded = false;
		if (this.$container.length != 0) {
			this.$container.appendTo($(document.body));
			this.init();
		}
	};
	$.extend($ushb.EBuilder.prototype, $usof.mixins.Events, {
		init: function(){
			this.$title = this.$container.find('.us-bld-window-title');
			this.titles = this.$title[0].onclick() || {};
			this.$title.removeAttr('onclick');
			this.$closer = this.$container.find('.us-bld-window-closer, .us-bld-window-btn.for_close');
			this.$header = this.$container.find('.us-bld-window-header');
			// EForm containers and class instances
			this.$eforms = {};
			this.eforms = {};
			// Set of default values for each elements form
			this.defaults = {};
			this.$container.find('.usof-form').each(function(index, eform){
				var $eform = $(eform).css('display', 'none'),
					name = $eform.usMod('for');
				this.$eforms[name] = $eform;
			}.bind(this));
			this.$btnSave = this.$container.find('.us-bld-window-btn.for_save');
			// Actve element
			this.active = false;
			this._events = {
				hide: this.hide.bind(this),
				save: this.save.bind(this)
			};
			this.$closer.on('click', this._events.hide);
			this.$btnSave.on('click', this._events.save);
		},
		/**
		 * Show element form for a specified element name and initial values
		 * @param {String} name
		 * @param {Object} values
		 */
		show: function(name, values){
			if (this.$container.css('display') == 'block') {
				// If some other form is already shown, hiding it before proceeding
				this.hide();
			}
			if (!this.loaded) {
				this.$title.html(this.titles[name] || '');
				this.$container.css('display', 'block');
				// Loading ebuilder and initial form's html
				$.ajax({
					type: 'post',
					url: $ushb.ajaxUrl,
					data: {
						action: 'ushb_get_ebuilder_html'
					},
					success: function(html){
						if (html == '') return;
						// Removing additionally appended assets
						var regexp = /(\<link rel=\'stylesheet\' id=\'([^\']+)\'[^\>]+?\>)|(\<style type\=\"text\/css\"\>([^\<]*)\<\/style\>)|(\<script type=\'text\/javascript\' src=\'([^\']+)\'\><\/script\>)|(\<script type\=\'text\/javascript\'\>([^`]*?)\<\/script\>)/g;
						html = html.replace(regexp, '');
						this.$container.remove();
						this.$container = $(html).css('display', 'none').addClass('loaded').appendTo($(document.body));
						this.loaded = true;
						this.init();
						this.show(name, values);
					}.bind(this)
				});
				return;
			}
			if (this.eforms[name] === undefined) {
				// Initializing EForm on the first show
				if (this.$eforms[name] === undefined) return;
				this.eforms[name] = new $ushb.EForm(this.$eforms[name]);
				this.defaults[name] = this.eforms[name].getValues();
			}
			// Filling missing values with defaults
			values = $.extend({}, this.defaults[name], values);
			this.eforms[name].setValues(values);
			if (this.eforms[name].tabs !== undefined) {
				this.eforms[name].tabs.$list.appendTo(this.$header);
				this.eforms[name].tabs.open(0);
			}
			this.$container.toggleClass('with_tabs', this.eforms[name].tabs !== undefined);
			this.$eforms[name].css('display', 'block');
			this.$title.html(this.titles[name] || '');
			this.active = name;
			this.trigger('beforeShow');
			this.$container.css('display', 'block');
			this.trigger('afterShow');
		},
		hide: function(){
			this.trigger('beforeHide');
			this.$container.css('display', 'none');
			if (this.$eforms[this.active] !== undefined) this.$eforms[this.active].css('display', 'none');
			this.trigger('afterHide');
			if (this.eforms[this.active].tabs !== undefined) {
				this.eforms[this.active].tabs.$list.prependTo(this.eforms[this.active].$tabs);
			}
		},
		/**
		 * Get values of the active form
		 * @return {Object}
		 */
		getValues: function(){
			return (this.eforms[this.active] !== undefined) ? this.eforms[this.active].getValues() : {};
		},
		/**
		 * Get default values of the active form
		 * @return {Object}
		 */
		getDefaults: function(){
			return (this.defaults[this.active] || {});
		},
		save: function(){
			this.hide();
			this.trigger('save', this.getValues(), this.getDefaults());
		}
	});
	// Singletone instance
	$ushb.ebuilder = new $ushb.EBuilder;
	/**
	 * $ushb.ExportImport class: a popup with Export/Import dialog
	 * Boundable events: beforeShow, afterShow, beforeHide, afterHide, import
	 * @constructor
	 */
	$ushb.ExportImport = function(){
		this.$body = $(document.body);
		this.$container = $('.us-bld-window.for_export_import');
		if (this.$container.length != 0) {
			this.$container.appendTo(this.$body);
			this.init();
		}
	};
	$.extend($ushb.ExportImport.prototype, $usof.mixins.Events, {
		init: function(){
			this.$closer = this.$container.find('.us-bld-window-closer');
			this.$closeButton = this.$container.find('.us-bld-window-btn.for_close');
			this.$importButton = this.$container.find('.us-bld-window-btn.for_save');
			this.$row = this.$container.find('.usof-form-row').first();
			this.$rowState = this.$row.find('.usof-form-row-state');
			this.$textarea = this.$row.find('textarea');
			this.error = false;
			this._events = {
				import: function(event){
					var data = this.$textarea.val();
					if (data.charAt(0) == '{') {
						try {
							data = JSON.parse(data);
							if (data) {
								this.trigger('import', 'import', data);
								this.hide();
							}
						} catch (error) {
							this.error = true;
						}
					} else {
						this.error = true;
					}
					if (this.error) {
						this.$row.addClass('validate_error');
					}
				}.bind(this),
				hide: this.hide.bind(this)
			};
			this.$closer.on('click', this._events.hide);
			this.$closeButton.on('click', this._events.hide);
			this.$importButton.on('click', this._events.import);
		},
		show: function(value){
			this.$textarea.val(value);
			this.trigger('beforeShow');
			this.$container.css('display', 'block');
			this.trigger('afterShow');
		},
		hide: function(){
			this.trigger('beforeHide');
			this.$row.removeClass('validate_error');
			this.$container.css('display', 'none');
			this.trigger('afterHide');
		}
	});
	// Singletone instance
	$ushb.exportimport = new $ushb.ExportImport;
	/**
	 * $ushb.HTemplates class: a popup with header templates
	 * Boundable events: beforeShow, afterShow, beforeHide, afterHide, select
	 * @constructor
	 */
	$ushb.HTemplates = function(){
		this.$body = $(document.body);
		this.$container = $('.us-bld-window.for_templates');
		this.loaded = false;
		if (this.$container.length != 0) {
			this.$container.appendTo(this.$body);
			this.init();
		}
	};
	$.extend($ushb.HTemplates.prototype, $usof.mixins.Events, {
		init: function(){
			this.$closer = this.$container.find('.us-bld-window-closer');
			this.$list = this.$container.find('.us-bld-window-list');
			this._events = {
				select: function(event){
					var $item = $(event.target).closest('.us-bld-window-item');
					if ($ushb.instance.value.data && Object.keys($ushb.instance.value.data).length && !confirm($ushb.instance.translations['template_replace_confirm'])) return;
					this.hide();
					var data = $item.find('.us-bld-window-item-data')[0].onclick();
					this.trigger('select', $item.data('name'), data);
				}.bind(this),
				hide: this.hide.bind(this)
			};
			this.$closer.on('click', this._events.hide);
			this.$list.on('click', '.us-bld-window-item', this._events.select);
		},
		show: function(){
			if (!this.loaded) {
				this.$container.css('display', 'block');
				// Loading elements list html via ajax
				$.ajax({
					type: 'post',
					url: $ushb.ajaxUrl,
					data: {
						action: 'ushb_get_htemplates_html'
					},
					success: function(html){
						this.$container.remove();
						this.$container = $(html).css('display', 'none').addClass('loaded').appendTo($(document.body));
						this.loaded = true;
						this.init();
						this.show();
					}.bind(this)
				});
				return;
			}
			this.trigger('beforeShow');
			this.$container.css('display', 'block');
			this.$body.addClass('us-popup');
			this.trigger('afterShow');
		},
		hide: function(){
			this.trigger('beforeHide');
			this.$body.removeClass('us-popup');
			this.$container.css('display', 'none');
			this.trigger('afterHide');
		}
	});
	// Singletone instance
	$ushb.htemplates = new $ushb.HTemplates;
	/**
	 * Side settings
	 */
	var HBOptions = function(container){
		this.$container = $(container);
		this.$sections = this.$container.find('.us-bld-options-section');
		this.$sections.not('.active').children('.us-bld-options-section-content').slideUp();
		this.$container.find('.us-bld-options-section-title').click(function(event){
			var $parentSection = $(event.target).parent();
			if ($parentSection.hasClass('active')) return;
			var $previousActive = this.$sections.filter('.active');
			this.fireFieldEvent($previousActive, 'beforeHide');
			$previousActive.removeClass('active').children('.us-bld-options-section-content').slideUp(function(){
				this.fireFieldEvent($previousActive, 'afterHide');
			}.bind(this));
			this.fireFieldEvent($parentSection, 'beforeShow');
			$parentSection.addClass('active').children('.us-bld-options-section-content').slideDown(function(){
				this.fireFieldEvent($parentSection, 'afterShow');
			}.bind(this));
		}.bind(this));
		this.$container.find('.usof-subform-row, .usof-subform-wrapper').each(function(index, elm){
			elm.className = elm.className.replace('usof-subform-', 'usof-form-');
		});
		this.initFields(this.$container);
		var activeSection = this.$sections.filter('.active');
		this.fireFieldEvent(activeSection, 'beforeShow');
		this.fireFieldEvent(activeSection, 'afterShow');
	};
	$.extend(HBOptions.prototype, $usof.mixins.Fieldset, {
		getValue: function(id){
			if (id == 'state') return $ushb.instance.state;
			if (this.fields[id] === undefined) return undefined;
			return this.fields[id].getValue();
		}
	});
	/**
	 * USOF Field: Header Builder
	 */
	$usof.field['header_builder'] = {
		init: function(options){
			$ushb.instance = this;
			this.parentInit(options);
			this.$container = this.$row.find('.us-bld');
			this.$workspace = this.$container.find('.us-bld-workspace');
			this.$body = $(document.body);
			this.$window = $(window);
			this.$editor = $('.us-bld-editor');
			this.$dragshadow = $('<div class="us-bld-editor-dragshadow"></div>');
			this.$rows = this.$container.find('.us-bld-editor-row');
			this.$stateTabs = this.$container.find('.us-bld-state');
			this.params = this.$container.find('.us-bld-params')[0].onclick() || {};
			this.elmsDefaults = this.$container.find('.us-bld-defaults')[0].onclick() || {};
			this.translations = this.$container.find('.us-bld-translations')[0].onclick() || {};
			this.value = this.$container.find('.us-bld-value')[0].onclick() || {};
			this.states = ['default', 'tablets', 'mobiles'];
			this.state = 'default';
			this._events = {
				_maybeDragMove: this._maybeDragMove.bind(this),
				_dragMove: this._dragMove.bind(this),
				_dragEnd: this._dragEnd.bind(this)
			};
			this.$places = {hidden: this.$editor.find('.us-bld-editor-row.for_hidden > .us-bld-editor-row-h')};
			this.$editor.find('.us-bld-editor-cell').each(function(index, cell){
				var $cell = $(cell);
				this.$places[$cell.parent().parent().usMod('at') + '_' + $cell.usMod('at')] = $cell;
			}.bind(this));
			this.$wrappers = {};
			this.$editor.find('.us-bld-editor-wrapper').each(function(index, wrapper){
				var $wrapper = $(wrapper);
				this.$wrappers[$wrapper.data('id')] = $wrapper;
			}.bind(this));
			this.$elms = {};
			this.$editor.find('.us-bld-editor-elm').each(function(index, elm){
				var $elm = $(elm);
				this.$elms[$elm.data('id')] = $elm;
			}.bind(this));
			this.$templatesBtn = $('.usof-control.for_templates').on('click', this._showTemplatesBtnClick.bind(this));
			$('.usof-control.for_import').on('click', this._showExportImportBtnClick.bind(this));
			// Elements modification events
			this.$container.on('click', '.us-bld-editor-add, .us-bld-editor-control.type_add, .us-bld-editor-wrapper-content:empty', this._addBtnClick.bind(this));
			this.$container.on('click', '.us-bld-editor-control.type_edit', this._editBtnClick.bind(this));
			this.$container.on('click', '.us-bld-editor-control.type_clone', this._cloneBtnClick.bind(this));
			this.$container.on('mousedown', '.us-bld-editor-elm, .us-bld-editor-wrapper', this._dragStart.bind(this));
			this.$container.on('click', '.us-bld-editor-control.type_delete', this._deleteBtnClick.bind(this));
			// Preventing browser native drag event
			this.$container.on('dragstart', function(event){
				event.preventDefault();
			});
			// Options that has no responsive values
			this.sharedOptions = ['top_fullwidth', 'middle_fullwidth', 'bottom_fullwidth'];
			this.sideOptions = new HBOptions(this.$container.find('.us-bld-options:first'));
			$.each(this.sideOptions.fields, function(fieldId, field){
				field.on('change', this._optionChanged.bind(this));
			}.bind(this));
			this.sideOptions.fields.orientation.$row.find('label').on('click', function(event){
				if (!confirm(this.translations['orientation_change_confirm'])) event.preventDefault();
			}.bind(this));
			// State togglers
			this.$stateTabs.on('click', function(event){
				var $stateTab = $(event.target),
					newState = $stateTab.usMod('for');
				this.setState(newState);
			}.bind(this));
			// Highlight rows on side options hover
			this.$container.find('.us-bld-options-section').each(function(index, section){
				var $section = $(section),
					id = $section.data('id');
				$section.hover(function(){
					this.$editor.addClass('highlight_' + id);
				}.bind(this), function(){
					this.$editor.removeClass('highlight_' + id);
				}.bind(this));
			}.bind(this));
			// Showing templates for empty case
			if (!this.value.data || !Object.keys(this.value.data).length) this.$templatesBtn.addClass('start');
		},
		setValue: function(value){
			// Fixing missing datas
			if (!value) value = {};
			if (value.data === undefined) value.data = {};
			if (value.default === undefined) value.default = {};
			if (value.default.options === undefined) value.default.options = {};
			this.value = $.extend({}, value);
			this.setState('default', true);
		},
		getValue: function(){
			return this.value;
		},
		/**
		 * Buttons events
		 */
		_addBtnClick: function(event){
			var $target = $(event.target),
				placeType, place;
			if ($target.hasClass('us-bld-editor-add')) {
				var $cell = $target.closest('.us-bld-editor-cell');
				place = $cell.parent().parent().usMod('at') + '_' + $cell.usMod('at');
				placeType = 'cell';
			} else {
				place = $target.closest('.us-bld-editor-wrapper').data('id');
				placeType = place.split(':')[0];
			}
			$ushb.elist.off('beforeShow').on('beforeShow', function(){
				$ushb.elist.$container
					.toggleClass('hide_search', this.value.data['search:1'] !== undefined)
					.toggleClass('hide_cart', this.value.data['cart:1'] !== undefined)
					.usMod('orientation', this.value[this.state].options.orientation)
					.usMod('addto', placeType);
			}.bind(this));
			$ushb.elist.off('select').on('select', function(elist, type){
				var elmId = this.createElement(place, type);
				// Opening editing form for standard elements
				if (type.substr(1) != 'wrapper') {
					this.$elms[elmId].find('.us-bld-editor-control.type_edit').trigger('click');
				}
			}.bind(this));
			$ushb.elist.show();
		},
		_editBtnClick: function(event){
			var $target = $(event.target),
				$elm = $target.closest('.us-bld-editor-elm, .us-bld-editor-wrapper'),
				id = $elm.data('id'),
				type = id.split(':')[0],
				values = (this.value.data[id] || {});
			$ushb.ebuilder.off('save').on('save', function(ebuilder, values, defaults){
				this.updateElement(id, values);
			}.bind(this));
			$ushb.ebuilder.show(type, values);
		},
		_cloneBtnClick: function(event){
			var $target = $(event.target),
				$elm = $target.closest('.us-bld-editor-elm, .us-bld-editor-wrapper'),
				id = $elm.data('id'),
				type = id.split(':')[0];
			// createElement: function(place, type, index, values){
			var newId = this.createElement('top_left', type, undefined, this.value.data[id] || {});
			this.states.forEach(function(state){
				this.moveElement(newId, id, 'after', state);
			}.bind(this));
		},
		_deleteBtnClick: function(event){
			var $target = $(event.target);
			if (!confirm(this.translations['element_delete_confirm'])) return;
			var id = $target.parent().parent().data('id');
			this.deleteElement(id);
		},
		_showTemplatesBtnClick: function(event){
			if (event !== undefined) event.preventDefault();
			$ushb.htemplates.off('select').on('select', function(dialog, name, data){
				this.setValue(data);
				this.trigger('change', this.value);
			}.bind(this));
			$ushb.htemplates.show();
			this.$templatesBtn.removeClass('start');
		},
		_showExportImportBtnClick: function(event){
			event.preventDefault();
			$ushb.exportimport.off('import').on('import', function(dialog, name, data){
				this.setValue(data);
				this.trigger('change', this.value);
			}.bind(this));
			$ushb.exportimport.show(JSON.stringify(this.getValue()));
		},
		// Drag'n'drop functions
		_dragStart: function(event){
			event.stopPropagation();
			this.$draggedElm = $(event.target).closest('.us-bld-editor-elm, .us-bld-editor-wrapper');
			this.elmType = this.$draggedElm.data('id').split(':')[0];
			this.detached = false;
			this._updateBlindSpot(event);
			this.elmPointerOffset = [parseInt(event.pageX), parseInt(event.pageY)];
			this.$body.on('mousemove', this._events._maybeDragMove);
			this.$window.on('mouseup', this._events._dragEnd);
		},
		_updateBlindSpot: function(event){
			this.blindSpot = [event.pageX, event.pageY];
		},
		_isInBlindSpot: function(event){
			return Math.abs(event.pageX - this.blindSpot[0]) <= 20 && Math.abs(event.pageY - this.blindSpot[1]) <= 20;
		},
		_maybeDragMove: function(event){
			event.stopPropagation();
			if (this._isInBlindSpot(event)) return;
			this.$body.off('mousemove', this._events._maybeDragMove);
			this._detach();
			this.$body.on('mousemove', this._events._dragMove);
		},
		_dragMove: function(event){
			event.stopPropagation();
			this.$draggedElm.css({
				left: event.pageX - this.elmPointerOffset[0],
				top: event.pageY - this.elmPointerOffset[1]
			});
			if (this._isInBlindSpot(event)) return;
			var elm = event.target;
			// Checking two levels up
			for (var level = 0; level <= 2; level++, elm = elm.parentNode) {
				if (this._isShadow(elm)) return;
				// Workaround for IE9-10 that don't support css pointer-events property
				if (this._hasClass(elm, 'detached')) {
					this.$draggedElm.detach();
					break;
				}
				var parentType;
				if (this._isSortable(elm)) {
					parentType = this._isWrapperContent(elm.parentNode) ? ($(elm).parent().parent().usMod('type')[0] + 'wrapper') : 'cell';
					if (!this._canBeDropped(this.elmType, parentType)) break;
					// Dropping element before or after sortables based on their relative position in DOM
					var nextElm = elm.previousSibling,
						shadowAtLeft = false;
					while (nextElm) {
						if (nextElm == this.$dragshadow[0]) {
							shadowAtLeft = true;
							break;
						}
						nextElm = nextElm.previousSibling;
					}
					this.$dragshadow[shadowAtLeft ? 'insertAfter' : 'insertBefore'](elm);
					this._dragDrop(event);
					break;
				} else if (this._isWrapperContent(elm)) {
					if ($.contains(elm, this.$dragshadow[0])) break;
					parentType = $(elm).parent().usMod('type')[0] + 'wrapper';
					if (!this._canBeDropped(this.elmType, parentType)) break;
					// Cannot drop a wrapper to the wrapper of the same type
					this.$dragshadow.appendTo(elm);
					this._dragDrop(event);
					break;
				} else if (this._isControls(elm)) {
					if (!this._canBeDropped(this.elmType, 'cell')) break;
					// Always dropping element before controls
					this.$dragshadow.insertBefore(elm);
					this._dragDrop(event);
					break;
				} else if (this._hasClass(elm, 'us-bld-editor-cell')) {
					if (!this._canBeDropped(this.elmType, 'cell')) break;
					// If not already in this cell, moving to it
					var $shadowCell = this.$dragshadow.closest('.us-bld-editor-cell');
					if ($shadowCell.length == 0 || $shadowCell[0] != elm) {
						this.$dragshadow.insertBefore($(elm).find('.us-bld-editor-add'));
						this._dragDrop(event);
					}
					break;
				} else if (this._hasClass(elm, 'us-bld-editor-row for_hidden')) {
					// Moving to hidden elements container directly
					if (!this.$dragshadow.closest('.us-bld-editor-row').hasClass('for_hidden')) {
						this.$dragshadow.appendTo($(elm).children('.us-bld-editor-row-h'));
						this._dragDrop(event);
					}
					break;
				}
			}
		},
		_detach: function(event){
			var offset = this.$draggedElm.offset();
			this.elmPointerOffset[0] -= offset.left;
			this.elmPointerOffset[1] -= offset.top;
			this.$dragshadow.css({
				width: this.$draggedElm.outerWidth(),
				height: this.$draggedElm.outerHeight()
			}).insertBefore(this.$draggedElm);
			this.$draggedElm.addClass('detached').css({
				position: 'absolute',
				'pointer-events': 'none',
				zIndex: 10000,
				width: this.$draggedElm.width(),
				height: this.$draggedElm.height()
			}).css(offset).appendTo(this.$body);
			this.$editor.addClass('dragstarted');
			this.detached = true;
		},
		/**
		 * Complete drop
		 * @param event
		 */
		_dragDrop: function(event){
			this.$container.find('.us-bld-editor-wrapper').removeClass('empty').find('.us-bld-editor-wrapper-content:empty').parent().addClass('empty');
			this._updateBlindSpot(event);
		},
		_dragEnd: function(event){
			this.$body.off('mousemove', this._events._maybeDragMove).off('mousemove', this._events._dragMove);
			this.$window.off('mouseup', this._events._dragEnd);
			if (this.detached) {
				this.$draggedElm.removeClass('detached').removeAttr('style').insertBefore(this.$dragshadow);
				this.$dragshadow.detach();
				this.$editor.removeClass('dragstarted');
				// Getting the new element position and performing the actual drag
				var elmId = this.$draggedElm.data('id'),
					$prev = this.$draggedElm.prev();
				if ($prev.length == 0) {
					var $parent = this.$draggedElm.parent().closest('.us-bld-editor-cell, .us-bld-editor-wrapper, .us-bld-editor-row.for_hidden'),
						place = 'hidden';
					if ($parent.hasClass('us-bld-editor-cell')) {
						place = $parent.parent().parent().usMod('at') + '_' + $parent.usMod('at');
					} else if ($parent.hasClass('us-bld-editor-wrapper')) {
						place = $parent.data('id');
					}
					this.moveElement(elmId, place, 'first_child')
				} else {
					this.moveElement(elmId, $prev.data('id'), 'after');
				}
			}
		},
		_hasClass: function(elm, cls){
			return (' ' + elm.className + ' ').indexOf(' ' + cls + ' ') > -1;
		},
		_isShadow: function(elm){
			return this._hasClass(elm, 'us-bld-editor-dragshadow');
		},
		_isSortable: function(elm){
			return this._hasClass(elm, 'us-bld-editor-elm') || this._hasClass(elm, 'us-bld-editor-wrapper');
		},
		_isWrapperContent: function(elm){
			return this._hasClass(elm, 'us-bld-editor-wrapper-content');
		},
		_isControls: function(elm){
			return this._hasClass(elm, 'us-bld-editor-add');
		},
		_canBeDropped: function(elmType, placeType){
			if (elmType == 'hwrapper') {
				if (placeType == 'hwrapper') return false;
				if (placeType == 'cell' && this.value[this.state].options.orientation == 'hor') return false;
			}
			else if (elmType == 'vwrapper') {
				if (placeType == 'vwrapper') return false;
				if (placeType == 'cell' && this.value[this.state].options.orientation == 'ver') return false;
			}
			return true;
		},
		setState: function(newState, force){
			if (newState == this.state && !force) return;
			// Changing the active tab setting
			this.$stateTabs.removeClass('active').filter('.for_' + newState).addClass('active');
			this.$workspace.usMod('for', newState);
			this.state = newState;
			// Changing side options view
			if (this.value[newState].options !== undefined) {
				var options = $.extend({}, this.value[newState].options);
				if (newState != 'default') {
					for (var i = 0; i < this.sharedOptions.length; i++) {
						options[this.sharedOptions[i]] = this.value.default.options[this.sharedOptions[i]];
					}
				}
				this.setOptions(options);
			}
			this.renderLayout();
		},
		/**
		 * Create element at the end of the specified place
		 * @param {String} place Place Cell name or wrapper ID
		 * @param {String} type Element type Element type
		 * @param {Number} [index] Element index, starting from 1. If not set will be generated automatically.
		 * @param {Object} [values] Element values
		 * @returns {String} New element ID
		 * @private
		 */
		createElement: function(place, type, index, values){
			if (index === undefined) {
				// If index is not defined generating a spare one
				index = 1;
				while (this.value.data[type + ':' + index] !== undefined) index++;
			}
			var id = type + ':' + index;
			for (var i = 0, state = this.states[i]; i < this.states.length; state = this.states[++i]) {
				if (this.value[state] === undefined) this.value[state] = {};
				if (this.value[state].layout === undefined) this.value[state].layout = {};
				if (this.value[state].layout[place] === undefined) this.value[state].layout[place] = [];
				this.value[state].layout[place].push(id);
				if (type.substr(1) == 'wrapper') this.value[state].layout[id] = [];
			}
			this.value.data[id] = $.extend({}, this.elmsDefaults[type] || {}, values || {});
			this.renderLayout();
			this.trigger('change', this.value);
			return id;
		},
		/**
		 * Move a specified element to a specified place
		 * @param {String} id Element ID
		 * @param {String} place Cell name or element ID
		 * @param {String} [position] Relation to place: "last_child" / "first_child" / "before" / "after"
		 * @param {String} [state] If not specified, the current active state will be used
		 * @private
		 */
		moveElement: function(id, place, position, state){
			if (this.value.data[id] === undefined) return;
			position = position || 'last_child';
			state = state || this.state;
			if (this.value[state] === undefined) this.value[state] = {};
			if (this.value[state].layout === undefined) this.value[state].layout = {};
			// Cropping out the element from the previous place ...
			var plc, elmPos;
			for (plc in this.value[state].layout) {
				if (!this.value[state].layout.hasOwnProperty(plc)) continue;
				elmPos = this.value[state].layout[plc].indexOf(id);
				if (elmPos != -1) {
					this.value[state].layout[plc].splice(elmPos, 1);
					break;
				}
			}
			// ... and placing it to the new one
			if (position == 'first_child' || position == 'last_child') {
				if (this.value[state].layout[place] === undefined) this.value[state].layout[place] = [];
				this.value[state].layout[place][(position == 'first_child') ? 'unshift' : 'push'](id);
			} else if (position == 'before' || position == 'after') {
				for (plc in this.value[state].layout) {
					if (!this.value[state].layout.hasOwnProperty(plc)) continue;
					elmPos = this.value[state].layout[plc].indexOf(place);
					if (elmPos != -1) {
						this.value[state].layout[plc].splice(elmPos + ((position == 'after') ? 1 : 0), 0, id);
						break;
					}
				}
			}
			this.renderLayout();
			this.trigger('change', this.value);
		},
		/**
		 * Update the specified element's values
		 * @param {String} id Element ID
		 * @param {Object} values Element values
		 * @private
		 */
		updateElement: function(id, values){
			var type = id.split(':')[0];
			this.value.data[id] = $.extend({}, this.elmsDefaults[type] || {}, values);
			var $elm = this[(type.substr(1) == 'wrapper') ? '$wrappers' : '$elms'][id];
			if ($elm !== undefined) {
				this._updateElementPlaceholder($elm, id, this.value.data[id]);
			}
			this.trigger('change', this.value);
		},
		/**
		 * Delete the specified element
		 * @param {String} id Element ID
		 * @private
		 */
		deleteElement: function(id){
			var type = id.split(':')[0];
			for (var i = 0, state = this.states[i]; i < this.states.length; state = this.states[++i]) {
				if (this.value[state] === undefined) this.value[state] = {};
				if (this.value[state].layout === undefined) this.value[state].layout = {};
				if (this.value[state].layout.hidden === undefined) this.value[state].layout.hidden = [];
				if (id.substr(1, 7) == 'wrapper' && this.value[state].layout[id] !== undefined) {
					// Moving wrapper's inner elements to hidden block
					this.value[state].layout.hidden = this.value[state].layout.hidden.concat(this.value[state].layout[id]);
					delete this.value[state].layout[id];
				}
				for (var plc in this.value[state].layout) {
					if (!this.value[state].layout.hasOwnProperty(plc)) continue;
					var elmPos = this.value[state].layout[plc].indexOf(id);
					if (elmPos != -1) {
						this.value[state].layout[plc].splice(elmPos, 1);
						break;
					}
				}
			}
			if (this.value.data[id] !== undefined) delete this.value.data[id];
			this.renderLayout();
			this.trigger('change', this.value);
		},
		/**
		 * Load attachments withing the given jQuery DOM object
		 * @param {jQuery} $html
		 */
		_loadAttachments: function($html){
			$html.find('img[data-wpattachment]').each(function(index, elm){
				var $elm = $(elm),
					id = $elm.data('wpattachment'),
					attachment = wp.media.attachment(id);
				if (!attachment || !attachment.attributes.id) return '';
				var renderAttachmentImage = function(){
					var src = attachment.attributes.url;
					if (attachment.attributes.sizes !== undefined) {
						var size = (attachment.attributes.sizes.medium !== undefined) ? 'medium' : 'full';
						src = attachment.attributes.sizes[size].url;
					}
					$elm.attr('src', src).removeAttr('data-wpattachment');
				};
				if (attachment.attributes.url !== undefined) {
					renderAttachmentImage();
				} else {
					// Loading missing data via ajax
					attachment.fetch({success: renderAttachmentImage});
				}
			}.bind(this));
		},
		/**
		 * Create a base part of elements DOM placeholder: the one that doesn't depend on values
		 * @param {String} id
		 * @returns {jQuery} Created (but not placed to document) placeholder's DOM element
		 * @private
		 */
		_createElementPlaceholderBase: function(id){
			var type = id.split(':')[0],
				html = '';
			if (type.substr(1) == 'wrapper') {
				// Wrappers
				html += '<div class="us-bld-editor-wrapper type_' + ((type == 'hwrapper') ? 'horizontal' : 'vertical') + ' empty">';
				html += '<div class="us-bld-editor-wrapper-content"></div>';
				html += '<div class="us-bld-editor-wrapper-controls">';
				html += '<a title="' + this.translations['add_element'] + '" class="us-bld-editor-control type_add" href="javascript:void(0)"></a>';
				html += '<a title="' + this.translations['edit_wrapper'] + '" class="us-bld-editor-control type_edit" href="javascript:void(0)"></a>';
				html += '<a title="' + this.translations['delete_wrapper'] + '" class="us-bld-editor-control type_delete" href="javascript:void(0)"></a>';
				html += '</div>';
				html += '</div>';
				this.$wrappers[id] = $(html).data('id', id);
				return this.$wrappers[id];
			} else {
				// Standard elements
				html += '<div class="us-bld-editor-elm type_' + type + '">';
				html += '<div class="us-bld-editor-elm-content"></div>';
				html += '<div class="us-bld-editor-elm-controls">';
				html += '<a href="javascript:void(0)" class="us-bld-editor-control type_edit" title="' + this.translations['edit_element'] + '"></a>';
				html += '<a href="javascript:void(0)" class="us-bld-editor-control type_clone" title="' + this.translations['clone_element'] + '"></a>';
				html += '<a href="javascript:void(0)" class="us-bld-editor-control type_delete" title="' + this.translations['delete_element'] + '"></a>';
				html += '</div>';
				html += '</div>';
				this.$elms[id] = $(html).data('id', id);
				return this.$elms[id];
			}
		},
		/**
		 * Update element DOM placeholder with the current values
		 * @param {jQuery} $elm
		 * @param {String} id
		 * @param {Object} values
		 * @private
		 */
		_updateElementPlaceholder: function($elm, id, values){
			if (id.substr(1, 7) == 'wrapper') return;
			values = $.extend({}, this.elmsDefaults[type] || {}, values || {});
			var type = id.split(':')[0],
				$content = $elm.find('.us-bld-editor-elm-content:first'),
				content = '';
			if (type == 'text' && (values.text || values.icon)) {
				if (values.icon) {
					content += $usof.instance.prepareIconTag(values.icon);
				}
				// Strip tags
				content += values.text.replace(/(\r\n|\n|\r)+/gm, ' ').replace(/<\/?([^>]+)?>/gi, '');
			} else if (type == 'image') {
				if (values.img) {
					var imgValue = values.img;
					if (imgValue.indexOf('|') != -1) imgValue = imgValue.substr(0, imgValue.indexOf('|'));
					if ($.isNumeric(imgValue)) {
						content += '<img src="" data-wpattachment="' + imgValue + '" />';
					} else {
						content += '<img src="' + imgValue + '" />';
					}
				} else {
					content += '<i class="fa fa-image"></i>';
				}
			} else if (type == 'menu') {
				if (values.source) {
					content += this.params.navMenus[values.source] || values.source;
				} else {
					content += this.translations['menu'];
				}
			} else if (type == 'additional_menu') {
				if (values.source) {
					content += this.params.navMenus[values.source] || values.source;
				} else {
					content += this.translations['additional_menu'];
				}
			} else if (type == 'search' && values.text) {
				if (values.icon) {
					content += $usof.instance.prepareIconTag(values.icon);
				}
				content += values.text.replace(/(\r\n|\n|\r)+/gm, ' ').replace(/<\/?([^>]+)?>/gi, '');
			} else if (type == 'dropdown') {
				if (values.source == 'wpml') {
					content += 'WPML';
				} else if (values.source == 'polylang') {
					content += 'Polylang';
				} else if (values.source == 'qtranslate') {
					content += 'qTranslate X';
				} else {
					content += values.link_title || this.translations['dropdown'];
				}
			} else if (type == 'socials') {
				var socialsHtml = '';
				$.each(values['items'], function(key, value){
					if (value['type'] == 'custom') {
						var icon_value = value['icon'].trim().split('|'),
							icon_set = icon_value[0],
							icon_name = icon_value[1];
						if ( icon_name != '' ) {
							if ( icon_set == 'material' ) {
								socialsHtml += '<i class="material-icons">'+icon_name+'</i>';
							} else {
								socialsHtml += '<i class="'+icon_set+' fa-'+icon_name+'"></i>';
							}
						}
					} else {
						socialsHtml += '<i class="fab fa-' + value['type'] + '"></i>';
					}
				});
				if (values.custom_icon && values.custom_url) {
					socialsHtml += $usof.instance.prepareIconTag(values.custom_icon);
				}
				content += socialsHtml || this.translations['social_links'];
			} else if (type == 'btn') {
				if (values.icon) {
					content += $usof.instance.prepareIconTag(values.icon);
				}
				if (values.label) {
					content += values.label.replace(/(\r\n|\n|\r)+/gm, ' ').replace(/<\/?([^>]+)?>/gi, '');
				} else {
					content += this.translations['button'];
				}
			} else if (type == 'html') {
				content += 'HTML';
			} else if (type == 'cart') {
				if (values.icon) {
					content += $usof.instance.prepareIconTag(values.icon);
				}
				content += this.translations['cart'];
			} else {
				content += type[0].toUpperCase() + type.substr(1);
			}
			$content.html(content);
			this._loadAttachments($content);
		},
		/**
		 * Create DOM placeholder element for the specified header builder element / wrapper
		 * @param {String} id Element ID
		 * @param {Object} [values]
		 * @returns {jQuery} Created (but not yet placed to document) jQuery object with the element's DOMElement
		 * @private
		 */
		_createElementPlaceholder: function(id, values){
			var type = id.split(':')[0],
				$elm = this._createElementPlaceholderBase(id);
			this._updateElementPlaceholder($elm, id, values);
			return $elm;
		},
		/**
		 * Delete DOM placeholder for the specified header element / wrapper
		 * @param {String} id
		 * @private
		 */
		_removeElementPlaceholder: function(id){
			var container = (id.substr(1, 7) == 'wrapper') ? '$wrappers' : '$elms';
			if (this[container][id] === undefined) return;
			this[container][id].remove();
			delete this[container][id];
		},
		/**
		 * Render current layout based on current value and state
		 */
		renderLayout: function(){
			// Making sure the provided data is consistent
			if (this.value.data === undefined) this.value.data = {};
			if (this.value[this.state].layout === undefined) this.value[this.state].layout = {};
			if (this.value[this.state].layout.hidden === undefined) this.value[this.state].layout.hidden = [];
			var elmsInNextLayout = [],
				plc, i, elmId;
			for (plc in this.value[this.state].layout) {
				if (!this.value[this.state].layout.hasOwnProperty(plc)) continue;
				for (i = 0; i < this.value[this.state].layout[plc].length; i++) {
					var id = this.value[this.state].layout[plc][i],
						type = id.split(':')[0];
					if (this.value.data[id] === undefined) this.value.data[id] = $.extend({}, this.elmsDefaults[type] || {});
					elmsInNextLayout.push(this.value[this.state].layout[plc][i]);
				}
			}
			for (elmId in this.value.data) {
				if (!this.value.data.hasOwnProperty(elmId)) continue;
				if (elmsInNextLayout.indexOf(elmId) == -1) this.value[this.state].layout.hidden.push(elmId);
			}
			// Retrieving the currently shown layout structure
			var prevLayout = {},
				parsePlace = function(place, $place){
					if ($place.hasClass('us-bld-editor-wrapper')) $place = $place.children('.us-bld-editor-wrapper-content');
					prevLayout[place] = [];
					$place.children().each(function(index, elm){
						var $elm = $(elm),
							id = $elm.data('id');
						if (!id) return;
						prevLayout[place].push(id);
					});
				};
			$.each(this.$places, parsePlace);
			$.each(this.$wrappers, parsePlace);
			// Iteratively looping through the needed structure
			for (plc in this.value[this.state].layout) {
				if (!this.value[this.state].layout.hasOwnProperty(plc)) continue;
				if (plc.indexOf(':') != -1 && prevLayout[plc] === undefined) {
					// Creating the missing wrapper
					if (this.$wrappers[plc] === undefined) {
						this._createElementPlaceholder(plc, this.value.data[plc]);
					}
					prevLayout[plc] = [];
				}
				var $place = (plc.indexOf(':') == -1) ? this.$places[plc] : this.$wrappers[plc].children('.us-bld-editor-wrapper-content');
				for (i = 0; i < this.value[this.state].layout[plc].length; i++) {
					elmId = this.value[this.state].layout[plc][i];
					var $elm = this[(elmId.substr(1, 7) == 'wrapper') ? '$wrappers' : '$elms'][elmId];
					if ($elm === undefined) {
						$elm = this._createElementPlaceholder(elmId, this.value.data[elmId]);
					}
					if (prevLayout[plc][i] != elmId) {
						if (i == 0) {
							$elm.prependTo($place);
						} else {
							var prevElmId = this.value[this.state].layout[plc][i - 1],
								$prevElm = this[(prevElmId.substr(1, 7) == 'wrapper') ? '$wrappers' : '$elms'][prevElmId];
							$elm.insertAfter($prevElm);
						}
						prevLayout[plc].splice(i, 0, elmId);
					}
				}
			}
			// Removing excess elements
			for (plc in prevLayout) {
				if (!prevLayout.hasOwnProperty(plc))continue;
				for (i = 0, elmId = prevLayout[plc][i]; i < prevLayout[plc].length; i++, elmId = prevLayout[plc][i]) {
					if (this.value.data[elmId] === undefined) this._removeElementPlaceholder(elmId);
				}
			}
			// Updating elements' placeholders contents
			for (elmId in this.$elms) {
				if (!this.$elms.hasOwnProperty(elmId)) continue;
				this._updateElementPlaceholder(this.$elms[elmId], elmId, this.value.data[elmId]);
			}
			// Fixing wrappers
			this.$container.find('.us-bld-editor-wrapper').removeClass('empty').find('.us-bld-editor-wrapper-content:empty').parent().addClass('empty');
		},
		/**
		 * Event that is called on manual side option change
		 * @param {$usof.Field} field
		 * @private
		 */
		_optionChanged: function(field){
			if (this.ignoreOptionsChanges) return;
			var fieldId = field.name,
				value = field.getValue(),
				state = ($.inArray(fieldId, this.sharedOptions) != -1) ? 'default' : this.state;
			if (this.value[state] === undefined) this.value[state] = {};
			if (this.value[state].options === undefined) this.value[state].options = {};
			this.value[state].options[fieldId] = value;
			this.renderOptions();
			this.trigger('change', this.value);
		},
		/**
		 * Change side options
		 * @param options
		 */
		setOptions: function(options){
			this.ignoreOptionsChanges = true;
			this.sideOptions.setValues(options);
			this.ignoreOptionsChanges = false;
			this.renderOptions();
		},
		/**
		 * Render current options
		 */
		renderOptions: function(){
			var prevOrientation = this.$editor.usMod('type'),
				nextOrientation = this.value[this.state].options.orientation || 'hor';
			if (nextOrientation != prevOrientation) {
				this.$editor.usMod('type', nextOrientation);
				if (nextOrientation == 'ver') {
					// Moving elements from removed cells to remaining ones
					if (this.value[this.state].layout.hidden === undefined) this.value[this.state].layout.hidden = [];
					for (var place in this.value[this.state].layout) {
						if (!this.value[this.state].layout.hasOwnProperty(place)) continue;
						if (place.indexOf(':') != -1 || place == 'hidden' || place.substr(place.length - 5) == '_left') continue;
						var align = place.split('_'),
							newPlace = (align.length == 2) ? (align[0] + '_left') : 'hidden';
						if (this.value[this.state].layout[newPlace] === undefined) this.value[this.state].layout[newPlace] = [];
						this.value[this.state].layout[newPlace] = this.value[this.state].layout[newPlace].concat(this.value[this.state].layout[place]);
						this.value[this.state].layout[place] = [];
					}
					this.renderLayout();
				}
			}
			$.each(['top', 'bottom'], function(index, vpos){
				var $row = this.$rows.filter('.at_' + vpos),
					prevShown = !$row.hasClass('disabled'),
					nextShown = !!parseInt(this.value[this.state].options[vpos + '_show']);
				if (prevShown != nextShown) {
					$row.toggleClass('disabled', !nextShown);
				}
			}.bind(this));
		}
	};
}(jQuery);
jQuery(function($){
	var USHB = function(container){
		this.$container = $(container);
		if (!this.$container.length) return;
		this.initFields(this.$container);
		this.fireFieldEvent(this.$container, 'beforeShow');
		this.fireFieldEvent(this.$container, 'afterShow');
		// Save action
		this.$saveControl = this.$container.find('.usof-control.for_save');
		this.$saveBtn = this.$saveControl.find('.usof-button').on('click', this.save.bind(this));
		this.$saveMessage = this.$saveControl.find('.usof-control-message');
		this.valuesChanged = {};
		this.saveStateTimer = null;
		for (var fieldId in this.fields) {
			if (!this.fields.hasOwnProperty(fieldId)) continue;
			this.fields[fieldId].on('change', function(field, value){
				if ($.isEmptyObject(this.valuesChanged)) {
					clearTimeout(this.saveStateTimer);
					this.$saveControl.usMod('status', 'notsaved');
				}
				this.valuesChanged[field.name] = value;
			}.bind(this));
		}
		$(window).bind('keydown', function(event) {
			if (event.ctrlKey || event.metaKey) {
				if (String.fromCharCode(event.which).toLowerCase() == 's') {
					event.preventDefault();
					this.save();
				}
			}
		}.bind(this));
	};
	$.extend(USHB.prototype, $usof.mixins.Fieldset, {
		/**
		 * Save the new values
		 */
		save: function(){
			if ($.isEmptyObject(this.valuesChanged)) return;
			clearTimeout(this.saveStateTimer);
			this.$saveMessage.html('');
			this.$saveControl.usMod('status', 'loading');
			$.ajax({
				type: 'POST',
				url: $usof.ajaxUrl,
				dataType: 'json',
				data: {
					action: 'ushb_save',
					ID: this.$container.data('id'),
					post_title: this.getValue('post_title'),
					post_content: JSON.stringify(this.getValue('post_content')),
					_wpnonce: this.$container.find('[name="_wpnonce"]').val(),
					_wp_http_referer: this.$container.find('[name="_wp_http_referer"]').val()
				},
				success: function(result){
					if (result.success) {
						this.valuesChanged = {};
						this.$saveMessage.html(result.data.message);
						this.$saveControl.usMod('status', 'success');
						this.saveStateTimer = setTimeout(function(){
							this.$saveMessage.html('');
							this.$saveControl.usMod('status', 'clear');
						}.bind(this), 4000);
					} else {
						this.$saveMessage.html(result.data.message);
						this.$saveControl.usMod('status', 'error');
						this.saveStateTimer = setTimeout(function(){
							this.$saveMessage.html('');
							this.$saveControl.usMod('status', 'notsaved');
						}.bind(this), 4000);
					}
				}.bind(this)
			});
		}
	});
	new USHB('.usof-container.type_builder');
	// Pencil icon hear the header edit
	var $headerTitle = $('input[name="post_title"]'),
		$headerEditIcon = $('<span class="usof-form-row-control-icon"></span>').text($headerTitle.val()).insertAfter($headerTitle);
	$headerTitle.on('change keyup', function(){
		$headerEditIcon.text($headerTitle.val() || $headerTitle.attr('placeholder'));
	});
});