/*! 
 * ************************************************
 * Uix Custom Metaboxes
 *
 * @version		: 2.2 (October 24, 2022)
 * @author 		: UIUX Lab
 * @author URI 	: https://uiux.cc
 * @license     : MIT
 *
 *************************************************
 */
 const UixCustomMetaboxes = function( obj ) {
	"use strict";


	const UixCustomMetaboxesConstructor = function( obj ) {
		this.init = obj;
	};

	UixCustomMetaboxesConstructor.prototype = {

		
		/*! 
		 * 
		 * Initialize the custom meta box
		 * ---------------------------------------------------
		 *
		 * @return {void}                  - The constructor.
		 */
		getInstance: function() {

			jQuery( document ).ready( function() {

				//(Calling "radio"... method using JavaScript prototype)
				UixCustomMetaboxesConstructor.prototype.radio.call( this, '.uix-cmb__radio-selector' );
				UixCustomMetaboxesConstructor.prototype.toggle.call( this, '.uix-cmb__toggle-selector' );
				UixCustomMetaboxesConstructor.prototype.color.call( this, '.uix-cmb__color-selector' );
				UixCustomMetaboxesConstructor.prototype.tabs.call( this, '.uix-cmb__tabsgroup-selector' );
				UixCustomMetaboxesConstructor.prototype.date.call( this, '.uix-cmb__date-selector' );
				UixCustomMetaboxesConstructor.prototype.customAttrs.call( this, '.uix-cmb__custom-attributes-field', 100 );
                UixCustomMetaboxesConstructor.prototype.expandItem.call( this, '.uix-cmb__text--div--toggle__trigger' );
                UixCustomMetaboxesConstructor.prototype.titleChange.call( this, '.uix-cmb__text--div--toggle', '.uix-cmb__text--div--toggle__trigger', '.uix-cmb__text--div--toggle__title' );          
                UixCustomMetaboxesConstructor.prototype.upload.call( this );
                UixCustomMetaboxesConstructor.prototype.editor.call( this, false );
                UixCustomMetaboxesConstructor.prototype.toggleSelect.call( this );
				
			});

			//Chain method calls
			return this;
		},
		
		
		/*! 
		 * 
		 * Expand Item Interaction
		 * ---------------------------------------------------
		 *
		 * @param  {string} selector       - The selector ID or class
		 * @return {void}                  - The constructor.
		 */
		expandItem: function( selector ) {

			jQuery( document ).ready( function() {
                jQuery( document ).off( 'click.UixToggle' ).on( 'click.UixToggle', selector, function(e) {
                    e.preventDefault();
                    jQuery( this ).parent().toggleClass( 'active' );
                    jQuery( this ).toggleClass( 'active' );
                });

			});
			
			//Chain method calls
			return this;
		},		
        
		/*! 
		 * 
		 * Title Change Interaction
		 * ---------------------------------------------------
		 *
         * @param  {string} wrapper        - Wrapper of this item.
         * @param  {string} trigger        - Trigger of this item.
         * @param  {string} title          - Title of this item.
		 * @return {void}                  - The constructor.
		 */
		titleChange: function( wrapper, trigger, title ) {

			jQuery( document ).ready( function() {
                jQuery( document ).off( 'change.UixTitle' ).on( 'change.UixTitle', title, function() {
                    jQuery( this ).closest( wrapper ).find( trigger + '> span' ).html( jQuery( this ).val() );
                }); 
                
			});
            
            
			
			//Chain method calls
			return this;
		},	    
        
		/*! 
		 * 
		 * Radio
		 * ---------------------------------------------------
		 *
		 * @param  {string} selector       - The selector ID or class
		 * @return {void}                  - The constructor.
		 */
		radio: function( selector ) {

	
			jQuery( document ).ready( function() {
	
				jQuery( selector ).each(function(){

					const $this = jQuery( this ),
						tid   = $this.data( 'target-id' );
					
					
					//get all switch ids
					let allSwitchIds = '';
					$this.find( '[data-switch-ids]' ).each( function()  {
						allSwitchIds += jQuery( this ).attr( 'data-switch-ids' );
					});

					//Switch with radios
					const switchFun = function( curSel ) {
						
						$this.find( '[data-switch-ids]' ).each( function()  {
							const _targetID      = jQuery( this ).attr( 'data-switch-ids' ),
								_targetIDs     = UixGetRealIds( _targetID  );

							if ( _targetIDs != '' ) {
								const	_$wrapper = jQuery( _targetIDs ).closest( 'tr' );
								_$wrapper.hide();	
							}


						});

						//
						if ( allSwitchIds != '' ) {
							jQuery( UixGetRealIds( allSwitchIds  ) ).closest( 'tr' ).hide();
						}
						
						
						
						//
						const switchTargetID = curSel.attr( 'data-switch-ids' ),
							switchTargetIDs = UixGetRealIds( switchTargetID  );

						if ( switchTargetIDs != '' ) {
							jQuery( switchTargetIDs ).closest( 'tr' ).show();
						}


					};

					if ( $this.find( '[data-switch-ids]' ).length > 0 ) {
						switchFun( $this.find( '[data-switch-ids]' ).first() );
					}
					
					
					$this.find( '[data-value]' ).on( 'click', function() {
					
						//Do not use preventDefault()
						//---------
						const _curValue = jQuery( this ).attr( 'data-value' );
						$this.find( '[data-value]' ).removeClass( 'active' );
						jQuery( '#' + tid ).val( _curValue );
						jQuery( this ).addClass( 'active' );
						
						
						//Switch with radios
						//---------
						if ( $this.find( '[data-switch-ids]' ).length > 0 ) {
							switchFun( jQuery( this ) );
						}
						


						
					} );	

				} );			
			
				
			});
			

			//Chain method calls
			return this;
		},
		
		
	
		
		/*! 
		 * 
		 * Toggle
		 * ---------------------------------------------------
		 *
		 * @param  {string} selector       - The selector ID or class
		 * @return {void}                  - The constructor.
		 */
		toggle: function( selector ) {

	
			jQuery( document ).ready( function() {
				
				jQuery( selector ).each(function(){

					
					const $this = jQuery( this );

                    const tid = $this.attr( 'data-toggle-id' );
                    if ( $this.hasClass( 'active' ) ) {
                        if ( tid != '' || typeof tid !== typeof undefined ) {
                            $this.closest( '[data-target-id]' ).find( '.uix-cmb__toggle-target' ).hide();
                            jQuery( '#' + tid ).show();
                        }
                    }

					$this.on( "click", function() {
						const tid = jQuery( this ).attr( 'data-toggle-id' );
						$this.removeClass( 'active' );

						if ( tid != '' || typeof tid !== typeof undefined ) {
							$this.closest( '[data-target-id]' ).find( '.uix-cmb__toggle-target' ).hide();
							jQuery( '#' + tid ).show();
						}

						jQuery( this ).addClass( 'active' );
					} );	


				} );			
			
				
			});
			

			//Chain method calls
			return this;
		},
			
		
		/*! 
		 * 
		 * Tabs
		 * ---------------------------------------------------
		 *
		 * @param  {string} selector       - The selector ID or class
		 * @return {void}                  - The constructor.
		 */
		tabs: function( selector ) {

	
			jQuery( document ).ready( function() {
				
				jQuery( selector ).each(function(){

					
					const $this = jQuery( this ),
						tabID = $this.attr( 'id' );
					
					//Create ID
					$this.find( '> ul' ).find( 'li' ).each(function(index) {
						jQuery( ' a', this).attr( 'href', '#tab-' + index + tabID);
					});
					$this.find( '.item' ).each(function(index) {
						jQuery( this ).attr( 'id', 'tab-' + index + tabID);
					});

					$this.find( '> ul' ).each(function() {
						// For each set of tabs, we want to keep track of
						// which tab is active and its associated content
						let $active, content, links = jQuery( this ).find( 'a' );

						// If the location.hash matches one of the links, use that as the active tab.
						// If no match is found, use the first link as the initial active tab.
						$active = jQuery(links.filter( '[href="' + location.hash + '"]' )[0] || links[0]);
						$active.addClass( 'active' );

						content = jQuery($active[0].hash);

						// Hide the remaining content
						$this.find( '> ul' ).find( 'li a' ).removeClass( 'active' );
						links.not( $active ).each(function() {
							jQuery(this.hash).hide();
						});

						$this.find( '> ul' ).find( 'li:first a' ).addClass( 'active' );
						$this.find( '.item:first' ).show();

						//Prevent duplicate function assigned
						jQuery( this ).find( 'a' ).off( 'click' );
						
						// Bind the click event handler
						jQuery( this ).on( 'click', 'a',
						function(e) {
							// Make the old tab inactive.
							$active.removeClass( 'active' );
							content.hide();

							// Update the variables with the new link and content
							$active = jQuery( this );
							content = jQuery(this.hash);

							// Make the tab active.
							$active.addClass( 'active' );
							content.show();

							// Prevent the anchor's default click action
							e.preventDefault();
						});

					});

					


				} );			
			
				
			});
			

			//Chain method calls
			return this;
		},
			
			
		/*! 
		 * 
		 * Color Picker
		 * ---------------------------------------------------
		 *
		 * @param  {string} selector       - The selector ID or class
		 * @return {void}                  - The constructor.
		 */
		color: function( selector ) {

	
			jQuery( document ).ready( function() {
				if ( jQuery.isFunction( jQuery.fn.wpColorPicker ) ){
					jQuery( selector ).wpColorPicker();	
				}	
			});
			

			//Chain method calls
			return this;
		},		
		
		
		/*! 
		 * 
		 * Date Picker
		 * ---------------------------------------------------
		 *
		 * @param  {string} selector       - The selector ID or class
		 * @return {void}                  - The constructor.
		 */
		date: function( selector ) {

			jQuery( document ).ready( function() {
				if ( jQuery.isFunction( jQuery.fn.datepicker ) ) {
					
					jQuery( selector ).each( function(){

						const $this  = jQuery( this ),
							format = $this.data( 'format' );

						$this.datepicker({
							dateFormat : format,
                            changeMonth: true,
                            changeYear: true,
                            nextText: '→',
                            prevText: '←'
						});

					} );		
					
					
						
				}
			});
			

			//Chain method calls
			return this;
		},		
		
		/*! 
		 * 
		 * Editor
		 * ---------------------------------------------------
		 *
         * @param  {boolean} init          - Whether to reset the editor.
		 * @return {void}                  - The constructor.
		 */
		editor: function( reset ) {

			jQuery( document ).ready( function() {
                
               
                //Initialize Editor
                jQuery( '.uix-cmb__mce-editor' ).UixEditorInit({init: reset});

                
			});
			

			//Chain method calls
			return this;
		},		
        
		/*! 
		 * 
		 * Select of Toggle
		 * ---------------------------------------------------
		 *
		 * @return {void}                  - The constructor.
		 */
		toggleSelect: function() {

			jQuery( document ).ready( function() {
                
                //Initialize Select of Toggle (include parent category)
                jQuery( '.uix-cmb__wrapper.uix-cmb__custom-attributes-field.uix-cmb__custom-attributes-field--customlevel' ).UixToggleSelectInit();
				
				//Initialize Select of Toggle
                jQuery( '.uix-cmb__text--div--toggle__simple-sel' ).UixToggleSimpleSelectInit({ type: 'file'});

                
			});
			

			//Chain method calls
			return this;
		},	   
        
						
			

		/*! 
		 * 
		 * Upload Media Control
		 * ---------------------------------------------------
		 *
		 * @return {void}                  - The constructor.
		 */
		upload: function() {

	
			jQuery( document ).ready( function() {
                

                const selector = '.uix-cmb__upload-target';
                const videoReg = /^.*\.(avi|AVI|wmv|WMV|flv|FLV|mpg|MPG|mp4|MP4)$/gi;
				const imgReg   = /^.*\.(gif|jpe?g|tiff|png|webp|bmp)$/gi;
				const placeholderImg = '<svg width="135" style="padding: 50px 40px;border: 1px solid #ddd;pointer-events: none;box-shadow: 0 4px 8px 0 rgba(0,0,0,0.12), 0 6px 30px 0 rgba(0,0,0,0.1);" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 102.55 122.88" enable-background="new 0 0 24 24" transform="scale(0.7) translate(-30 -55)"><path d="M102.55,122.88H0V0h77.66l24.89,26.44L102.55,122.88L102.55,122.88z M25.51,53.72h15.67V43.33H25.51V32.56 l15.67,0V21.85H25.51V11.08h15.67V7.83H8.43v106.23h85.77V32.36H71.52V7.83H56.86v3.29H41.18v10.71l15.68,0V32.6H41.18v10.49h15.68 v24.99c0,7.9-6.46,14.36-14.36,14.36l-2.63,0c-7.9,0-14.36-6.46-14.36-14.36V53.72L25.51,53.72z M36.28,63.07h10.28v4.06 c0,2.23-2.12,4.05-4.71,4.05h-0.86c-2.59,0-4.71-1.83-4.71-4.05V63.07L36.28,63.07L36.28,63.07z"></path></svg>';

				
                //Custom selectors
				jQuery( selector ).each( function()  {
					const $this     = jQuery( this ),
                        uuid      = UixGUIDCreate(),
					    pid       = $this.data( 'insert-preview' ).replace(/\{id\}/g, uuid ),
						tid       = $this.data( 'insert-img' ).replace(/\{id\}/g, uuid ),
						_closebtn = '.uix-cmb__removebtn';

					
                    //init button and preview status
                    $this.attr( 'aria-disabled', true );
					
					
					//The RegExp object keeps track of the lastIndex where a match occurred, so on 
					//subsequent matches it will start from the last used index, instead of 0.
					videoReg.lastIndex = 0;
					imgReg.lastIndex = 0;	


					
					
					const element = jQuery( '#' + tid ).val();
					if ( element != '' ) {
                        
                        //image or video preview
						if ( videoReg.test( element ) ) {
							jQuery( '#' + pid ).html( '<video width="200" height="150" src="'+element+'" controls></video>' );
						} else if ( imgReg.test( element ) ) {
							jQuery( '#' + pid ).html( '<img src="'+element+'" alt="">' );
						} else {
							jQuery( '#' + pid ).html( '<img src="'+element+'" style="display: none"><a href="'+element+'" target="_blank" style="display: block;max-width: 180px;max-height: 197px;overflow: hidden;">'+placeholderImg+'</a>' );
						}
			
                        
                        //
						$this.next( _closebtn ).show();
						$this.hide();
					} else {
						$this.show();
					}

					 //Delete image   
                    $this.next( _closebtn ).off( 'click.UixUploadClose' ).on( 'click.UixUploadClose', function( event ){
                        event.preventDefault();

                        jQuery( '#' + tid ).val( '' );
                        
                        //hide element
                        jQuery( '#' + pid ).html( '' );
                        jQuery( '#' + pid ).hide();

                        jQuery( this ).hide();
                        jQuery( this ).closest( '.uix-cmb__upload-wrapper' ).find( selector ).show();
                        jQuery( this ).closest( '.uix-cmb__upload-wrapper' ).find( selector ).attr( 'aria-disabled', true );

                    } );	
                    
                    
                    //Prevent duplicate function assigned
                    $this.off( 'click.UixUpload' ).on( 'click.UixUpload', function( e ) {
                        e.preventDefault();

                        let upload_frame, 
                            attachment,
                            $thisClick = jQuery( this );

                        if ( typeof upload_frame === typeof undefined ) $thisClick.attr( 'aria-disabled', true );

                        if ( $thisClick.attr( 'aria-disabled' ) == 'true' ) {

                            if( upload_frame ){
                                upload_frame.open();
                                return;
                            }
                            upload_frame = wp.media( {
								title: uix_custom_metaboxes_lang.ed_media_title,
								button: {
								text: uix_custom_metaboxes_lang.ed_media_text,
                            },
                                multiple: false
                            } );
                            upload_frame.on( 'select',function(){
                                attachment = upload_frame.state().get( 'selection' ).first().toJSON();
                                jQuery( '#' + tid ).val( attachment.url );
                        
								
								//The RegExp object keeps track of the lastIndex where a match occurred, so on 
								//subsequent matches it will start from the last used index, instead of 0.
								videoReg.lastIndex = 0;
								imgReg.lastIndex = 0;	

                            
								const element = attachment.url;
						
								//image or video preview
								if ( videoReg.test( element ) ) {
                                    jQuery( '#' + pid ).html( '<video width="200" height="150" src="'+element+'" controls></video>' );
                                    jQuery( '#' + tid + '_filetype' ).val( 'video' );
								} else if ( imgReg.test( element ) ) {
                                    jQuery( '#' + pid ).html( '<img src="'+element+'" alt="">' );
                                    jQuery( '#' + tid + '_filetype' ).val( 'image' );
								} else {
                                    jQuery( '#' + pid ).html( '<img src="'+element+'" style="display: none"><a href="'+element+'" target="_blank" style="display: block;max-width: 180px;max-height: 197px;overflow: hidden;">'+placeholderImg+'</a>' );
                                    jQuery( '#' + tid + '_filetype' ).val( 'file' );
								}

								
                                
                              
                                //display element
                                jQuery( '#' + pid ).show();

                                $thisClick.next( _closebtn ).show();
                                $thisClick.hide();

                            } );

                            upload_frame.open();


                        }//end if $this.attr( 'aria-disabled' )


                        $this.attr( 'aria-disabled', false );


                    });//endif click.UixUpload
                    

				});//end each
                

				
				
			});
			

			//Chain method calls
			return this;
		},
			
			
			
			
			
			
			


			
		
		/*! 
		 * 
		 * Custom Attributes
		 * ---------------------------------------------------
		 *
		 * @param  {string} selector       - The selector ID or class
		 * @param  {number} max            - Increase the maximum number dynamically.
		 * @return {void}                  - The constructor.
		 */
		customAttrs: function( selector, max ) {

	
			jQuery( document ).ready( function() {
				
				
				jQuery( selector ).each(function(){

					
					const $this     = jQuery( this ),
						$addButton  = $this.find( '.uix-cmb__custom-attributes-field__addbtn' ), //The add button selector ID or class
						wrapperID   = '#' + $this.data( 'append-id' ), //The field wrapper ID or class 
						maxField    = max,
						fieldHTML   = $this.data( 'tmpl' );
					
					let x = 1;
					
					
					//Prevent duplicate function assigned
					$addButton.off( 'click.UixCustomMetaboxes_customAttrs_add' ).on( 'click.UixCustomMetaboxes_customAttrs_add', function( e ) {
						e.preventDefault();
                        
                        const $btn = jQuery( this );
                      
						if( x < maxField ){ 
							x++;

                            const uuid = UixGUIDCreate();
                            
							jQuery( wrapperID ).append( fieldHTML.replace(/\{id\}/g, uuid ) );
                            jQuery.when( jQuery( wrapperID ).length > 0 ).then( function() {
                                
                                
                                if ( typeof $btn.data( 'type' ) !== typeof undefined ) {
									
									//Initialize Select of Toggle
                                   jQuery( '.uix-cmb__text--div--toggle__simple-sel' ).UixToggleSimpleSelectInit({ type: $btn.data( 'type' ) });
									
                                } else {
									
									//Initialize Select of Toggle (include parent category)
									jQuery( '.uix-cmb__wrapper.uix-cmb__custom-attributes-field.uix-cmb__custom-attributes-field--customlevel' ).UixToggleSelectInit();
								}
                                
                                
                                

                                //Initialize Editor
                                UixCustomMetaboxesInit.editor( false );
                                
                                

                                //Initialize Uploader
                                UixCustomMetaboxesInit.upload();
                                
                                
                            });
                            
						}
						
						
						//Fold all items
						jQuery( '.uix-cmb__text--div--toggle__trigger' ).parent().removeClass( 'active' );
						jQuery( '.uix-cmb__text--div--toggle__trigger' ).removeClass( 'active' );

                        
						
						return false;
					});

					//Remove per item
					
					//Prevent duplicate function assigned
					jQuery( '.uix-cmb__custom-attributes-field__removebtn' ).off( 'click.UixCustomMetaboxes_customAttrs_remove' );
					jQuery( document ).on( 'click.UixCustomMetaboxes_customAttrs_remove', '.uix-cmb__custom-attributes-field__removebtn', function( e ) {
						e.preventDefault();
                        
                        //fixed click events firing multiple times
                        e.stopImmediatePropagation();
                        
                        if ( confirm( uix_custom_metaboxes_lang.delete_confirm_text ) ) {
                            const $li = jQuery( this ).closest( '.uix-cmb__text--div' );

                            if ( jQuery( '.uix-cmb__custom-attributes-field .uix-cmb__text--div' ).length == 1 ) {
                                $li.find( 'input' ).val( '' );
                                $li.hide();
                            } else {
                                $li.remove();
                            }


                            x--;   
                        }


					});	

                    // Custom attributes field ordering
                    jQuery( '.uix-cmb__custom-attributes-field' ).sortable({
                        items                   : '.uix-cmb__text--div--toggle--sortable',
                        handle                  : '.uix-cmb__custom-attributes-field__sortablebtn',
                        cursor                  : 'move',
                        scrollSensitivity       : 40,
                        forcePlaceholderSize    : true,
                        forceHelperSize         : false,
                        helper                  : 'clone',
                        opacity                 : 0.65,
                        placeholder             : 'wc-metabox-sortable-placeholder',
                        start:function( event,ui ) {
                            ui.item.css( 'background-color', '#f6f6f6' );
                        },
                        stop:function( event,ui ){
                            ui.item.removeAttr( 'style' );
                            
                            //Initialize Editor
                            UixCustomMetaboxesInit.editor( true );   
                            
                        },
                        update: function( event, ui ) {

                        }
                    });       
                    
                    
					
					
				} );		
		
				
			});
			

			//Chain method calls
			return this;
		},

			
		
	};

	return new UixCustomMetaboxesConstructor( obj );
};




