﻿﻿simple_upsell_section.php                                                                           0000666                 00000003205 15226760543 0011674 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Simple upsell customizer section.
 *
 * @package Neve
 */

namespace Neve\Customizer\Controls;

/**
 * Customizer section.
 *
 * @since  2.8.3
 * @see        WP_Customize_Section
 */
class Simple_Upsell_Section extends \WP_Customize_Section {
	/**
	 * Type of this section.
	 *
	 * @var string
	 */
	public $type = 'nv_simple_upsell_section';

	/**
	 * Button text.
	 *
	 * @var   string
	 */
	public $button_text = '';

	/**
	 * Button link.
	 *
	 * @var   string
	 */
	public $link = '';

	/**
	 * List of features.
	 *
	 * @var   string
	 */
	public $text = '';

	/**
	 * Screen reader text.
	 *
	 * @var string
	 */
	public $screen_reader = '';

	/**
	 * Gather the parameters passed to client JavaScript via JSON.
	 *
	 * @return array The array to be exported to the client as JSON.
	 */
	public function json() {
		$json                  = parent::json();
		$json['button_text']   = $this->button_text;
		$json['link']          = $this->link;
		$json['text']          = $this->text;
		$json['screen_reader'] = __( '(opens in a new tab)', 'neve' );

		return $json;
	}

	/**
	 * Render template.
	 */
	protected function render_template() {
		?>
		<li id="accordion-section-{{ data.id }}" class="control-section-{{ data.type }}">
			<div class="nv-simple-upsell">
				<# if( data.text ) { #>
					<p>{{data.text}}</p>
				<# } #>
				<# if( data.link && data.button_text ) { #>
					<a rel="external noreferrer noopener" target="_blank" href="{{data.link}}" class='button button-secondary'>
						{{data.button_text}}
						<span class="components-visually-hidden">{{data.screen_reader}}</span>
					</a>
				<# } #>
			</div>
		</li>
		<?php
	}
}


                                                                                                                                                                                                                                                                                                                                                                                           tabs.php                                                                                            0000666                 00000004153 15226760543 0006227 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * The tabs customize control extends the WP_Customize_Control class. This class allows
 * developers to create tabs and hide the sections' settings easily.
 *
 * @package    Neve\Customizer\Controls
 * @since      1.1.45
 * @author     Andrei Baicus <andrei@themeisle.com>
 * @copyright  Copyright (c) 2017, Themeisle
 * @link       http://themeisle.com/
 * @license    http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 */

namespace Neve\Customizer\Controls;

/**
 * Radio image customize control.
 *
 * @since  1.1.45
 * @access public
 */
class Tabs extends \WP_Customize_Control {

	/**
	 * The type of customize control being rendered.
	 *
	 * @since 1.1.45
	 * @var   string
	 */
	public $type = 'interface-tabs';

	/**
	 * The tabs with keys of the controls that are under each tab.
	 *
	 * @since 1.1.45
	 * @var array
	 */
	public $tabs;

	/**
	 * Controls from tabs.
	 *
	 * @var array
	 */
	public $controls;

	/**
	 * Add custom JSON parameters to use in the JS template.
	 *
	 * @return array
	 */
	public function json() {
		$json             = parent::json();
		$json['tabs']     = $this->tabs;
		$json['controls'] = $this->controls;
		return $json;
	}

	/**
	 * Underscore JS template to handle the control's output.
	 *
	 * @return void
	 */
	public function content_template() {
		?>
		<# if ( ! data.tabs ) { return; } #>

		<div class="neve-tabs-control" id="">
		<# var i = 1;
			for( tab in data.tabs) { #>
				<#
				var allControlsInTabs = ''
				_.each( data.controls[tab], function( val, key ) {
					allControlsInTabs+= key + ' '
					if(val){
						var allvals = Object.keys(val).map(function(e) {
							return val[e]
						});
						allvals = _.uniq(_.flatten(allvals))
						allvals = allvals.join(' ')
						allControlsInTabs += allvals
					}
				});
				#>
			<div class="neve-customizer-tab <# if( i === 1 ){#> active <#}#>" data-tab="{{tab}}">
				<label class="{{allControlsInTabs}}">
					<# if(data.tabs[tab]['icon']) { #>
						<i class="dashicons dashicons-{{data.tabs[tab]['icon']}}"></i>
					<# } #>
					{{data.tabs[tab]['label']}}
				</label>
			</div>
		<# i++;} #>
		</div>


		<?php
	}
}

                                                                                                                                                                                                                                                                                                                                                                                                                     ordering.php                                                                                        0000666                 00000006570 15226760543 0007114 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Author:          Andrei Baicus <andrei@themeisle.com>
 * Created on:      29/08/2018
 *
 * @package Ordering.php
 */

namespace Neve\Customizer\Controls;

/**
 * Class Ordering
 *
 * @package Neve\Customizer\Controls
 */
class Ordering extends \WP_Customize_Control {

	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'ordering';

	/**
	 * Orderable components.
	 *
	 * @var array
	 */
	private $components = array();

	/**
	 * Ordering constructor.
	 *
	 * @param \WP_Customize_Manager $manager Wp customize.
	 * @param string                $id      control id.
	 * @param array                 $args    control args.
	 */
	public function __construct( \WP_Customize_Manager $manager, $id, array $args = array() ) {
		parent::__construct( $manager, $id, $args );
		$this->components = $args['components'] ? $args['components'] : array();

		$this->setup_components();
	}

	/**
	 * Get disabled components
	 * Add them at the end of all components in the customizer
	 */
	private function setup_components() {
		$val = $this->value();
		if ( ! is_string( $val ) ) {
			$val = '[]';
		}
		$val = json_decode( $val, true );

		if ( ! is_array( $val ) ) {
			$val = array();
		}

		$enabled          = array_combine( $val, $val );
		$disabled         = array_diff_assoc( $this->components, $enabled );
		$this->components = array_merge( $enabled, $disabled );
	}

	/**
	 * Render content of control.
	 */
	public function render_content() {
		$this->render_control_label();
		$this->render_sortable_list();
		$this->render_collector_input();
	}

	/**
	 * Render title and description.
	 *
	 * @return void
	 */
	private function render_control_label() {
		if ( empty( $this->label ) && empty( $this->description ) ) {
			return;
		}
		echo '<label>';
		if ( ! empty( $this->label ) ) {
			echo '<span class="customize-control-title">' . esc_html( $this->label ) . '</span>';
		}
		if ( ! empty( $this->description ) ) {
			echo '<span class="description customize-control-description">' . wp_kses_post( $this->description ) . '</span>';
		}
		echo '</label>';
	}

	/**
	 * Render sortable list.
	 *
	 * @return void
	 */
	private function render_sortable_list() {
		if ( empty( $this->components ) ) {
			return;
		}

		echo '<ul class="ti-order-sortable">';
		foreach ( $this->components as $component => $name ) {
			if ( $component === $name ) {
				continue;
			}
			echo '<li class="ui-state-default order-component' . esc_attr( $this->get_component_status_class( $component ) ) . '" data-id="' . esc_attr( $component ) . '">';
			echo '<span class="toggle-display"></span>';
			echo '<p>' . esc_html( $name ) . '</p>';
			echo '<span class="dashicons dashicons-menu drag"></span>';
			echo '</li>';
		}
		echo '</ul>';
	}

	/**
	 * Get the class for the component. (enabled/disabled)
	 *
	 * @param string $component the component to check.
	 *
	 * @return string
	 */
	private function get_component_status_class( $component ) {
		$value = $this->value();
		if ( empty( $value ) ) {
			return ' enabled';
		}
		$value = json_decode( $value, true );

		if ( ! is_array( $value ) ) {
			$value = array();
		}

		if ( ! in_array( $component, $value, true ) ) {
			return '';
		}

		return ' enabled';
	}

	/**
	 * Render the collector input.
	 *
	 * @return void
	 */
	private function render_collector_input() {
		echo '<input type="hidden" class="ti-order-collector"' . wp_kses_post( $this->get_link() ) . '>';
	}
}
                                                                                                                                        button_group.php                                                                                    0000666                 00000003553 15226760543 0010030 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Button group control.
 *
 * @package Neve\Customizer\Controls
 */

namespace Neve\Customizer\Controls;

/**
 * Class Button_Group
 *
 * @package Neve\Customizer\Controls
 */
class Button_Group extends \WP_Customize_Control {
	/**
	 * Render content for the control.
	 */
	public function render_content() {
		$this->render_control_header();
		$name     = 'nv_radio_' . $this->id;
		$input_id = 'nv_customize-input-' . $this->id;
		?>
		<div class="nv-button-group">
			<?php
			foreach ( $this->choices as $value => $icon_class ) {
				?>
				<input
						id="<?php echo esc_attr( $input_id . '-radio-' . $value ); ?>"
						type="radio"
						value="<?php echo esc_attr( $value ); ?>"
						name="<?php echo esc_attr( $name ); ?>"
					<?php $this->link(); ?>
					<?php checked( $this->value(), $value ); ?>
				/>
				<label for="<?php echo esc_attr( $input_id . '-radio-' . $value ); ?>" class="button">
					<i class="dashicons <?php echo esc_attr( $icon_class ); ?>"></i>
				</label>
			<?php } ?>
		</div>
		<?php
	}

	/**
	 * Render control header.
	 */
	private function render_control_header() {
		if ( empty( $this->label ) && empty( $this->description ) ) {
			return;
		} 
		?>
		<div class="nv-button-group-header">
			<?php if ( ! empty( $this->label ) ) { ?>
				<span class="customize-control-title">
				<span><?php echo esc_html( $this->label ); ?></span>
			</span>
				<?php 
			}
			if ( ! empty( $this->description ) ) { 
				?>
				<label class="nv-radio-description-info"
						for="<?php echo esc_attr( $this->id . '-description-toggle' ); ?>">
					<i class="dashicons dashicons-info"></i>
				</label>
				<input id="<?php echo esc_attr( $this->id . '-description-toggle' ); ?>" type="checkbox"
						class="expand-description">
				<span class="nv-radio-hidden-info"><?php echo esc_html( $this->description ); ?></span>
			<?php } ?>
		</div>
		<?php
	}
}
                                                                                                                                                     upsell_control.php                                                                                  0000666                 00000006430 15226760543 0010342 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * The upsell customize control extends the WP_Customize_Control class.
 *
 * @package    Neve\Customizer\Controls
 * @since      2.3.10
 * @copyright  Copyright (c) 2017, Themeisle
 * @link       http://themeisle.com/
 * @license    http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 */

namespace Neve\Customizer\Controls;

/**
 * Radio image customize control.
 *
 * @since  2.3.10
 * @access public
 */
class Upsell_Control extends \WP_Customize_Control {

	/**
	 * The type of customize control being rendered.
	 *
	 * @since 2.3.10
	 * @var   string
	 */
	public $type = 'neve-control-upsell';

	/**
	 * Button text.
	 *
	 * @since 2.3.10
	 * @var   string
	 */
	public $button_text = '';

	/**
	 * Button link.
	 *
	 * @since 2.3.10
	 * @var   string
	 */
	public $button_url = '';

	/**
	 * List of features.
	 *
	 * @since 2.3.10
	 * @var   array
	 */
	public $options = array();

	/**
	 * List of explained features.
	 *
	 * @since 2.3.10
	 * @var   array
	 */
	public $explained_features = array();

	/**
	 * Label text for each feature.
	 *
	 * @since 2.3.10
	 * @var   string
	 */
	public $pro_label = '';

	/**
	 * Screen reader text.
	 *
	 * @since 2.11.2
	 * @var   string
	 */
	public $screen_reader = '';

	/**
	 * Boolean to check if the pro label is displayed or not.
	 *
	 * @since 2.3.10
	 * @var   bool
	 */
	public $show_pro_label = true;

	/**
	 * Constructor.
	 *
	 * @param \WP_Customize_Manager $manager Customizer manager.
	 * @param string                $id      Control id.
	 * @param array                 $args    Argument.
	 */
	public function __construct( \WP_Customize_Manager $manager, $id, array $args ) {
		parent::__construct( $manager, $id, $args );
		$this->pro_label = esc_html__( 'PRO', 'neve' );
	}

	/**
	 * Add custom JSON parameters to use in the JS template.
	 *
	 * @return array
	 */
	public function json() {
		$json                       = parent::json();
		$json['button_text']        = $this->button_text;
		$json['button_url']         = $this->button_url;
		$json['options']            = $this->options;
		$json['explained_features'] = $this->explained_features;
		$json['show_pro_label']     = $this->show_pro_label;
		$json['pro_label']          = $this->pro_label;
		$json['screen_reader']      = $this->screen_reader;
		return $json;
	}

	/**
	 * Underscore JS template to handle the control's output.
	 *
	 * @return void
	 */
	public function content_template() {
		?>
		<div class="nv-upsell">
			<# if ( data.options ) { #>
			<ul class="nv-upsell-features">
				<# for (option in data.options) { #>
				<li>
					<# if( data.show_pro_label === true ) { #>
					<span class="upsell-pro-label">{{ data.pro_label }}</span>
					<# } #>
					{{ data.options[option] }}
				</li>
				<# } #>
			</ul>
			<# } #>

			<# if ( data.button_text && data.button_url ) { #>
			<a rel="external noreferrer noopener" target="_blank" href="{{ data.button_url }}" class="button button-primary">{{
				data.button_text }}
				<span class="components-visually-hidden">{{ data.screen_reader }}</span>
			</a>
			<# } #>

			<# if ( data.explained_features.length > 0 ) { #>
			<hr>
			<ul class="nv-upsell-feature-list">
				<# for (requirement in data.explained_features) { #>
				<li>* {{ data.explained_features[requirement] }}</li>
				<# } #>
			</ul>
			<# } #>
		</div>
		<?php
	}
}
                                                                                                                                                                                                                                        react/upsell_section.php                                                                            0000666                 00000002047 15226760543 0011424 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Description Upsell Section
 *
 * Author:      Bogdan Preda <bogdan.preda@themeisle.com>
 * Created on:  20-12-{2021}
 *
 * @package neve/neve-pro
 */
namespace Neve\Customizer\Controls\React;

/**
 * Customizer section.
 *
 * @package    WordPress
 * @subpackage Customize
 * @since      4.1.0
 * @see        WP_Customize_Section
 */
class Upsell_Section extends \WP_Customize_Section {
	/**
	 * Type of this section.
	 *
	 * @var string
	 */
	public $type = 'neve_upsell';

	/**
	 * Upgrade URL.
	 *
	 * @var string
	 */
	public $url = '';

	/**
	 * Gather the parameters passed to client JavaScript via JSON.
	 *
	 * @return array The array to be exported to the client as JSON.
	 * @since 4.1.0
	 */
	public function json() {
		$json        = parent::json();
		$json['url'] = $this->url;
		return $json;
	}

