PluginProbe
WP Directory Kit / 1.5.4
WP Directory Kit v1.5.4
1.5.9 1.5.7 1.5.6 1.5.5 1.5.4 1.5.3 trunk 1.1.0 1.1.6 1.1.8 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.8 All 37 releases
wpdirectorykit / elementor-elements / classes / wdk-listings-carousel.php

wdk-listings-carousel.php in WP Directory Kit 1.5.4, at elementor-elements/classes/wdk-listings-carousel.php

1,421 lines 57.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Wdk\Elementor\Widgets;
4
5 use Wdk\Elementor\Widgets\WdkElementorBase;
6 use Elementor\Widget_Base;
7 use Elementor\Controls_Manager;
8 use Elementor\Utils;
9 use Elementor\Typography;
10 use Elementor\Editor;
11 use Elementor\Plugin;
12 use Elementor\Repeater;
13 use Elementor\Core\Schemes;
14 use Elementor\Icons_Manager;
15 use Elementor\Group_Control_Typography;
16 use Elementor\Group_Control_Border;
17 use Elementor\Group_Control_Box_Shadow;
18 use Elementor\Group_Control_Image_Size;
19
20 if (!defined('ABSPATH'))
21 exit; // Exit if accessed directly
22
23 /**
24 * @since 1.1.0
25 */
26 class WdkListingsCarousel extends WdkElementorBase {
27
28 public function __construct($data = array(), $args = null) {
29
30 \Elementor\Controls_Manager::add_tab(
31 'tab_conf',
32 esc_html__('Settings', 'wpdirectorykit')
33 );
34
35 \Elementor\Controls_Manager::add_tab(
36 'tab_layout',
37 esc_html__('Layout', 'wpdirectorykit')
38 );
39
40 \Elementor\Controls_Manager::add_tab(
41 'tab_content',
42 esc_html__('Main', 'wpdirectorykit')
43 );
44
45 if ($this->is_edit_mode_load()) {
46 $this->enqueue_styles_scripts();
47 }
48
49 parent::__construct($data, $args);
50 }
51
52 /**
53 * Retrieve the widget name.
54 *
55 * @since 1.1.0
56 *
57 * @access public
58 *
59 * @return string Widget name.
60 */
61 public function get_name() {
62 return 'wdk-listings-carousel';
63 }
64
65 /**
66 * Retrieve the widget title.
67 *
68 * @since 1.1.0
69 *
70 * @access public
71 *
72 * @return string Widget title.
73 */
74 public function get_title() {
75 return esc_html__('Wdk Listings Carousel', 'wpdirectorykit');
76 }
77
78 /**
79 * Retrieve the widget icon.
80 *
81 * @since 1.1.0
82 *
83 * @access public
84 *
85 * @return string Widget icon.
86 */
87 public function get_icon() {
88 return 'eicon-post-navigation';
89 }
90
91 /**
92 * Register the widget controls.
93 *
94 * Adds different input fields to allow the user to change and customize the widget settings.
95 *
96 * @since 1.1.0
97 *
98 * @access protected
99 */
100 protected function register_controls() {
101 $this->generate_controls_conf();
102 $this->generate_controls_layout();
103 $this->generate_controls_styles();
104 $this->generate_controls_content();
105
106 $this->insert_pro_message('tab_conf');
107 parent::register_controls();
108 }
109
110 /**
111 * Render the widget output on the frontend.
112 *
113 * Written in PHP and used to generate the final HTML.
114 *
115 * @since 1.1.0
116 *
117 * @access protected
118 */
119 protected function render() {
120 parent::render();
121 $this->data['id_element'] = $this->get_id();
122 $this->data['settings'] = $this->get_settings();
123
124 $this->data['listings_count'] = 0;
125 $this->data['results'] = array();
126 $this->data['pagination_output'] = '';
127 $columns = array('ID', 'location_id', 'category_id', 'post_title', 'post_date', 'search', 'order_by', 'is_featured', 'address');
128 $custom_parameters = array();
129 $skip_postget = TRUE;
130
131 if($this->data['settings']['conf_results_type'] == 'results_listings') {
132 $controller = 'listing';
133 $offset = NULL;
134
135 if(!isset($custom_parameters['order_by'])) {
136 $custom_parameters['order_by'] = $this->data['settings']['conf_order_by'].' '.$this->data['settings']['conf_order'];
137 }
138
139 if(!isset($custom_parameters['conf_order_by_custom'])) {
140 $custom_parameters['order_by'] = $this->data['settings']['conf_order_by_custom'].' '.$this->data['settings']['conf_order'];
141 }
142
143 if(!empty($this->data['settings']['conf_query'])) {
144 $qr_string = trim($this->data['settings']['conf_query'],'?');
145 $string_par = array();
146 parse_str($qr_string, $string_par);
147 $custom_parameters += array_map('trim', $string_par);
148 }
149
150 if($this->data['settings']['only_is_featured'] == 'yes') {
151 $custom_parameters['is_featured'] = 'on';
152 }
153
154
155 if(wmvc_show_data('get_filters_enable', $this->data['settings']) == 'yes') {
156 $skip_postget = FALSE;
157 }
158
159 $external_columns = array('location_id', 'category_id', 'post_title', 'is_featured');
160
161 wdk_prepare_search_query_GET($columns, $controller.'_m', $external_columns, $custom_parameters, $skip_postget);
162 $this->data['results'] = $this->WMVC->listing_m->get_pagination($this->data['settings']['conf_limit'], $offset, array('is_activated' => 1,'is_approved'=>1));
163
164 } else if($this->data['settings']['conf_results_type'] == 'custom_listings') {
165 $listings_ids = array();
166 foreach($this->data['settings']['conf_custom_results'] as $listing) {
167 if(isset($listing['listing_post_id']) && !empty($listing['listing_post_id'])) {
168 $listings_ids [] = $listing['listing_post_id'];
169 }
170 }
171 /* where in */
172 if(!empty($listings_ids)){
173 $this->WMVC->db->where( $this->WMVC->db->prefix.'wdk_listings.post_id IN(' . implode(',', $listings_ids) . ')', null, false);
174 $this->WMVC->db->where(array('is_activated' => 1));
175 $this->WMVC->db->order_by('FIELD('.$this->WMVC->db->prefix.'wdk_listings.post_id, '. implode(',', $listings_ids) . ')');
176 $this->data['results'] = $this->WMVC->listing_m->get();
177 }
178 }
179
180 if(!empty($this->data['results']) && $this->data['listings_count'] == 0)
181 $this->data['listings_count'] = wmvc_count($this->data['results']);
182
183 $this->data['settings']['content_button_icon'] = $this->generate_icon($this->data['settings']['content_button_icon']);
184 $this->data['is_edit_mode'] = false;
185 if(Plugin::$instance->editor->is_edit_mode())
186 $this->data['is_edit_mode'] = true;
187
188 echo $this->view('wdk-listings-carousel', $this->data);
189
190 }
191
192
193 private function generate_controls_conf() {
194 $this->start_controls_section(
195 'tab_conf_main_section',
196 [
197 'label' => esc_html__('Main', 'wpdirectorykit'),
198 'tab' => 'tab_conf',
199 ]
200 );
201
202 $this->add_control(
203 'conf_results_type',
204 [
205 'label' => __( 'Carousel type', 'wpdirectorykit' ),
206 'type' => \Elementor\Controls_Manager::SELECT,
207 'default' => 'results_listings',
208 'options' => [
209 'results_listings' => __( 'Results Listings', 'wpdirectorykit' ),
210 'custom_listings' => __( 'Specific Listings', 'wpdirectorykit' ),
211 ],
212 'separator' => 'after',
213 ]
214 );
215
216 $this->add_control(
217 'important_note',
218 [
219 'label' => '',
220 'type' => \Elementor\Controls_Manager::RAW_HTML,
221 'raw' => wdk_sprintf(__( 'Edit Result Card Designer <a href="%1$s" target="_blank"> open </a>', 'wpdirectorykit' ), admin_url('admin.php?page=wdk_resultitem')),
222 'content_classes' => 'wdk_elementor_hint',
223 'separator' => 'after',
224 ]
225 );
226
227 $this->add_control(
228 'important_note2',
229 [
230 'label' => '',
231 'type' => \Elementor\Controls_Manager::RAW_HTML,
232 'raw' => wdk_sprintf(__( 'Manage Listings <a href="%1$s" target="_blank"> open </a>', 'wpdirectorykit' ), admin_url('admin.php?page=wdk')),
233 'content_classes' => 'wdk_elementor_hint',
234 'separator' => 'after',
235 ]
236 );
237
238 /* conf_results_type :: results_listings */
239 if(true){
240 $this->add_control(
241 'conf_results_type_results_listings_header',
242 [
243 'label' => esc_html__('Results listings', 'wpdirectorykit'),
244 'type' => Controls_Manager::HEADING,
245 'separator' => 'before',
246 'conditions' => [
247 'terms' => [
248 [
249 'name' => 'conf_results_type',
250 'operator' => '==',
251 'value' => 'results_listings',
252 ]
253 ],
254 ],
255 ]
256 );
257
258
259 $this->add_control(
260 'get_filters_enable',
261 [
262 'label' => __( 'Filtering based on URL enable', 'wpdirectorykit' ),
263 'type' => \Elementor\Controls_Manager::SWITCHER,
264 'label_on' => __( 'True', 'wpdirectorykit' ),
265 'label_off' => __( 'False', 'wpdirectorykit' ),
266 'return_value' => 'yes',
267 'default' => '',
268 'conditions' => [
269 'terms' => [
270 [
271 'name' => 'conf_results_type',
272 'operator' => '==',
273 'value' => 'results_listings',
274 ]
275 ],
276 ],
277 ]
278 );
279
280 $this->add_control(
281 'conf_limit',
282 [
283 'label' => __( 'Limit Results', 'wpdirectorykit' ),
284 'type' => \Elementor\Controls_Manager::NUMBER,
285 'min' => 1,
286 'max' => 250,
287 'step' => 1,
288 'default' => 6,
289 'conditions' => [
290 'terms' => [
291 [
292 'name' => 'conf_results_type',
293 'operator' => '==',
294 'value' => 'results_listings',
295 ]
296 ],
297 ],
298 ]
299 );
300
301 $this->add_control(
302 'only_is_featured',
303 [
304 'label' => __( 'Only show featured', 'wpdirectorykit' ),
305 'type' => \Elementor\Controls_Manager::SWITCHER,
306 'label_on' => __( 'True', 'wpdirectorykit' ),
307 'label_off' => __( 'False', 'wpdirectorykit' ),
308 'return_value' => 'yes',
309 'default' => '',
310 ]
311 );
312
313 $this->add_control(
314 'conf_query',
315 [
316 'label' => __( 'Query', 'wpdirectorykit' ),
317 'type' => \Elementor\Controls_Manager::TEXTAREA,
318 'rows' => 5,
319 'default' => '',
320 'placeholder' => __( 'Type your query here, example xxx', 'wpdirectorykit' ),
321 'description' => '<span style="word-break: break-all;">'.__( 'Example (same like on url):', 'wpdirectorykit' ).
322 ' field_6_min=100&field_6_max=200&field_5=rent&is_featured=on&search_category=3&search_location=4&search_agents_ids=3'.
323 '</span>',
324 'conditions' => [
325 'terms' => [
326 [
327 'name' => 'conf_results_type',
328 'operator' => '==',
329 'value' => 'results_listings',
330 ]
331 ],
332 ],
333 ]
334 );
335
336 $this->add_control(
337 'conf_order_by',
338 [
339 'label' => __('Default Sort By Column', 'wpdirectorykit'),
340 'type' => Controls_Manager::SELECT,
341 'label_block' => true,
342 'options' => [
343 'none' => __('None', 'wpdirectorykit'),
344 'post_id' => __('ID', 'wpdirectorykit'),
345 'post_title' => __('Title', 'wpdirectorykit'),
346 ],
347 'default' => 'post_id',
348 'conditions' => [
349 'terms' => [
350 [
351 'name' => 'conf_results_type',
352 'operator' => '==',
353 'value' => 'results_listings',
354 ]
355 ],
356 ],
357 ]
358 );
359
360 $this->add_control(
361 'conf_order_by_custom',
362 [
363 'label' => __('Default Custom Sort By (Column)', 'wpdirectorykit'),
364 'description' => '<span style="word-break: break-all;">'.__( 'Example:', 'wpdirectorykit' ).
365 '<br> field_13_NUMBER - where 13 is field id, NUMBER - field type'.
366 '<br> field_4_NUMBER - where 4 is field id, NUMBER - field type'.
367 '<br> field_6_DROPDOWN - where 6 is field id, DROPDOWN - field type'.
368 '<br> category_title - Category Title'.
369 '<br> location_title - Location Title'.
370 '</span>',
371 'type' => Controls_Manager::TEXT,
372 'label_block' => true,
373 'default' => 'post_id',
374 'conditions' => [
375 'terms' => [
376 [
377 'name' => 'conf_results_type',
378 'operator' => '==',
379 'value' => 'results_listings',
380 ]
381 ],
382 ],
383 ]
384 );
385
386 $this->add_control(
387 'conf_order',
388 [
389 'label' => __('Default Post Order', 'wpdirectorykit'),
390 'type' => Controls_Manager::SELECT,
391 'label_block' => true,
392 'options' => [
393 'asc' => __('Ascending', 'wpdirectorykit'),
394 'desc' => __('Descending', 'wpdirectorykit')
395 ],
396 'default' => 'desc',
397 'conditions' => [
398 'terms' => [
399 [
400 'name' => 'conf_results_type',
401 'operator' => '==',
402 'value' => 'results_listings',
403 ]
404 ],
405 ],
406 ]
407 );
408
409
410 }
411
412 if(true) {
413 $this->add_control(
414 'conf_results_type_custom_listings_header',
415 [
416 'label' => esc_html__('Custom listings', 'wpdirectorykit'),
417 'type' => Controls_Manager::HEADING,
418 'separator' => 'before',
419 'conditions' => [
420 'terms' => [
421 [
422 'name' => 'conf_results_type',
423 'operator' => '==',
424 'value' => 'custom_listings',
425 ]
426 ],
427 ],
428 ]
429 );
430
431
432 if(true){
433 $repeater = new Repeater();
434 $repeater->start_controls_tabs( 'listings' );
435 $repeater->add_control(
436 'listing_post_id',
437 [
438 'label' => __( 'ID Post Listing', 'wpdirectorykit' ),
439 'type' => \Elementor\Controls_Manager::NUMBER,
440 'min' => 1,
441 'step' => 1,
442 ]
443 );
444 $repeater->end_controls_tabs();
445
446
447 $this->add_control(
448 'conf_custom_results',
449 [
450 'type' => Controls_Manager::REPEATER,
451 'fields' => $repeater->get_controls(),
452 'default' => [
453 ],
454 'title_field' => '{{{ listing_post_id }}}',
455 'conditions' => [
456 'terms' => [
457 [
458 'name' => 'conf_results_type',
459 'operator' => '==',
460 'value' => 'custom_listings',
461 ]
462 ],
463 ],
464 ]
465 );
466
467 }
468 }
469
470 $this->end_controls_section();
471
472 }
473
474 private function generate_controls_layout() {
475 $this->start_controls_section(
476 'tab_content',
477 [
478 'label' => esc_html__('Basic', 'wpdirectorykit'),
479 'tab' => 'tab_layout',
480 ]
481 );
482
483 /* Carousel Grid Config */
484 if(true) {
485 $this->add_responsive_control(
486 'carousel_column_gap_carousel',
487 [
488 'label' => esc_html__('Slider Gap', 'wpdirectorykit'),
489 'type' => Controls_Manager::SLIDER,
490 'range' => [
491 'px' => [
492 'min' => 0,
493 'max' => 60,
494 ],
495 ],
496 'selectors' => [
497 '{{WRAPPER}} .slick-slider.wdk_results_listings_slider_ini ' => 'padding-left: {{SIZE}}{{UNIT}};padding-right: {{SIZE}}{{UNIT}};',
498 ],
499 ]
500 );
501
502 $this->add_responsive_control (
503 'carousel_column_gap',
504 [
505 'label' => esc_html__('Columns Gap', 'wpdirectorykit'),
506 'type' => Controls_Manager::SLIDER,
507 'default' => [
508 'size' => 10,
509 ],
510 'range' => [
511 'px' => [
512 'min' => 0,
513 'max' => 60,
514 ],
515 ],
516 'selectors' => [
517 '{{WRAPPER}} .slick-slider.wdk_results_listings_slider_ini .wdk-col' => 'padding-left: {{SIZE}}{{UNIT}};padding-right: {{SIZE}}{{UNIT}};',
518 '{{WRAPPER}} .slick-slider.wdk_results_listings_slider_ini' => 'margin-left: -{{SIZE}}{{UNIT}};margin-right: -{{SIZE}}{{UNIT}};',
519 ],
520 ]
521 );
522
523 $this->add_responsive_control(
524 'carousel_column_gap_top',
525 [
526 'label' => esc_html__('Columns Gap Top', 'wpdirectorykit'),
527 'type' => Controls_Manager::SLIDER,
528 'default' => [
529 'size' => 0,
530 ],
531 'range' => [
532 'px' => [
533 'min' => 0,
534 'max' => 60,
535 ],
536 ],
537 'selectors' => [
538 '{{WRAPPER}} .wdk_results_listings_slider_box' => 'padding-top: {{SIZE}}{{UNIT}};',
539 ],
540 ]
541 );
542
543 $this->add_responsive_control(
544 'carousel_column_gap_bottom',
545 [
546 'label' => esc_html__('Columns Gap Bottom', 'wpdirectorykit'),
547 'type' => Controls_Manager::SLIDER,
548 'default' => [
549 'size' => 10,
550 ],
551 'range' => [
552 'px' => [
553 'min' => 0,
554 'max' => 60,
555 ],
556 ],
557 'selectors' => [
558 '{{WRAPPER}} .wdk_results_listings_slider_box' => 'padding-bottom: {{SIZE}}{{UNIT}};',
559 ],
560 ]
561 );
562 }
563
564
565 $this->add_control(
566 'basic_el_header_1',
567 [
568 'label' => esc_html__('Text', 'wpdirectorykit'),
569 'type' => Controls_Manager::HEADING,
570 'separator' => 'before',
571 ]
572 );
573
574 $this->add_control(
575 'content_button_text',
576 [
577 'label' => __( 'Button Open Text', 'wpdirectorykit' ),
578 'type' => \Elementor\Controls_Manager::TEXT,
579 'default' => '',
580 ]
581 );
582
583 $this->end_controls_section();
584
585 $this->start_controls_section(
586 'layout_carousel_sec',
587 [
588 'label' => esc_html__('Carousel Options', 'wpdirectorykit'),
589 'tab' => 'tab_layout',
590 ]
591 );
592
593 $this->add_control(
594 'layout_carousel_is_infinite',
595 [
596 'label' => __( 'Infinite', 'wpdirectorykit' ),
597 'type' => \Elementor\Controls_Manager::SWITCHER,
598 'label_on' => __( 'On', 'wpdirectorykit' ),
599 'label_off' => __( 'Off', 'wpdirectorykit' ),
600 'return_value' => 'true',
601 'default' => 'true',
602 ]
603 );
604
605 $this->add_control(
606 'layout_carousel_is_autoplay',
607 [
608 'label' => __( 'Autoplay', 'wpdirectorykit' ),
609 'type' => \Elementor\Controls_Manager::SWITCHER,
610 'label_on' => __( 'On', 'wpdirectorykit' ),
611 'label_off' => __( 'Off', 'wpdirectorykit' ),
612 'return_value' => 'true',
613 'default' => '',
614 ]
615 );
616
617 $this->add_control(
618 'layout_carousel_speed',
619 [
620 'label' => __( 'Speed', 'wpdirectorykit' ),
621 'type' => \Elementor\Controls_Manager::NUMBER,
622 'min' => 0,
623 'max' => 100000,
624 'step' => 100,
625 'default' => 500,
626 ]
627 );
628
629 $this->add_control(
630 'layout_carousel_animation_style',
631 [
632 'label' => __( 'Animation Style', 'wpdirectorykit' ),
633 'type' => \Elementor\Controls_Manager::SELECT,
634 'default' => 'fade',
635 'options' => [
636 'slide' => __( 'Slide', 'wpdirectorykit' ),
637 'fade' => __( 'Fade', 'wpdirectorykit' ),
638 'fade_in_in' => __( 'Fade in', 'wpdirectorykit' ),
639 ],
640 ]
641 );
642
643 $this->add_control(
644 'layout_carousel_cssease',
645 [
646 'label' => __( 'cssEase', 'wpdirectorykit' ),
647 'type' => \Elementor\Controls_Manager::SELECT,
648 'default' => 'linear',
649 'options' => [
650 'linear' => __( 'linear', 'wpdirectorykit' ),
651 'ease' => __( 'ease', 'wpdirectorykit' ),
652 'ease-in' => __( 'ease-in', 'wpdirectorykit' ),
653 'ease-out' => __( 'ease-out', 'wpdirectorykit' ),
654 'ease-in-out' => __( 'ease-in-out', 'wpdirectorykit' ),
655 'step-start' => __( 'step-start', 'wpdirectorykit' ),
656 'step-end' => __( 'step-end', 'wpdirectorykit' ),
657 ],
658 ]
659 );
660
661 $this->add_responsive_control(
662 'layout_carousel_columns',
663 [
664 'label' => __( 'Count grid', 'wpdirectorykit' ),
665 'type' => \Elementor\Controls_Manager::NUMBER,
666 'min' => 1,
667 'max' => 10,
668 'step' => 1,
669 'default' => 3,
670 ]
671 );
672
673 $this->end_controls_section();
674
675 }
676
677 private function generate_controls_styles() {
678 $this->start_controls_section(
679 'sstyles_thmbn_section',
680 [
681 'label' => esc_html__('Section Image', 'wpdirectorykit'),
682 'tab' => Controls_Manager::TAB_STYLE,
683 ]
684 );
685
686 $this->add_group_control(
687 Group_Control_Image_Size::get_type(),
688 [
689 'name' => 'thumbnail_image', // Usage: `{name}_size` and `{name}_custom_dimension`, in this case `thumbnail_size` and `thumbnail_custom_dimension`.
690 'default' => 'full',
691 'separator' => 'none',
692 ]
693 );
694
695 $this->add_responsive_control(
696 'styles_thmbn_des_type',
697 [
698 'label' => __( 'Design type', 'wpdirectorykit' ),
699 'type' => \Elementor\Controls_Manager::SELECT,
700 'default' => 'wdk_size_image_cover',
701 'options' => [
702 'wdk_size_image_ori' => __( 'Default Sizes', 'wpdirectorykit' ),
703 'wdk_size_image_cover' => __( 'Image auto crop/resize', 'wpdirectorykit' ),
704 ],
705 ]
706 );
707
708 $this->add_responsive_control(
709 'styles_thmbn_des_height',
710 [
711 'label' => esc_html__('Height', 'wpdirectorykit'),
712 'type' => Controls_Manager::SLIDER,
713 'range' => [
714 'px' => [
715 'min' => 300,
716 'max' => 1500,
717 ],
718 'vw' => [
719 'min' => 0,
720 'max' => 100,
721 ],
722 ],
723 'size_units' => [ 'px','em', 'vw', '%', 'custom' ],
724 'default' => [
725 'size' => 350,
726 'unit' => 'px',
727 ],
728 'selectors' => [
729 '{{WRAPPER}} .wdk-listings-results.wdk_size_image_cover .wdk-listing-card .wdk-thumbnail .wdk-image' => 'height: {{SIZE}}{{UNIT}}',
730 ],
731 'separator' => 'after',
732 'conditions' => [
733 'relation' => 'or',
734 'terms' => [
735 [
736 'name' => 'styles_thmbn_des_type',
737 'operator' => '==',
738 'value' => 'wdk_size_image_cover',
739 ],
740 [
741 'name' => 'styles_thmbn_des_type',
742 'operator' => '==',
743 'value' => 'wdk_image_cover',
744 ]
745 ],
746 ]
747 ]
748 );
749 $this->end_controls_section();
750
751 $this->start_controls_section(
752 'styles_carousel_arrows_section',
753 [
754 'label' => esc_html__('Carousel Arrows', 'wpdirectorykit'),
755 'tab' => Controls_Manager::TAB_STYLE,
756 ]
757 );
758
759 $this->add_responsive_control(
760 'styles_carousel_arrows_hide',
761 [
762 'label' => esc_html__( 'Hide Element', 'wpdirectorykit' ),
763 'type' => Controls_Manager::SWITCHER,
764 'none' => esc_html__( 'Hide', 'wpdirectorykit' ),
765 'block' => esc_html__( 'Show', 'wpdirectorykit' ),
766 'return_value' => 'none',
767 'default' => '',
768 'selectors' => [
769 '{{WRAPPER}} .wdk_results_listings_slider_box .wdk_slider_arrows' => 'display: {{VALUE}};',
770 ],
771 ]
772 );
773
774 $this->add_responsive_control(
775 'styles_carousel_arrows_position',
776 [
777 'label' => __( 'Position', 'wpdirectorykit' ),
778 'type' => \Elementor\Controls_Manager::SELECT,
779 'default' => 'wdk_slider_arrows_bottom',
780 'options' => [
781 'wdk_slider_arrows_bottom' => __( 'Bottom', 'wpdirectorykit' ),
782 'wdk_slider_arrows_middle' => __( 'Center', 'wpdirectorykit' ),
783 'wdk_slider_arrows_top' => __( 'Top', 'wpdirectorykit' ),
784 ],
785 ]
786 );
787
788 $this->add_responsive_control(
789 'styles_carousel_arrows_align',
790 [
791 'label' => __( 'Align', 'wpdirectorykit' ),
792 'type' => Controls_Manager::CHOOSE,
793 'options' => [
794 'left' => [
795 'title' => esc_html__( 'Left', 'wpdirectorykit' ),
796 'icon' => 'eicon-text-align-left',
797 ],
798 'center' => [
799 'title' => esc_html__( 'Center', 'wpdirectorykit' ),
800 'icon' => 'eicon-text-align-center',
801 ],
802 'right' => [
803 'title' => esc_html__( 'Right', 'wpdirectorykit' ),
804 'icon' => 'eicon-text-align-right',
805 ],
806 'justify' => [
807 'title' => esc_html__( 'Justified', 'wpdirectorykit' ),
808 'icon' => 'eicon-text-align-justify',
809 ],
810 ],
811 'render_type' => 'ui',
812 'selectors_dictionary' => [
813 'left' => 'justify-content: flex-start;',
814 'center' => 'justify-content: center;',
815 'right' => 'justify-content: flex-end;',
816 'justify' => 'justify-content: space-between;',
817 ],
818 'selectors' => [
819 '{{WRAPPER}} .wdk_results_listings_slider_box .wdk_slider_arrows' => '{{VALUE}};',
820 ],
821 'conditions' => [
822 'relation' => 'or',
823 'terms' => [
824 [
825 'name' => 'styles_thmbn_des_type',
826 'operator' => '==',
827 'value' => 'wdk_size_image_cover',
828 ],
829 [
830 'name' => 'styles_thmbn_des_type',
831 'operator' => '==',
832 'value' => 'wdk_image_cover',
833 ]
834 ],
835 ],
836 ]
837 );
838
839 $this->add_responsive_control(
840 'styles_carousel_arrows_icon_left_h',
841 [
842 'label' => esc_html__('Arrow left', 'wpdirectorykit'),
843 'type' => Controls_Manager::HEADING,
844 'separator' => 'before',
845 ]
846 );
847 $this->add_responsive_control(
848 'styles_carousel_arrows_s_m_left_margin',
849 [
850 'label' => esc_html__( 'Margin', 'wpdirectorykit' ),
851 'type' => Controls_Manager::DIMENSIONS,
852 'size_units' => [ 'px', 'em', '%' ],
853 'allowed_dimensions' => 'horizontal',
854 'selectors' => [
855 '{{WRAPPER}} .wdk_results_listings_slider_box .wdk_slider_arrows .wdk_lr_slider_arrow.wdk-slider-prev' => 'margin-right:{{RIGHT}}{{UNIT}}; margin-left:{{LEFT}}{{UNIT}};',
856 ],
857 ]
858 );
859
860 $this->add_responsive_control(
861 'styles_carousel_arrows_icon_left',
862 [
863 'label' => esc_html__('Icon', 'wpdirectorykit'),
864 'type' => Controls_Manager::ICONS,
865 'label_block' => true,
866 'default' => [
867 'value' => 'fa fa-angle-left',
868 'library' => 'solid',
869 ],
870 ]
871 );
872
873 $this->add_responsive_control(
874 'styles_carousel_arrows_icon_right_h',
875 [
876 'label' => esc_html__('Arrow right', 'wpdirectorykit'),
877 'type' => Controls_Manager::HEADING,
878 'separator' => 'before',
879 ]
880 );
881
882 $this->add_responsive_control(
883 'styles_carousel_arrows_s_m_right_margin',
884 [
885 'label' => esc_html__( 'Margin', 'wpdirectorykit' ),
886 'type' => Controls_Manager::DIMENSIONS,
887 'size_units' => [ 'px', 'em', '%' ],
888 'allowed_dimensions' => 'horizontal',
889 'selectors' => [
890 '{{WRAPPER}} .wdk_results_listings_slider_box .wdk_slider_arrows .wdk_lr_slider_arrow.wdk-slider-next' => 'margin-right:{{RIGHT}}{{UNIT}}; margin-left:{{LEFT}}{{UNIT}};',
891 ],
892 ]
893 );
894
895 $this->add_responsive_control(
896 'styles_carousel_arrows_icon_right',
897 [
898 'label' => esc_html__('Icon', 'wpdirectorykit'),
899 'type' => Controls_Manager::ICONS,
900 'label_block' => true,
901 'default' => [
902 'value' => 'fa fa-angle-right',
903 'library' => 'solid',
904 ],
905 ]
906 );
907
908 $selectors = array(
909 'normal' => '{{WRAPPER}} .wdk_results_listings_slider_box .wdk_slider_arrows .wdk_lr_slider_arrow',
910 'hover'=>'{{WRAPPER}} .wdk_results_listings_slider_box .wdk_slider_arrows .wdk_lr_slider_arrow%1$s'
911 );
912 $this->generate_renders_tabs($selectors, 'styles_carousel_arrows_dynamic', ['margin','color','background','border','border_radius','padding','shadow','transition','font-size','hover_animation']);
913
914 $this->end_controls_section();
915
916 $this->start_controls_section(
917 'styles_carousel_dots_section',
918 [
919 'label' => esc_html__('Section Dots', 'wpdirectorykit'),
920 'tab' => Controls_Manager::TAB_STYLE,
921 ]
922 );
923
924 $this->add_responsive_control(
925 'styles_carousel_dots_hide',
926 [
927 'label' => esc_html__( 'Hide Element', 'wpdirectorykit' ),
928 'type' => Controls_Manager::SWITCHER,
929 'none' => esc_html__( 'Hide', 'wpdirectorykit' ),
930 'block' => esc_html__( 'Show', 'wpdirectorykit' ),
931 'return_value' => 'none',
932 'default' => '',
933 'selectors' => [
934 '{{WRAPPER}} .wdk_results_listings_slider_box .slick-dots' => 'display: {{VALUE}} !important;',
935 ],
936 ]
937 );
938
939 $this->add_responsive_control(
940 'styles_carousel_dots_position_style',
941 [
942 'label' => __( 'Position Style', 'wpdirectorykit' ),
943 'type' => \Elementor\Controls_Manager::SELECT,
944 'default' => 'wdk_slider_dots_out',
945 'options' => [
946 'wdk_slider_dots_out' => __( 'Out', 'wpdirectorykit' ),
947 'wdk_slider_dots_in' => __( 'In', 'wpdirectorykit' ),
948 ],
949 ]
950 );
951
952 $this->add_responsive_control(
953 'styles_carousel_dots_align',
954 [
955 'label' => __( 'Position', 'wpdirectorykit' ),
956 'type' => Controls_Manager::CHOOSE,
957 'options' => [
958 'left' => [
959 'title' => esc_html__( 'Left', 'wpdirectorykit' ),
960 'icon' => 'eicon-text-align-left',
961 ],
962 'center' => [
963 'title' => esc_html__( 'Center', 'wpdirectorykit' ),
964 'icon' => 'eicon-text-align-center',
965 ],
966 'right' => [
967 'title' => esc_html__( 'Right', 'wpdirectorykit' ),
968 'icon' => 'eicon-text-align-right',
969 ],
970 'justify' => [
971 'title' => esc_html__( 'Justified', 'wpdirectorykit' ),
972 'icon' => 'eicon-text-align-justify',
973 ],
974 ],
975 'render_type' => 'ui',
976 'selectors_dictionary' => [
977 'left' => 'justify-content: flex-start;',
978 'center' => 'justify-content: center;',
979 'right' => 'justify-content: flex-end;',
980 'justify' => 'justify-content: space-between;',
981 ],
982 'selectors' => [
983 '{{WRAPPER}} .wdk_results_listings_slider_box .slick-dots' => '{{VALUE}};',
984 ],
985 ]
986 );
987
988 $this->add_responsive_control(
989 'styles_carousel_dots_icon',
990 [
991 'label' => esc_html__('Icon', 'wpdirectorykit'),
992 'type' => Controls_Manager::ICONS,
993 'label_block' => true,
994 'default' => [
995 'value' => 'fas fa-circle',
996 'library' => 'solid',
997 ],
998 ]
999 );
1000
1001 $selectors = array(
1002 'normal' => '{{WRAPPER}} .wdk_results_listings_slider_box .slick-dots li .wdk_lr_dot',
1003 'hover'=>'{{WRAPPER}} .wdk_results_listings_slider_box .slick-dots li .wdk_lr_dot%1$s',
1004 'active'=>'{{WRAPPER}} .wdk_results_listings_slider_box .slick-dots li.slick-active .wdk_lr_dot'
1005 );
1006
1007 $this->generate_renders_tabs($selectors, 'styles_carousel_dots_dynamic', ['margin','color','background','border','border_radius','padding','shadow','transition','font-size','hover_animation']);
1008 $this->end_controls_section();
1009 }
1010
1011 private function generate_controls_content() {
1012 $this->start_controls_section(
1013 'content_thumbnail_section',
1014 [
1015 'label' => esc_html__('Colors', 'wpdirectorykit'),
1016 'tab' => '1',
1017 ]
1018 );
1019
1020 $this->add_control(
1021 'content_thumbnail_section_header',
1022 [
1023 'label' => esc_html__('Color Hover Thumbnail', 'wpdirectorykit'),
1024 'type' => Controls_Manager::HEADING,
1025 ]
1026 );
1027
1028 $this->add_responsive_control(
1029 'content_thumbnail_section_d_background',
1030 [
1031 'label' => esc_html__( 'Color', 'wpdirectorykit' ),
1032 'description' => esc_html__( 'Set some opacity for color', 'wpdirectorykit' ),
1033 'type' => Controls_Manager::COLOR,
1034 'selectors' => [
1035 '{{WRAPPER}} .wdk-listing-card .wdk-thumbnail::before, {{WRAPPER}} .wdk-listing-card .wdk-thumbnail::after,{{WRAPPER}} .wdk-listing-card .overlay' => 'background-color: {{VALUE}};',
1036 ],
1037 ]
1038 );
1039
1040 $this->add_control(
1041 'content_thumbnail_section_header_f',
1042 [
1043 'label' => esc_html__('Shadow around Card, for Featured Listings', 'wpdirectorykit'),
1044 'type' => Controls_Manager::HEADING,
1045 ]
1046 );
1047
1048 $this->add_group_control(
1049 Group_Control_Box_Shadow::get_type(),
1050 [
1051 'name' => 'content_thumbnail_section_d_featured',
1052 'exclude' => [
1053 'field_shadow_position',
1054 ],
1055 'selector' => '{{WRAPPER}} .wdk-listing-card.is_featured',
1056 ]
1057 );
1058
1059 $this->end_controls_section();
1060
1061
1062 $items = [
1063 [
1064 'key'=>'content_card',
1065 'label'=> esc_html__('Card', 'wpdirectorykit'),
1066 'selector'=>'.wdk-element .wdk-listing-card',
1067 'options'=>'full',
1068 ],
1069 [
1070 'key'=>'content_label',
1071 'label'=> esc_html__('Over Image Top', 'wpdirectorykit'),
1072 'selector'=>'.wdk-element .wdk-listing-card .wdk-thumbnail .wdk-over-image-top span',
1073 'options'=>'full',
1074 ],
1075 [
1076 'key'=>'content_type',
1077 'label'=> esc_html__('Over Image Bottom', 'wpdirectorykit'),
1078 'selector'=>'.wdk-element .wdk-listing-card .wdk-thumbnail .wdk-over-image-bottom',
1079 'is_featured'=>'.wdk-element .wdk-listing-card.is_featured .wdk-thumbnail .wdk-over-image-bottom',
1080 'options'=>'full',
1081 ],
1082 [
1083 'key'=>'content_title',
1084 'label'=> esc_html__('Title Part', 'wpdirectorykit'),
1085 'selector'=>'.wdk-element .wdk-listing-card .wdk-title .title',
1086 'options'=>'full',
1087 ],
1088 [
1089 'key'=>'content_description',
1090 'label'=> esc_html__('Subtitle part', 'wpdirectorykit'),
1091 'selector'=>'.wdk-element .wdk-listing-card .wdk-subtitle-part',
1092 'options'=>'full',
1093 ],
1094 [
1095 'key'=>'content_items',
1096 'label'=> esc_html__('Features part', 'wpdirectorykit'),
1097 'selector'=>'.wdk-element .wdk-listing-card .wdk-features-part span',
1098 'options'=>'full',
1099 ],
1100 [
1101 'key'=>'wdk-divider',
1102 'label'=> esc_html__('Divider', 'wpdirectorykit'),
1103 'selector'=>'.wdk-element .wdk-listing-card .wdk-divider',
1104 'options'=>'full',
1105 ],
1106 [
1107 'key'=>'content_price',
1108 'label'=> esc_html__('Pricing part', 'wpdirectorykit'),
1109 'selector'=>'.wdk-element .wdk-listing-card .wdk-footer .wdk-price',
1110 'options'=>'full',
1111 ],
1112 [
1113 'key'=>'content_button',
1114 'label'=> esc_html__('Button Open', 'wpdirectorykit'),
1115 'selector'=>'.wdk-element .wdk-listing-card .wdk-footer .wdk-btn',
1116 'options'=>'full',
1117 ],
1118 ];
1119
1120 foreach ($items as $item) {
1121 $this->start_controls_section(
1122 $item['key'].'_section',
1123 [
1124 'label' => $item['label'],
1125 'tab' => '1',
1126 ]
1127 );
1128 $this->add_responsive_control(
1129 $item['key'].'_hide',
1130 [
1131 'label' => esc_html__( 'Hide Element', 'wpdirectorykit' ),
1132 'type' => Controls_Manager::SWITCHER,
1133 'none' => esc_html__( 'Hide', 'wpdirectorykit' ),
1134 'block' => esc_html__( 'Show', 'wpdirectorykit' ),
1135 'return_value' => 'none',
1136 'default' => '',
1137 'selectors' => [
1138 '{{WRAPPER}} '.$item['selector'] => 'display: {{VALUE}};',
1139 ],
1140 ]
1141 );
1142
1143
1144 $this->add_responsive_control(
1145 $item['key'].'_min-height',
1146 [
1147 'label' => esc_html__('Min Height', 'wpdirectorykit'),
1148 'type' => Controls_Manager::SLIDER,
1149 'range' => [
1150 'px' => [
1151 'min' => 10,
1152 'max' => 1500,
1153 ],
1154 'vw' => [
1155 'min' => 0,
1156 'max' => 100,
1157 ],
1158 '%' => [
1159 'min' => 0,
1160 'max' => 100,
1161 ],
1162 ],
1163 'size_units' => [ 'px', 'vw','%' ],
1164 'selectors' => [
1165 '{{WRAPPER}} '.$item['selector'] => 'min-height: {{SIZE}}{{UNIT}}',
1166 ],
1167
1168 ]
1169 );
1170 /* special for some elements */
1171 if ($item['key'] == 'content_description') {
1172
1173 $this->add_control(
1174 'content_description_limit',
1175 [
1176 'label' => __( 'Limit Line (per field)', 'wpdirectorykit' ),
1177 'type' => \Elementor\Controls_Manager::NUMBER,
1178 'min' => 1,
1179 'max' => 10,
1180 'step' => 1,
1181 'default' => 3,
1182 'selectors' => [
1183 '{{WRAPPER}} .wdk-listing-card .wdk-subtitle-part span' => '-webkit-line-clamp: {{VALUE}};',
1184 ],
1185 ]
1186 );
1187 }
1188 if ($item['key'] == 'content_title') {
1189
1190 $this->add_control(
1191 'content_title_limit',
1192 [
1193 'label' => __( 'Limit Line (per field)', 'wpdirectorykit' ),
1194 'type' => \Elementor\Controls_Manager::NUMBER,
1195 'min' => 1,
1196 'max' => 10,
1197 'step' => 1,
1198 'default' => 3,
1199 'selectors' => [
1200 '{{WRAPPER}} .wdk-listing-card .wdk-title span' => '-webkit-line-clamp: {{VALUE}};',
1201 ],
1202 ]
1203 );
1204 }
1205
1206 $selectors = array(
1207 'normal' => '{{WRAPPER}} '.$item['selector'],
1208 'hover'=>'{{WRAPPER}} '.$item['selector'].'%1$s'
1209 );
1210
1211 if(isset($item['is_featured'])) {
1212 $selectors['featured'] = '{{WRAPPER}} '.$item['is_featured'];
1213 }
1214 $this->generate_renders_tabs($selectors, $item['key'].'_dynamic', $item['options']);
1215
1216
1217
1218 if($item['key'] == 'content_button') {
1219 $this->add_control(
1220 $item['key'].'_icon',
1221 [
1222 'label' => esc_html__('Icon', 'wpdirectorykit'),
1223 'type' => Controls_Manager::ICONS,
1224 'label_block' => true,
1225 'default' => [
1226 'value' => 'fa fa-angle-right',
1227 'library' => 'solid',
1228 ],
1229 ]
1230 );
1231
1232 $selectors = array(
1233 'normal' => '{{WRAPPER}} '.$item['selector'].' i',
1234 );
1235 $this->generate_renders_tabs($selectors, $item['key'].'_icon_dynamic', ['margin']);
1236 }
1237
1238 if($item['key'] == 'content_items') {
1239 $this->add_control(
1240 $item['key'].'_parent_head',
1241 [
1242 'label' => esc_html__('Parent Box', 'wpdirectorykit'),
1243 'type' => Controls_Manager::HEADING,
1244 'separator' => 'before',
1245 ]
1246 );
1247
1248 $selectors = array(
1249 'normal' => '{{WRAPPER}} .wdk-element .wdk-listing-card .wdk-features-part',
1250 );
1251 $this->generate_renders_tabs($selectors, $item['key'].'_parent_dynamic', ['margin']);
1252 }
1253
1254 if($item['key'] == 'content_label') {
1255 $this->add_control(
1256 $item['key'].'_parent_head',
1257 [
1258 'label' => esc_html__('Parent Box', 'wpdirectorykit'),
1259 'type' => Controls_Manager::HEADING,
1260 'separator' => 'before',
1261 ]
1262 );
1263
1264 $selectors = array(
1265 'normal' => '{{WRAPPER}} .wdk-element .wdk-listing-card .wdk-over-image-top',
1266 );
1267 $this->generate_renders_tabs($selectors, $item['key'].'_parent_dynamic', ['margin','align']);
1268 }
1269
1270
1271 if($item['key'] == 'content_label') {
1272 $this->add_responsive_control(
1273 $item['key'] .'content_label_positions_y',
1274 [
1275 'label' => __( 'Position Y', 'wpdirectorykit' ),
1276 'type' => Controls_Manager::CHOOSE,
1277 'options' => [
1278 'top' => [
1279 'title' => esc_html__( 'Top', 'wpdirectorykit' ),
1280 'icon' => 'eicon-text-align-top',
1281 ],
1282 'center' => [
1283 'title' => esc_html__( 'Center', 'wpdirectorykit' ),
1284 'icon' => 'eicon-text-align-center',
1285 ],
1286 'bottom' => [
1287 'title' => esc_html__( 'Bottom', 'wpdirectorykit' ),
1288 'icon' => 'eicon-text-align-bottom',
1289 ],
1290 ],
1291 'default' => 'left',
1292 'render_type' => 'ui',
1293 'selectors_dictionary' => [
1294 'top' => 'top:0;bottom:initial',
1295 'center' => 'top:50%;transform: translateY(-50%)',
1296 'bottom' => 'top:initial;bottom:0',
1297 ],
1298 'selectors' => [
1299 '{{WRAPPER}} .wdk-listing-card .wdk-thumbnail .wdk-over-image-top' => '{{VALUE}};',
1300 ],
1301 ]
1302 );
1303
1304 $this->add_responsive_control(
1305 $item['key'] .'content_label_positions_x',
1306 [
1307 'label' => __( 'Position X', 'wpdirectorykit' ),
1308 'type' => Controls_Manager::CHOOSE,
1309 'options' => [
1310 'left' => [
1311 'title' => esc_html__( 'Left', 'wpdirectorykit' ),
1312 'icon' => 'eicon-text-align-left',
1313 ],
1314 'center' => [
1315 'title' => esc_html__( 'Center', 'wpdirectorykit' ),
1316 'icon' => 'eicon-text-align-center',
1317 ],
1318 'right' => [
1319 'title' => esc_html__( 'Right', 'wpdirectorykit' ),
1320 'icon' => 'eicon-text-align-right',
1321 ],
1322 ],
1323 'default' => 'left',
1324 'render_type' => 'ui',
1325 'selectors_dictionary' => [
1326 'left' => 'left:0',
1327 'center' => 'left:50%;transform: translateX(-50%)',
1328 'right' => 'left:initial; right:0',
1329 ],
1330 'selectors' => [
1331 '{{WRAPPER}} .wdk-listing-card .wdk-thumbnail .wdk-over-image-top' => '{{VALUE}};',
1332 ],
1333 ]
1334 );
1335 }
1336
1337 if($item['key'] == 'content_type') {
1338 $this->add_responsive_control(
1339 $item['key'] .'content_label_positions_y',
1340 [
1341 'label' => __( 'Position Y', 'wpdirectorykit' ),
1342 'type' => Controls_Manager::CHOOSE,
1343 'options' => [
1344 'top' => [
1345 'title' => esc_html__( 'Top', 'wpdirectorykit' ),
1346 'icon' => 'eicon-text-align-top',
1347 ],
1348 'center' => [
1349 'title' => esc_html__( 'Center', 'wpdirectorykit' ),
1350 'icon' => 'eicon-text-align-center',
1351 ],
1352 'bottom' => [
1353 'title' => esc_html__( 'Bottom', 'wpdirectorykit' ),
1354 'icon' => 'eicon-text-align-bottom',
1355 ],
1356 ],
1357 'default' => 'left',
1358 'render_type' => 'ui',
1359 'selectors_dictionary' => [
1360 'top' => 'top:0;bottom:initial',
1361 'center' => 'top:50%;transform: translateY(-50%)',
1362 'bottom' => 'top:initial;bottom:0',
1363 ],
1364 'selectors' => [
1365 '{{WRAPPER}} '.$item['selector'] => '{{VALUE}};',
1366 ],
1367 ]
1368 );
1369
1370 $this->add_responsive_control(
1371 $item['key'] .'content_label_positions_x',
1372 [
1373 'label' => __( 'Position X', 'wpdirectorykit' ),
1374 'type' => Controls_Manager::CHOOSE,
1375 'options' => [
1376 'left' => [
1377 'title' => esc_html__( 'Left', 'wpdirectorykit' ),
1378 'icon' => 'eicon-text-align-left',
1379 ],
1380 'center' => [
1381 'title' => esc_html__( 'Center', 'wpdirectorykit' ),
1382 'icon' => 'eicon-text-align-center',
1383 ],
1384 'right' => [
1385 'title' => esc_html__( 'Right', 'wpdirectorykit' ),
1386 'icon' => 'eicon-text-align-right',
1387 ],
1388 'justify' => [
1389 'title' => esc_html__( 'Justified', 'wpdirectorykit' ),
1390 'icon' => 'eicon-text-align-justify',
1391 ],
1392 ],
1393 'default' => 'left',
1394 'render_type' => 'ui',
1395 'selectors_dictionary' => [
1396 'top' => 'justify-content: flex-start;',
1397 'center' => 'justify-content: center;',
1398 'bottom' => 'justify-content: flex-end;',
1399 'justify' => 'justify-content: stretch;',
1400 ],
1401 'selectors' => [
1402 '{{WRAPPER}} '.$item['selector'] => '{{VALUE}};',
1403 ],
1404 ]
1405 );
1406 }
1407 $this->end_controls_section();
1408 }
1409 }
1410
1411 public function enqueue_styles_scripts() {
1412 wp_enqueue_style('slick');
1413 wp_enqueue_style('slick-theme');
1414 wp_enqueue_script('slick');
1415
1416 wp_enqueue_style('wdk-notify');
1417 wp_enqueue_script('wdk-notify');
1418 wp_enqueue_style('wdk-listings-carousel');
1419 }
1420 }
1421