//--------
const UixCustomMetaboxesInit = new UixCustomMetaboxes();
UixCustomMetaboxesInit.getInstance(); 



/*! 
 * ************************************
 * Initialize editor
 *************************************
 */	
/**
 * Based on "code" plugin
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */
( function( $ ) {
"use strict";
    $( function() {

		
		if ( typeof(tinymce) !== 'undefined' ) {
			
			tinymce.PluginManager.add('uix_cmb_customcode', function(editor) {
				function showDialog() {
					const win = editor.windowManager.open({
						title: uix_custom_metaboxes_lang.ed_sourcecode_title,
						body: {
							type: 'textbox',
							name: 'uix_cmb_customcode',
							multiline: true,
							minWidth: editor.getParam("code_dialog_width", 600),
							minHeight: editor.getParam("code_dialog_height", Math.min(tinymce.DOM.getViewPort().h - 200, 500)),
							spellcheck: false,
							style: 'direction: ltr; text-align: left'
						},
						onSubmit: function(e) {
							// We get a lovely "Wrong document" error in IE 11 if we
							// don't move the focus to the editor before creating an undo
							// transation since it tries to make a bookmark for the current selection
							editor.focus();

							if(editor.readonly != true){
								editor.undoManager.transact(function() {
									editor.setContent(e.data.uix_cmb_customcode);
								});
							}

							editor.selection.setCursorLocation();
							editor.nodeChanged();

						}
					});


					// Gecko has a major performance issue with textarea
					// contents so we need to set it when all reflows are done
					win.find('#uix_cmb_customcode').value(editor.getContent({source_view: true}));

					//disable source code editing while in readonly mode
					if(editor.readonly){
						const id = win.find('#uix_cmb_customcode')[0]._id;
						$(win.find('#uix_cmb_customcode')[0]._elmCache[id]).prop('readonly', true);
					}

					//This was an attempt to disable the "save" button but nothing I've tried is working. 
					//So far we are good because the user cannot modify the source code anyway
					/*for (let property in win.find('#code')[0].rootControl.controlIdLookup) {
						if (win.find('#code')[0].rootControl.controlIdLookup.hasOwnProperty(property)) {
							const realProperty = win.find('#code')[0].rootControl.controlIdLookup[property];
							const element = $($(realProperty._elmCache[realProperty._id])[0].children[0]);
							if(element.prop('type') == 'button'){
								$(element).prop('disabled', true);
								//console.log(element.attr('disabled'));
								//console.log(element.prop('disabled'));
							}
						}
					}*/
				}

				editor.addCommand("mceCustomCodeEditor", showDialog);

				editor.addButton('uix_cmb_customcode', {
					icon: 'code',
					tooltip: uix_custom_metaboxes_lang.ed_sourcecode_title,
					onclick: showDialog,
					classes:'uix_cmb_customcode'
				});

				editor.addMenuItem('uix_cmb_customcode', {
					icon: 'code',
					text: uix_custom_metaboxes_lang.ed_sourcecode_title,
					context: 'tools',
					onclick: showDialog
				});
			});	
			
		}



	} );
    
    
} ) ( jQuery );