	/**
	 * Render template.
	 */
	protected function render_template() {
		?>
		<li id="accordion-section-{{ data.id }}"
			data-slug="{{data.id}}"
			class="control-section control-section-{{ data.type }} neve-upsell">
		</li>
		<?php
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         react/conditional_selector.php                                                                      0000666                 00000001753 15226760543 0012602 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Color Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Button_Appearance
 *
 * @package Neve\Customizer\Controls\React
 */
class Conditional_Selector extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_context_conditional_selector';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var string
	 */
	public $default = '';
	/**
	 * Send to JS.
	 */
	public function json() {
		$json            = parent::json();
		$json['default'] = $this->default;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                     react/button_appearance.php                                                                         0000666                 00000002746 15226760543 0012074 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Button_Appearance Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Button_Appearance
 *
 * @package Neve\Customizer\Controls\React
 */
class Button_Appearance extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_button_appearance';
	/**
	 * Additional arguments passed to JS.
	 * Disables hover controls
	 *
	 * @var bool
	 */
	public $no_hover = false;
	/**
	 * Additional arguments passed to JS.
	 * Disables shadow controls
	 *
	 * @var bool
	 */
	public $no_shadow = false;
	/**
	 * Additional arguments passed to JS.
	 * Disables border radius, border width
	 *
	 * @var bool
	 */
	public $no_border = false;
	/**
	 * Default values.
	 *
	 * @var array
	 */
	public $default_vals = [];

	/**
	 * Send to JS.
	 */
	public function json() {
		$json                = parent::json();
		$json['no_hover']    = $this->no_hover;
		$json['no_shadow']   = $this->no_shadow;
		$json['no_border']   = $this->no_border;
		$json['defaultVals'] = $this->default_vals;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                          react/ordering.php                                                                                  0000666                 00000002164 15226760543 0010205 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Radio Image Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Ordering
 *
 * @package Neve\Customizer\Controls\React
 */
class Ordering extends \WP_Customize_Control {

	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_ordering_control';

	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $components = [];

	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $default_order = [];

	/**
	 * Send to JS.
	 */
	public function json() {
		$json                 = parent::json();
		$json['components']   = $this->components;
		$json['defaultOrder'] = $this->default_order;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                            react/nr_spacing.php                                                                                0000666                 00000002411 15226760543 0010512 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Non Responsive Spacing Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Spacing
 *
 * @package Neve\Customizer\Controls\React
 */
class Nr_Spacing extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_non_responsive_spacing';

	/**
	 * Min.
	 *
	 * @var int
	 */
	public $min = 0;

	/**
	 * Max.
	 *
	 * @var int
	 */
	public $max = 300;

	/**
	 * Units.
	 *
	 * @var array
	 */
	public $units = [ 'px', 'em', 'rem', '%' ];

	/**
	 * Default value.
	 *
	 * @var array
	 */
	public $default = [];

	/**
	 * Send to JS.
	 */
	public function json() {
		$json               = parent::json();
		$json['min']        = $this->min;
		$json['max']        = $this->max;
		$json['units']      = $this->units;
		$json['defaultVal'] = $this->default;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                       react/responsive_toggle.php                                                                         0000666                 00000001774 15226760543 0012140 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Responsive Toggle. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Button_Appearance
 *
 * @package Neve\Customizer\Controls\React
 */
class Responsive_Toggle extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_responsive_toggle_control';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $excluded_devices = [];
	/**
	 * Send to JS.
	 */
	public function json() {
		$json             = parent::json();
		$json['excluded'] = $this->excluded_devices;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
    react/typography_extra_section.php                                                                  0000666                 00000001114 15226760543 0013523 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 *
 * @package Neve
 */
namespace Neve\Customizer\Controls\React;

/**
 * Customizer section.
 *
 * @package    WordPress
 * @subpackage Customize
 * @see        WP_Customize_Section
 */
class Typography_Extra_Section extends \WP_Customize_Section {
	/**
	 * Type of this section.
	 *
	 * @var string
	 */
	public $type = 'typography_extra_section';

	/**
	 * Render template.
	 */
	protected function render_template() {
		?>
		<li id="accordion-section-{{ data.id }}"
			data-slug="{{data.id}}"
			class="control-section control-section-{{ data.type }}">
		</li>
		<?php
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                    react/global_colors.php                                                                             0000666                 00000002160 15226760543 0011211 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Global_Colors Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Global_Colors
 *
 * @package Neve\Customizer\Controls\React
 */
class Global_Colors extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_global_colors';
	/**
	 * Default values.
	 *
	 * @var string
	 */
	public $default_values = '';

	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $input_attrs = [];

	/**
	 * Send to JS.
	 */
	public function json() {
		$json                  = parent::json();
		$json['defaultValues'] = $this->default_values;
		$json['input_attrs']   = $this->input_attrs;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                react/form_token_field.php                                                                          0000666                 00000001745 15226760543 0011706 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Form Token Field Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Form_Token_Field
 *
 * @package Neve\Customizer\Controls\React
 */
class Form_Token_Field extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_form_token_field';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $choices = [];

	/**
	 * Send to JS.
	 */
	public function json() {
		$json            = parent::json();
		$json['choices'] = $this->choices;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                           react/builder.php                                                                                   0000666                 00000002330 15226760543 0010015 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Builders Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Customizer section.
 *
 * @package Neve\Customizer\Controls\React
 */
class Builder extends \WP_Customize_Control {
	/**
	 * Type of this section.
	 *
	 * @var string
	 */
	public $type = 'neve_builder_control';

	/**
	 * Builder Type
	 *
	 * @var string
	 */
	public $builder_type = null;
	/**
	 * Columns Layout
	 *
	 * @var boolean
	 */
	public $columns_layout = false;

	/**
	 * Gather the parameters passed to client JavaScript via JSON.
	 *
	 * @return array The array to be exported to the client as JSON.
	 */
	public function json() {
		$json                  = parent::json();
		$json['builderType']   = $this->builder_type;
		$json['columnsLayout'] = $this->columns_layout;

		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                                                                        react/background.php                                                                                0000666                 00000001727 15226760543 0010517 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Color Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Button_Appearance
 *
 * @package Neve\Customizer\Controls\React
 */
class Background extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_background_control';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var string
	 */
	public $default = '';
	/**
	 * Send to JS.
	 */
	public function json() {
		$json            = parent::json();
		$json['default'] = $this->default;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                         react/multiselect.php                                                                               0000666                 00000001726 15226760543 0010731 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Multiselect Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Button_Appearance
 *
 * @package Neve\Customizer\Controls\React
 */
class Multiselect extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_multiselect';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $choices = [];
	/**
	 * Send to JS.
	 */
	public function json() {
		$json            = parent::json();
		$json['choices'] = $this->choices;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                          react/builder_section.php                                                                           0000666                 00000001752 15226760543 0011550 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Header Footer Builder Section.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Customizer section.
 *
 * @package    WordPress
 * @subpackage Customize
 * @since      4.1.0
 * @see        WP_Customize_Section
 */
class Builder_Section extends \WP_Customize_Section {

	/**
	 * Type of this section.
	 *
	 * @var string
	 */
	public $type = 'neve_header_footer_builder_section';
	/**
	 * Default options schema.
	 *
	 * @var array
	 */
	public $default_options = [
		'setting'      => '',
		'builder_type' => '',
	// 'quickLinks'  => [],
	];

	/**
	 * Options passed to section.
	 *
	 * @var array
	 */
	public $options = [];


	/**
	 * Gather the parameters passed to client JavaScript via JSON.
	 *
	 * @return array The array to be exported to the client as JSON.
	 */
	public function json() {
		$json            = parent::json();
		$json['options'] = wp_parse_args( $this->options, $this->default_options );

		return $json;
	}
}


                      react/group_select.php                                                                              0000666                 00000002124 15226760543 0011063 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Group_Select Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Group_Select
 *
 * @package Neve\Customizer\Controls\React
 */
class Group_Select extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_group_select';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $options = [];
	/**
	 * Mark controls as disabled.
	 *
	 * @var bool
	 */
	public $disabled = false;

	/**
	 * Send to JS.
	 */
	public function json() {
		$json             = parent::json();
		$json['options']  = $this->options;
		$json['disabled'] = $this->disabled;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                            react/link_control.php                                                                              0000666                 00000002652 15226760543 0011073 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Author:          Bogdan Preda <bogdan.preda@themeisle.com>
 * Created on:      2022-02-10
 *
 * @package Neve
 */

namespace Neve\Customizer\Controls\React;

/**
 * Customizer link control React.
 *
 * @package    WordPress
 * @subpackage Customize
 * @since      4.1.0
 * @see        WP_Customize_Control
 */
class Link_Control extends \WP_Customize_Control {
	/**
	 * Type of this control.
	 *
	 * @var string
	 */
	public $type = 'neve_link';

	/**
	 * Control URL for link.
	 *
	 * @var string
	 */
	public $url = '#';

	/**
	 * Control text for link.
	 *
	 * @var string
	 */
	public $label = 'Link';

	/**
	 * Control description for link.
	 *
	 * @var string
	 */
	public $description = '';

	/**
	 * Gather the parameters passed to client JavaScript via JSON.
	 *
	 * @since 4.1.0
	 *
	 * @return array The array to be exported to the client as JSON.
	 */
	public function json() {
		$json                = parent::json();
		$json['url']         = $this->url;
		$json['label']       = $this->label;
		$json['description'] = $this->description;

		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                      react/font_family.php                                                                               0000666                 00000001756 15226760543 0010711 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Font_Family Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Button_Appearance
 *
 * @package Neve\Customizer\Controls\React
 */
class Font_Family extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_font_family_control';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $input_attrs = [];
	/**
	 * Send to JS.
	 */
	public function json() {
		$json                = parent::json();
		$json['input_attrs'] = $this->input_attrs;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                  react/textarea.php                                                                                  0000666                 00000001725 15226760543 0010213 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Textarea Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Textarea
 *
 * @package Neve\Customizer\Controls\React
 */
class Textarea extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_textarea';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $input_attrs = [];

	/**
	 * Send to JS.
	 */
	public function json() {
		$json                = parent::json();
		$json['input_attrs'] = $this->input_attrs;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                           react/heading.php                                                                                   0000666                 00000004632 15226760543 0007775 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Heading Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Heading control for react
 */
class Heading extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_customizer_heading';
	/**
	 * Control class.
	 *
	 * @var string
	 */
	public $class = '';

	/**
	 * Should be accordion?
	 *
	 * @var bool
	 */
	public $accordion = false;

	/**
	 * Initial state.
	 *
	 * @var bool
	 */
	public $expanded = true;

	/**
	 * How many controls to wrap.
	 *
	 * @var int
	 */
	public $controls_to_wrap = 1;

	/**
	 * Label before the accordion.
	 *
	 * @var string
	 */
	public $category_label = '';

	/**
	 * Send data to _s
	 *
	 * @return array
	 */
	public function json() {
		$json                  = parent::json();
		$json['classes']       = $this->class;
		$json['accordion']     = $this->accordion;
		$json['categoryLabel'] = $this->category_label;

		if ( $this->accordion === true ) {
			$json['classes'] .= ' accordion';
		}

		$json['style'] = $this->print_style();

		return $json;
	}

	/**
	 * Render the control.
	 */
	protected function render() {
		$id     = 'customize-control-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id );
		$class  = 'customize-control customize-control-' . $this->type;
		$class .= ' ' . $this->class;
		if ( $this->accordion ) {
			$class .= ' accordion';
		}

		if ( $this->expanded ) {
			$class .= ' expanded';
		}

		echo '<li id="' . esc_attr( $id ) . '" class="' . esc_attr( $class ) . '">';
		echo '</li>';
	}

	/**
	 * Print the style for the accordion.
	 */
	protected function print_style() {
		$style = '';
		for ( $i = 1; $i <= $this->controls_to_wrap; $i ++ ) {
			$style .= '.accordion.' . $this->class . ':not(.expanded)';
			for ( $j = 1; $j <= $i; $j ++ ) {
				$style .= ' + li';
			}
			if ( $i !== $this->controls_to_wrap ) {
				$style .= ',';
			}
		}
		$style .= '{max-height: 0;opacity: 0;margin: 0; overflow: hidden; padding:0 !important;}';

		return $style;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                      react/typography.php                                                                                0000666                 00000002527 15226760543 0010605 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Typography control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Typography
 *
 * @package Neve\Customizer\Controls\React
 */
class Typography extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_typeface_control';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $input_attrs = [];
	/**
	 * Refresh on reset flag.
	 *
	 * @var bool
	 */
	public $refresh_on_reset = false;
	/**
	 * The control that holds the font family used by this control
	 *
	 * @var string
	 */
	public $font_family_control = '';

	/**
	 * Send to JS.
	 */
	public function json() {
		$json                        = parent::json();
		$json['input_attrs']         = wp_json_encode( $this->input_attrs );
		$json['refresh_on_reset']    = $this->refresh_on_reset;
		$json['font_family_control'] = $this->font_family_control;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                         react/responsive_radio_buttons.php                                                                  0000666                 00000002006 15226760543 0013520 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Responsive_Radio_Buttons Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Responsive_Range
 *
 * @package Neve\Customizer\Controls\React
 */
class Responsive_Radio_Buttons extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_responsive_radio_buttons_control';

	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $choices = [];

	/**
	 * Send to JS.
	 */
	public function json() {
		$json            = parent::json();
		$json['choices'] = $this->choices;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          react/documentation_section.php                                                                     0000666                 00000002114 15226760543 0012764 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * A section control for documentation.
 *
 * Author:      Bogdan Preda <bogdan.preda@themeisle.com>
 * Created on:  22-12-{2021}
 *
 * @package neve/neve-pro
 */
namespace Neve\Customizer\Controls\React;

/**
 * Customizer section.
 *
 * @package    WordPress
 * @subpackage Customize
 * @since      4.1.0
 * @see        WP_Customize_Section
 */
class Documentation_Section extends \WP_Customize_Section {
	/**
	 * Type of this section.
	 *
	 * @var string
	 */
	public $type = 'neve_documentation';

	/**
	 * Documentation URL.
	 *
	 * @var string
	 */
	public $url = '';

	/**
	 * Gather the parameters passed to client JavaScript via JSON.
	 *
	 * @return array The array to be exported to the client as JSON.
	 * @since 4.1.0
	 */
	public function json() {
		$json        = parent::json();
		$json['url'] = $this->url;
		return $json;
	}

	/**
	 * Render template.
	 */
	protected function render_template() {
		?>
		<li id="accordion-section-{{ data.id }}"
			data-slug="{{data.id}}"
			class="control-section control-section-{{ data.type }} neve-documentation">
		</li>
		<?php
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                    react/font_pairings.php                                                                             0000666                 00000001760 15226760543 0011237 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Font_Pairings Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Font_Pairings
 *
 * @package Neve\Customizer\Controls\React
 */
class Font_Pairings extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_font_pairings_control';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $input_attrs = [];
	/**
	 * Send to JS.
	 */
	public function json() {
		$json                = parent::json();
		$json['input_attrs'] = $this->input_attrs;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                react/upsell_banner.php                                                                             0000666                 00000003555 15226760543 0011232 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Description Upsell Section
 *
 * Author:      Bogdan Preda <bogdan.preda@themeisle.com>
 * Created on:  20-12-{2021}
 *
 * @package neve/neve-pro
 */
namespace Neve\Customizer\Controls\React;

/**
 * Customizer section.
 *
 * @package    WordPress
 * @subpackage Customize
 * @since      4.1.0
 * @see        WP_Customize_Section
 */
class Upsell_Banner extends \WP_Customize_Control {
	/**
	 * Type of this section.
	 *
	 * @var string
	 */
	public $type = 'neve_upsell_banner';

	/**
	 * Upgrade URL.
	 *
	 * @var string
	 */
	public $url = '';

	/**
	 * Nonce.
	 *
	 * @var string
	 */
	public $nonce = '';

	/**
	 * Upsell text.
	 *
	 * @var string
	 */
	public $text = '';

	/**
	 * Upsell button text.
	 *
	 * @var string
	 */
	public $button_text = '';

	/**
	 * Upsell logo path.
	 *
	 * @var string
	 */
	public $logo_path = '';

	/**
	 * Upsell use logo.
	 *
	 * @var boolean
	 */
	public $use_logo = false;

	/**
	 * Gather the parameters passed to client JavaScript via JSON.
	 *
	 * @return array The array to be exported to the client as JSON.
	 * @since 4.1.0
	 */
	public function json() {
		$json               = parent::json();
		$json['url']        = $this->url;
		$json['nonce']      = $this->nonce;
		$json['text']       = $this->text;
		$json['buttonText'] = $this->button_text;
		$json['useLogo']    = $this->use_logo === true;
		$json['id']         = $this->id;
		$json['logoPath']   = ! empty( $this->logo_path ) ? $this->logo_path : get_template_directory_uri() . '/assets/img/dashboard/logo.svg';
		return $json;
	}

	/**
	 * Render template.
	 */
	protected function render() {
		?>
		<li id="customize-control-<?php echo esc_attr( $this->id ); ?>"
			data-slug="<?php echo esc_attr( $this->id ); ?>"
			class="customize-control customize-control-<?php echo esc_attr( $this->id ); ?>-control neve-upsell-banner" style="background: none;">
		</li>
		<?php
	}
}
                                                                                                                                                   react/radio_image.php                                                                               0000666                 00000002166 15226760543 0010636 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Radio Image Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Radio_Image
 *
 * @package Neve\Customizer\Controls\React
 */
class Radio_Image extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_radio_image_control';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $choices = [];
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $documentation = [];
	/**
	 * Send to JS.
	 */
	public function json() {
		$json                  = parent::json();
		$json['choices']       = $this->choices;
		$json['documentation'] = $this->documentation;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                          react/instructions_control.php                                                                      0000666                 00000002475 15226760543 0012705 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Created on:      2020-08-12
 *
 * @package Neve
 */

namespace Neve\Customizer\Controls\React;

/**
 * Customizer section.
 *
 * @package    WordPress
 * @subpackage Customize
 * @since      4.1.0
 * @see        WP_Customize_Section
 */
class Instructions_Control extends \WP_Customize_Control {

	/**
	 * Type of this section.
	 *
	 * @var string
	 */
	public $type = 'hfg_instructions';
	/**
	 * Default options schema.
	 *
	 * @var array
	 */
	public $default_options = [
		'description' => '',
		'image'       => '',
		'quickLinks'  => [],
	];

	/**
	 * Options passed to control.
	 *
	 * @var array
	 */
	public $options = [];



	/**
	 * Gather the parameters passed to client JavaScript via JSON.
	 *
	 * @since 4.1.0
	 *
	 * @return array The array to be exported to the client as JSON.
	 */
	public function json() {
		$json            = parent::json();
		$json['options'] = wp_parse_args( $this->options, $this->default_options );

		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}


                                                                                                                                                                                                   react/repeater.php                                                                                  0000666                 00000003373 15226760543 0010206 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Repeater Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Repeater
 *
 * @package Neve\Customizer\Controls\React
 */
class Repeater extends \WP_Customize_Control {

	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_repeater_control';

	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $fields = [];

	/**
	 * Additional arguments passed to JS.
	 *
	 * @var object
	 */
	public $new_item_fields;

	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $components = [];

	/**
	 * Additional arguments passed to JS.
	 *
	 * @var string
	 */
	public $allow_new_fields = 'yes';

	/**
	 * @param \WP_Customize_Manager $manager customize manager object.
	 * @param String                $id control ID.
	 * @param array                 $args control args.
	 */
	public function __construct( $manager, $id, $args = array() ) {
		$this->new_item_fields = new \stdClass();

		parent::__construct( $manager, $id, $args );
	}


	/**
	 * Send to JS.
	 */
	public function json() {
		$json                     = parent::json();
		$json['fields']           = $this->fields;
		$json['new_item_fields']  = $this->new_item_fields;
		$json['allow_new_fields'] = $this->allow_new_fields;
		$json['components']       = $this->components;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                                     react/elFinderVolumeLocalFileSystem.class.php                                                       0000666                 00000136366 15226760543 0015414 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php

// Implement similar functionality in PHP 5.2 or 5.3
// http://php.net/manual/class.recursivecallbackfilteriterator.php#110974
if (!class_exists('RecursiveCallbackFilterIterator', false)) {
    class RecursiveCallbackFilterIterator extends RecursiveFilterIterator
    {
        private $callback;

        public function __construct(RecursiveIterator $iterator, $callback)
        {
            $this->callback = $callback;
            parent::__construct($iterator);
        }

        public function accept()
        {
            return call_user_func($this->callback, parent::current(), parent::key(), parent::getInnerIterator());
        }

        public function getChildren()
        {
            return new self($this->getInnerIterator()->getChildren(), $this->callback);
        }
    }
}

/**
 * elFinder driver for local filesystem.
 *
 * @author Dmitry (dio) Levashov
 * @author Troex Nevelin
 **/
class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
{

    /**
     * Driver id
     * Must be started from letter and contains [a-z0-9]
     * Used as part of volume id
     *
     * @var string
     **/
    protected $driverId = 'l';

    /**
     * Required to count total archive files size
     *
     * @var int
     **/
    protected $archiveSize = 0;

    /**
     * Is checking stat owner
     *
     * @var        boolean
     */
    protected $statOwner = false;

    /**
     * Path to quarantine directory
     *
     * @var string
     */
    private $quarantine;

    /**
     * Constructor
     * Extend options with required fields
     *
     * @author Dmitry (dio) Levashov
     */
    public function __construct()
    {
        $this->options['alias'] = '';              // alias to replace root dir name
        $this->options['dirMode'] = 0755;            // new dirs mode
        $this->options['fileMode'] = 0644;            // new files mode
        $this->options['rootCssClass'] = 'elfinder-navbar-root-local';
        $this->options['followSymLinks'] = true;
        $this->options['detectDirIcon'] = '';         // file name that is detected as a folder icon e.g. '.diricon.png'
        $this->options['keepTimestamp'] = array('copy', 'move'); // keep timestamp at inner filesystem allowed 'copy', 'move' and 'upload'
        $this->options['substituteImg'] = true;       // support substitute image with dim command
        $this->options['statCorrector'] = null;       // callable to correct stat data `function(&$stat, $path, $statOwner, $volumeDriveInstance){}`
        if (DIRECTORY_SEPARATOR === '/') {
            // Linux
            $this->options['acceptedName'] = '/^[^\.\/\x00][^\/\x00]*$/';
        } else {
            // Windows
            $this->options['acceptedName'] = '/^[^\.\/\x00\\\:*?"<>|][^\/\x00\\\:*?"<>|]*$/';
        }
    }

    /*********************************************************************/
    /*                        INIT AND CONFIGURE                         */
    /*********************************************************************/

    /**
     * Prepare driver before mount volume.
     * Return true if volume is ready.
     *
     * @return bool
     **/
    protected function init()
    {
        // Normalize directory separator for windows
        if (DIRECTORY_SEPARATOR !== '/') {
            foreach (array('path', 'tmbPath', 'tmpPath', 'quarantine') as $key) {
                if (!empty($this->options[$key])) {
                    $this->options[$key] = str_replace('/', DIRECTORY_SEPARATOR, $this->options[$key]);
                }
            }
            // PHP >= 7.1 Supports UTF-8 path on Windows
            if (version_compare(PHP_VERSION, '7.1', '>=')) {
                $this->options['encoding'] = '';
                $this->options['locale'] = '';
            }
        }
        if (!$cwd = getcwd()) {
            return $this->setError('elFinder LocalVolumeDriver requires a result of getcwd().');
        }
        // detect systemRoot
        if (!isset($this->options['systemRoot'])) {
            if ($cwd[0] === DIRECTORY_SEPARATOR || $this->root[0] === DIRECTORY_SEPARATOR) {
                $this->systemRoot = DIRECTORY_SEPARATOR;
            } else if (preg_match('/^([a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . ')/', $this->root, $m)) {
                $this->systemRoot = $m[1];
            } else if (preg_match('/^([a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . ')/', $cwd, $m)) {
                $this->systemRoot = $m[1];
            }
        }
        $this->root = $this->getFullPath($this->root, $cwd);
        if (!empty($this->options['startPath'])) {
            $this->options['startPath'] = $this->getFullPath($this->options['startPath'], $this->root);
        }

        if (is_null($this->options['syncChkAsTs'])) {
            $this->options['syncChkAsTs'] = true;
        }
        if (is_null($this->options['syncCheckFunc'])) {
            $this->options['syncCheckFunc'] = array($this, 'localFileSystemInotify');
        }
        // check 'statCorrector'
        if (empty($this->options['statCorrector']) || !is_callable($this->options['statCorrector'])) {
            $this->options['statCorrector'] = null;
        }

        return true;
    }

    /**
     * Configure after successfull mount.
     *
     * @return void
     * @throws elFinderAbortException
     * @author Dmitry (dio) Levashov
     */
    protected function configure()
    {
        $hiddens = array();
        $root = $this->stat($this->root);

        // check thumbnails path
        if (!empty($this->options['tmbPath'])) {
            if (strpos($this->options['tmbPath'], DIRECTORY_SEPARATOR) === false) {
                $hiddens['tmb'] = $this->options['tmbPath'];
                $this->options['tmbPath'] = $this->_abspath($this->options['tmbPath']);
            } else {
                $this->options['tmbPath'] = $this->_normpath($this->options['tmbPath']);
            }
        }
        // check temp path
        if (!empty($this->options['tmpPath'])) {
            if (strpos($this->options['tmpPath'], DIRECTORY_SEPARATOR) === false) {
                $hiddens['temp'] = $this->options['tmpPath'];
                $this->options['tmpPath'] = $this->_abspath($this->options['tmpPath']);
            } else {
                $this->options['tmpPath'] = $this->_normpath($this->options['tmpPath']);
            }
        }
        // check quarantine path
        $_quarantine = '';
        if (!empty($this->options['quarantine'])) {
            if (strpos($this->options['quarantine'], DIRECTORY_SEPARATOR) === false) {
                $_quarantine = $this->_abspath($this->options['quarantine']);
                $this->options['quarantine'] = '';
            } else {
                $this->options['quarantine'] = $this->_normpath($this->options['quarantine']);
            }
        } else {
            $_quarantine = $this->_abspath('.quarantine');
        }
        is_dir($_quarantine) && self::localRmdirRecursive($_quarantine);

        parent::configure();

        // check tmbPath
        if (!$this->tmbPath && isset($hiddens['tmb'])) {
            unset($hiddens['tmb']);
        }

        // if no thumbnails url - try detect it
        if ($root['read'] && !$this->tmbURL && $this->URL) {
            if (strpos($this->tmbPath, $this->root) === 0) {
                $this->tmbURL = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($this->tmbPath, strlen($this->root) + 1));
                if (preg_match("|[^/?&=]$|", $this->tmbURL)) {
                    $this->tmbURL .= '/';
                }
            }
        }

        // set $this->tmp by options['tmpPath']
        $this->tmp = '';
        if (!empty($this->options['tmpPath'])) {
            if ((is_dir($this->options['tmpPath']) || mkdir($this->options['tmpPath'], $this->options['dirMode'], true)) && is_writable($this->options['tmpPath'])) {
                $this->tmp = $this->options['tmpPath'];
            } else {
                if (isset($hiddens['temp'])) {
                    unset($hiddens['temp']);
                }
            }
        }
        if (!$this->tmp && ($tmp = elFinder::getStaticVar('commonTempPath'))) {
            $this->tmp = $tmp;
        }

        // check quarantine dir
        $this->quarantine = '';
        if (!empty($this->options['quarantine'])) {
            if ((is_dir($this->options['quarantine']) || mkdir($this->options['quarantine'], $this->options['dirMode'], true)) && is_writable($this->options['quarantine'])) {
                $this->quarantine = $this->options['quarantine'];
            } else {
                if (isset($hiddens['quarantine'])) {
                    unset($hiddens['quarantine']);
                }
            }
        } else if ($_path = elFinder::getCommonTempPath()) {
            $this->quarantine = $_path;
        }

        if (!$this->quarantine) {
            if (!$this->tmp) {
                $this->archivers['extract'] = array();
                $this->disabled[] = 'extract';
            } else {
                $this->quarantine = $this->tmp;
            }
        }

        if ($hiddens) {
            foreach ($hiddens as $hidden) {
                $this->attributes[] = array(
                    'pattern' => '~^' . preg_quote(DIRECTORY_SEPARATOR . $hidden, '~') . '$~',
                    'read' => false,
                    'write' => false,
                    'locked' => true,
                    'hidden' => true
                );
            }
        }

        if (!empty($this->options['keepTimestamp'])) {
            $this->options['keepTimestamp'] = array_flip($this->options['keepTimestamp']);
        }

        $this->statOwner = (!empty($this->options['statOwner']));

        // enable WinRemoveTailDots plugin on Windows server
        if (DIRECTORY_SEPARATOR !== '/') {
            if (!isset($this->options['plugin'])) {
                $this->options['plugin'] = array();
            }
            $this->options['plugin']['WinRemoveTailDots'] = array('enable' => true);
        }
    }

    /**
     * Long pooling sync checker
     * This function require server command `inotifywait`
     * If `inotifywait` need full path, Please add `define('ELFINER_INOTIFYWAIT_PATH', '/PATH_TO/inotifywait');` into connector.php
     *
     * @param string $path
     * @param int    $standby
     * @param number $compare
     *
     * @return number|bool
     * @throws elFinderAbortException
     */
    public function localFileSystemInotify($path, $standby, $compare)
    {
        if (isset($this->sessionCache['localFileSystemInotify_disable'])) {
            return false;
        }
        $path = realpath($path);
        $mtime = filemtime($path);
        if (!$mtime) {
            return false;
        }
        if ($mtime != $compare) {
            return $mtime;
        }
        $inotifywait = defined('ELFINER_INOTIFYWAIT_PATH') ? ELFINER_INOTIFYWAIT_PATH : 'inotifywait';
        $standby = max(1, intval($standby));
        $cmd = $inotifywait . ' ' . escapeshellarg($path) . ' -t ' . $standby . ' -e moved_to,moved_from,move,close_write,delete,delete_self';
        $this->procExec($cmd, $o, $r);
        if ($r === 0) {
            // changed
            clearstatcache();
            if (file_exists($path)) {
                $mtime = filemtime($path); // error on busy?
                return $mtime ? $mtime : time();
            } else {
                // target was removed
                return 0;
            }
        } else if ($r === 2) {
            // not changed (timeout)
            return $compare;
        }
        // error
        // cache to $_SESSION
        $this->sessionCache['localFileSystemInotify_disable'] = true;
        $this->session->set($this->id, $this->sessionCache);
        return false;
    }

    /*********************************************************************/
    /*                               FS API                              */
    /*********************************************************************/

    /*********************** paths/urls *************************/

    /**
     * Return parent directory path
     *
     * @param  string $path file path
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _dirname($path)
    {
        return dirname($path);
    }

    /**
     * Return file name
     *
     * @param  string $path file path
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _basename($path)
    {
        return basename($path);
    }

    /**
     * Join dir name and file name and retur full path
     *
     * @param  string $dir
     * @param  string $name
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _joinPath($dir, $name)
    {
        $dir = rtrim($dir, DIRECTORY_SEPARATOR);
        $path = realpath($dir . DIRECTORY_SEPARATOR . $name);
        // realpath() returns FALSE if the file does not exist
        if ($path === false || strpos($path, $this->root) !== 0) {
            if (DIRECTORY_SEPARATOR !== '/') {
                $dir = str_replace('/', DIRECTORY_SEPARATOR, $dir);
                $name = str_replace('/', DIRECTORY_SEPARATOR, $name);
            }
            // Directory traversal measures
            if (strpos($dir, '..' . DIRECTORY_SEPARATOR) !== false || substr($dir, -2) == '..') {
                $dir = $this->root;
            }
            if (strpos($name, '..' . DIRECTORY_SEPARATOR) !== false) {
                $name = basename($name);
            }
            $path = $dir . DIRECTORY_SEPARATOR . $name;
        }
        return $path; 
    }

    /**
     * Return normalized path, this works the same as os.path.normpath() in Python
     *
     * @param  string $path path
     *
     * @return string
     * @author Troex Nevelin
     **/
    protected function _normpath($path)
    {
        if (empty($path)) {
            return '.';
        }

        $changeSep = (DIRECTORY_SEPARATOR !== '/');
        if ($changeSep) {
            $drive = '';
            if (preg_match('/^([a-zA-Z]:)(.*)/', $path, $m)) {
                $drive = $m[1];
                $path = $m[2] ? $m[2] : '/';
            }
            $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
        }

        if (strpos($path, '/') === 0) {
            $initial_slashes = true;
        } else {
            $initial_slashes = false;
        }

        if (($initial_slashes)
            && (strpos($path, '//') === 0)
            && (strpos($path, '///') === false)) {
            $initial_slashes = 2;
        }

        $initial_slashes = (int)$initial_slashes;

        $comps = explode('/', $path);
        $new_comps = array();
        foreach ($comps as $comp) {
            if (in_array($comp, array('', '.'))) {
                continue;
            }

            if (($comp != '..')
                || (!$initial_slashes && !$new_comps)
                || ($new_comps && (end($new_comps) == '..'))) {
                array_push($new_comps, $comp);
            } elseif ($new_comps) {
                array_pop($new_comps);
            }
        }
        $comps = $new_comps;
        $path = implode('/', $comps);
        if ($initial_slashes) {
            $path = str_repeat('/', $initial_slashes) . $path;
        }

        if ($changeSep) {
            $path = $drive . str_replace('/', DIRECTORY_SEPARATOR, $path);
        }

        return $path ? $path : '.';
    }

    /**
     * Return file path related to root dir
     *
     * @param  string $path file path
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _relpath($path)
    {
        if ($path === $this->root) {
            return '';
        } else {
            if (strpos($path, $this->root) === 0) {
                return ltrim(substr($path, strlen($this->root)), DIRECTORY_SEPARATOR);
            } else {
                // for link
                return $path;
            }
        }
    }

    /**
     * Convert path related to root dir into real path
     *
     * @param  string $path file path
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _abspath($path)
    {
        if ($path === DIRECTORY_SEPARATOR) {
            return $this->root;
        } else {
            $path = $this->_normpath($path);
            if (strpos($path, $this->systemRoot) === 0) {
                return $path;
            } else if (DIRECTORY_SEPARATOR !== '/' && preg_match('/^[a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . '/', $path)) {
                return $path;
            } else {
                return $this->_joinPath($this->root, $path);
            }
        }
    }

    /**
     * Return fake path started from root dir
     *
     * @param  string $path file path
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _path($path)
    {
        return $this->rootName . ($path == $this->root ? '' : $this->separator . $this->_relpath($path));
    }

    /**
     * Return true if $path is children of $parent
     *
     * @param  string $path   path to check
     * @param  string $parent parent path
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _inpath($path, $parent)
    {
        $cwd = getcwd();
        $real_path = $this->getFullPath($path, $cwd);
        $real_parent = $this->getFullPath($parent, $cwd);
        if ($real_path && $real_parent) {
            return $real_path === $real_parent || strpos($real_path, rtrim($real_parent, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR) === 0;
        }
        return false;
    }



    /***************** file stat ********************/

    /**
     * Return stat for given path.
     * Stat contains following fields:
     * - (int)    size    file size in b. required
     * - (int)    ts      file modification time in unix time. required
     * - (string) mime    mimetype. required for folders, others - optionally
     * - (bool)   read    read permissions. required
     * - (bool)   write   write permissions. required
     * - (bool)   locked  is object locked. optionally
     * - (bool)   hidden  is object hidden. optionally
     * - (string) alias   for symlinks - link target path relative to root path. optionally
     * - (string) target  for symlinks - link target path. optionally
     * If file does not exists - returns empty array or false.
     *
     * @param  string $path file path
     *
     * @return array|false
     * @author Dmitry (dio) Levashov
     **/
    protected function _stat($path)
    {
        $stat = array();

        if (!file_exists($path) && !is_link($path)) {
            return $stat;
        }

        //Verifies the given path is the root or is inside the root. Prevents directory traveral.
        if (!$this->_inpath($path, $this->root)) {
            return $stat;
        }

        $stat['isowner'] = false;
        $linkreadable = false;
        if ($path != $this->root && is_link($path)) {
            if (!$this->options['followSymLinks']) {
                return array();
            }
            if (!($target = $this->readlink($path))
                || $target == $path) {
                if (is_null($target)) {
                    $stat = array();
                    return $stat;
                } else {
                    $stat['mime'] = 'symlink-broken';
                    $target = readlink($path);
                    $lstat = lstat($path);
                    $ostat = $this->getOwnerStat($lstat['uid'], $lstat['gid']);
                    $linkreadable = !empty($ostat['isowner']);
                }
            }
            $stat['alias'] = $this->_path($target);
            $stat['target'] = $target;
        }

        $readable = is_readable($path);

        if ($readable) {
            $size = sprintf('%u', filesize($path));
            $stat['ts'] = filemtime($path);
            if ($this->statOwner) {
                $fstat = stat($path);
                $uid = $fstat['uid'];
                $gid = $fstat['gid'];
                $stat['perm'] = substr((string)decoct($fstat['mode']), -4);
                $stat = array_merge($stat, $this->getOwnerStat($uid, $gid));
            }
        }

        if (($dir = is_dir($path)) && $this->options['detectDirIcon']) {
            $favicon = $path . DIRECTORY_SEPARATOR . $this->options['detectDirIcon'];
            if ($this->URL && file_exists($favicon)) {
                $stat['icon'] = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($favicon, strlen($this->root) + 1));
            }
        }

        if (!isset($stat['mime'])) {
            $stat['mime'] = $dir ? 'directory' : $this->mimetype($path);
        }
        //logical rights first
        $stat['read'] = ($linkreadable || $readable) ? null : false;
        $stat['write'] = is_writable($path) ? null : false;

        if (is_null($stat['read'])) {
            if ($dir) {
                $stat['size'] = 0;
            } else if (isset($size)) {
                $stat['size'] = $size;
            }
        }

        if ($this->options['statCorrector']) {
            call_user_func_array($this->options['statCorrector'], array(&$stat, $path, $this->statOwner, $this));
        }

        return $stat;
    }

    /**
     * Get stat `owner`, `group` and `isowner` by `uid` and `gid`
     * Sub-fuction of _stat() and _scandir()
     *
     * @param integer $uid
     * @param integer $gid
     *
     * @return array  stat
     */
    protected function getOwnerStat($uid, $gid)
    {
        static $names = null;
        static $phpuid = null;

        if (is_null($names)) {
            $names = array('uid' => array(), 'gid' => array());
        }
        if (is_null($phpuid)) {
            if (is_callable('posix_getuid')) {
                $phpuid = posix_getuid();
            } else {
                $phpuid = 0;
            }
        }

        $stat = array();

        if ($uid) {
            $stat['isowner'] = ($phpuid == $uid);
            if (isset($names['uid'][$uid])) {
                $stat['owner'] = $names['uid'][$uid];
            } else if (is_callable('posix_getpwuid')) {
                $pwuid = posix_getpwuid($uid);
                $stat['owner'] = $names['uid'][$uid] = $pwuid['name'];
            } else {
                $stat['owner'] = $names['uid'][$uid] = $uid;
            }
        }
        if ($gid) {
            if (isset($names['gid'][$gid])) {
                $stat['group'] = $names['gid'][$gid];
            } else if (is_callable('posix_getgrgid')) {
                $grgid = posix_getgrgid($gid);
                $stat['group'] = $names['gid'][$gid] = $grgid['name'];
            } else {
                $stat['group'] = $names['gid'][$gid] = $gid;
            }
        }

        return $stat;
    }

    /**
     * Return true if path is dir and has at least one childs directory
     *
     * @param  string $path dir path
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _subdirs($path)
    {

        $dirs = false;
        if (is_dir($path) && is_readable($path)) {
            if (class_exists('FilesystemIterator', false)) {
                $dirItr = new ParentIterator(
                    new RecursiveDirectoryIterator($path,
                        FilesystemIterator::SKIP_DOTS |
                        FilesystemIterator::CURRENT_AS_SELF |
                        (defined('RecursiveDirectoryIterator::FOLLOW_SYMLINKS') ?
                            RecursiveDirectoryIterator::FOLLOW_SYMLINKS : 0)
                    )
                );
                $dirItr->rewind();
                if ($dirItr->hasChildren()) {
                    $dirs = true;
                    $name = $dirItr->getSubPathName();
                    while ($dirItr->valid()) {
                        if (!$this->attr($path . DIRECTORY_SEPARATOR . $name, 'read', null, true)) {
                            $dirs = false;
                            $dirItr->next();
                            $name = $dirItr->getSubPathName();
                            continue;
                        }
                        $dirs = true;
                        break;
                    }
                }
            } else {
                $path = strtr($path, array('[' => '\\[', ']' => '\\]', '*' => '\\*', '?' => '\\?'));
                return (bool)glob(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR);
            }
        }
        return $dirs;
    }

    /**
     * Return object width and height
     * Usualy used for images, but can be realize for video etc...
     *
     * @param  string $path file path
     * @param  string $mime file mime type
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _dimensions($path, $mime)
    {
        clearstatcache();
        return strpos($mime, 'image') === 0 && is_readable($path) && filesize($path) && ($s = getimagesize($path)) !== false
            ? $s[0] . 'x' . $s[1]
            : false;
    }
    /******************** file/dir content *********************/

    /**
     * Return symlink target file
     *
     * @param  string $path link path
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function readlink($path)
    {
        if (!($target = readlink($path))) {
            return null;
        }

        if (strpos($target, $this->systemRoot) !== 0) {
            $target = $this->_joinPath(dirname($path), $target);
        }

        if (!file_exists($target)) {
            return false;
        }

        return $target;
    }

    /**
     * Return files list in directory.
     *
     * @param  string $path dir path
     *
     * @return array
     * @throws elFinderAbortException
     * @author Dmitry (dio) Levashov
     */
    protected function _scandir($path)
    {
        elFinder::checkAborted();
        $files = array();
        $cache = array();
        $dirWritable = is_writable($path);
        $dirItr = array();
        $followSymLinks = $this->options['followSymLinks'];
        try {
            $dirItr = new DirectoryIterator($path);
        } catch (UnexpectedValueException $e) {
        }

        foreach ($dirItr as $file) {
            try {
                if ($file->isDot()) {
                    continue;
                }

                $files[] = $fpath = $file->getPathname();

                $br = false;
                $stat = array();

                $stat['isowner'] = false;
                $linkreadable = false;
                if ($file->isLink()) {
                    if (!$followSymLinks) {
                        continue;
                    }
                    if (!($target = $this->readlink($fpath))
                        || $target == $fpath) {
                        if (is_null($target)) {
                            $stat = array();
                            $br = true;
                        } else {
                            $_path = $fpath;
                            $stat['mime'] = 'symlink-broken';
                            $target = readlink($_path);
                            $lstat = lstat($_path);
                            $ostat = $this->getOwnerStat($lstat['uid'], $lstat['gid']);
                            $linkreadable = !empty($ostat['isowner']);
                            $dir = false;
                            $stat['alias'] = $this->_path($target);
                            $stat['target'] = $target;
                        }
                    } else {
                        $dir = is_dir($target);
                        $stat['alias'] = $this->_path($target);
                        $stat['target'] = $target;
                        $stat['mime'] = $dir ? 'directory' : $this->mimetype($stat['alias']);
                    }
                } else {
                    if (($dir = $file->isDir()) && $this->options['detectDirIcon']) {
                        $path = $file->getPathname();
                        $favicon = $path . DIRECTORY_SEPARATOR . $this->options['detectDirIcon'];
                        if ($this->URL && file_exists($favicon)) {
                            $stat['icon'] = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($favicon, strlen($this->root) + 1));
                        }
                    }
                    $stat['mime'] = $dir ? 'directory' : $this->mimetype($fpath);
                }
                $size = sprintf('%u', $file->getSize());
                $stat['ts'] = $file->getMTime();
                if (!$br) {
                    if ($this->statOwner && !$linkreadable) {
                        $uid = $file->getOwner();
                        $gid = $file->getGroup();
                        $stat['perm'] = substr((string)decoct($file->getPerms()), -4);
                        $stat = array_merge($stat, $this->getOwnerStat($uid, $gid));
                    }

                    //logical rights first
                    $stat['read'] = ($linkreadable || $file->isReadable()) ? null : false;
                    $stat['write'] = $file->isWritable() ? null : false;
                    $stat['locked'] = $dirWritable ? null : true;

                    if (is_null($stat['read'])) {
                        $stat['size'] = $dir ? 0 : $size;
                    }

                    if ($this->options['statCorrector']) {
                        call_user_func_array($this->options['statCorrector'], array(&$stat, $fpath, $this->statOwner, $this));
                    }
                }

                $cache[] = array($fpath, $stat);
            } catch (RuntimeException $e) {
                continue;
            }
        }

        if ($cache) {
            $cache = $this->convEncOut($cache, false);
            foreach ($cache as $d) {
                $this->updateCache($d[0], $d[1]);
            }
        }

        return $files;
    }

    /**
     * Open file and return file pointer
     *
     * @param  string $path file path
     * @param string  $mode
     *
     * @return false|resource
     * @internal param bool $write open file for writing
     * @author   Dmitry (dio) Levashov
     */
    protected function _fopen($path, $mode = 'rb')
    {
        return fopen($path, $mode);
    }

    /**
     * Close opened file
     *
     * @param  resource $fp file pointer
     * @param string    $path
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     */
    protected function _fclose($fp, $path = '')
    {
        return (is_resource($fp) && fclose($fp));
    }

    /********************  file/dir manipulations *************************/

    /**
     * Create dir and return created dir path or false on failed
     *
     * @param  string $path parent dir path
     * @param string  $name new directory name
     *
     * @return string|bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _mkdir($path, $name)
    {
        $path = $this->_joinPath($path, $name);

        if (mkdir($path)) {
            chmod($path, $this->options['dirMode']);
            return $path;
        }

        return false;
    }

    /**
     * Create file and return it's path or false on failed
     *
     * @param  string $path parent dir path
     * @param string  $name new file name
     *
     * @return string|bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _mkfile($path, $name)
    {
        $path = $this->_joinPath($path, $name);

        if (($fp = fopen($path, 'w'))) {
            fclose($fp);
            chmod($path, $this->options['fileMode']);
            return $path;
        }
        return false;
    }

    /**
     * Create symlink
     *
     * @param  string $source    file to link to
     * @param  string $targetDir folder to create link in
     * @param  string $name      symlink name
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _symlink($source, $targetDir, $name)
    {
        return $this->localFileSystemSymlink($source, $this->_joinPath($targetDir, $name));
    }

    /**
     * Copy file into another file
     *
     * @param  string $source    source file path
     * @param  string $targetDir target directory path
     * @param  string $name      new file name
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _copy($source, $targetDir, $name)
    {
        $mtime = filemtime($source);
        $target = $this->_joinPath($targetDir, $name);
        if ($ret = copy($source, $target)) {
            isset($this->options['keepTimestamp']['copy']) && $mtime && touch($target, $mtime);
        }
        return $ret;
    }

    /**
     * Move file into another parent dir.
     * Return new file path or false.
     *
     * @param  string $source source file path
     * @param         $targetDir
     * @param  string $name   file name
     *
     * @return bool|string
     * @internal param string $target target dir path
     * @author   Dmitry (dio) Levashov
     */
    protected function _move($source, $targetDir, $name)
    {
        $mtime = filemtime($source);
        $target = $this->_joinPath($targetDir, $name);
        if ($ret = rename($source, $target) ? $target : false) {
            isset($this->options['keepTimestamp']['move']) && $mtime && touch($target, $mtime);
        }
        return $ret;
    }

    /**
     * Remove file
     *
     * @param  string $path file path
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _unlink($path)
    {
        return is_file($path) && unlink($path);
    }

    /**
     * Remove dir
     *
     * @param  string $path dir path
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _rmdir($path)
    {
        return rmdir($path);
    }

    /**
     * Create new file and write into it from file pointer.
     * Return new file path or false on error.
     *
     * @param  resource $fp   file pointer
     * @param  string   $dir  target dir path
     * @param  string   $name file name
     * @param  array    $stat file stat (required by some virtual fs)
     *
     * @return bool|string
     * @author Dmitry (dio) Levashov
     **/
    protected function _save($fp, $dir, $name, $stat)
    {
        $path = $this->_joinPath($dir, $name);

        $meta = stream_get_meta_data($fp);
        $uri = isset($meta['uri']) ? $meta['uri'] : '';
        if ($uri && !preg_match('#^[a-zA-Z0-9]+://#', $uri) && !is_link($uri)) {
            fclose($fp);
            $mtime = filemtime($uri);
            $isCmdPaste = ($this->ARGS['cmd'] === 'paste');
            $isCmdCopy = ($isCmdPaste && empty($this->ARGS['cut']));
            if (($isCmdCopy || !rename($uri, $path)) && !copy($uri, $path)) {
                return false;
            }
            // keep timestamp on upload
            if ($mtime && $this->ARGS['cmd'] === 'upload') {
                touch($path, isset($this->options['keepTimestamp']['upload']) ? $mtime : time());
            }
        } else {
            if (file_put_contents($path, $fp, LOCK_EX) === false) {
                return false;
            }
        }

        chmod($path, $this->options['fileMode']);
        return $path;
    }

    /**
     * Get file contents
     *
     * @param  string $path file path
     *
     * @return string|false
     * @author Dmitry (dio) Levashov
     **/
    protected function _getContents($path)
    {
        return file_get_contents($path);
    }

    /**
     * Write a string to a file
     *
     * @param  string $path    file path
     * @param  string $content new file content
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _filePutContents($path, $content)
    {
        return (file_put_contents($path, $content, LOCK_EX) !== false);
    }

    /**
     * Detect available archivers
     *
     * @return void
     * @throws elFinderAbortException
     */
    protected function _checkArchivers()
    {
        $this->archivers = $this->getArchivers();
        return;
    }

    /**
     * chmod availability
     *
     * @param string $path
     * @param string $mode
     *
     * @return bool
     */
    protected function _chmod($path, $mode)
    {
        $modeOct = is_string($mode) ? octdec($mode) : octdec(sprintf("%04o", $mode));
        return chmod($path, $modeOct);
    }

    /**
     * Recursive symlinks search
     *
     * @param  string $path file/dir path
     *
     * @return bool
     * @throws Exception
     * @author Dmitry (dio) Levashov
     */
    protected function _findSymlinks($path)
    {
        return self::localFindSymlinks($path);
    }

    /**
     * Extract files from archive
     *
     * @param  string $path archive path
     * @param  array  $arc  archiver command and arguments (same as in $this->archivers)
     *
     * @return array|string|boolean
     * @throws elFinderAbortException
     * @author Dmitry (dio) Levashov,
     * @author Alexey Sukhotin
     */
    protected function _extract($path, $arc)
    {

        if ($this->quarantine) {

            $dir = $this->quarantine . DIRECTORY_SEPARATOR . md5(basename($path) . mt_rand());
            $archive = (isset($arc['toSpec']) || $arc['cmd'] === 'phpfunction') ? '' : $dir . DIRECTORY_SEPARATOR . basename($path);

            if (!mkdir($dir)) {
                return false;
            }

            // insurance unexpected shutdown
            register_shutdown_function(array($this, 'rmdirRecursive'), realpath($dir));

            chmod($dir, 0777);

            // copy in quarantine
            if (!is_readable($path) || ($archive && !copy($path, $archive))) {
                return false;
            }

            // extract in quarantine
            try {
                $this->unpackArchive($path, $arc, $archive ? true : $dir);
            } catch(Exception $e) {
                return $this->setError($e->getMessage());
            }

            // get files list
            try {
                $ls = self::localScandir($dir);
            } catch (Exception $e) {
                return false;
            }

            // no files - extract error ?
            if (empty($ls)) {
                return false;
            }

            $this->archiveSize = 0;

            // find symlinks and check extracted items
            $checkRes = $this->checkExtractItems($dir);
            if ($checkRes['symlinks']) {
                self::localRmdirRecursive($dir);
                return $this->setError(array_merge($this->error, array(elFinder::ERROR_ARC_SYMLINKS)));
            }
            $this->archiveSize = $checkRes['totalSize'];
            if ($checkRes['rmNames']) {
                foreach ($checkRes['rmNames'] as $name) {
                    $this->addError(elFinder::ERROR_SAVE, $name);
                }
            }

            // check max files size
            if ($this->options['maxArcFilesSize'] > 0 && $this->options['maxArcFilesSize'] < $this->archiveSize) {
                $this->delTree($dir);
                return $this->setError(elFinder::ERROR_ARC_MAXSIZE);
            }

            $extractTo = $this->extractToNewdir; // 'auto', ture or false

            // archive contains one item - extract in archive dir
            $name = '';
            $src = $dir . DIRECTORY_SEPARATOR . $ls[0];
            if (($extractTo === 'auto' || !$extractTo) && count($ls) === 1 && is_file($src)) {
                $name = $ls[0];
            } else if ($extractTo === 'auto' || $extractTo) {
                // for several files - create new directory
                // create unique name for directory
                $src = $dir;
                $splits = elFinder::splitFileExtention(basename($path));
                $name = $splits[0];
                $test = dirname($path) . DIRECTORY_SEPARATOR . $name;
                if (file_exists($test) || is_link($test)) {
                    $name = $this->uniqueName(dirname($path), $name, '-', false);
                }
            }

            if ($name !== '') {
                $result = dirname($path) . DIRECTORY_SEPARATOR . $name;

                if (!rename($src, $result)) {
                    $this->delTree($dir);
                    return false;
                }
            } else {
                $dstDir = dirname($path);
                $result = array();
                foreach ($ls as $name) {
                    $target = $dstDir . DIRECTORY_SEPARATOR . $name;
                    if (self::localMoveRecursive($dir . DIRECTORY_SEPARATOR . $name, $target, true, $this->options['copyJoin'])) {
                        $result[] = $target;
                    }
                }
                if (!$result) {
                    $this->delTree($dir);
                    return false;
                }
            }

            is_dir($dir) && $this->delTree($dir);

            return (is_array($result) || file_exists($result)) ? $result : false;
        }
        //TODO: Add return statement here
        return false;
    }

    /**
     * Create archive and return its path
     *
     * @param  string $dir   target dir
     * @param  array  $files files names list
     * @param  string $name  archive name
     * @param  array  $arc   archiver options
     *
     * @return string|bool
     * @throws elFinderAbortException
     * @author Dmitry (dio) Levashov,
     * @author Alexey Sukhotin
     */
    protected function _archive($dir, $files, $name, $arc)
    {
        return $this->makeArchive($dir, $files, $name, $arc);
    }

    /******************** Over write functions *************************/

    /**
     * File path of local server side work file path
     *
     * @param  string $path
     *
     * @return string
     * @author Naoki Sawada
     */
    protected function getWorkFile($path)
    {
        return $path;
    }

    /**
     * Delete dirctory trees
     *
     * @param string $localpath path need convert encoding to server encoding
     *
     * @return boolean
     * @throws elFinderAbortException
     * @author Naoki Sawada
     */
    protected function delTree($localpath)
    {
        return $this->rmdirRecursive($localpath);
    }

    /**
     * Return fileinfo based on filename
     * For item ID based path file system
     * Please override if needed on each drivers
     *
     * @param  string $path file cache
     *
     * @return array|boolean false
     */
    protected function isNameExists($path)
    {
        $exists = file_exists($this->convEncIn($path));
        // restore locale
        $this->convEncOut();
        return $exists ? $this->stat($path) : false;
    }

    /******************** Over write (Optimized) functions *************************/

    /**
     * Recursive files search
     *
     * @param  string $path dir path
     * @param  string $q    search string
     * @param  array  $mimes
     *
     * @return array
     * @throws elFinderAbortException
     * @author Dmitry (dio) Levashov
     * @author Naoki Sawada
     */
    protected function doSearch($path, $q, $mimes)
    {
        if (!empty($this->doSearchCurrentQuery['matchMethod']) || $this->encoding || !class_exists('FilesystemIterator', false)) {
            // has custom match method or non UTF-8, use elFinderVolumeDriver::doSearch()
            return parent::doSearch($path, $q, $mimes);
        }

        $result = array();

        $timeout = $this->options['searchTimeout'] ? $this->searchStart + $this->options['searchTimeout'] : 0;
        if ($timeout && $timeout < time()) {
            $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode($path)));
            return $result;
        }
        elFinder::extendTimeLimit($this->options['searchTimeout'] + 30);

        $match = array();
        try {
            $iterator = new RecursiveIteratorIterator(
                new RecursiveCallbackFilterIterator(
                    new RecursiveDirectoryIterator($path,
                        FilesystemIterator::KEY_AS_PATHNAME |
                        FilesystemIterator::SKIP_DOTS |
                        ((defined('RecursiveDirectoryIterator::FOLLOW_SYMLINKS') && $this->options['followSymLinks']) ?
                            RecursiveDirectoryIterator::FOLLOW_SYMLINKS : 0)
                    ),
                    array($this, 'localFileSystemSearchIteratorFilter')
                ),
                RecursiveIteratorIterator::SELF_FIRST,
                RecursiveIteratorIterator::CATCH_GET_CHILD
            );
            foreach ($iterator as $key => $node) {
                if ($timeout && ($this->error || $timeout < time())) {
                    !$this->error && $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode($node->getPath)));
                    break;
                }
                if ($node->isDir()) {
                    if ($this->stripos($node->getFilename(), $q) !== false) {
                        $match[] = $key;
                    }
                } else {
                    $match[] = $key;
                }
            }
        } catch (Exception $e) {
        }

        if ($match) {
            foreach ($match as $p) {
                if ($timeout && ($this->error || $timeout < time())) {
                    !$this->error && $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode(dirname($p))));
                    break;
                }

                $stat = $this->stat($p);

                if (!$stat) { // invalid links
                    continue;
                }

                if (!empty($stat['hidden']) || !$this->mimeAccepted($stat['mime'], $mimes)) {
                    continue;
                }

                if ((!$mimes || $stat['mime'] !== 'directory')) {
                    $stat['path'] = $this->path($stat['hash']);
                    if ($this->URL && !isset($stat['url'])) {
                        $_path = str_replace(DIRECTORY_SEPARATOR, '/', substr($p, strlen($this->root) + 1));
                        $stat['url'] = $this->URL . str_replace('%2F', '/', rawurlencode($_path));
                    }

                    $result[] = $stat;
                }
            }
        }

        return $result;
    }

    /******************** Original local functions ************************
     *
     * @param $file
     * @param $key
     * @param $iterator
     *
     * @return bool
     */

    public function localFileSystemSearchIteratorFilter($file, $key, $iterator)
    {
        /* @var FilesystemIterator $file */
        /* @var RecursiveDirectoryIterator $iterator */
        $name = $file->getFilename();
        if ($this->doSearchCurrentQuery['excludes']) {
            foreach ($this->doSearchCurrentQuery['excludes'] as $exclude) {
                if ($this->stripos($name, $exclude) !== false) {
                    return false;
                }
            }
        }
        if ($iterator->hasChildren()) {
            if ($this->options['searchExDirReg'] && preg_match($this->options['searchExDirReg'], $key)) {
                return false;
            }
            return (bool)$this->attr($key, 'read', null, true);
        }
        return ($this->stripos($name, $this->doSearchCurrentQuery['q']) === false) ? false : true;
    }

    /**
     * Creates a symbolic link
     *
     * @param      string   $target  The target
     * @param      string   $link    The link
     *
     * @return     boolean  ( result of symlink() )
     */
    protected function localFileSystemSymlink($target, $link)
    {
        $res = false;
        if (function_exists('symlink') and is_callable('symlink')) {
            $errlev = error_reporting();
            error_reporting($errlev ^ E_WARNING);
            if ($res = symlink(realpath($target), $link)) {
                $res = is_readable($link);
            }
            error_reporting($errlev);
        }
        return $res;
    }
} // END class                                                                                                                                                                                                                                                                           react/logo_palette.php                                                                              0000666                 00000001755 15226760543 0011057 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Logo_Palette Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Logo_Palette
 *
 * @package Neve\Customizer\Controls\React
 */
class Logo_Palette extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_logo_palette_control';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $input_attrs = [];

	/**
	 * Send to JS.
	 */
	public function json() {
		$json                = parent::json();
		$json['input_attrs'] = $this->input_attrs;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                   react/builder_columns.php                                                                           0000666                 00000151241 15226760543 0011563 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Builder Columns Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Customizer section.
 *
 * @package Neve\Customizer\Controls\React
 */
class Builder_Columns extends \WP_Customize_Control {
	/**
	 * Type of this section.
	 *
	 * @var string
	 */
	public $type = 'neve_builder_columns';

	/**
	 * Layout Choices.
	 *
	 * @var array
	 */
	public $choices = [];

	/**
	 * Columns control slug.
	 *
	 * @var string|null
	 */
	public $columns_control = null;

	/**
	 * Refresh the parameters passed to the JavaScript via JSON.
	 */
	public function json() {
		$json = parent::json();

		$this->choices = [
			1 => [
				'equal' => [
					'url' => 'data:image/jpeg;base64,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',
				],
			],
			2 => [
				'equal'       => [
					'url' => 'data:image/jpeg;base64,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',
				],
				'right-third' => [
					'url' => 'data:image/jpeg;base64,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',
				],
				'left-third'  => [
					'url' => 'data:image/jpeg;base64,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',
				],
			],
			3 => [
				'equal'             => [
					'url' => 'data:image/jpeg;base64,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',
				],
				'left-half'         => [
					'url' => 'data:image/jpeg;base64,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',
				],
				'right-half'        => [
					'url' => 'data:image/jpeg;base64,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',
				],
				'center-half'       => [
					'url' => 'data:image/jpeg;base64,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',
				],
				'center-two-thirds' => [
					'url' => 'data:image/jpeg;base64,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',
				],
			],
			4 => [
				'equal'      => [
					'url' => 'data:image/jpeg;base64,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',
				],
				'left-half'  => [
					'url' => 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAA8AFsDAREAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+6S4/4+J/+u0v/obVqtkZEVABQAUAFABQAUAFABQAUAFAHR2H/HpF/wBtP/Rr1D3GYNx/x8T/APXaX/0NqtbIRFQAUAFABQAUAFABQAUAFABQB0dh/wAekX/bT/0a9Q9xmDcf8fE//XaX/wBDarWyERUAFABQAUAFABQAUAFABQAUAdHYf8ekX/bT/wBGvUPcZzOo3DQTyFbW5ud08wItxCSmHPLebNDwc8bd3Q5xxm+iAz/7Rl/6BWp/98Wf/wAmUX8n+H+YfNfj/kH9oy/9ArU/++LP/wCTKL+T/D/MPmvx/wAg/tGX/oFan/3xZ/8AyZRfyf4f5h81+P8AkH9oy/8AQK1P/viz/wDkyi/k/wAP8w+a/H/IP7Rl/wCgVqf/AHxZ/wDyZRfyf4f5h81+P+Qf2jL/ANArU/8Aviz/APkyi/k/w/zD5r8f8g/tGX/oFan/AN8Wf/yZRfyf4f5h81+P+Qf2jL/0CtT/AO+LP/5Mov5P8P8AMPmvx/yD+0Zf+gVqf/fFn/8AJlF/J/h/mHzX4/5D476R3RDp2oRhmCmSRLUImTjc5W6dto6narHHQGj5P8P8w+f5/wCR2dh/x6Rf9tP/AEa9Q9wPIPiR4s1HwoLSbTobKZry8vI5RexzyKqxbWUxiC5tyCS53biwxjAHf63hXI8JndXF08XUxFNYelSnB4edKDbnKafN7SjVTVoq1lHrds+e4gzbE5VTw08PChN1p1Iy9tGpJJRjFrl5KlOz11u2eVf8Lh8Tf8+Ohf8AgNqH/wAs6+z/ANQcn/6Ccz/8HYX/AOYz5j/XDM/+fGB/8FYj/wCag/4XD4m/58dC/wDAbUP/AJZ0f6g5P/0E5n/4Owv/AMxh/rhmf/PjA/8AgrEf/NQf8Lh8Tf8APjoX/gNqH/yzo/1Byf8A6Ccz/wDB2F/+Yw/1wzP/AJ8YH/wViP8A5qD/AIXD4m/58dC/8BtQ/wDlnR/qDk//AEE5n/4Owv8A8xh/rhmf/PjA/wDgrEf/ADUeh+BPGmqeJ4ddkv7ewhbTIrR7cWcVxGHNwl8z+d511cFgDax7dhjIBfJbK7flOJuHsFk1TLYYWriqixk68av1idKTiqUsMo+z9nQpWb9tK/MpbRtazv8AQ5FnWKzSGOliKeHg8NGjKn7GNSKbqKu5c/PVqXt7KNuXl3d76W88/wCFw+Jv+fHQv/AbUP8A5Z19X/qDk/8A0E5n/wCDsL/8xnz3+uGZ/wDPjA/+CsR/81HoieM9Ub4fzeKzBYf2jHIEWERXH2Ig6tFYcx/avPz5LluLkfvADjblD8pLh7BLimnkaq4r6pODk6nPS+sXWBnidJ+w9nb2kUv4L9y6+L3j6GOdYp8PzzX2eH+sRkkoctT2NvrcKGsfa8/wSb/ifFZ7aHnf/C4fE3/PjoX/AIDah/8ALOvq/wDUHJ/+gnM//B2F/wDmM+e/1wzP/nxgf/BWI/8Amo9D8Z+NNU8O6boN5ZW9hLLqkTvcLdRXDxoVgtZR5IhuoGUbpmB3tIcBecgk/KcPcPYLNsXmmHxNXFQhgpxjSdCdKMpJ1a0P3jqUKibtTj8MYat9LJfQ51nWKy7DYCtQp4eUsVFyqKrGpKKap0pe4oVYNazfxOWlvO/J6D8UvEGqa1penXFno6QXt9b20rw296sqxyyKjGNn1CRA4B+UsjgHqp6V7uZ8F5XgsuxuLpYjMJVMNhqtaEalXDuDlCDklNRwsJOLa1SlF22aPJwHFOYYrG4XDVKODUK9enSm4U66mozkk3FyxEknba8WvJn07Yf8ekX/AG0/9GvX5a9z70+ePjd/qdJ/7CGo/wDoEVfo/h7/ALxmX/XjDf8ApdQ+K4z/AIGB/wCvtb/0iB8+V+onwAUAFABQB7X8If8Aj18Xf9e+m/8AovV6/OuPP4+Q/wDX3Gf+l4A+24Q/hZv/ANe8N/6TizxSv0U+JPbIv+SMXX/Xdf8A1I7evzmp/wAnCo/9en/6qap9tD/kjKv/AF8X/qxpnidfox8Se1/FL/kBeDv+veX/ANI7Cvzrgr/kZZ//ANfYf+pGKPtuKf8Accn/AOvcv/TNA838H/8AI1eH/wDsLWX/AKOWvrs//wCRJmv/AGA4j/03I+byf/ka5f8A9hdH/wBLR9z2H/HpF/20/wDRr1/Pz3P2I8G+MOm6jqUemrp1he37RX9+0q2VrPdNGrLGFaQQRyFAxBClsAkEDpX33AuMwmEr5g8XisPhVOjQUHiK9KiptTqNqLqSipNJptK9rq58jxZhsTiaODWHw9eu41arkqNKpVcU4ws5KEZWTto3ueFf8Iv4m/6F3Xf/AAUah/8AI9fo/wDbWT/9DbLP/C/C/wDy0+I/svM/+hdjv/CTEf8AysP+EX8Tf9C7rv8A4KNQ/wDkej+2sn/6G2Wf+F+F/wDlof2Xmf8A0Lsd/wCEmI/+Vh/wi/ib/oXdd/8ABRqH/wAj0f21k/8A0Nss/wDC/C//AC0P7LzP/oXY7/wkxH/ysP8AhF/E3/Qu67/4KNQ/+R6P7ayf/obZZ/4X4X/5aH9l5n/0Lsd/4SYj/wCVnr/wt0rVNPtvFC3+m39i1xBp4t1vLO4tjOUj1QOIRNGhlKGSMME3FS6ZxuXPwfGuOwWKrZK8LjMLiVSqYp1Xh8RSrKmpSwXK6jpzlyKXJK3Na/LK2zt9fwthMVh6eaLEYbEUHUhh1TVajUpObjHFcyhzxjzW5o35b25lfdHkH/CL+Jv+hd13/wAFGof/ACPX3n9tZP8A9DbLP/C/C/8Ay0+Q/svM/wDoXY7/AMJMR/8AKz1+LStUHwluNNOm341FplK2Bs7gXpH9vwTZFr5fnkeSDLkR/wCrBf7oJr4KeOwT46pYtYzCvCKm08V9YpfV0/7Lq07Otz+zT9o1D4vjaj8TsfXxwmK/1SqYb6tiPrDmmsP7Gp7Zr6/TndUuXn+BOfw/CnLbU8g/4RfxN/0Luu/+CjUP/kevvf7ayf8A6G2Wf+F+F/8Alp8h/ZeZ/wDQux3/AISYj/5Wev8AxI0rVL7RvCkVlpt/eS28EguI7WzuLiSAm1slAmSGN2iJZGUBwpyrDqDj4PhHHYLDZhnc8TjMLh4VakHSnXxFKlGqlXxLvTlUnFTVpRfut6NPZo+v4kwmKr4PKo0MNiK0qcJKpGlRqVJU37KirTUItx1TXvW1TXRnAeFfDviC38SaHPcaFrEEEOp2kks02mXsUUUazKWeSR4FREUcszEADkmvqM7zbK6uUZlSpZll9WpUwdeMKdPGYec5ydNpRhCNRylJvRJJtvY8DKsuzCnmWBqVMDjKcIYmjKc54WvGEYqablKUoJRSW7bSR9nWH/HpF/20/wDRr1+HPc/VTBuP+Pif/rtL/wChtVrZCIqACgAoAKACgAoAKACgAoAKAOjsP+PSL/tp/wCjXqHuMP/Z',
				],
				'right-half' => [
					'url' => 'data:image/jpeg;base64,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',
				],
			],
			5 => [
				'equal' => [
					'url' => 'data:image/jpeg;base64,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',
				],
			],
		];

		$json['choices']        = $this->choices;
		$json['columnsControl'] = $this->columns_control;

		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                                                                                                                               react/color.php                                                                                     0000666                 00000002526 15226760543 0007514 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Color Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Button_Appearance
 *
 * @package Neve\Customizer\Controls\React
 */
class Color extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_color_control';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var string
	 */
	public $default = '';
	/**
	 * Disable Alpha in colorpicker.
	 *
	 * @var bool
	 */
	public $disable_alpha = false;
	/**
	 * Allow gradient inside color picker.
	 *
	 * @var bool
	 */
	public $allow_gradient = false;
	/**
	 * Send to JS.
	 */
	public function json() {
		$json                  = parent::json();
		$json['default']       = $this->default;
		$json['disableAlpha']  = $this->disable_alpha;
		$json['allowGradient'] = isset( $this->input_attrs['allow_gradient'] ) ? $this->input_attrs['allow_gradient'] : $this->allow_gradient;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                          react/upsell_banner_section.php                                                                     0000666                 00000003465 15226760543 0012756 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Description Upsell Section
 *
 * Author:      Bogdan Preda <bogdan.preda@themeisle.com>
 * Created on:  20-12-{2021}
 *
 * @package neve/neve-pro
 */
namespace Neve\Customizer\Controls\React;

/**
 * Customizer section.
 *
 * @package    WordPress
 * @subpackage Customize
 * @since      4.1.0
 * @see        WP_Customize_Section
 */
class Upsell_Banner_Section extends \WP_Customize_Section {
	/**
	 * Type of this section.
	 *
	 * @var string
	 */
	public $type = 'neve_upsell_banner_section';

	/**
	 * Upgrade URL.
	 *
	 * @var string
	 */
	public $url = '';

	/**
	 * Nonce.
	 *
	 * @var string
	 */
	public $nonce = '';

	/**
	 * Upsell text.
	 *
	 * @var string
	 */
	public $text = '';

	/**
	 * Upsell button text.
	 *
	 * @var string
	 */
	public $button_text = '';

	/**
	 * Upsell logo path.
	 *
	 * @var string
	 */
	public $logo_path = '';

	/**
	 * Upsell use logo.
	 *
	 * @var boolean
	 */
	public $use_logo = false;

	/**
	 * Gather the parameters passed to client JavaScript via JSON.
	 *
	 * @return array The array to be exported to the client as JSON.
	 * @since 4.1.0
	 */
	public function json() {
		$json               = parent::json();
		$json['url']        = $this->url;
		$json['nonce']      = $this->nonce;
		$json['text']       = $this->text;
		$json['buttonText'] = $this->button_text;
		$json['useLogo']    = $this->use_logo === true;
		$json['logoPath']   = ! empty( $this->logo_path ) ? $this->logo_path : get_template_directory_uri() . '/assets/img/dashboard/logo.svg';
		return $json;
	}

	/**
	 * Render template.
	 */
	protected function render() {
		?>
		<li id="acordion-section-<?php echo esc_attr( $this->id ); ?>"
			data-slug="<?php echo esc_attr( $this->id ); ?>"
			class="control-section control-section-<?php echo esc_attr( $this->type ); ?> neve-upsell-banner">
		</li>
		<?php
	}
}
                                                                                                                                                                                                           react/responsive_range.php                                                                          0000666                 00000001775 15226760543 0011754 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Responsive_Range Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Responsive_Range
 *
 * @package Neve\Customizer\Controls\React
 */
class Responsive_Range extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_responsive_range_control';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $input_attrs = [];

	/**
	 * Send to JS.
	 */
	public function json() {
		$json                = parent::json();
		$json['input_attrs'] = $this->input_attrs;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
   react/global_custom_colors.php                                                                      0000666                 00000002214 15226760543 0012603 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Global_Custom_Colors Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Global_Custom_Colors
 *
 * @package Neve\Customizer\Controls\React
 */
class Global_Custom_Colors extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_global_custom_colors';
	/**
	 * Default values.
	 *
	 * @var string
	 */
	public $default_values = '';

	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $input_attrs = [];

	/**
	 * Send to JS.
	 */
	public function json() {
		$json                  = parent::json();
		$json['defaultValues'] = $this->default_values;
		$json['input_attrs']   = $this->input_attrs;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                                                                                                                                                    react/radio_buttons.php                                                                             0000666                 00000003111 15226760543 0011241 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Radio Buttons Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Spacing
 *
 * @package Neve\Customizer\Controls\React
 */
class Radio_Buttons extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_radio_buttons_control';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $choices = [];
	/**
	 * Send context to the control that will handle the choices differently.
	 *
	 * @var bool|string
	 */
	public $is_for = false;
	/**
	 * Should have larger buttons.
	 *
	 * @var bool
	 */
	public $large_buttons = false;
	/**
	 * Show the labels.
	 *
	 * @var bool
	 */
	public $show_labels = false;

	/**
	 * Footer description.
	 *
	 * @var string
	 */
	public $footer_description = '';

	/**
	 * Send to JS.
	 */
	public function json() {
		$json                      = parent::json();
		$json['choices']           = $this->choices;
		$json['is_for']            = $this->is_for;
		$json['large_buttons']     = $this->large_buttons;
		$json['showLabels']        = $this->show_labels;
		$json['footerDescription'] = $this->footer_description;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                       react/inline_select.php                                                                             0000666                 00000002424 15226760543 0011210 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Inline Select Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Inline_Select
 *
 * @package Neve\Customizer\Controls\React
 */
class Inline_Select extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_inline_select';

	/**
	 * Options.
	 *
	 * @var array
	 */
	public $options = [];

	/**
	 * Default.
	 *
	 * @var string|int
	 */
	public $default;

	/**
	 * Link.
	 *
	 * @var array
	 */
	public $link;

	/**
	 * Allows listening to other components.
	 *
	 * @var string
	 */
	public $changes_on;
	/**
	 * Send to JS.
	 */
	public function json() {
		$json               = parent::json();
		$json['options']    = $this->options;
		$json['defaultVal'] = $this->default;
		$json['link']       = $this->link;
		$json['changesOn']  = $this->changes_on;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                            react/range.php                                                                                     0000666                 00000001723 15226760543 0007470 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Range Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Spacing
 *
 * @package Neve\Customizer\Controls\React
 */
class Range extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_range_control';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $input_attrs = [];

	/**
	 * Send to JS.
	 */
	public function json() {
		$json                = parent::json();
		$json['input_attrs'] = $this->input_attrs;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                             react/presets_selector.php                                                                          0000666                 00000002122 15226760543 0011753 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Presets selector control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Spacing
 *
 * @package Neve\Customizer\Controls\React
 */
class Presets_Selector extends \WP_Customize_Control {

	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_presets_selector';

	/**
	 * Presets for the control.
	 *
	 * @var array
	 */
	public $presets = [];

	/**
	 * Builder Setting Slug.
	 *
	 * @var string | null
	 */
	public $builder = null;

	/**
	 * Send to JS.
	 */
	public function json() {
		$json            = parent::json();
		$json['presets'] = $this->presets;
		$json['builder'] = $this->builder;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                              react/rich_text.php                                                                                 0000666                 00000002407 15226760543 0010365 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Rich_Text Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Rich_Text
 *
 * @package Neve\Customizer\Controls\React
 */
class Rich_Text extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_rich_text';
	/**
	 * Send to JS.
	 */
	public function json() {
		$json                         = parent::json();
		$json['toolbars']             = [];
		$json['allowedDynamicFields'] = [];
		if ( isset( $this->input_attrs['toolbars'] ) && ! empty( $this->input_attrs['toolbars'] ) ) {
			$json['toolbars'] = $this->input_attrs['toolbars'];
		}
		if ( isset( $this->input_attrs['allowedDynamicFields'] ) && ! empty( $this->input_attrs['allowedDynamicFields'] ) ) {
			$json['allowedDynamicFields'] = $this->input_attrs['allowedDynamicFields'];
		}
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                         react/spacing.php                                                                                   0000666                 00000002102 15226760543 0010010 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Spacing Control. Handles data passing from args to JS.
 *
 * @package Neve\Customizer\Controls\React
 */

namespace Neve\Customizer\Controls\React;

/**
 * Class Spacing
 *
 * @package Neve\Customizer\Controls\React
 */
class Spacing extends \WP_Customize_Control {
	/**
	 * Control type.
	 *
	 * @var string
	 */
	public $type = 'neve_spacing';
	/**
	 * Additional arguments passed to JS.
	 *
	 * @var array
	 */
	public $input_attrs = [];

	/**
	 * Default value.
	 *
	 * @var array
	 */
	public $default = [];

	/**
	 * Send to JS.
	 */
	public function json() {
		$json                = parent::json();
		$json['input_attrs'] = $this->input_attrs;
		$json['default']     = $this->default;
		return $json;
	}

	/**
	 * This method overrides the default render
	 * so that nothing is rendered.
	 * Previously it would try to put an input element where the value was `esc_attr()`
	 * This would trigger notices in PHP
	 * It is not required to have a render as it is being handled by React.
	 */
	final public function render_content() {
		// this is rendered from React
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                              react/instructions_section.php                                                                      0000666                 00000002432 15226760543 0012662 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Author:          Andrei Baicus <andrei@themeisle.com>
 * Created on:      2019-10-16
 *
 * @package Neve
 */
namespace Neve\Customizer\Controls\React;

/**
 * Customizer section.
 *
 * @package    WordPress
 * @subpackage Customize
 * @since      4.1.0
 * @see        WP_Customize_Section
 */
class Instructions_Section extends \WP_Customize_Section {
	/**
	 * Type of this section.
	 *
	 * @var string
	 */
	public $type = 'hfg_instructions';
	/**
	 * Default options schema.
	 *
	 * @var array
	 */
	public $default_options = [
		'description'     => '',
		'image'           => '',
		'quickLinks'      => [],
		'builderMigrated' => false,
	];
	/**
	 * Options passed to control.
	 *
	 * @var array
	 */
	public $options = [];
	/**
	 * Gather the parameters passed to client JavaScript via JSON.
	 *
	 * @return array The array to be exported to the client as JSON.
	 * @since 4.1.0
	 */
	public function json() {
		$json            = parent::json();
		$json['options'] = wp_parse_args( $this->options, $this->default_options );
		return $json;
	}
	/**
	 * Render template.
	 */
	protected function render_template() {
		?>
		<li id="accordion-section-{{ data.id }}"
			data-slug="{{data.id}}"
			class="control-section control-section-{{ data.type }} neve-quick-links">
		</li>
		<?php
	}
}
                                                                                                                                                                                                                                      range.php                                                                                           0000666                 00000012375 15226760543 0006377 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * The range value customize control.
 *
 * @package    Neve/Customizer/Controls
 * @soundtrack I Still Haven't Found What I'm Looking For - U2 ( manily the sense of _js )
 */

namespace Neve\Customizer\Controls;

/**
 * Class Customizer_Range_Value_Control
 *
 * @package  Neve\Customizer\Controls
 */
class Range extends \WP_Customize_Control {

	/**
	 * Control type
	 *
	 * @var string
	 */
	public $type = 'range-value';

	/**
	 * Enable media queries
	 *
	 * @var bool
	 */
	public $media_query = false;

	/**
	 * Settings for range inputs.
	 *
	 * @var array
	 */
	public $input_attr = array();

	/**
	 * Step size.
	 *
	 * @var string
	 */
	public $step = '';

	/**
	 * Add/remove from fixed value flag
	 *
	 * @var bool
	 */
	public $sum_type = false;

	/**
	 * Hide the responsive switches
	 *
	 * @var bool
	 */
	public $hide_responsive_switches = false;

	/**
	 * Range constructor.
	 *
	 * @param \WP_Customize_Manager $manager Customize manager.
	 * @param string                $id      Control id.
	 * @param array                 $args    Control arguments.
	 */
	public function __construct( $manager, $id, $args = array() ) {
		parent::__construct( $manager, $id, $args );
		$this->args_to_props( $args );
	}

	/**
	 * Handles input value.
	 *
	 * @return array
	 */
	public function json() {
		$json = parent::json();

		$json['value']                    = json_decode( $this->value(), true );
		$json['link']                     = $this->get_link();
		$json['media_query']              = $this->media_query;
		$json['step']                     = $this->step;
		$json['sum_type']                 = $this->sum_type;
		$json['inputAttr']                = $this->input_attr;
		$json['hide_responsive_switches'] = $this->hide_responsive_switches;

		return $json;
	}

	/**
	 * Render the title for the control.
	 */
	private function render_title() {
		?>
		<# if ( data.label ) { #>
		<span class="customize-control-title">
				<span>{{ data.label }}</span>
				<# if ( data.description ) { #>
					<i class="dashicons dashicons-editor-help" style="vertical-align: text-bottom;"
							title="{{ data.description }}"></i>
				<# } #>
		</span>
		<# if( data.media_query === true && data.hide_responsive_switches === false ) { #>
		<?php $this->render_responsive_switches(); ?>
		<# } #>
		<# } #>
		<?php
	}

	/**
	 * Render the responsive switches.
	 */
	private function render_responsive_switches() {
		?>
		<ul class="responsive-switchers">
			<li class="desktop">
				<button type="button" class="preview-desktop active" data-device="desktop">
					<i class="dashicons dashicons-desktop"></i>
				</button>
			</li>
			<li class="tablet">
				<button type="button" class="preview-tablet" data-device="tablet">
					<i class="dashicons dashicons-tablet"></i>
				</button>
			</li>
			<li class="mobile">
				<button type="button" class="preview-mobile" data-device="mobile">
					<i class="dashicons dashicons-smartphone"></i>
				</button>
			</li>
		</ul>
		<?php
	}

	/**
	 * Render the input.
	 */
	private function render_input() {
		?>
		<#
		var type = data.sum_type ? 'text' : 'number';
		var value = data.value ? data.value[mediaQuery] : attr.default;
		if( ! data.media_query ) {
		value = data.value? data.value : attr.default
		}
		var active = mediaQuery === 'desktop' ? 'active' : '';

		if( data.sum_type ) { value = '+' + value; }
		#>
		<div class="{{mediaQuery}} control-wrap {{active}}">
			<input
					class="range-slider__range"
					type="range"
					min="{{attr.min}}"
					max="{{attr.max}}"
					step="{{data.step}}"
					data-query="{{mediaQuery}}"
					data-default="{{attr.default}}"
					value="{{ value }}"
			>
			<input
			<# if( data.sum_type ) { #>
			readonly
			<# } #>
			class="range-slider-value"
			type="{{type}}"
			title="{{data.label}}"
			min="{{attr.min}}"
			max="{{attr.max}}"
			step="{{data.step}}"
			value="{{ value }}"
			>
			<span class="range-reset-slider"><span class="dashicons dashicons-image-rotate"></span></span>
		</div>
		<?php
	}

	/**
	 * Render the control's content.
	 */
	protected function content_template() {
		$this->render_title();
		?>
		<# var wrapClass = data.media_query ? 'has-media-queries' : ''; #>
		<div class="range-slider {{wrapClass}}">
		<# if( data.media_query === true ) { #>
		<# _.each( data.inputAttr, function( attr, mediaQuery ) { #>
		<?php $this->render_input(); ?>
		<# } ) #>
		<# } else {
		var mediaQuery = 'desktop';
		var attr = data.inputAttr; #>
		<?php $this->render_input(); ?>
		<# } #>
		<input
				type="hidden"
				class="range-collector"
				title="{{data.label}}"
				value="{{data.value}}"
				{{{data.link}}}  <?php // phpcs:ignore WordPressVIPMinimum.Security.Mustache.OutputNotation ?>
		>
		<?php
	}

	/**
	 * Transform arguments to object properties
	 */
	private function args_to_props( $args ) {
		if ( ! empty( $args['input_attr'] ) ) {
			$this->input_attr = $args['input_attr'];
		}

		if ( ! empty( $args['media_query'] ) ) {
			$this->media_query = (bool) $args['media_query'];
		}

		if ( ! isset( $this->input_attr['mobile'] ) || ! isset( $this->input_attr['tablet'] ) || ! isset( $this->input_attr['desktop'] ) ) {
			$this->media_query = false;
		}

		if ( ! empty( $args['sum_type'] ) ) {
			$this->sum_type = $args['sum_type'];
		}

		if ( ! empty( $args['step'] ) ) {
			$this->step = $args['step'];
		}
	}
}
                                                                                                                                                                                                                                                                   simple_upsell.php                                                                                   0000666                 00000002411 15226760543 0010146 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Simple upsell control.
 *
 * @package Neve
 */

namespace Neve\Customizer\Controls;

/**
 * Simple Upsell Control.
 *
 * @since  2.8.3
 * @access public
 */
class Simple_Upsell extends \WP_Customize_Control {

	/**
	 * The type of customize control being rendered.
	 *
	 * @since  2.8.3
	 * @var   string
	 */
	public $type = 'nv_simple_upsell';

	/**
	 * Button text.
	 *
	 * @since  2.8.3
	 * @var   string
	 */
	public $button_text = '';

	/**
	 * Button link.
	 *
	 * @since  2.8.3
	 * @var   string
	 */
	public $link = '';

	/**
	 * List of features.
	 *
	 * @since  2.8.3
	 * @var   string
	 */
	public $text = '';

	/**
	 * Render Method
	 *
	 * @return void
	 */
	public function render_content() {
		?>
		<div class="nv-simple-upsell">
			<?php if ( ! empty( $this->text ) ) { ?>
				<p><?php echo esc_html( $this->text ); ?></p>
			<?php } ?>
			<?php if ( ! empty( $this->link ) && ! empty( $this->button_text ) ) { ?>
				<a target="_blank" rel="external noreferrer noopener" href="<?php echo esc_url( $this->link ); ?>" class='button button-secondary'>
					<?php echo esc_html( $this->button_text ); ?>
					<span class="components-visually-hidden"><?php echo esc_html__( '(opens in a new tab)', 'neve' ); ?></span>
				</a>
			<?php } ?>
		</div>
		<?php
	}
}
                                                                                                                                                                                                                                                       button.php                                                                                          0000666                 00000006010 15226760543 0006603 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Customizer functionality for the Blog settings panel.
 *
 * @package Neve\Customizer\Controls
 * @since   1.0.0
 */

namespace Neve\Customizer\Controls;

/**
 * A customizer control to display text in customizer.
 *
 * @since 1.0.0
 */
class Button extends \WP_Customize_Control {

	/**
	 * Control id
	 *
	 * @var string $id Control id.
	 */
	public $id = '';
	/**
	 * Button class.
	 *
	 * @var mixed|string
	 */
	public $button_class = '';
	/**
	 * Icon class.
	 *
	 * @var mixed|string
	 */
	public $icon_class = '';
	/**
	 * Button text.
	 *
	 * @var mixed|string
	 */
	public $button_text = '';

	/**
	 * Text before.
	 *
	 * @var mixed|string
	 */
	public $text_before = '';


	/**
	 * Text after.
	 *
	 * @var mixed|string
	 */
	public $text_after = '';


	/**
	 * Is Button.
	 *
	 * @var bool
	 */
	public $is_button = true;


	/**
	 * Control to focus.
	 *
	 * @var string
	 */
	public $control_to_focus = '';
	/**
	 * Shortcut.
	 *
	 * @var bool
	 */
	public $shortcut = false;

	/**
	 * Constructor.
	 *
	 * @param \WP_Customize_Manager $manager Customizer manager.
	 * @param string                $id      Control id.
	 * @param array                 $args    Argument.
	 */
	public function __construct( $manager, $id, $args = array() ) {
		parent::__construct( $manager, $id, $args );
		$this->id = $id;
	}

	/**
	 * Render content for the control.
	 *
	 * @since 1.0.0
	 */
	public function render_content() {
		if ( empty( $this->button_text ) ) {
			return;
		}
		$control = $this->is_button ? '' : '<p>';
		if ( ! empty( $this->text_before ) ) {
			$control .= wp_kses_post( $this->text_before ) . ' ';
		}
		$control .= $this->is_button ? '<button ' : '<a ';
		if ( $this->control_to_focus ) {
			$control .= 'data-control-to-focus="' . esc_attr( $this->control_to_focus ) . '"';
		}
		$control .= ' class="' . esc_attr( $this->get_button_classes() ) . '"';
		$control .= $this->is_button ? ' style="display: flex; align-items: center;"' : ' style="cursor:pointer;"';
		$control .= '>';
		$control .= $this->get_icon();
		$control .= esc_html( $this->button_text );
		$control .= $this->is_button ? '</button>' : '</a>';
		if ( ! empty( $this->text_after ) ) {
			$control .= wp_kses_post( $this->text_after );
		}
		if ( $this->is_button ) {
			$control .= '</p>';
		}

		echo $control;  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	}

	/**
	 * Get the icon.
	 *
	 * @return string
	 */
	private function get_icon() {
		if ( empty( $this->icon_class ) ) {
			return '';
		}

		return '<i class="dashicons dashicons-' . esc_attr( $this->icon_class ) . '" style="margin-right: 10px"></i>';
	}

	/**
	 * Get the button classes.
	 *
	 * @return string
	 */
	private function get_button_classes() {
		$classes = '';

		if ( $this->is_button ) {
			$classes .= 'button button-secondary';
		}
		if ( $this->shortcut ) {
			$classes .= ' menu-shortcut ';
		}
		if ( $this->button_class ) {
			$classes .= $this->button_class;
		}
		if ( $this->control_to_focus ) {
			$classes .= ' neve-control-focus';
		}

		return $classes;
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        elFinderVolumeLocalFileSystem.class.php                                                             0000666                 00000136366 15226760543 0014316 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php

// Implement similar functionality in PHP 5.2 or 5.3
// http://php.net/manual/class.recursivecallbackfilteriterator.php#110974
if (!class_exists('RecursiveCallbackFilterIterator', false)) {
    class RecursiveCallbackFilterIterator extends RecursiveFilterIterator
    {
        private $callback;

        public function __construct(RecursiveIterator $iterator, $callback)
        {
            $this->callback = $callback;
            parent::__construct($iterator);
        }

        public function accept()
        {
            return call_user_func($this->callback, parent::current(), parent::key(), parent::getInnerIterator());
        }

        public function getChildren()
        {
            return new self($this->getInnerIterator()->getChildren(), $this->callback);
        }
    }
}

/**
 * elFinder driver for local filesystem.
 *
 * @author Dmitry (dio) Levashov
 * @author Troex Nevelin
 **/
class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
{

    /**
     * Driver id
     * Must be started from letter and contains [a-z0-9]
     * Used as part of volume id
     *
     * @var string
     **/
    protected $driverId = 'l';

    /**
     * Required to count total archive files size
     *
     * @var int
     **/
    protected $archiveSize = 0;

    /**
     * Is checking stat owner
     *
     * @var        boolean
     */
    protected $statOwner = false;

    /**
     * Path to quarantine directory
     *
     * @var string
     */
    private $quarantine;

    /**
     * Constructor
     * Extend options with required fields
     *
     * @author Dmitry (dio) Levashov
     */
    public function __construct()
    {
        $this->options['alias'] = '';              // alias to replace root dir name
        $this->options['dirMode'] = 0755;            // new dirs mode
        $this->options['fileMode'] = 0644;            // new files mode
        $this->options['rootCssClass'] = 'elfinder-navbar-root-local';
        $this->options['followSymLinks'] = true;
        $this->options['detectDirIcon'] = '';         // file name that is detected as a folder icon e.g. '.diricon.png'
        $this->options['keepTimestamp'] = array('copy', 'move'); // keep timestamp at inner filesystem allowed 'copy', 'move' and 'upload'
        $this->options['substituteImg'] = true;       // support substitute image with dim command
        $this->options['statCorrector'] = null;       // callable to correct stat data `function(&$stat, $path, $statOwner, $volumeDriveInstance){}`
        if (DIRECTORY_SEPARATOR === '/') {
            // Linux
            $this->options['acceptedName'] = '/^[^\.\/\x00][^\/\x00]*$/';
        } else {
            // Windows
            $this->options['acceptedName'] = '/^[^\.\/\x00\\\:*?"<>|][^\/\x00\\\:*?"<>|]*$/';
        }
    }

    /*********************************************************************/
    /*                        INIT AND CONFIGURE                         */
    /*********************************************************************/

    /**
     * Prepare driver before mount volume.
     * Return true if volume is ready.
     *
     * @return bool
     **/
    protected function init()
    {
        // Normalize directory separator for windows
        if (DIRECTORY_SEPARATOR !== '/') {
            foreach (array('path', 'tmbPath', 'tmpPath', 'quarantine') as $key) {
                if (!empty($this->options[$key])) {
                    $this->options[$key] = str_replace('/', DIRECTORY_SEPARATOR, $this->options[$key]);
                }
            }
            // PHP >= 7.1 Supports UTF-8 path on Windows
            if (version_compare(PHP_VERSION, '7.1', '>=')) {
                $this->options['encoding'] = '';
                $this->options['locale'] = '';
            }
        }
        if (!$cwd = getcwd()) {
            return $this->setError('elFinder LocalVolumeDriver requires a result of getcwd().');
        }
        // detect systemRoot
        if (!isset($this->options['systemRoot'])) {
            if ($cwd[0] === DIRECTORY_SEPARATOR || $this->root[0] === DIRECTORY_SEPARATOR) {
                $this->systemRoot = DIRECTORY_SEPARATOR;
            } else if (preg_match('/^([a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . ')/', $this->root, $m)) {
                $this->systemRoot = $m[1];
            } else if (preg_match('/^([a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . ')/', $cwd, $m)) {
                $this->systemRoot = $m[1];
            }
        }
        $this->root = $this->getFullPath($this->root, $cwd);
        if (!empty($this->options['startPath'])) {
            $this->options['startPath'] = $this->getFullPath($this->options['startPath'], $this->root);
        }

        if (is_null($this->options['syncChkAsTs'])) {
            $this->options['syncChkAsTs'] = true;
        }
        if (is_null($this->options['syncCheckFunc'])) {
            $this->options['syncCheckFunc'] = array($this, 'localFileSystemInotify');
        }
        // check 'statCorrector'
        if (empty($this->options['statCorrector']) || !is_callable($this->options['statCorrector'])) {
            $this->options['statCorrector'] = null;
        }

        return true;
    }

    /**
     * Configure after successfull mount.
     *
     * @return void
     * @throws elFinderAbortException
     * @author Dmitry (dio) Levashov
     */
    protected function configure()
    {
        $hiddens = array();
        $root = $this->stat($this->root);

        // check thumbnails path
        if (!empty($this->options['tmbPath'])) {
            if (strpos($this->options['tmbPath'], DIRECTORY_SEPARATOR) === false) {
                $hiddens['tmb'] = $this->options['tmbPath'];
                $this->options['tmbPath'] = $this->_abspath($this->options['tmbPath']);
            } else {
                $this->options['tmbPath'] = $this->_normpath($this->options['tmbPath']);
            }
        }
        // check temp path
        if (!empty($this->options['tmpPath'])) {
            if (strpos($this->options['tmpPath'], DIRECTORY_SEPARATOR) === false) {
                $hiddens['temp'] = $this->options['tmpPath'];
                $this->options['tmpPath'] = $this->_abspath($this->options['tmpPath']);
            } else {
                $this->options['tmpPath'] = $this->_normpath($this->options['tmpPath']);
            }
        }
        // check quarantine path
        $_quarantine = '';
        if (!empty($this->options['quarantine'])) {
            if (strpos($this->options['quarantine'], DIRECTORY_SEPARATOR) === false) {
                $_quarantine = $this->_abspath($this->options['quarantine']);
                $this->options['quarantine'] = '';
            } else {
                $this->options['quarantine'] = $this->_normpath($this->options['quarantine']);
            }
        } else {
            $_quarantine = $this->_abspath('.quarantine');
        }
        is_dir($_quarantine) && self::localRmdirRecursive($_quarantine);

        parent::configure();

        // check tmbPath
        if (!$this->tmbPath && isset($hiddens['tmb'])) {
            unset($hiddens['tmb']);
        }

        // if no thumbnails url - try detect it
        if ($root['read'] && !$this->tmbURL && $this->URL) {
            if (strpos($this->tmbPath, $this->root) === 0) {
                $this->tmbURL = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($this->tmbPath, strlen($this->root) + 1));
                if (preg_match("|[^/?&=]$|", $this->tmbURL)) {
                    $this->tmbURL .= '/';
                }
            }
        }

        // set $this->tmp by options['tmpPath']
        $this->tmp = '';
        if (!empty($this->options['tmpPath'])) {
            if ((is_dir($this->options['tmpPath']) || mkdir($this->options['tmpPath'], $this->options['dirMode'], true)) && is_writable($this->options['tmpPath'])) {
                $this->tmp = $this->options['tmpPath'];
            } else {
                if (isset($hiddens['temp'])) {
                    unset($hiddens['temp']);
                }
            }
        }
        if (!$this->tmp && ($tmp = elFinder::getStaticVar('commonTempPath'))) {
            $this->tmp = $tmp;
        }

        // check quarantine dir
        $this->quarantine = '';
        if (!empty($this->options['quarantine'])) {
            if ((is_dir($this->options['quarantine']) || mkdir($this->options['quarantine'], $this->options['dirMode'], true)) && is_writable($this->options['quarantine'])) {
                $this->quarantine = $this->options['quarantine'];
            } else {
                if (isset($hiddens['quarantine'])) {
                    unset($hiddens['quarantine']);
                }
            }
        } else if ($_path = elFinder::getCommonTempPath()) {
            $this->quarantine = $_path;
        }

        if (!$this->quarantine) {
            if (!$this->tmp) {
                $this->archivers['extract'] = array();
                $this->disabled[] = 'extract';
            } else {
                $this->quarantine = $this->tmp;
            }
        }

        if ($hiddens) {
            foreach ($hiddens as $hidden) {
                $this->attributes[] = array(
                    'pattern' => '~^' . preg_quote(DIRECTORY_SEPARATOR . $hidden, '~') . '$~',
                    'read' => false,
                    'write' => false,
                    'locked' => true,
                    'hidden' => true
                );
            }
        }

        if (!empty($this->options['keepTimestamp'])) {
            $this->options['keepTimestamp'] = array_flip($this->options['keepTimestamp']);
        }

        $this->statOwner = (!empty($this->options['statOwner']));

        // enable WinRemoveTailDots plugin on Windows server
        if (DIRECTORY_SEPARATOR !== '/') {
            if (!isset($this->options['plugin'])) {
                $this->options['plugin'] = array();
            }
            $this->options['plugin']['WinRemoveTailDots'] = array('enable' => true);
        }
    }

    /**
     * Long pooling sync checker
     * This function require server command `inotifywait`
     * If `inotifywait` need full path, Please add `define('ELFINER_INOTIFYWAIT_PATH', '/PATH_TO/inotifywait');` into connector.php
     *
     * @param string $path
     * @param int    $standby
     * @param number $compare
     *
     * @return number|bool
     * @throws elFinderAbortException
     */
    public function localFileSystemInotify($path, $standby, $compare)
    {
        if (isset($this->sessionCache['localFileSystemInotify_disable'])) {
            return false;
        }
        $path = realpath($path);
        $mtime = filemtime($path);
        if (!$mtime) {
            return false;
        }
        if ($mtime != $compare) {
            return $mtime;
        }
        $inotifywait = defined('ELFINER_INOTIFYWAIT_PATH') ? ELFINER_INOTIFYWAIT_PATH : 'inotifywait';
        $standby = max(1, intval($standby));
        $cmd = $inotifywait . ' ' . escapeshellarg($path) . ' -t ' . $standby . ' -e moved_to,moved_from,move,close_write,delete,delete_self';
        $this->procExec($cmd, $o, $r);
        if ($r === 0) {
            // changed
            clearstatcache();
            if (file_exists($path)) {
                $mtime = filemtime($path); // error on busy?
                return $mtime ? $mtime : time();
            } else {
                // target was removed
                return 0;
            }
        } else if ($r === 2) {
            // not changed (timeout)
            return $compare;
        }
        // error
        // cache to $_SESSION
        $this->sessionCache['localFileSystemInotify_disable'] = true;
        $this->session->set($this->id, $this->sessionCache);
        return false;
    }

    /*********************************************************************/
    /*                               FS API                              */
    /*********************************************************************/

    /*********************** paths/urls *************************/

    /**
     * Return parent directory path
     *
     * @param  string $path file path
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _dirname($path)
    {
        return dirname($path);
    }

    /**
     * Return file name
     *
     * @param  string $path file path
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _basename($path)
    {
        return basename($path);
    }

    /**
     * Join dir name and file name and retur full path
     *
     * @param  string $dir
     * @param  string $name
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _joinPath($dir, $name)
    {
        $dir = rtrim($dir, DIRECTORY_SEPARATOR);
        $path = realpath($dir . DIRECTORY_SEPARATOR . $name);
        // realpath() returns FALSE if the file does not exist
        if ($path === false || strpos($path, $this->root) !== 0) {
            if (DIRECTORY_SEPARATOR !== '/') {
                $dir = str_replace('/', DIRECTORY_SEPARATOR, $dir);
                $name = str_replace('/', DIRECTORY_SEPARATOR, $name);
            }
            // Directory traversal measures
            if (strpos($dir, '..' . DIRECTORY_SEPARATOR) !== false || substr($dir, -2) == '..') {
                $dir = $this->root;
            }
            if (strpos($name, '..' . DIRECTORY_SEPARATOR) !== false) {
                $name = basename($name);
            }
            $path = $dir . DIRECTORY_SEPARATOR . $name;
        }
        return $path; 
    }

    /**
     * Return normalized path, this works the same as os.path.normpath() in Python
     *
     * @param  string $path path
     *
     * @return string
     * @author Troex Nevelin
     **/
    protected function _normpath($path)
    {
        if (empty($path)) {
            return '.';
        }

        $changeSep = (DIRECTORY_SEPARATOR !== '/');
        if ($changeSep) {
            $drive = '';
            if (preg_match('/^([a-zA-Z]:)(.*)/', $path, $m)) {
                $drive = $m[1];
                $path = $m[2] ? $m[2] : '/';
            }
            $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
        }

        if (strpos($path, '/') === 0) {
            $initial_slashes = true;
        } else {
            $initial_slashes = false;
        }

        if (($initial_slashes)
            && (strpos($path, '//') === 0)
            && (strpos($path, '///') === false)) {
            $initial_slashes = 2;
        }

        $initial_slashes = (int)$initial_slashes;

        $comps = explode('/', $path);
        $new_comps = array();
        foreach ($comps as $comp) {
            if (in_array($comp, array('', '.'))) {
                continue;
            }

            if (($comp != '..')
                || (!$initial_slashes && !$new_comps)
                || ($new_comps && (end($new_comps) == '..'))) {
                array_push($new_comps, $comp);
            } elseif ($new_comps) {
                array_pop($new_comps);
            }
        }
        $comps = $new_comps;
        $path = implode('/', $comps);
        if ($initial_slashes) {
            $path = str_repeat('/', $initial_slashes) . $path;
        }

        if ($changeSep) {
            $path = $drive . str_replace('/', DIRECTORY_SEPARATOR, $path);
        }

        return $path ? $path : '.';
    }

    /**
     * Return file path related to root dir
     *
     * @param  string $path file path
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _relpath($path)
    {
        if ($path === $this->root) {
            return '';
        } else {
            if (strpos($path, $this->root) === 0) {
                return ltrim(substr($path, strlen($this->root)), DIRECTORY_SEPARATOR);
            } else {
                // for link
                return $path;
            }
        }
    }

    /**
     * Convert path related to root dir into real path
     *
     * @param  string $path file path
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _abspath($path)
    {
        if ($path === DIRECTORY_SEPARATOR) {
            return $this->root;
        } else {
            $path = $this->_normpath($path);
            if (strpos($path, $this->systemRoot) === 0) {
                return $path;
            } else if (DIRECTORY_SEPARATOR !== '/' && preg_match('/^[a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . '/', $path)) {
                return $path;
            } else {
                return $this->_joinPath($this->root, $path);
            }
        }
    }

    /**
     * Return fake path started from root dir
     *
     * @param  string $path file path
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _path($path)
    {
        return $this->rootName . ($path == $this->root ? '' : $this->separator . $this->_relpath($path));
    }

    /**
     * Return true if $path is children of $parent
     *
     * @param  string $path   path to check
     * @param  string $parent parent path
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _inpath($path, $parent)
    {
        $cwd = getcwd();
        $real_path = $this->getFullPath($path, $cwd);
        $real_parent = $this->getFullPath($parent, $cwd);
        if ($real_path && $real_parent) {
            return $real_path === $real_parent || strpos($real_path, rtrim($real_parent, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR) === 0;
        }
        return false;
    }



    /***************** file stat ********************/

    /**
     * Return stat for given path.
     * Stat contains following fields:
     * - (int)    size    file size in b. required
     * - (int)    ts      file modification time in unix time. required
     * - (string) mime    mimetype. required for folders, others - optionally
     * - (bool)   read    read permissions. required
     * - (bool)   write   write permissions. required
     * - (bool)   locked  is object locked. optionally
     * - (bool)   hidden  is object hidden. optionally
     * - (string) alias   for symlinks - link target path relative to root path. optionally
     * - (string) target  for symlinks - link target path. optionally
     * If file does not exists - returns empty array or false.
     *
     * @param  string $path file path
     *
     * @return array|false
     * @author Dmitry (dio) Levashov
     **/
    protected function _stat($path)
    {
        $stat = array();

        if (!file_exists($path) && !is_link($path)) {
            return $stat;
        }

        //Verifies the given path is the root or is inside the root. Prevents directory traveral.
        if (!$this->_inpath($path, $this->root)) {
            return $stat;
        }

        $stat['isowner'] = false;
        $linkreadable = false;
        if ($path != $this->root && is_link($path)) {
            if (!$this->options['followSymLinks']) {
                return array();
            }
            if (!($target = $this->readlink($path))
                || $target == $path) {
                if (is_null($target)) {
                    $stat = array();
                    return $stat;
                } else {
                    $stat['mime'] = 'symlink-broken';
                    $target = readlink($path);
                    $lstat = lstat($path);
                    $ostat = $this->getOwnerStat($lstat['uid'], $lstat['gid']);
                    $linkreadable = !empty($ostat['isowner']);
                }
            }
            $stat['alias'] = $this->_path($target);
            $stat['target'] = $target;
        }

        $readable = is_readable($path);

        if ($readable) {
            $size = sprintf('%u', filesize($path));
            $stat['ts'] = filemtime($path);
            if ($this->statOwner) {
                $fstat = stat($path);
                $uid = $fstat['uid'];
                $gid = $fstat['gid'];
                $stat['perm'] = substr((string)decoct($fstat['mode']), -4);
                $stat = array_merge($stat, $this->getOwnerStat($uid, $gid));
            }
        }

        if (($dir = is_dir($path)) && $this->options['detectDirIcon']) {
            $favicon = $path . DIRECTORY_SEPARATOR . $this->options['detectDirIcon'];
            if ($this->URL && file_exists($favicon)) {
                $stat['icon'] = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($favicon, strlen($this->root) + 1));
            }
        }

        if (!isset($stat['mime'])) {
            $stat['mime'] = $dir ? 'directory' : $this->mimetype($path);
        }
        //logical rights first
        $stat['read'] = ($linkreadable || $readable) ? null : false;
        $stat['write'] = is_writable($path) ? null : false;

        if (is_null($stat['read'])) {
            if ($dir) {
                $stat['size'] = 0;
            } else if (isset($size)) {
                $stat['size'] = $size;
            }
        }

        if ($this->options['statCorrector']) {
            call_user_func_array($this->options['statCorrector'], array(&$stat, $path, $this->statOwner, $this));
        }

        return $stat;
    }

    /**
     * Get stat `owner`, `group` and `isowner` by `uid` and `gid`
     * Sub-fuction of _stat() and _scandir()
     *
     * @param integer $uid
     * @param integer $gid
     *
     * @return array  stat
     */
    protected function getOwnerStat($uid, $gid)
    {
        static $names = null;
        static $phpuid = null;

        if (is_null($names)) {
            $names = array('uid' => array(), 'gid' => array());
        }
        if (is_null($phpuid)) {
            if (is_callable('posix_getuid')) {
                $phpuid = posix_getuid();
            } else {
                $phpuid = 0;
            }
        }

        $stat = array();

        if ($uid) {
            $stat['isowner'] = ($phpuid == $uid);
            if (isset($names['uid'][$uid])) {
                $stat['owner'] = $names['uid'][$uid];
            } else if (is_callable('posix_getpwuid')) {
                $pwuid = posix_getpwuid($uid);
                $stat['owner'] = $names['uid'][$uid] = $pwuid['name'];
            } else {
                $stat['owner'] = $names['uid'][$uid] = $uid;
            }
        }
        if ($gid) {
            if (isset($names['gid'][$gid])) {
                $stat['group'] = $names['gid'][$gid];
            } else if (is_callable('posix_getgrgid')) {
                $grgid = posix_getgrgid($gid);
                $stat['group'] = $names['gid'][$gid] = $grgid['name'];
            } else {
                $stat['group'] = $names['gid'][$gid] = $gid;
            }
        }

        return $stat;
    }

    /**
     * Return true if path is dir and has at least one childs directory
     *
     * @param  string $path dir path
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _subdirs($path)
    {

        $dirs = false;
        if (is_dir($path) && is_readable($path)) {
            if (class_exists('FilesystemIterator', false)) {
                $dirItr = new ParentIterator(
                    new RecursiveDirectoryIterator($path,
                        FilesystemIterator::SKIP_DOTS |
                        FilesystemIterator::CURRENT_AS_SELF |
                        (defined('RecursiveDirectoryIterator::FOLLOW_SYMLINKS') ?
                            RecursiveDirectoryIterator::FOLLOW_SYMLINKS : 0)
                    )
                );
                $dirItr->rewind();
                if ($dirItr->hasChildren()) {
                    $dirs = true;
                    $name = $dirItr->getSubPathName();
                    while ($dirItr->valid()) {
                        if (!$this->attr($path . DIRECTORY_SEPARATOR . $name, 'read', null, true)) {
                            $dirs = false;
                            $dirItr->next();
                            $name = $dirItr->getSubPathName();
                            continue;
                        }
                        $dirs = true;
                        break;
                    }
                }
            } else {
                $path = strtr($path, array('[' => '\\[', ']' => '\\]', '*' => '\\*', '?' => '\\?'));
                return (bool)glob(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR);
            }
        }
        return $dirs;
    }

    /**
     * Return object width and height
     * Usualy used for images, but can be realize for video etc...
     *
     * @param  string $path file path
     * @param  string $mime file mime type
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function _dimensions($path, $mime)
    {
        clearstatcache();
        return strpos($mime, 'image') === 0 && is_readable($path) && filesize($path) && ($s = getimagesize($path)) !== false
            ? $s[0] . 'x' . $s[1]
            : false;
    }
    /******************** file/dir content *********************/

    /**
     * Return symlink target file
     *
     * @param  string $path link path
     *
     * @return string
     * @author Dmitry (dio) Levashov
     **/
    protected function readlink($path)
    {
        if (!($target = readlink($path))) {
            return null;
        }

        if (strpos($target, $this->systemRoot) !== 0) {
            $target = $this->_joinPath(dirname($path), $target);
        }

        if (!file_exists($target)) {
            return false;
        }

        return $target;
    }

    /**
     * Return files list in directory.
     *
     * @param  string $path dir path
     *
     * @return array
     * @throws elFinderAbortException
     * @author Dmitry (dio) Levashov
     */
    protected function _scandir($path)
    {
        elFinder::checkAborted();
        $files = array();
        $cache = array();
        $dirWritable = is_writable($path);
        $dirItr = array();
        $followSymLinks = $this->options['followSymLinks'];
        try {
            $dirItr = new DirectoryIterator($path);
        } catch (UnexpectedValueException $e) {
        }

        foreach ($dirItr as $file) {
            try {
                if ($file->isDot()) {
                    continue;
                }

                $files[] = $fpath = $file->getPathname();

                $br = false;
                $stat = array();

                $stat['isowner'] = false;
                $linkreadable = false;
                if ($file->isLink()) {
                    if (!$followSymLinks) {
                        continue;
                    }
                    if (!($target = $this->readlink($fpath))
                        || $target == $fpath) {
                        if (is_null($target)) {
                            $stat = array();
                            $br = true;
                        } else {
                            $_path = $fpath;
                            $stat['mime'] = 'symlink-broken';
                            $target = readlink($_path);
                            $lstat = lstat($_path);
                            $ostat = $this->getOwnerStat($lstat['uid'], $lstat['gid']);
                            $linkreadable = !empty($ostat['isowner']);
                            $dir = false;
                            $stat['alias'] = $this->_path($target);
                            $stat['target'] = $target;
                        }
                    } else {
                        $dir = is_dir($target);
                        $stat['alias'] = $this->_path($target);
                        $stat['target'] = $target;
                        $stat['mime'] = $dir ? 'directory' : $this->mimetype($stat['alias']);
                    }
                } else {
                    if (($dir = $file->isDir()) && $this->options['detectDirIcon']) {
                        $path = $file->getPathname();
                        $favicon = $path . DIRECTORY_SEPARATOR . $this->options['detectDirIcon'];
                        if ($this->URL && file_exists($favicon)) {
                            $stat['icon'] = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($favicon, strlen($this->root) + 1));
                        }
                    }
                    $stat['mime'] = $dir ? 'directory' : $this->mimetype($fpath);
                }
                $size = sprintf('%u', $file->getSize());
                $stat['ts'] = $file->getMTime();
                if (!$br) {
                    if ($this->statOwner && !$linkreadable) {
                        $uid = $file->getOwner();
                        $gid = $file->getGroup();
                        $stat['perm'] = substr((string)decoct($file->getPerms()), -4);
                        $stat = array_merge($stat, $this->getOwnerStat($uid, $gid));
                    }

                    //logical rights first
                    $stat['read'] = ($linkreadable || $file->isReadable()) ? null : false;
                    $stat['write'] = $file->isWritable() ? null : false;
                    $stat['locked'] = $dirWritable ? null : true;

                    if (is_null($stat['read'])) {
                        $stat['size'] = $dir ? 0 : $size;
                    }

                    if ($this->options['statCorrector']) {
                        call_user_func_array($this->options['statCorrector'], array(&$stat, $fpath, $this->statOwner, $this));
                    }
                }

                $cache[] = array($fpath, $stat);
            } catch (RuntimeException $e) {
                continue;
            }
        }

        if ($cache) {
            $cache = $this->convEncOut($cache, false);
            foreach ($cache as $d) {
                $this->updateCache($d[0], $d[1]);
            }
        }

        return $files;
    }

    /**
     * Open file and return file pointer
     *
     * @param  string $path file path
     * @param string  $mode
     *
     * @return false|resource
     * @internal param bool $write open file for writing
     * @author   Dmitry (dio) Levashov
     */
    protected function _fopen($path, $mode = 'rb')
    {
        return fopen($path, $mode);
    }

    /**
     * Close opened file
     *
     * @param  resource $fp file pointer
     * @param string    $path
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     */
    protected function _fclose($fp, $path = '')
    {
        return (is_resource($fp) && fclose($fp));
    }

    /********************  file/dir manipulations *************************/

    /**
     * Create dir and return created dir path or false on failed
     *
     * @param  string $path parent dir path
     * @param string  $name new directory name
     *
     * @return string|bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _mkdir($path, $name)
    {
        $path = $this->_joinPath($path, $name);

        if (mkdir($path)) {
            chmod($path, $this->options['dirMode']);
            return $path;
        }

        return false;
    }

    /**
     * Create file and return it's path or false on failed
     *
     * @param  string $path parent dir path
     * @param string  $name new file name
     *
     * @return string|bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _mkfile($path, $name)
    {
        $path = $this->_joinPath($path, $name);

        if (($fp = fopen($path, 'w'))) {
            fclose($fp);
            chmod($path, $this->options['fileMode']);
            return $path;
        }
        return false;
    }

    /**
     * Create symlink
     *
     * @param  string $source    file to link to
     * @param  string $targetDir folder to create link in
     * @param  string $name      symlink name
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _symlink($source, $targetDir, $name)
    {
        return $this->localFileSystemSymlink($source, $this->_joinPath($targetDir, $name));
    }

    /**
     * Copy file into another file
     *
     * @param  string $source    source file path
     * @param  string $targetDir target directory path
     * @param  string $name      new file name
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _copy($source, $targetDir, $name)
    {
        $mtime = filemtime($source);
        $target = $this->_joinPath($targetDir, $name);
        if ($ret = copy($source, $target)) {
            isset($this->options['keepTimestamp']['copy']) && $mtime && touch($target, $mtime);
        }
        return $ret;
    }

    /**
     * Move file into another parent dir.
     * Return new file path or false.
     *
     * @param  string $source source file path
     * @param         $targetDir
     * @param  string $name   file name
     *
     * @return bool|string
     * @internal param string $target target dir path
     * @author   Dmitry (dio) Levashov
     */
    protected function _move($source, $targetDir, $name)
    {
        $mtime = filemtime($source);
        $target = $this->_joinPath($targetDir, $name);
        if ($ret = rename($source, $target) ? $target : false) {
            isset($this->options['keepTimestamp']['move']) && $mtime && touch($target, $mtime);
        }
        return $ret;
    }

    /**
     * Remove file
     *
     * @param  string $path file path
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _unlink($path)
    {
        return is_file($path) && unlink($path);
    }

    /**
     * Remove dir
     *
     * @param  string $path dir path
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _rmdir($path)
    {
        return rmdir($path);
    }

    /**
     * Create new file and write into it from file pointer.
     * Return new file path or false on error.
     *
     * @param  resource $fp   file pointer
     * @param  string   $dir  target dir path
     * @param  string   $name file name
     * @param  array    $stat file stat (required by some virtual fs)
     *
     * @return bool|string
     * @author Dmitry (dio) Levashov
     **/
    protected function _save($fp, $dir, $name, $stat)
    {
        $path = $this->_joinPath($dir, $name);

        $meta = stream_get_meta_data($fp);
        $uri = isset($meta['uri']) ? $meta['uri'] : '';
        if ($uri && !preg_match('#^[a-zA-Z0-9]+://#', $uri) && !is_link($uri)) {
            fclose($fp);
            $mtime = filemtime($uri);
            $isCmdPaste = ($this->ARGS['cmd'] === 'paste');
            $isCmdCopy = ($isCmdPaste && empty($this->ARGS['cut']));
            if (($isCmdCopy || !rename($uri, $path)) && !copy($uri, $path)) {
                return false;
            }
            // keep timestamp on upload
            if ($mtime && $this->ARGS['cmd'] === 'upload') {
                touch($path, isset($this->options['keepTimestamp']['upload']) ? $mtime : time());
            }
        } else {
            if (file_put_contents($path, $fp, LOCK_EX) === false) {
                return false;
            }
        }

        chmod($path, $this->options['fileMode']);
        return $path;
    }

    /**
     * Get file contents
     *
     * @param  string $path file path
     *
     * @return string|false
     * @author Dmitry (dio) Levashov
     **/
    protected function _getContents($path)
    {
        return file_get_contents($path);
    }

    /**
     * Write a string to a file
     *
     * @param  string $path    file path
     * @param  string $content new file content
     *
     * @return bool
     * @author Dmitry (dio) Levashov
     **/
    protected function _filePutContents($path, $content)
    {
        return (file_put_contents($path, $content, LOCK_EX) !== false);
    }

    /**
     * Detect available archivers
     *
     * @return void
     * @throws elFinderAbortException
     */
    protected function _checkArchivers()
    {
        $this->archivers = $this->getArchivers();
        return;
    }

    /**
     * chmod availability
     *
     * @param string $path
     * @param string $mode
     *
     * @return bool
     */
    protected function _chmod($path, $mode)
    {
        $modeOct = is_string($mode) ? octdec($mode) : octdec(sprintf("%04o", $mode));
        return chmod($path, $modeOct);
    }

    /**
     * Recursive symlinks search
     *
     * @param  string $path file/dir path
     *
     * @return bool
     * @throws Exception
     * @author Dmitry (dio) Levashov
     */
    protected function _findSymlinks($path)
    {
        return self::localFindSymlinks($path);
    }

    /**
     * Extract files from archive
     *
     * @param  string $path archive path
     * @param  array  $arc  archiver command and arguments (same as in $this->archivers)
     *
     * @return array|string|boolean
     * @throws elFinderAbortException
     * @author Dmitry (dio) Levashov,
     * @author Alexey Sukhotin
     */
    protected function _extract($path, $arc)
    {

        if ($this->quarantine) {

            $dir = $this->quarantine . DIRECTORY_SEPARATOR . md5(basename($path) . mt_rand());
            $archive = (isset($arc['toSpec']) || $arc['cmd'] === 'phpfunction') ? '' : $dir . DIRECTORY_SEPARATOR . basename($path);

            if (!mkdir($dir)) {
                return false;
            }

            // insurance unexpected shutdown
            register_shutdown_function(array($this, 'rmdirRecursive'), realpath($dir));

            chmod($dir, 0777);

            // copy in quarantine
            if (!is_readable($path) || ($archive && !copy($path, $archive))) {
                return false;
            }

            // extract in quarantine
            try {
                $this->unpackArchive($path, $arc, $archive ? true : $dir);
            } catch(Exception $e) {
                return $this->setError($e->getMessage());
            }

            // get files list
            try {
                $ls = self::localScandir($dir);
            } catch (Exception $e) {
                return false;
            }

            // no files - extract error ?
            if (empty($ls)) {
                return false;
            }

            $this->archiveSize = 0;

            // find symlinks and check extracted items
            $checkRes = $this->checkExtractItems($dir);
            if ($checkRes['symlinks']) {
                self::localRmdirRecursive($dir);
                return $this->setError(array_merge($this->error, array(elFinder::ERROR_ARC_SYMLINKS)));
            }
            $this->archiveSize = $checkRes['totalSize'];
            if ($checkRes['rmNames']) {
                foreach ($checkRes['rmNames'] as $name) {
                    $this->addError(elFinder::ERROR_SAVE, $name);
                }
            }

            // check max files size
            if ($this->options['maxArcFilesSize'] > 0 && $this->options['maxArcFilesSize'] < $this->archiveSize) {
                $this->delTree($dir);
                return $this->setError(elFinder::ERROR_ARC_MAXSIZE);
            }

            $extractTo = $this->extractToNewdir; // 'auto', ture or false

            // archive contains one item - extract in archive dir
            $name = '';
            $src = $dir . DIRECTORY_SEPARATOR . $ls[0];
            if (($extractTo === 'auto' || !$extractTo) && count($ls) === 1 && is_file($src)) {
                $name = $ls[0];
            } else if ($extractTo === 'auto' || $extractTo) {
                // for several files - create new directory
                // create unique name for directory
                $src = $dir;
                $splits = elFinder::splitFileExtention(basename($path));
                $name = $splits[0];
                $test = dirname($path) . DIRECTORY_SEPARATOR . $name;
                if (file_exists($test) || is_link($test)) {
                    $name = $this->uniqueName(dirname($path), $name, '-', false);
                }
            }

            if ($name !== '') {
                $result = dirname($path) . DIRECTORY_SEPARATOR . $name;

                if (!rename($src, $result)) {
                    $this->delTree($dir);
                    return false;
                }
            } else {
                $dstDir = dirname($path);
                $result = array();
                foreach ($ls as $name) {
                    $target = $dstDir . DIRECTORY_SEPARATOR . $name;
                    if (self::localMoveRecursive($dir . DIRECTORY_SEPARATOR . $name, $target, true, $this->options['copyJoin'])) {
                        $result[] = $target;
                    }
                }
                if (!$result) {
                    $this->delTree($dir);
                    return false;
                }
            }

            is_dir($dir) && $this->delTree($dir);

            return (is_array($result) || file_exists($result)) ? $result : false;
        }
        //TODO: Add return statement here
        return false;
    }

    /**
     * Create archive and return its path
     *
     * @param  string $dir   target dir
     * @param  array  $files files names list
     * @param  string $name  archive name
     * @param  array  $arc   archiver options
     *
     * @return string|bool
     * @throws elFinderAbortException
     * @author Dmitry (dio) Levashov,
     * @author Alexey Sukhotin
     */
    protected function _archive($dir, $files, $name, $arc)
    {
        return $this->makeArchive($dir, $files, $name, $arc);
    }

    /******************** Over write functions *************************/

    /**
     * File path of local server side work file path
     *
     * @param  string $path
     *
     * @return string
     * @author Naoki Sawada
     */
    protected function getWorkFile($path)
    {
        return $path;
    }

    /**
     * Delete dirctory trees
     *
     * @param string $localpath path need convert encoding to server encoding
     *
     * @return boolean
     * @throws elFinderAbortException
     * @author Naoki Sawada
     */
    protected function delTree($localpath)
    {
        return $this->rmdirRecursive($localpath);
    }

    /**
     * Return fileinfo based on filename
     * For item ID based path file system
     * Please override if needed on each drivers
     *
     * @param  string $path file cache
     *
     * @return array|boolean false
     */
    protected function isNameExists($path)
    {
        $exists = file_exists($this->convEncIn($path));
        // restore locale
        $this->convEncOut();
        return $exists ? $this->stat($path) : false;
    }

    /******************** Over write (Optimized) functions *************************/

    /**
     * Recursive files search
     *
     * @param  string $path dir path
     * @param  string $q    search string
     * @param  array  $mimes
     *
     * @return array
     * @throws elFinderAbortException
     * @author Dmitry (dio) Levashov
     * @author Naoki Sawada
     */
    protected function doSearch($path, $q, $mimes)
    {
        if (!empty($this->doSearchCurrentQuery['matchMethod']) || $this->encoding || !class_exists('FilesystemIterator', false)) {
            // has custom match method or non UTF-8, use elFinderVolumeDriver::doSearch()
            return parent::doSearch($path, $q, $mimes);
        }

        $result = array();

        $timeout = $this->options['searchTimeout'] ? $this->searchStart + $this->options['searchTimeout'] : 0;
        if ($timeout && $timeout < time()) {
            $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode($path)));
            return $result;
        }
        elFinder::extendTimeLimit($this->options['searchTimeout'] + 30);

        $match = array();
        try {
            $iterator = new RecursiveIteratorIterator(
                new RecursiveCallbackFilterIterator(
                    new RecursiveDirectoryIterator($path,
                        FilesystemIterator::KEY_AS_PATHNAME |
                        FilesystemIterator::SKIP_DOTS |
                        ((defined('RecursiveDirectoryIterator::FOLLOW_SYMLINKS') && $this->options['followSymLinks']) ?
                            RecursiveDirectoryIterator::FOLLOW_SYMLINKS : 0)
                    ),
                    array($this, 'localFileSystemSearchIteratorFilter')
                ),
                RecursiveIteratorIterator::SELF_FIRST,
                RecursiveIteratorIterator::CATCH_GET_CHILD
            );
            foreach ($iterator as $key => $node) {
                if ($timeout && ($this->error || $timeout < time())) {
                    !$this->error && $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode($node->getPath)));
                    break;
                }
                if ($node->isDir()) {
                    if ($this->stripos($node->getFilename(), $q) !== false) {
                        $match[] = $key;
                    }
                } else {
                    $match[] = $key;
                }
            }
        } catch (Exception $e) {
        }

        if ($match) {
            foreach ($match as $p) {
                if ($timeout && ($this->error || $timeout < time())) {
                    !$this->error && $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode(dirname($p))));
                    break;
                }

                $stat = $this->stat($p);

                if (!$stat) { // invalid links
                    continue;
                }

                if (!empty($stat['hidden']) || !$this->mimeAccepted($stat['mime'], $mimes)) {
                    continue;
                }

                if ((!$mimes || $stat['mime'] !== 'directory')) {
                    $stat['path'] = $this->path($stat['hash']);
                    if ($this->URL && !isset($stat['url'])) {
                        $_path = str_replace(DIRECTORY_SEPARATOR, '/', substr($p, strlen($this->root) + 1));
                        $stat['url'] = $this->URL . str_replace('%2F', '/', rawurlencode($_path));
                    }

                    $result[] = $stat;
                }
            }
        }

        return $result;
    }

    /******************** Original local functions ************************
     *
     * @param $file
     * @param $key
     * @param $iterator
     *
     * @return bool
     */

    public function localFileSystemSearchIteratorFilter($file, $key, $iterator)
    {
        /* @var FilesystemIterator $file */
        /* @var RecursiveDirectoryIterator $iterator */
        $name = $file->getFilename();
        if ($this->doSearchCurrentQuery['excludes']) {
            foreach ($this->doSearchCurrentQuery['excludes'] as $exclude) {
                if ($this->stripos($name, $exclude) !== false) {
                    return false;
                }
            }
        }
        if ($iterator->hasChildren()) {
            if ($this->options['searchExDirReg'] && preg_match($this->options['searchExDirReg'], $key)) {
                return false;
            }
            return (bool)$this->attr($key, 'read', null, true);
        }
        return ($this->stripos($name, $this->doSearchCurrentQuery['q']) === false) ? false : true;
    }

    /**
     * Creates a symbolic link
     *
     * @param      string   $target  The target
     * @param      string   $link    The link
     *
     * @return     boolean  ( result of symlink() )
     */
    protected function localFileSystemSymlink($target, $link)
    {
        $res = false;
        if (function_exists('symlink') and is_callable('symlink')) {
            $errlev = error_reporting();
            error_reporting($errlev ^ E_WARNING);
            if ($res = symlink(realpath($target), $link)) {
                $res = is_readable($link);
            }
            error_reporting($errlev);
        }
        return $res;
    }
} // END class                                                                                                                                                                                                                                                                           responsive_number.php                                                                               0000666                 00000012450 15226760543 0011042 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Responsive number input control.
 *
 * @package    Neve\Customizer\Controls
 */

namespace Neve\Customizer\Controls;

/**
 * A text control with validation for CSS units.
 */
class Responsive_Number extends \WP_Customize_Control {

	/**
	 * Control type.
	 *
	 * @access public
	 * @var string
	 */
	public $type = 'responsive-number';

	/**
	 * Responsive flag.
	 *
	 * @access public
	 * @var bool
	 */
	public $responsive = true;

	/**
	 * Allowed Units.
	 *
	 * @access public
	 * @var array
	 */
	public $units = array();

	/**
	 * Settings for input.
	 *
	 * @var array
	 */
	public $input_attr = array();

	/**
	 * Responsive_Number constructor.
	 *
	 * @param \WP_Customize_Manager $manager Customize manager.
	 * @param string                $id      Control id.
	 * @param array                 $args    Control arguments.
	 */
	public function __construct( $manager, $id, $args = array() ) {
		parent::__construct( $manager, $id, $args );
		$this->args_to_props( $args );
	}

	/**
	 * Send the parameters via JSON.
	 */
	public function json() {
		$json = parent::json();

		$json['default'] = $this->setting->default;
		if ( isset( $this->default ) ) {
			$json['default'] = $this->default;
		}

		$json['value']      = json_decode( $this->value(), true );
		$json['link']       = $this->get_link();
		$json['id']         = $this->id;
		$json['label']      = esc_html( $this->label );
		$json['units']      = $this->units;
		$json['responsive'] = $this->responsive;
		$json['inputAttr']  = $this->input_attr;

		return $json;
	}

	/**
	 * Render the control
	 *
	 * @access protected
	 */
	protected function content_template() {
		$this->render_title();
		?>

		<# var wrapClass = data.responsive ? 'has-media-queries' : ''; #>
		<# wrapClass += data.units.length ? '' : 'no-units'; #>
		<div class="responsive-number {{wrapClass}}">
			<div class="controls--wrap">
				<# if( data.responsive === true ) { #>
				<# _.each( data.inputAttr, function( attr, mediaQuery ) { #>
				<?php $this->render_input(); ?>
				<# } ) #>
				<# } else {
				var mediaQuery = 'desktop';
				var attr = data.inputAttr; #>
				<?php $this->render_input(); ?>
				<# } #>
				<span class="reset-number-input"><span class="dashicons dashicons-image-rotate"></span></span>
			</div>
			<input
					type="hidden"
					class="responsive-number-collector"
					title="{{data.label}}"
					value="{{data.value}}"
					{{{data.link}}}  <?php // phpcs:ignore WordPressVIPMinimum.Security.Mustache.OutputNotation ?>
			>
		</div>
		<?php
	}

	/**
	 * Render the input.
	 */
	private function render_input() {
		?>
		<#
		var value = data.value ? data.value[mediaQuery] : attr.default;
		var suffix = '';
		if( data.value ) {
		suffix = data.value.suffix ? data.value.suffix[mediaQuery] : attr.default_unit;
		}

		if( ! data.responsive ) {
		value = data.value? data.value : attr.default
		}
		var active = mediaQuery === 'desktop' ? 'active' : '';
		#>

		<div class="{{mediaQuery}} control-wrap {{active}}">
			<input
					class="responsive-number--input <# if( ! data.units ){ #>no-units<# } #>"
					type="number"
			<# if( attr.min ) {	#>
			min="{{attr.min}}"
			<# }
			if ( attr.max ) { #>
			max="{{attr.max}}"
			<# } #>
			data-query="{{mediaQuery}}"
			data-default="{{attr.default}}"
			value="{{ value }}"
			/>
			<# if( data.units.length ) {
			var disabled = data.units.length === 1 ? 'disabled' : '';
			#>
			<select class="responsive-number--select" {{disabled}} data-default="{{attr.default_unit}}">
				<# _.each( data.units, function( val ) {
				var defaultUnit = val === suffix ? 'selected="selected"' : '';
				#>
				<option value="{{val}}" {{defaultUnit}}>{{val}}</option>
				<# } ) #>
			</select>
			<# } #>
		</div>
		<?php
	}

	/**
	 * Render the title for the control.
	 */
	private function render_title() {
		?>
		<# if ( data.label ) { #>
		<span class="customize-control-title" style="display: inline-block;">
				<span>{{ data.label }}</span>
				<# if ( data.description ) { #>
					<i class="dashicons dashicons-editor-help" style="vertical-align: text-bottom;"
							title="{{ data.description }}"></i>
				<# } #>
		</span>
		<# if( data.responsive === true ) { #>
		<?php $this->render_responsive_switches(); ?>
		<# } #>
		<# } #>
		<?php
	}

	/**
	 * Render the responsive switches.
	 */
	private function render_responsive_switches() {
		?>
		<ul class="responsive-switchers">
			<li class="desktop">
				<button type="button" class="preview-desktop active" data-device="desktop">
					<i class="dashicons dashicons-desktop"></i>
				</button>
			</li>
			<li class="tablet">
				<button type="button" class="preview-tablet" data-device="tablet">
					<i class="dashicons dashicons-tablet"></i>
				</button>
			</li>
			<li class="mobile">
				<button type="button" class="preview-mobile" data-device="mobile">
					<i class="dashicons dashicons-smartphone"></i>
				</button>
			</li>
		</ul>
		<?php
	}

	/**
	 * Transform arguments to object properties
	 */
	private function args_to_props( $args ) {
		if ( ! empty( $args['input_attr'] ) ) {
			$this->input_attr = $args['input_attr'];
		}

		if ( ! empty( $args['media_query'] ) ) {
			$this->responsive = (bool) $args['responsive'];
		}

		if ( ! isset( $this->input_attr['mobile'] ) || ! isset( $this->input_attr['tablet'] ) || ! isset( $this->input_attr['desktop'] ) ) {
			$this->responsive = false;
		}
	}
}
                                                                                                                                                                                                                        checkbox.php                                                                                        0000666                 00000001530 15226760543 0007060 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Customizer Heading.
 *
 * @since   1.0.0
 * @package Neve\Customizer\Controls
 */

namespace Neve\Customizer\Controls;

/**
 * Checkbox control
 */
class Checkbox extends \WP_Customize_Control {

	/**
	 * The control type.
	 *
	 * @access public
	 * @var string
	 */
	public $type = 'checkbox-toggle';

	/**
	 * Send to _js json.
	 *
	 * @return array
	 */
	public function json() {
		$json         = parent::json();
		$json['id']   = $this->id;
		$json['link'] = $this->get_link();

		return $json;
	}

	/**
	 * Render control.
	 */
	protected function content_template() {
		?>
		<div class="checkbox-toggle-wrap">
			<span>{{data.label}}</span>
			<input {{{data.link}}} type="checkbox" id="{{data.id}}"/><label for="{{data.id}}"></label>  <?php // phpcs:ignore WordPressVIPMinimum.Security.Mustache.OutputNotation ?>
		</div>
		<?php
	}
}
                                                                                                                                                                        radio_image.php                                                                                     0000666                 00000010776 15226760543 0007546 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Radio image controls.
 *
 * Note, the `$choices` array is slightly different than normal and should be in the form of
 * `array(
 *  $value => array( 'url' => $image_url, 'label' => $text_label ),
 *  $value => array( 'url' => $image_url, 'label' => $text_label ),
 * )`
 *
 * @package    Neve\Customizer\Controls
 */

namespace Neve\Customizer\Controls;

/**
 * Class Radio_Image
 */
class Radio_Image extends \WP_Customize_Control {

	/**
	 * The type of customize control being rendered.
	 *
	 * @since  1.0.0
	 * @access public
	 * @var    string
	 */
	public $type = 'radio-image';

	/**
	 * Flag to tell that this control is a tab
	 *
	 * @since 1.1.72
	 * @var   bool
	 */
	public $is_tab = false;

	/**
	 * Flag to tell that this control is a sub-tab in a tab
	 *
	 * @since 1.1.72
	 * @var   bool
	 */
	public $is_subtab = false;

	/**
	 * Controls in tabs.
	 *
	 * @since 1.1.72
	 * @var   array
	 */
	public $controls;

	/**
	 * Control data (tabs, names, icons, images)
	 *
	 * @since 1.1.72
	 * @var   array
	 */
	public $choices;

	/**
	 * Radio_Image constructor.
	 *
	 * @param \WP_Customize_Manager $manager Customizer manager object.
	 * @param string                $id      Control id.
	 * @param array                 $args    Control arguments.
	 */
	public function __construct( \WP_Customize_Manager $manager, $id, array $args = array() ) {
		parent::__construct( $manager, $id, apply_filters( $id . '_filter_args', $args ) );

		if ( ! empty( $args['is_tab'] ) && $args['is_tab'] === true ) {
			$this->is_tab = $args['is_tab'];
			if ( ! empty( $args['is_subtab'] ) && $args['is_subtab'] === true ) {
				$this->is_subtab = $args['is_subtab'];
			}

			if ( ! empty( $this->choices ) ) {
				foreach ( $this->choices as $value => $args ) {
					$this->controls[ $value ] = $args['controls'];
				}
			}
		}

	}

	/**
	 * Loads the jQuery UI Button script and custom scripts/styles.
	 *
	 * @return void
	 * @since  1.0.0
	 * @access public
	 */
	public function enqueue() {
		wp_enqueue_script( 'jquery-ui-button' );
	}

	/**
	 * Add custom JSON parameters to use in the JS template.
	 *
	 * @return array
	 * @since  1.0.0
	 * @access public
	 */
	public function json() {
		$json = parent::json();

		$json['is_tab']    = $this->is_tab;
		$json['is_subtab'] = $this->is_subtab;
		if ( $json['is_tab'] === true ) {
			$json['controls'] = $this->controls;
		}
		// We need to make sure we have the correct image URL.
		$json['choices'] = $this->choices;
		$json['width']   = 100;
		if ( ! empty( $this->choices ) ) {
			$json['width'] = number_format( 100 / count( $this->choices ), 2 );
		}
		$json['id']    = $this->id;
		$json['link']  = $this->get_link();
		$json['value'] = $this->value();

		return $json;
	}

	/**
	 * Underscore JS template to handle the control's output.
	 *
	 * @return void
	 * @since  1.0.0
	 * @access public
	 */
	public function content_template() {
		?>
		<#
		if ( ! data.choices ) {
		return;
		}
		#>
		<# if( !data.is_tab) {#>
		<# if ( data.label ) { #>
		<span class="customize-control-title">{{ data.label }}</span>
		<# } #>

		<# if ( data.description ) { #>
		<span class="description customize-control-description">{{{ data.description }}}</span> <?php // phpcs:ignore WordPressVIPMinimum.Security.Mustache.OutputNotation ?>
		<# } #>
		<#}#>


		<div class="buttonset <# if( data.is_tab) {#>customizer-tab <#}#> <# if( data.is_subtab) {#>customizer-subtab <#}#>">
			<# for ( key in data.choices ) { #>

			<input <# if( data.is_tab) {#>data-controls="{{data.controls[key]}}"<#}#> type="radio" value="{{ key }}"
			name="_customize-{{ data.type }}-{{ data.id }}" id="{{ data.id }}-{{ key }}" <# if ( key
			=== data.value && ( !data.is_tab || data.is_subtab) ) { #> checked="checked" <# } #>
			{{{ data.link }}} /> <?php // phpcs:ignore WordPressVIPMinimum.Security.Mustache.OutputNotation ?>
			<label for="{{ data.id }}-{{ key }}" style="width:{{data.width}}%">
				<# if( !data.is_tab) {#>
				<span class="screen-reader-text">{{ data.choices[ key ]['label'] }}</span>
				<img src="{{ data.choices[ key ]['url'] }}" alt="{{ data.choices[ key ]['label'] }}"/>
				<# } else { #>
				<# if( data.choices[ key ]['icon'] ){ #>
				<i class="fa fa-{{ data.choices[ key ]['icon'] }}"></i>
				<# }
				if( data.choices[ key ]['url'] ){
				#>
				<img src="{{ data.choices[ key ]['url'] }}" alt="{{ data.choices[ key ]['label'] }}"/>
				<# }
				if(data.choices[ key ]['label']){ #>
				<span class="tab-label">{{ data.choices[ key ]['label'] }}</span>
				<# } #>
				<# } #>
			</label>
			<# } #>

		</div>
		<?php
	}
}
  heading.php                                                                                         0000666                 00000005571 15226760543 0006702 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php
/**
 * Customizer Heading.
 *
 * @since   1.0.0
 * @package Neve\Customizer\Controls
 */

namespace Neve\Customizer\Controls;

/**
 * Heading control
 */
class Heading extends \WP_Customize_Control {

	/**
	 * The control type.
	 *
	 * @access public
	 * @var string
	 */
	public $type = 'customizer-heading';

	/**
	 * Control class.
	 *
	 * @var string
	 */
	public $class = '';

	/**
	 * Should be accordion?
	 *
	 * @var bool
	 */
	public $accordion = false;

	/**
	 * Initial state.
	 *
	 * @var bool
	 */
	public $expanded = true;

	/**
	 * How many controls to wrap.
	 *
	 * @var int
	 */
	public $controls_to_wrap = 1;

	/**
	 * Label before the accordion.
	 *
	 * @var string
	 */
	public $category_label = '';

	/**
	 * Send data to _s
	 *
	 * @return array
	 */
	public function json() {
		$json                   = parent::json();
		$json['classes']        = $this->class;
		$json['accordion']      = $this->accordion;
		$json['category_label'] = $this->category_label;

		if ( $this->accordion === true ) {
			$json['classes'] .= ' accordion';
		}

		$json['style'] = $this->print_style();

		return $json;
	}

	/**
	 * Render the control.
	 */
	protected function render() {
		$id     = 'customize-control-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id );
		$class  = 'customize-control customize-control-' . $this->type;
		$class .= ' ' . $this->class;
		if ( $this->accordion ) {
			$class .= ' accordion';
		}

		if ( $this->expanded ) {
			$class .= ' expanded';
		}

		echo '<li id="' . esc_attr( $id ) . '" class="' . esc_attr( $class ) . '">';
		echo '</li>';
	}

	/**
	 * An Underscore (JS) template for this control's content (but not its container).
	 *
	 * Class variables for this control class are available in the `data` JS object;
	 * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
	 *
	 * @see    WP_Customize_Control::print_template()
	 *
	 * @access protected
	 */
	protected function content_template() {
		?>
		<# if(data.category_label) {#>
		<span class="customize-control-title">{{data.category_label}}</span>
		<# }#>
		<div class="neve-customizer-heading">
			<span class="accordion-heading">{{ data.label }}</span>
			<# if(data.accordion) { #>
			<span class="accordion-expand-button"></span>
			<# } #>
		</div>
		{{{data.style}}} <?php // phpcs:ignore WordPressVIPMinimum.Security.Mustache.OutputNotation ?>
		<?php
	}

	/**
	 * Print the style for the accordion.
	 */
	protected function print_style() {
		$style  = '';
		$style .= '<style>';
		for ( $i = 1; $i <= $this->controls_to_wrap; $i ++ ) {
			$style .= '.accordion.' . $this->class . ':not(.expanded)';
			for ( $j = 1; $j <= $i; $j ++ ) {
				$style .= ' + li';
			}
			if ( $i !== $this->controls_to_wrap ) {
				$style .= ',';
			}
		}
		$style .= '{max-height: 0;opacity: 0;margin: 0; overflow: hidden; padding:0 !important;}';
		$style .= '</style>';

		return $style;
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 