/*! 
 * @param  {number} id            - The ID of editor.
 * @param  {string} toolbar       - Toolbar of editor.
 * @param  {number} height        - Set editor height.
 * @return {void}                 - The constructor.
 */	
( function ( $ ) {
	'use strict';
    $.fn.UixMCEEditor = function( options ) {
		
 
        // This is the easiest way to have default options.
        const settings = $.extend({
			speed    : 0.25,
			bg       : { enable: true, xPos: '50%' }
        }, options );
 
        this.each( function() {
	
            const id       = settings.id, 
                toolbar  = settings.toolbar, 
                height   = settings.height;
			
	
            if( typeof id !== typeof undefined ) {
				
				
				tinyMCE.execCommand( 'mceRemoveEditor', true, id );
				tinymce.init({
					//tinyMCE Image Displaying Correctly, but not Updating src
					relative_urls : false,
					content_css : '',
					convert_urls : false,
					media_live_embeds: true,
					//---
					language_url : (uix_custom_metaboxes_lang.ed_lang != 'en_US' ) ? uix_custom_metaboxes_lang.ed_url +  'js/tinymce/langs/'+uix_custom_metaboxes_lang.ed_lang+'.js' : false,  // site absolute URL
					//---
					selector:  'textarea#' + id,
					height : height,
					menubar: false,
					extended_valid_elements: "a[*],svg[*],defs[*],pattern[*],desc[*],metadata[*],g[*],mask[*],path[*],line[*],marker[*],rect[*],circle[*],ellipse[*],polygon[*],polyline[*],linearGradient[*],radialGradient[*],stop[*],image[*],view[*],text[*],textPath[*],title[*],tspan[*],glyph[*],symbol[*],switch[*],use[*]",
					plugins: 'textcolor image media hr uix_cmb_customcode colorpicker lists fullscreen',		
				    toolbar: toolbar,
					setup:function( ed ) {
						
					   //Avoid formatting all contents of <textarea> 
					   const $sync = jQuery( 'textarea#' + id + '-sync' );
					   ed.on( 'change', function(e) {
						   
						   //Dynamically filter content in TinyMCE
						   var newvalue = ed.getContent()
														 .replace(/\r?\n/gm, '' )
														 .replace(/\.\.\/wp-content\/uploads\//g, uix_custom_metaboxes_lang.upload_dir_url );

						   
						   
						   $sync.val( newvalue ).trigger( 'change' );
					   });
						
						
                        //Add media button
						function uix_mce_insertImage() {
							let upload_frame;
							if( upload_frame ){
								upload_frame.open();
								return;
							}
							upload_frame = wp.media( {
								title: uix_custom_metaboxes_lang.ed_media_title,
								button: {
								text: uix_custom_metaboxes_lang.ed_media_text,
							},
								multiple: false
							} );
							upload_frame.on( 'select',function() {
								let attachment;
								attachment = upload_frame.state().get( 'selection' ).first().toJSON();
								
								//
								const videoReg = /^.*\.(avi|AVI|wmv|WMV|flv|FLV|mpg|MPG|mp4|MP4)$/gi;
								const imgReg   = /^.*\.(gif|jpe?g|tiff|png|webp|bmp)$/gi;
								const placeholderImg = '<svg width="135" x="0px" y="0px" viewBox="0 0 102.55 122.88" transform="scale(0.7) translate(-30 -55)"><path fill="#333" d="M102.55,122.88H0V0h77.66l24.89,26.44L102.55,122.88L102.55,122.88z M25.51,53.72h15.67V43.33H25.51V32.56 l15.67,0V21.85H25.51V11.08h15.67V7.83H8.43v106.23h85.77V32.36H71.52V7.83H56.86v3.29H41.18v10.71l15.68,0V32.6H41.18v10.49h15.68 v24.99c0,7.9-6.46,14.36-14.36,14.36l-2.63,0c-7.9,0-14.36-6.46-14.36-14.36V53.72L25.51,53.72z M36.28,63.07h10.28v4.06 c0,2.23-2.12,4.05-4.71,4.05h-0.86c-2.59,0-4.71-1.83-4.71-4.05V63.07L36.28,63.07L36.28,63.07z"/></svg>';
								
								
								//The RegExp object keeps track of the lastIndex where a match occurred, so on 
								//subsequent matches it will start from the last used index, instead of 0.
								videoReg.lastIndex = 0;
								imgReg.lastIndex = 0;	
								
								
								const element = attachment.url;
								
								//image or video preview
								if ( videoReg.test( element ) ) {
                                    ed.insertContent( '<video width="400" height="300" src="'+element+'" controls></video>' );
								} else if ( imgReg.test( element ) ) {
                                    ed.insertContent( '<img src="'+element+'" alt="">' );
								} else {
									ed.insertContent( '<img style="display:none;" class="mce-ed-intertplaceholder d-none" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="null"><a class="mce-ed-intertfile d-block" href="'+element+'" target="_blank" style="display: block;max-width: 100px;max-height: 120px;padding-top: 18px;">'+placeholderImg+'</a>' );
								}
		

								
							} );

							upload_frame.open();
							
						}

						ed.addButton('uix_cmb_image', {
						  icon: 'mce-ico mce-i-image',
						  tooltip: uix_custom_metaboxes_lang.ed_image,
						  onclick: uix_mce_insertImage
						});
						
						
						// Add link button
						ed.addButton('uix_cmb_link', {
							icon: 'mce-ico mce-i-link',
							tooltip: uix_custom_metaboxes_lang.ed_link_title,
							onclick: function (e) {
								
								const urlRegex     = /<a href="(.*?)"/g,
									urlMatch     = '',
									selectedtxt  = ed.selection.getContent(),
									curlabel     = selectedtxt.replace(/<a\b[^>]*>/i, '' ).replace(/<\/a>/i, '' );
								
								let	curlinkURL   = '';
								
								while( urlMatch = urlRegex.exec( selectedtxt ) ){
									curlinkURL = urlMatch[1];
								}	

								ed.windowManager.open( {
									title: uix_custom_metaboxes_lang.ed_link_title,
									body: [
									{
										type: 'textbox',
										label: uix_custom_metaboxes_lang.ed_link_field_url,
										name: 'link_url',
										value: curlinkURL,
										placeholder: 'https://',
										multiline: true,
										minWidth: 500,
										minHeight: 30,
									},
									{
										type: 'textbox',
										label: uix_custom_metaboxes_lang.ed_link_field_text,
										name: 'link_text',
										value: curlabel,
										multiline: true,
										minWidth: 500,
										minHeight: 30,
									},	   
										
									{
										type: 'checkbox',
										name: 'link_target',
										label: ' ',
										text: ' ' + uix_custom_metaboxes_lang.ed_link_field_win,
									},
				
										
									],
									onsubmit: function( e ) {
										
										const curtxt      = ( e.data.link_text != '' ) ? e.data.link_text : e.data.link_url,
											target      = ( e.data.link_target ) ? 'target="_blank"' : '';
										
										ed.insertContent( '<a href="' + e.data.link_url + '" ' + target + '>' + curtxt + '</a>');
									}
								});
							}
						});
						
						
						//Delete link button
						ed.addButton('uix_cmb_unlink', {
							icon: 'mce-ico mce-i-unlink',
							tooltip: uix_custom_metaboxes_lang.ed_unlink_title,
							onclick: function (e) {
								
								const selectedtxt  = ed.selection.getContent();
								selectedtxt = selectedtxt.replace(/<a\b[^>]*>/i, '' ).replace(/<\/a>/i, '' );
								ed.insertContent(  selectedtxt );
								
							}
						});
                        
                        
						// Add Syntax Highlight Code button
						ed.addButton('uix_cmb_highlightcode', {
							image: 'data:image/png;base64, ',
							tooltip: uix_custom_metaboxes_lang.ed_hcode_title,
							onclick: function (e) {
								
								
								ed.windowManager.open( {
									title: uix_custom_metaboxes_lang.ed_hcode_title,
									body: [
                                        {
                                            type   : 'listbox',
                                            name   : 'lang',
                                            label  : uix_custom_metaboxes_lang.ed_hcode_field_label,
                                            values : [
                                                { value: 'xml', text: 'xml' },
                                                { value: 'css', text: 'css' },
                                                { value: 'html', text: 'html/xhtml' },
                                                { value: 'xslt', text: 'xslt' },
                                                { value: 'php', text: 'php' },
                                                { value: 'javascript', text: 'javascript' },
                                                { value: 'python', text: 'python' },
                                                { value: 'applescript', text: 'applescript' },
                                                { value: 'as3', text: 'as3' },
                                                { value: 'plain', text: 'plain' },
                                                { value: 'perl', text: 'perl' },
                                                { value: 'bash', text: 'bash' },
                                                { value: 'javafx', text: 'javafx' },
                                                { value: 'ruby', text: 'ruby' },
                                                { value: 'shell', text: 'shell' },
                                                { value: 'java', text: 'java' },
                                                { value: 'sass', text: 'sass' },
                                                { value: 'scss', text: 'scss' },
                                                { value: 'scala', text: 'scala' },
                                                { value: 'sql', text: 'sql' },
                                                { value: 'coldfusion', text: 'coldfusion' },
                                                { value: 'vb', text: 'vb' },
                                                { value: 'groovy', text: 'groovy' },
                                                { value: 'erlang', text: 'erlang' },
                                                { value: 'diff', text: 'diff' },
                                                { value: 'patch', text: 'patch' },
                                                { value: 'delphi', text: 'delphi' },
                                                { value: 'pascal', text: 'pascal' },
                                                { value: 'c#', text: 'c#' },
                                                { value: 'cpp', text: 'c/c++' }
                                            ],
                                            minWidth: 350
                                        },
                                        {
                                            type: 'textbox',
                                            name: 'content',
                                            multiline: true,
                                            minWidth: ed.getParam("code_dialog_width", 600),
                                            minHeight: ed.getParam("code_dialog_height", Math.min(tinymce.DOM.getViewPort().h - 200, 500)),
                                            spellcheck: false,
                                            style: 'direction: ltr; text-align: left'
                                        },	   
										
									],
									onsubmit: function( e ) {
										
										var _content = e.data.content.replace(/(\r)*\n/g, "<br>" );

										ed.insertContent( '<pre data-language="' + e.data.lang + '" class="' + e.data.lang + ' brush: ' + e.data.lang + ';">' + _content + '</pre>');
										
										
									}
								});
							}
						});                   
                        

						
				   },
				  content_css: [
					uix_custom_metaboxes_lang.ed_url + 'css/uix-custom-metaboxes-editor.css'
				  ]
				});	
			}
			
	
			
		});
 
    };
 
}( jQuery ));


( function ( $ ) {
	'use strict';
    $.fn.UixEditorInit = function( options ) {
 
        // This is the easiest way to have default options.
        const settings = $.extend({
            id      : '', 
            toolbar : '', 
            height  : '',
            init    : false
        }, options );
 
        this.each( function() {
	
            const $this    = $( this ),
                id       = settings.id, 
                toolbar  = settings.toolbar, 
                height   = settings.height;
            
            
            if ( settings.init ) {
                $this.attr( 'aria-init', 0 );
            }
			
            if ( $this.attr( 'aria-init' ) == 0 ) {
                const _textarea = $this.find( 'textarea' );
                $( document ).UixMCEEditor({
                    id      : _textarea.attr( 'id' ), 
                    toolbar : _textarea.data( 'editor-toolbar' ), 
                    height  : _textarea.data( 'editor-height' )
                });     

                $this.attr( 'aria-init', 1 );
            }

	
			
		});
 
    };
 
}( jQuery ));



/*! 
 * ************************************
 * Initialize Select of Toggle (include parent category)
 *************************************
 */	

( function ( $ ) {
	'use strict';
    $.fn.UixToggleSelectInit = function( options ) {
 
        // This is the easiest way to have default options.
        const settings = $.extend({
            wrapper           : '.uix-cmb__text--div--toggle.uix-cmb__text--div--toggle-customlevel',
            wrapperChild      : '.uix-cmb__text--div--toggle--child',
            fieldSelect       : '.uix-cmb__text--div--toggle__sel', 
            fieldId           : '.uix-cmb__text--div--toggle__id',
            fieldTitle        : '.uix-cmb__text--div--toggle__title',
            fieldDefaultValue : '.uix-cmb__text--div--toggle__toggleSelect',
            trigger           : '.uix-cmb__text--div--toggle__trigger'
        }, options );
 
        this.each( function() {
            
            

			// Step (1)
			// Add position attribute to each list
			//---------------
			const listItemsPosition = [];
			const $listItemsContainer = $( settings.wrapper ).first().closest( 'td' );
			$( settings.wrapper ).each( function( i )  {
				$( this ).attr('data-position', i);

				listItemsPosition.push({
					"id": $( this ).find( settings.fieldId ).val(),
					"position": i
				});
			});	


			//console.log( 'items position: ', listItemsPosition );



			// Step (2)
			// Traverse all the item IDs in the form as `all options` of select
			//---------------
			const formData = $( 'form#post' ).serializeArray();
			const variableData = Object.assign([], formData);
			//console.log('orginal data: ', formData);


			// Step (3)
			// Extract the selected options, filter other form types, and create a new array
			//---------------

			// Traverse all titles
			let _titles = [];

			formData.forEach(function(item, index){
				if ( item.name.indexOf( '_attrs_title[]' ) >= 0 ) {
					_titles.push(item.value);
				}
			});


			// Get the default parent ID (if it exists)
			let _parentIDs = [];

			formData.forEach(function(item, index){
				if ( item.name.indexOf( '_attrs_parent[]' ) >= 0 ) {
					_parentIDs.push(item.value);
				}
			});


			//
			let selectAllIDsRes = [];

			formData.forEach(function(item, index){
				if ( item.name.indexOf( '_attrs_id[]' ) >= 0 ) {
					selectAllIDsRes.push(
					   {  
						  "id": item.value
					   }
					);
				}
			});


			selectAllIDsRes.forEach(function(item, index){
				selectAllIDsRes[index].name = _titles[index];
				selectAllIDsRes[index].parent = _parentIDs[index];
			});


			//console.log('variable all data', selectAllIDsRes);

			/*
			Target data structure (selectAllIDsRes): 
			[
				{id: "1", name: "Title 1", parent: ""},
				{id: "2", name: "Title 2", parent: ""},
				{id: "3", name: "Title 3", parent: "5"},
				{id: "4", name: "Title 4", parent: "2"},
				{id: "5", name: "Title 5", parent: ""},
				{id: "6", name: "Title 6", parent: "5"},
				{id: "7", name: "Title 7", parent: ""},
				{id: "8", name: "Title 8", parent: "5"},
				{id: "9", name: "Title 9", parent: ""}
			]
			*/



			// Step (4)
			// If there is already a parent, option cannot appear in the root list
			//---------------
			const filterData = function(allData) {

				let newData = Object.assign([], allData);
				allData.forEach(function(item, k){
					for (let i = 0; i < newData.length; i++) {
						if (newData[i].parent != '') {
							newData.splice(i, 1);
						}
					}
				});

				return newData;
			};

			const variableDefaultResDataFilter = filterData(selectAllIDsRes);
			//console.log('variable data (new)(default): ', variableDefaultResDataFilter);

			/*
			Target data structure (variableDefaultResDataFilter): 
			[
				{id: "1", name: "Title 1", parent: ""},
				{id: "2", name: "Title 2", parent: ""},
				{id: "5", name: "Title 5", parent: ""},
				{id: "7", name: "Title 7", parent: ""},
				{id: "9", name: "Title 9", parent: ""}
			]
			*/




			// Step (5)
			// Construct the select HTML structure and initialize it (do not trigger in the change event)
			//---------------

			// Update appearance for each item
			const updateAppearance = function( data, stylesAndOrderUpdate ) {

				// ++++++++++++++++++++++++++++
				// sort
				// ++++++++++++++++++++++++++++

				//get the grouped data by parent id
				const groupDataSortByParentID = [];
				data.forEach(function(item1, i){
					data.forEach(function(item2, j){
						if ( item1.id === item2.parent ) groupDataSortByParentID.push({
							"id": item2.id, 
							"name": item2.name, 
							"parent": item2.parent
						});
					});

				});
				//console.log('groupDataSortByParentID: ', groupDataSortByParentID);
				/*
				Target data structure (groupDataSortByParentID): 
				[
					{id: "4", name: "Title 4", parent: "2"},
					{id: "3", name: "Title 3", parent: "5"},
					{id: "6", name: "Title 6", parent: "5"},
					{id: "8", name: "Title 8", parent: "5"}
				]
				*/


				//combine all data
				const variableResDataSortAll = [];
				let allDataWithoutParentIds = Object.assign([], data);


				//delete json
				groupDataSortByParentID.forEach(function(childItem, k){
					for (let i = 0; i < allDataWithoutParentIds.length; i++) {
						if (allDataWithoutParentIds[i].id == childItem.id) {
							allDataWithoutParentIds.splice(i, 1);
						}
					}
				});


				//console.log('allDataWithoutParentIds: ', allDataWithoutParentIds);

				/*
				Target data structure (allDataWithoutParentIds): 
				[
					{id: "1", name: "Title 1", parent: ""},
					{id: "2", name: "Title 2", parent: ""},
					{id: "5", name: "Title 5", parent: ""},
					{id: "7", name: "Title 7", parent: ""},
					{id: "9", name: "Title 9", parent: ""}
				]
				*/


				allDataWithoutParentIds.forEach(function(item, i){

					variableResDataSortAll.push(item);

					groupDataSortByParentID.forEach(function(childItem, i){
						if ( childItem.parent === item.id ) {
							variableResDataSortAll.push( childItem );
						}
					});


				});

				//console.log('variable all data (sort list): ', variableResDataSortAll);

				
				
				/*
				Target data structure (variableResDataSortAll): 
				[
					{id: "1", name: "Title 1", parent: ""},
					{id: "2", name: "Title 2", parent: ""},
					{id: "4", name: "Title 4", parent: "2"},
					{id: "5", name: "Title 5", parent: ""},
					{id: "3", name: "Title 3", parent: "5"},
					{id: "6", name: "Title 6", parent: "5"},
					{id: "8", name: "Title 8", parent: "5"},
					{id: "7", name: "Title 7", parent: ""},
					{id: "9", name: "Title 9", parent: ""}	
				]
				*/	
				



				// Change the order of html elements through the `data-position` attribute
				const listItemsNewPosition = Object.assign([], listItemsPosition);
				listItemsNewPosition.forEach(function(oldItem, i){
					variableResDataSortAll.forEach(function(newItem, j){
						if ( oldItem.id === newItem.id ) {
							oldItem.position = j;
						}
					});

				});

				//console.log( 'items position (new): ', listItemsNewPosition);

				/*
				Target data structure (listItemsNewPosition): 
				[
					{id: "1", position: 0},
					{id: "2", position: 1},
					{id: "3", position: 4},
					{id: "4", position: 2},
					{id: "5", position: 3},
					{id: "6", position: 5},
					{id: "7", position: 7},
					{id: "8", position: 6},
					{id: "9", position: 8}
				]	

				*/	


				// Update the new `data-position` attribute to the HTML element
				listItemsNewPosition.forEach(function(item, i){
					const $wrapper = $( settings.fieldId + '[value="'+item.id+'"]').closest( settings.wrapper );
					$wrapper.attr( 'data-position', item.position );
				});


				// Sort HTML elements based on data attribute value
				if ( stylesAndOrderUpdate ) {
					
					const listItems = [];
					$( settings.wrapper ).each( function( i )  {
						listItems.push( $( this ) );
					});	

					listItems.sort(function (a, b) {
						return parseFloat( $(b).attr('data-position') ) < parseFloat( $(a).attr('data-position') ) ? 1 : -1;
					});


					listItems.forEach(function(item, i){
						item.appendTo( $listItemsContainer );
					});
					
					

					//Initialize Editor
					setTimeout(function() {
						UixCustomMetaboxesInit.editor( true );   
					}, 100);
					
				}//endif stylesAndOrderUpdate




				
				// ++++++++++++++++++++++++++++
				// styles
				// ++++++++++++++++++++++++++++
				if ( stylesAndOrderUpdate ) {
					
					data.forEach(function(item, index){

						const pid = item.parent;
						const $wrapper = $( settings.fieldId + '[value="'+item.id+'"]').closest( settings.wrapper );
						const childClassName = settings.wrapperChild.replace( '.', '' );
						if ( pid != '' ) {
							$wrapper.addClass( childClassName );
						} else {
							$wrapper.removeClass( childClassName );
						}	

					});
					
				}//endif stylesAndOrderUpdate

				
				
		
				// ++++++++++++++++++++++++++++
				// The data stored in PHP uses the reserved method
				// ++++++++++++++++++++++++++++
				
				// reversed method --> allDataWithoutParentIds
				const allDataWithoutParentIdsReversed = Object.assign([], allDataWithoutParentIds);
				const variableResDataSortAllReversed = [];
				allDataWithoutParentIdsReversed.reverse();
				
				allDataWithoutParentIdsReversed.forEach(function(item, i){

					variableResDataSortAllReversed.push(item);

			
					// Loop through an array backward
					const groupDataSortByParentIDReversed = groupDataSortByParentID.slice().reverse();		
					groupDataSortByParentIDReversed.forEach(function(childItem, i){
						if ( childItem.parent === item.id ) {
							variableResDataSortAllReversed.push( childItem );
						}
					});


				});
				
				//console.log('variable all data (sort list)(reversed): ', variableResDataSortAllReversed);
				
				
				
				
				//Repackage all the data of the form fields and save it to the database of the PHP 
				const createPHPData = function( data ) {
					const phpData = [];
					data.forEach(function(item, j){
						const $wrapper = $( settings.fieldId + '[value="'+item.id+'"]').closest( settings.wrapper );
						const fieldData = $wrapper.find( '*' ).serializeArray();
						

						// Traverse all field to match PHP array
						const phpDataItem = {};
						fieldData.forEach(function(item, index){
							if ( item.name.indexOf( '_attrs_title[]' ) >= 0 ) phpDataItem.name = item.value;
							if ( item.name.indexOf( '_attrs_id[]' ) >= 0 ) phpDataItem.id = item.value;
							if ( item.name.indexOf( '_attrs_parent[]' ) >= 0 ) phpDataItem.parent = item.value;
							if ( item.name.indexOf( '_attrs_desc[]' ) >= 0 ) phpDataItem.desc = item.value.replace(/ /g, '&nbsp;');
							if ( item.name.indexOf( '_attrs_classname[]' ) >= 0 ) phpDataItem.classname = item.value;
							if ( item.name.indexOf( '_attrs_value_sync[]' ) >= 0 ) phpDataItem.value = item.value;
						});

						
						phpData.push( phpDataItem );

					});	
			
					return JSON.stringify( phpData );
				};
				
				console.log( '"Multiple Content Area" data: ', variableResDataSortAllReversed, '"Multiple Content Area" data(reversed): ', variableResDataSortAll );
				
				
				$listItemsContainer.find( 'textarea.uix-cmb__custom-attributes-field__resultData' ).val( createPHPData(variableResDataSortAllReversed) );

				$listItemsContainer.find( 'textarea.uix-cmb__custom-attributes-field__resultReverseData' ).val( createPHPData(variableResDataSortAll) );
				
				

			};


			// Generate HTML code of select control
			const selectBuilder = function( data, parentID, removeID ) {
				let html_code = '<select class="uix-cmb__text--fullwidth uix-cmb__text--div--toggle__sel">';
				html_code += '<option value=""> - </option>';
				data.forEach(function(item, index){
					const selected = parentID ? (item.id === parentID ? 'selected' : '') : '';

					// If the current option and ID overlap, remove the current option
					if ( removeID && removeID != item.id ) {
						html_code += '<option value="' + item.id + '" '+selected+'>' + item.name + '</option>';
					}

				});

				html_code += '</select>';	

				return html_code;
			};


			// Update select controls and push to each list
			const updateSelects = function(dataFilter, dataAll) {


				// Get items with parent ID
				const hasParentIDs = [];
				for (let i = 0;i < dataAll.length; i++) {
					for (let j = 0;j < dataAll.length; j++) {
						//console.log( dataAll[i].id + '==== ' + dataAll[j].parent);
						if ( dataAll[i].id == dataAll[j].parent ) {
							hasParentIDs.push( dataAll[j].parent );
						}
					}
				}

				const hasParentIDsRes = [];
				for (let i = 0; i < hasParentIDs.length; i++) {
					if (hasParentIDsRes.indexOf(hasParentIDs[i]) === -1) {
						hasParentIDsRes.push(hasParentIDs[i]);
					}
				}



				//
				$( settings.wrapper ).each( function()  {

					const $wrapper = $( this );
					const _cid = $wrapper.find( settings.fieldId ).val();
					const _pid = $wrapper.find( settings.fieldDefaultValue ).val();
					let _code = selectBuilder( dataFilter, false, _cid );


					// If there is a parent ID, the parent option is empty 
					for (let k = 0; k < hasParentIDsRes.length; k++) {
						if (hasParentIDsRes[k] === _cid ) {
							let _codeEmpty = '<select class="uix-cmb__text--fullwidth uix-cmb__text--div--toggle__sel">';
							_codeEmpty += '<option value=""> - </option>';
							_codeEmpty += '</select>';	
							_code = _codeEmpty;	

							break;
						}
					}


					//
					$wrapper.find( '.uix-cmb__text--div--toggle__toggleSelect__append' ).html( _code ).promise().done( function(){

						//init default value for select control
						$wrapper.find( '.uix-cmb__text--div--toggle__toggleSelect__append > select' ).val( _pid );

					});
				});	


				//update appearance for each item (include styles & order HTML elements)
				updateAppearance( dataAll, true );



			};

			updateSelects( variableDefaultResDataFilter, selectAllIDsRes );


			
			

			// Step (6)
			// Change event, change json structure (do not trigger dom)
			//---------------
			const updateData = function(data, curID, targetValue) {

				//console.log('data: ', data);
				for (let i = 0; i < data.length; i++) {
					if (data[i]['id'] == curID) {
						data[i].parent = targetValue;
					}
				}
				return data;
			};

			//
			$( document ).off( 'change.UixToggleSelect' ).on( 'change.UixToggleSelect', settings.wrapper + ' .uix-cmb__text--div--toggle__toggleSelect__append > select', function() {

				const parentID = $( this ).val();
				const $wrapper = $( this ).closest( settings.wrapper );
				const curID = $wrapper.find( settings.fieldId ).val();
				const resData = updateData( selectAllIDsRes, curID, parentID );
				let variableResData = Object.assign([], resData);

				$wrapper.find( settings.fieldDefaultValue ).val( parentID );

		
				//console.clear();
				//console.log('variable all data (changed by select): ', resData);


				//filter data
				const variableResDataFilter = filterData(variableResData);
				//console.log('variable data (new): ', variableResDataFilter);

				//update options
				updateSelects( variableResDataFilter, resData );



			}); 


			
			//
			$( document ).off( 'change.UixInputTextarea' ).on( 'change.UixInputTextarea', settings.wrapper + ' .uix-cmb__text--div--toggle__title, ' + settings.wrapper + ' .uix-cmb__text--div--toggle__classname, ' + settings.wrapper + ' .uix-cmb__text--div--toggle__textarea, ' + settings.wrapper + ' textarea[data-enter-value="true"]', function() {

				//update appearance for each item
				updateAppearance( selectAllIDsRes, false );

			}); 

			
			
            
		});
 
    };
 
}( jQuery ));




/*! 
 * ************************************
 * Initialize Simple Select of Toggle
 *************************************
 */	
( function ( $ ) {
	'use strict';
    $.fn.UixToggleSimpleSelectInit = function( options ) {
 
        // This is the easiest way to have default options.
        const settings = $.extend({ 
            type              : 'file',
            wrapper           : '.uix-cmb__text--div--toggle:not(.uix-cmb__text--div--toggle-customlevel)',
            trigger           : '.uix-cmb__text--div--toggle__trigger'
        }, options );
 
        this.each( function( index ) {
            
            const $this = $( this ),
                $selInput = $this.prev( '[type="hidden"]' );
			
            let defaultVal = $selInput.val();
            
            
            if ( defaultVal == '' ) {
                defaultVal = $this.find( 'option:selected' ).val();
            }
            
            //Get the root container style
            let el = '';
            const elArr = $this[0].classList;

            if ( elArr && elArr.length ) {
                elArr.forEach( function( element ) {
                    el += '.' + element;
                });    
            }
            
            
            //Determine if it is the last element
            const last = ( index == $( el ).length - 1 ) ? true : false;
            
            
            if ( settings.type == 'html' && last ) {
                defaultVal = $this.find( 'option' ).eq( 1 ).val();
            }

            
            //set default value for select
            $selInput.val( defaultVal );    
            $this.val( defaultVal );    
            $this.closest( settings.wrapper ).find( settings.trigger ).find( 'span' ).html( $this.find( 'option:selected' ).text() );

            
            //Display or hide fields
            switch( defaultVal ) {
                case 'file':
                $this.closest( settings.wrapper ).find( '.uix-cmb__text--row[data-type="file"]' ).show();
                $this.closest( settings.wrapper ).find( '.uix-cmb__text--row[data-type="html"]' ).hide();
                break;

                case 'html':
                $this.closest( settings.wrapper ).find( '.uix-cmb__text--row[data-type="file"]' ).hide();
                $this.closest( settings.wrapper ).find( '.uix-cmb__text--row[data-type="html"]' ).show();
                break;      
            }      
            
               

            //Store temporary default value
            $this.off( 'change.UixToggleSimpleSelect' ).on( 'change.UixToggleSimpleSelect', function() {
                $selInput.val( $( this ).val() );
                $( this ).closest( settings.wrapper ).find( settings.trigger ).find( 'span' ).html( $( this ).find( 'option:selected' ).text() );
            }); 
            
                

            
		});
 
    };
 
}( jQuery ));

/*! 
 * ************************************
 * Create GUID / UUID
 *
 * @private
 * @description This function can be used separately in HTML pages or custom JavaScript.
 * @return {String}                        - The globally-unique identifiers.
 *************************************
 */	
function UixGUIDCreate() {
	return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
		const r = Math.random() * 16 | 0,
			  v = c == 'x' ? r : (r & 0x3 | 0x8);
		return v.toString(16);
	});
}



/*! 
 * ************************************
 * Get the real form ID from the associated attribute "data-targetid"
 *
 * Note: Used for controls "toggle", "checkbox", "radio"
 *
 * @param  {string} targetID          - All id of the target control. Like this: uix_pb_???_??, uix_pb_???_??, uix_pb_???_??,
 * @return {string}                   - Converted value matching this (clone) control ID. Note that the prefix has a "#".
                                            Like this: [name="cus_field_???1"],
											           [name="cus_field_???2"],
													   [name="cus_field_???3"],
 
 
 *	 
 *************************************
 */	
function UixGetRealIds( targetID ) {
	
	let result = '';
	if ( typeof targetID !== typeof undefined && targetID != '' ) {

		targetID = targetID.replace(/,\s*$/, '' );
		const ids = targetID.split( ',' );

		for ( let i = 0; i < ids.length; i++ ) {

			if ( ids[i] != '' ) {
				result += '[name="' + ids[i] + '"],';
			}

		}//end for
		result = result.replace(/,\s*$/, '' );

	}	
	return result;
}

