PageSourceSearch

https://unact.ru/assets/4.2/nodes.js?v=1777283056

js unact.ru collected 2026-10-07 15:07:08 UTC 101,613 bytes, 2,870 lines download raw bytes

1(function ($) {
2creatium.init.global(function () {
3    var $section = $('.section-layout');
4
5    var $toggle = $section.find('[cr-layout-left-toggle]');
6
7    $toggle.on('click', function () {
8        if (creatium.layout.mobile) {
9            $section.find('[cr-layout-root]').toggleClass('mobile-left-active');
10        } else {
11            if (cr.layout._left_current) {
12                $('body').removeClass('layout-left-active');
13                $section.find('[cr-layout-root]').removeClass('left-active');
14                cr.layout._left_current = 0;
15            } else {
16                $('body').addClass('layout-left-active');
17                $section.find('[cr-layout-root]').addClass('left-active');
18                cr.layout._left_current = cr.layout.left;
19            }
20        }
21
22        $(window).triggerHandler('resize');
23    });
24});
25creatium.init.global(function () {
26    var user_visit = creatium.store.get('user_visit');
27
28    if (user_visit) {
29        user_visit.last = Date.now();
30        user_visit.count++;
31    } else {
32        user_visit = {
33            first: Date.now(),
34            last: Date.now(),
35            lead: null,
36            count: 1,
37        };
38    }
39
40    $(creatium).on('submit-success', function () {
41        user_visit.lead = Date.now();
42        creatium.store.set('user_visit', user_visit);
43    });
44
45    creatium.store.set('user_visit', user_visit);
46
47    $('.section-modal').each(function () {
48        var section_el = this;
49        var $section = $(section_el);
50        var $modal = $section.find('.modal');
51
52        var $document = $(document);
53
54        var once = $section.data('once');
55        var trigger = $section.data('trigger');
56        var conversionlimit = $section.data('conversionlimit');
57
58        if (once && creatium.store.get('is_triggered_' + trigger)) {
59            return;
60        }
61
62        var was_shown = false;
63        $modal.one('show', function () {
64            was_shown = true;
65            creatium.store.set('is_triggered_' + trigger, true);
66        });
67
68        var should_prevent = function () {
69            if (was_shown) return true;
70
71            if (trigger.indexOf('leadback_') === 0) {
72                if (creatium.store.get('is_converted') !== true) return true;
73            } else {
74                if (conversionlimit && creatium.store.get('is_converted')) return true;
75            }
76
77            return false;
78        };
79
80        if (trigger === 'visit') {
81            if (should_prevent()) return;
82
83            creatium.modals.show($modal);
84        } else if (trigger === 'visit_10sec') {
85            setTimeout(function () {
86                if (should_prevent()) return;
87
88                creatium.modals.show($modal);
89            }, 1000 * 10);
90        }  else if (trigger === 'visit_30sec') {
91            setTimeout(function () {
92                if (should_prevent()) return;
93
94                creatium.modals.show($modal);
95            }, 1000 * 30);
96        }  else if (trigger === 'visit_1min') {
97            setTimeout(function () {
98                if (should_prevent()) return;
99
100                creatium.modals.show($modal);
101            }, 1000 * 60);
102        } else if (trigger === 'visit_2min') {
103            setTimeout(function () {
104                if (should_prevent()) return;
105
106                creatium.modals.show($modal);
107            }, 2000 * 60);
108        } else if (trigger === 'visit_3min') {
109            setTimeout(function () {
110                if (should_prevent()) return;
111
112                creatium.modals.show($modal);
113            }, 3000 * 60);
114        } else if (trigger === 'visit_4min') {
115            setTimeout(function () {
116                if (should_prevent()) return;
117
118                creatium.modals.show($modal);
119            }, 4000 * 60);
120        } else if (trigger === 'return_30min') {
121            if (should_prevent()) return;
122
123            if (user_visit.count === 2 && user_visit.last - user_visit.first < 1000 * 60 * 30) {
124                creatium.modals.show($modal);
125            }
126        } else if (trigger === 'return_day') {
127            if (should_prevent()) return;
128
129            if (user_visit.count === 2 && user_visit.last - user_visit.first < 1000 * 60 * 60 * 24) {
130                creatium.modals.show($modal);
131            }
132        } else if (trigger === 'return_week') {
133            if (should_prevent()) return;
134
135            if (user_visit.count === 3 && user_visit.last - user_visit.first < 1000 * 60 * 60 * 24 * 7) {
136                creatium.modals.show($modal);
137            }
138        } else if (trigger === 'leadback_hour') {
139            if (should_prevent()) return;
140
141            if (user_visit.last - user_visit.lead < 1000 * 60 * 60) {
142                creatium.modals.show($modal);
143            }
144        } else if (trigger === 'leadback_day') {
145            if (should_prevent()) return;
146
147            if (user_visit.last - user_visit.lead < 1000 * 60 * 60 * 24) {
148                creatium.modals.show($modal);
149            }
150        } else if (trigger === 'leadback_week') {
151            if (should_prevent()) return;
152
153            if (user_visit.last - user_visit.lead < 1000 * 60 * 60 * 24 * 7) {
154                creatium.modals.show($modal);
155            }
156        } else if (trigger === 'leadback_month') {
157            if (should_prevent()) return;
158
159            if (user_visit.last - user_visit.lead < 1000 * 60 * 60 * 24 * 30) {
160                creatium.modals.show($modal);
161            }
162        } else if (trigger === 'leave') {
163            $document.on('mouseleave', function (event) {
164                if (should_prevent()) return;
165
166                creatium.modals.show($modal);
167            });
168        } else if (trigger === 'scroll') {
169            $document.on('scroll', function (event) {
170                if (should_prevent()) return;
171
172                var rect = section_el.getBoundingClientRect();
173                if (rect.top > 0 && rect.top < window.innerHeight / 2) {
174                    creatium.modals.show($modal);
175                }
176            });
177        } else if (trigger === 'scroll_back') {
178            var scrolled = false;
179
180            $document.on('scroll', function (event) {
181                if (should_prevent()) return;
182
183                var rect = section_el.getBoundingClientRect();
184
185                if (scrolled) {
186                    if (rect.top > 0) {
187                        creatium.modals.show($modal);
188                    }
189                } else {
190                    if (rect.top + rect.height < 0) {
191                        scrolled = true;
192                    }
193                }
194            });
195        } else if (trigger === 'scroll_back_twice') {
196            var scrolled_1 = false;
197            var scrolled_2 = false;
198            var scrolled_3 = false;
199
200            $document.on('scroll', function (event) {
201                if (should_prevent()) return;
202
203                var rect = section_el.getBoundingClientRect();
204
205                if (scrolled_1) {
206                    if (rect.top > 0) {
207                        scrolled_2 = true;
208                    }
209                } else {
210                    if (rect.top + rect.height < 0) {
211                        scrolled_1 = true;
212                    }
213                }
214
215                if (scrolled_2) {
216                    if (scrolled_3) {
217                        if (rect.top > 0) {
218                            creatium.modals.show($modal);
219                        }
220                    } else {
221                        if (rect.top + rect.height < 0) {
222                            scrolled_3 = true;
223                        }
224                    }
225                }
226            });
227        } else if (trigger === 'scroll_end') {
228            $document.on('scroll', function (event) {
229                if (should_prevent()) return;
230
231                if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
232                    creatium.modals.show($modal);
233                }
234            });
235        } else if (trigger === 'form_fail_twice') {
236            var errors_count = 0;
237
238            $(creatium).on('submit-error', function () {
239                if (should_prevent()) return;
240
241                errors_count++;
242
243                if (errors_count === 2) {
244                    $(creatium).one('msg-close', function () {
245                        creatium.modals.show($modal);
246                    });
247                }
248            });
249        } else if (trigger === 'modal_twice') {
250            var modals_count = 0;
251
252            $(creatium).on('modal-hide', function (event, modal) {
253                if (should_prevent()) return;
254
255                // работаем только с теми окнами, которые клиент открывает сам
256                if (modal.$section.hasClass('section-modal')) return;
257
258                modals_count++;
259
260                if (modals_count === 2) {
261                    creatium.modals.show($modal);
262                }
263            });
264        }
265    });
266});
267
268creatium.init.global(function () {
269    var $preloader = $('.section-preloader').addClass('preloader-fading');
270
271    setTimeout(function () {
272        $preloader.hide();
273    }, 300);
274});
275creatium.init.global(function () {
276    var $section = $('.section-sidemenu');
277    if (!$section.length) return;
278
279    if (location.host === 'sections.creatium.site') {
280        var $template = $section.find('[cr-menu-page]');
281        $template.clone().insertBefore($template).addClass('highlight-100');
282        $template.clone().insertBefore($template).addClass('highlight-0');
283        $template.clone().insertBefore($template).addClass('highlight-0');
284        $template.clone().insertBefore($template).addClass('highlight-0');
285
286        return;
287    }
288
289    var $sections = $('.node.section:visible:not(.section-modal, .section-helper, .section-sidemenu, .fixation-top, .fixation-bottom)');
290
291    var $template = $section.find('[cr-menu-page]');
292    $sections.each(function () {
293        var $section = $(this);
294
295        var $dot = $template.clone().insertBefore($template);
296
297        $dot.addClass('highlight-0').data('highlight', 0);
298
299        $dot.on('click', function () {
300            creatium.scrollTo($section);
301        });
302    });
303    $template.remove();
304
305    var $dots = $section.find('[cr-menu-page]');
306
307    var scroll_handler = _.throttle(function () {
308        // Разделяем на 2 цикла, чтобы разделить этапы чтения DOM и записи
309        $sections.each(function (index) {
310            var $section = $(this);
311
312            var rect = this.getBoundingClientRect();
313
314            // В FF, при высоте экрана 437 пикселей, значение bottom
315            // самой нижней секции может быть 437.2166748046875, например
316            var top = Math.round(rect.top);
317            var bottom = Math.round(rect.bottom);
318
319            var win_height = $(window).height();
320
321            var highlight = 0;
322            if (bottom < 0 || top > win_height) highlight = 0;
323            else if (top >= 0 && bottom <= win_height) highlight = 1;
324            else if (top < 0) highlight = bottom / win_height;
325            else if (bottom > win_height) highlight = 1 - top / win_height;
326
327            if (highlight < 0) highlight = 0;
328            if (highlight > 1) highlight = 1;
329
330            $section.data('highlight2', Math.round(highlight * 10) * 10);
331        }).each(function (index) {
332            var $section = $(this);
333            var $dot = $dots.eq(index);
334
335            var highlight = $section.data('highlight2');
336
337            if ($section.data('highlight') !== highlight) {
338                $dot.removeClass('highlight-' + $dot.data('highlight'));
339                $dot.addClass('highlight-' + highlight).data('highlight', highlight);
340            }
341        });
342    }, 100);
343
344    $(document).on('scroll', scroll_handler);
345    scroll_handler();
346
347    if (creatium.scroll.snapping) {
348        creatium.syncInterval(scroll_handler, 500);
349    }
350});
351
352creatium.init.global(function () {
353    creatium.lazy.add($('.section-slider'), function init($section) {
354        if (!window.Swiper) return setTimeout(function () {
355            init($section);
356        }, 50);
357
358        var filter = function () {
359            return $(this).closest('.node')[0] === $section[0];
360        };
361
362        var $container = $section.find('.swiper-container').filter(filter);
363        var $next = $section.find('[cr-slider-next]').filter(filter);
364        var $previous = $section.find('[cr-slider-previous]').filter(filter);
365        var $pages = $section.find('[cr-slider-page]').filter(filter);
366        var $index = $section.find('[cr-slider-index]').filter(filter);
367
368        var params = $container.data();
369
370        var $icons = $section.find('[cr-slider-page_icon]').filter(filter).filter(function () {
371            return $(this).find('>.svgwrap').length > 1;
372        });
373        $icons.find('>.svgwrap').addClass('hidden');
374
375        var $labels = $section.find('[cr-slider-page_label]').filter(filter)
376            .filter(function () {
377                return $(this).find('>.textable').length > 1;
378            });
379        $labels.find('>.textable').addClass('hidden');
380
381        var swiper = new Swiper($container.get(0), {
382            autoHeight: params.fixheight === false,
383            autoplay: params.auto ? {
384                delay: params.pause,
385                stopOnLastSlide: !params.loop,
386            } : false,
387            allowTouchMove: params.touch,
388            effect: params.animated ? 'slide' : 'fade',
389            fadeEffect: { crossFade: true },
390            touchEventsTarget: 'container',
391            mousewheelEventsTarged: 'container',
392            on: {
393                slideChange: function () {
394                    $pages.filter('.is-active').removeClass('is-active');
395                    $pages.eq(swiper.activeIndex).addClass('is-active');
396
397                    setIcon(swiper.oldActiveIndex, swiper.activeIndex);
398                    setLabel(swiper.oldActiveIndex, swiper.activeIndex);
399
400                    $index.text(swiper.activeIndex + 1);
401
402                    swiper.oldActiveIndex = swiper.activeIndex;
403                },
404            },
405        });
406        $section.data('api-swiper', swiper);
407
408        swiper._params = params;
409        swiper.oldActiveIndex = swiper.activeIndex;
410
411        setIcon(swiper.oldActiveIndex, swiper.activeIndex);
412
413        function setIcon(oldIndex, newIndex) {
414            $icons.each(function () {
415                var $svgwraps = $(this).children('.svgwrap');
416                $svgwraps.eq(oldIndex).addClass('hidden');
417                $svgwraps.eq(newIndex).removeClass('hidden');
418            });
419        }
420
421        setLabel(swiper.oldActiveIndex, swiper.activeIndex);
422
423        function setLabel(oldIndex, newIndex) {
424            $labels.each(function () {
425                var $textables = $(this).children('.textable');
426                $textables.eq(oldIndex).addClass('hidden');
427                $textables.eq(newIndex).removeClass('hidden');
428            });
429        }
430
431        $section.on('slidenext', function (event) {
432            if (swiper.isEnd && params.loop) {
433                swiper.slideTo(0);
434            } else {
435                swiper.slideNext();
436            }
437
438            // если слайдер в другом слайдере, чтобы не листались оба
439            event.stopPropagation();
440        });
441
442        $next.on('click', function () {
443            $section.trigger('slidenext');
444        });
445
446        $section.on('slideprev', function (event) {
447            if (swiper.isBeginning && params.loop) {
448                swiper.slideTo(swiper.slides.length - 1);
449            } else {
450                swiper.slidePrev();
451            }
452
453            // если слайдер в другом слайдере, чтобы не листались оба
454            event.stopPropagation();
455        });
456
457        $previous.on('click', function () {
458            $section.trigger('slideprev');
459        });
460
461        $pages.on('click', function () {
462            swiper.slideTo($(this).index());
463        });
464
465        $section.find('.lazy').on('lazyload', _.throttle(function () {
466            swiper.update();
467        }, 500));
468
469        if (swiper.params.autoHeight) {
470            creatium.syncInterval(function () {
471                if (swiper.animating || !swiper.slides.length) return;
472
473                var wrapperHeight = swiper.wrapperEl.clientHeight;
474                var slideHeight = swiper.slides[swiper.activeIndex].clientHeight;
475                if (wrapperHeight !== slideHeight) swiper.update();
476            }, 40);
477        }
478    });
479});
480
481creatium.init.local(function ($root) {
482    $root.find('.widget-before-after').each(function () {
483        var $widget = $(this);
484        var $root = $widget.find('.root');
485
486        var $imgs = $root.find('> img');
487        var $handler = $root.find('> .handler');
488
489        $imgs.on('load', _.after($imgs.length, function () {
490            $root.css('height', $root.height());
491
492            var $layerBefore = $root.find('> .layer-before');
493            var $wrapBefore = $layerBefore.find('> .wrap');
494            var $imageBefore = $imgs.eq(0);
495            var imageLeftWidth = $imageBefore.width();
496            var imageLeftHeight = $imageBefore.height();
497            $imageBefore.removeAttr('style').appendTo($wrapBefore);
498
499            var $layerAfter = $root.find('> .layer-after');
500            var $wrapAfter = $layerAfter.find('> .wrap');
501            var $imageAfter = $imgs.eq(1);
502            var imageRightWidth = $imageAfter.width();
503            var imageRightHeight = $imageAfter.height();
504            $imageAfter.removeAttr('style').appendTo($wrapAfter);
505
506            $wrapBefore.add($wrapAfter).css({
507                'width': Math.max(imageLeftWidth, imageRightWidth),
508                'height': Math.max(imageLeftHeight, imageRightHeight),
509                'max-width': 'none',
510            });
511
512            var clickOffset = 0;
513
514            var eventHandler = function (event) {
515                var eventX = event.pageX;
516
517                if (eventX === undefined) {
518                    eventX = event.originalEvent.touches[0].pageX;
519                }
520
521                var rootWidth = $root.width();
522                var rootLeft = $root[0].getBoundingClientRect().left;
523                var wrapWidth = $wrapBefore.width();
524                var wrapLeft = $wrapBefore[0].getBoundingClientRect().left;
525
526                var mouseLeft = eventX - rootLeft - clickOffset;
527
528                if (mouseLeft < 0) mouseLeft = 0;
529                if (mouseLeft > rootWidth) mouseLeft = rootWidth;
530
531                $layerBefore.css('width', mouseLeft);
532                $layerAfter.css('width', rootWidth - mouseLeft);
533
534                $wrapBefore.css('right', - (rootWidth / 2 - mouseLeft));
535                $wrapAfter.css('left', rootWidth / 2 - (mouseLeft));
536
537                $handler.css('left', mouseLeft);
538                var handlerLeft = $handler[0].getBoundingClientRect().left + 2;
539
540                if (handlerLeft < wrapLeft) {
541                    $handler.css('left', mouseLeft + wrapLeft - handlerLeft);
542                }
543
544                if (handlerLeft > (wrapLeft + wrapWidth)) {
545                    $handler.css('left', mouseLeft - (handlerLeft - (wrapLeft + wrapWidth)));
546                }
547
548                event.stopPropagation();
549            };
550
551            $root.on('touchstart', function (event) {
552                eventX = event.originalEvent.touches[0].pageX;
553
554                if ($(event.target).closest($handler).length) {
555                    clickOffset = eventX - $handler[0].getBoundingClientRect().left;
556                } else {
557                    clickOffset = 0;
558                }
559
560                $(document).on('touchmove.beforeafter', eventHandler);
561                $(document).one('touchend', function () {
562                    $(document).off('touchmove.beforeafter');
563                });
564
565                event.preventDefault();
566                event.stopPropagation();
567            });
568
569            if ($root.data('trigger') === 'hover') {
570                $root.on('mousemove', eventHandler);
571                $root.on('mousedown', function (event) {
572                    event.preventDefault();
573                });
574            } else if ($root.data('trigger') === 'drag') {
575                $root.on('mousedown', function (event) {
576                    if ($(event.target).closest($handler).length) {
577                        clickOffset = event.pageX - $handler[0].getBoundingClientRect().left;
578                    } else {
579                        clickOffset = 0;
580                    }
581
582                    $(document).on('mousemove.beforeafter', eventHandler);
583                    $(document).one('mouseup', function () {
584                        $(document).off('mousemove.beforeafter');
585                    });
586
587                    event.preventDefault();
588                    event.stopPropagation();
589                });
590            }
591        }));
592    });
593});
594creatium.init.local(function ($root) {
595    $root.find('.widget-button').each(function () {
596        var $widget = $(this);
597
598        var filter = function () {
599            return $(this).closest('.widget-button')[0] === $widget[0];
600        };
601
602        var $btn = $widget.find('button').filter(filter);
603
604        if ($btn.is('[data-action="slideprev"]')) {
605            $btn.click(function () {
606                $widget.closest('.widget-slider, .widget-tabs, .
606widget-form2, .section-slider').trigger('slideprev');
607            });
608        }
609
610        if ($btn.is('[data-action="slidenext"]')) {
611            $btn.click(function () {
612                $widget.closest('.widget-slider, .widget-tabs, .widget-form2, .section-slider').trigger('slidenext');
613            });
614        }
615    });
616});
617
618creatium.init.local(function ($root) {
619    $root.find('.widget-cart').each(function () {
620        var $cart = $(this);
621
622        var $cont_full = $cart.find('.js-cart-full').first();
623        var $cont_empty = $cart.find('.js-cart-empty').first();
624
625        var state;
626
627        if (creatium.cart.list.length === 0) {
628            $cont_full.hide();
629            state = 'empty';
630        } else {
631            $cont_empty.hide();
632            state = 'full';
633        }
634
635        var updater = function () {
636            if (creatium.cart.list.length === 0) {
637                $cont_empty.show();
638                $cont_full.hide();
639            } else {
640                $cont_full.show();
641                $cont_empty.hide();
642            }
643        };
644
645        updater();
646        $(creatium).on('cart-change', updater);
647    });
648});
649creatium.init.local(function ($root) {
650    $root.find('.widget-cart-button').each(function () {
651        var $widget = $(this);
652
653        var updater = function () {
654            var count = 0;
655
656            _.each(creatium.cart.list, function (item) {
657                var amount = _.filter(item, { type: 'amount' })[0].value * 1;
658                count += amount;
659            });
660
661            $widget.find('.btn *').each(function () {
662                $(this).contents().each(function () {
663                    if (this.nodeType === 3) {
664                        if (this.data.match(/\d/)) {
665                            this.data = this.data.replace(/\d+/, count);
666                        }
667                    }
668                })
669            });
670        };
671
672        updater();
673        $(creatium).on('cart-change', updater);
674    });
675});
676// TODO Этот код перестал работать еще до 3.3, и никто не заметил - нужно его восстановить
677// creatium.init.local(function ($root) {
678//     $root.find('.widget-cart-image').each(function() {
679//         var $cbox = $(this).find('.colorbox');
680//
681//         if (!$cbox.length) return;
682//
683//         $cbox.colorbox({
684//             maxWidth: '80%',
685//             maxHeight: '80%'
686//         });
687//     });
688// });
689creatium.init.local(function ($root) {
690    var blankgif = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
691
692    $root.find('.widget-cart-list').each(function () {
693        var $widget = $(this);
694
695        var $template = $widget.children('script');
696        var template = $template.text().replace(/<\/_script>/g, '</script>');
697        $template.remove();
698
699        var updater = function () {
700            var $items = $widget.children('.cont');
701
702            creatium.cart.list.forEach(function (item) {
703                var name = _.filter(item, { type: 'title' })[0];
704                var price = _.filter(item, { type: 'price' })[0];
705                var amount = _.filter(item, { type: 'amount' })[0];
706                var photo = _.filter(item, { type: 'photo' })[0];
707
708                var $item = $items.filter(function () {
709                    return $(this).data('item') === item;
710                });
711
712                if ($item.length) {
713                    // Обновление
714
715                    $item.find('[data-role="setamount"]').val(amount.value);
716                    $item.find('[data-role="itemprice"]').html(price.value);
717                } else {
718                    // Добавление
719
720                    var $item = $(template);
721                    $widget.append($item);
722                    $item.data('item', item);
723
724                    $item.find('[data-role="setamount"]').val(amount.value);
725                    $item.find('[data-role="itemprice"]').html(price.value);
726                    $item.find('[data-role="itemname"]').html(name.value);
727                    $item.find('[data-role="itemphoto"]').attr(
728                        'data-lazy-bgimage', photo.value || blankgif
729                    );
730
731                    $item.find('[data-role="removefromcart"]').on('click', function () {
732                        creatium.cart.remove(item);
733                    });
734
735                    $item.find('[data-role="setamount"]').on('change', function () {
736                        var value = $(this).val() * 1;
737                        creatium.cart.setAmount(item, value);
738                    });
739
740                    $item.find('[data-role="increaseamount"]').on('click', function () {
741                        var value = amount.value + 1;
742                        creatium.cart.setAmount(item, value);
743                    });
744
745                    $item.find('[data-role="decreaseamount"]').on('click', function () {
746                        var value = amount.value - 1;
747                        creatium.cart.setAmount(item, value);
748                    });
749
750                    console.time('cart add trigger');
751                    creatium.init.trigger($item[0]);
752                    console.timeEnd('cart add trigger');
753                }
754            });
755
756            $items.each(function () {
757                var $item = $(this);
758
759                var item = $item.data('item');
760
761                if (creatium.cart.list.indexOf(item) < 0) {
762                    // Удаление
763
764                    $item.slideUp(250, function () {
765                        $item.remove();
766                    });
767                }
768            });
769        };
770
771        // Отсрочка нужна, чтобы сначала выполнился creatium.init.global,
772        // а только потом на страницу были добавлены новые компоненты в корзине
773        setTimeout(updater, 10);
774        $(creatium).on('cart-change', updater);
775    });
776});
777creatium.init.local(function ($root) {
778    $root.find('.widget-cart-total').each(function () {
779        var $widget = $(this);
780
781        var updater = function () {
782            var total = 0;
783            var currency;
784
785            _.each(creatium.cart.list, function (item) {
786                var amount = _.filter(item, { type: 'amount' })[0].value * 1;
787                var price = _.filter(item, { type: 'price' })[0].value;
788
789                total += creatium.cart.getPrice(price) * amount;
790                currency = currency || creatium.cart.getCurrency(price);
791            });
792
793            if (!creatium.cart.list.length) {
794                var result = '-';
795            } else {
796                var result = currency.replace('%s%', total);
797            }
798
799            $widget.find('[data-role="carttotal"] span').html(result);
800        };
801
802        updater();
803        $(creatium).on('cart-change', updater);
804    });
805});
806creatium.init.local(function ($root) {
807    $root.find('.widget-cms-table').each(function () {
808        var $widget = $(this);
809        var $root = $widget.find('.cms-table-root');
810
811        var table = $root.data('table');
812        var template = $root.data('template');
813
814        $.ajax(creatium.origin + '/app/cms/0.2/getAll', {
815            type: 'POST',
816            data: {},
817            dataType: 'json',
818            contentType: 'application/json',
819            success: function (data, status, xhr) {
820                console.log('CMS: getAll success', data);
821
822                try {
823                    $root.html(_.template(template, _.find(data.tables, { name: table })));
824                } catch (e) {
825                    console.error('CMS: template error', e);
826
827                    var $alert = $('<div class="alert alert-danger" style="margin: 0;"></div>');
828                    $alert.html(e.toString());
829                    $root.empty().append($alert);
830                }
831            },
832            error: function (data, status, xhr) {
833                console.log('CMS: getAll error', data);
834
835                var $alert = $('<div class="alert alert-danger" style="margin: 0;"></div>');
836                $alert.html('Cannot read data from server');
837                $root.empty().append($alert);
838            },
839        });
840    });
841});
842
843creatium.init.local(function ($root) {
844    $root.find('.widget-comments-fb').each(function () {
845        var $widget = $(this);
846
847        var $fb = $widget.find('.fb');
848
849        if ($fb.length) {
850            var fbjoint = $fb.attr('data-joint') === 'true';
851            var href = 'http://' + location.host.replace(/^www\./, '');
852
853            if (!fbjoint) {
854                href += '/' + location.pathname;
855            }
856
857            $fb.attr('data-href', href);
858            $fb.attr('data-width', $fb.width());
859
860            $('head').append('<meta property="fb:app_id" content="' + $fb.data('apiid') + '"/>');
861            $('<div id="fb-root"></div>').appendTo('body');
862
863            (function(d, s, id) {
864                var js, fjs = d.getElementsByTagName(s)[0];
865                if (d.getElementById(id)) return;
866                js = d.createElement(s); js.id = id;
867                js.src = "//connect.facebook.net/ru_RU/sdk.js#xfbml=1&version=v2.8";
868                fjs.parentNode.insertBefore(js, fjs);
869            }(document, 'script', 'facebook-jssdk'));
870        }
871    });
872});
873
874var inthash = function(str) {
875    return _.reduce(str, function(res, sym, key) {
876        return res + sym.charCodeAt() * Math.pow(key + 5, 5);
877    }, str.length);
878};
879
880creatium.init.local(function ($root) {
881    $root.find('.widget-comments-vk').each(function () {
882        var $widget = $(this);
883
884        var $vk = $widget.find('.vk');
885
886        if ($vk.length && $vk.data('apiid')) {
887            var id = _.uniqueId('vk_comments');
888            $vk.attr('id', id);
889
890            var vkjoint = $vk.attr('data-joint') === 'true';
891            var page_id = 1;
892
893            if (!vkjoint) {
894                page_id = inthash(location.host.replace(/^www\./, '') + '/' + location.pathname);
895            }
896
897            $.getScript("//vk.com/js/api/openapi.js?112", function () {
898                VK.init({
899                    apiId: $vk.data('apiid'),
900                    onlyWidgets: true
901                });
902
903                VK.Widgets.Comments(id, {
904                    limit: 5,
905                    width: $vk.width(),
906                    attach: "*"
907                }, page_id);
908            });
909        }
910    });
911});
912function ourDay(theirDay) {
913    if (theirDay > 0) return theirDay - 1;
914    if (theirDay === 0) return 6;
915}
916
917creatium.init.local(function ($root) {
918    $root.find('.widget-countdown').each(function() {
919        var $widget = $(this);
920        $widget.children('.metahtml').show();
921
922        var $root = $widget.find('[cr-countdown-root]');
923        var settings = $root.data('vals');
924        var variables = $root.data('variables') || {};
925        var now = new Date;
926
927        // Этот код должен быть синхронизирован с кодом в node.js
928        var date;
929        if (settings.type === 'full') {
930            settings.full_date.day++;
931            date = new Date(settings.full_date.year, settings.full_date.month, settings.full_date.day, settings.full_time.hour, settings.full_time.minute);
932        } else if (settings.type === 'month') {
933            settings.month_day++;
934            date = new Date(now.getFullYear(), now.getMonth(), settings.month_day, settings.month_time.hour, settings.month_time.minute);
935            if (date.getTime() < now.getTime()) {
936                date = new Date(now.getFullYear(), now.getMonth() + 1, settings.month_day, settings.month_time.hour, settings.month_time.minute);
937            }
938        } else if (settings.type === 'week') {
939            var add = settings.week_day - ourDay(now.getDay());
940            date = new Date(now.getFullYear(), now.getMonth(), now.getDate() + add, settings.week_time.hour, settings.week_time.minute);
941            if (date.getTime() < now.getTime()) {
942                add = 7 - ourDay(now.getDay()) + settings.week_day;
943                date = new Date(now.getFullYear(), now.getMonth(), now.getDate() + add, settings.week_time.hour, settings.week_time.minute);
944            }
945        } else if (settings.type === 'day') {
946            date = new Date(now.getFullYear(), now.getMonth(), now.getDate(), settings.day_time.hour, settings.day_time.minute);
947            if (date.getTime() < now.getTime()) {
948                date = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, settings.day_time.hour, settings.day_time.minute);
949            }
950        } else if (settings.type === 'fake') {
951            var hash = [settings.fake_days, settings.fake_time.hour, settings.fake_time.minute].join(':');
952            if (creatium.store.get(hash)) {
953                date = new Date(creatium.store.get(hash));
954            } else {
955                date = new Date(now.getFullYear(), now.getMonth(), now.getDate() + settings.fake_days, now.getHours() + settings.fake_time.hour, now.getMinutes() + settings.fake_time.minute);
956                creatium.store.set(hash, date.getTime());
957            }
958        }
959
960        var timezone = settings.type === 'fake' || settings.timezone === 'default' ? null : settings.timezone;
961
962        if (settings.action.type === "show_element") {
963            $('#' + settings.action.element_id).hide();
964        }
965
966        var onExpiry = function() {
967            if (settings.action.type === 'message') {
968                creatium['msg_' + settings.action.message.type](settings.action.message.title, settings.action.message.text);
969            }
970
971            if (settings.action.type === 'redirect') {
972                if (settings.action.url) {
973                    location.href = settings.action.url;
974                }
975            }
976
977            if (settings.action.type === 'show_element') {
978                $('#' + settings.action.element_id).show();
979            }
980
981            if (settings.action.type === 'hide_element') {
982                $('#' + settings.action.element_id).hide();
983            }
984
985            if (settings.action.type === 'show_popup') {
986                creatium.modals.show($widget.find('.modal').filter(function () {
987                    return $(this).closest('.node')[0] === $widget[0];
988                }));
989            }
990
991            if ($widget.data('api-expired') !== true) {
992                $widget.data('api-expired', true);
993                $widget.triggerHandler('api-expiry');
994            }
995        };
996
997        var countdown = keithWoodCountdown(window.creatium.lang);
998        var updater = creatium.watchDom($widget[0]);
999
1000        var tick = function () {
1001            if ($widget.data('api-expired')) return;
1002
1003            updater(_.extend(variables, countdown(date, timezone)));
1004            $widget.triggerHandler('api-tick');
1005
1006            if (date < new Date()) onExpiry();
1007        };
1008
1009        tick();
1010        creatium.syncInterval(tick, 1000);
1011
1012        $widget.data('api-until', countdown.getUntil());
1013
1014        $widget.data('api-setUntil', function (date2) {
1015            date = new Date(date2);
1016
1017            if (date.getTime() < new Date().getTime()) return;
1018
1019            timezone = null;
1020            $widget.data('api-until', date);
1021            $widget.data('api-expired', false);
1022            tick();
1023        });
1024    });
1025});
1026
1027creatium.init.local(function ($root) {
1028    $root.find('.widget-defer').each(function () {
1029        var $defer = $(this);
1030
1031        setTimeout(function () {
1032            $defer.show();
1033        }, $defer.data('timeout') * 1000)
1034    });
1035});
1036creatium.init.global(function () {
1037    creatium.syncInterval(function () {
1038        var $active = $(document.activeElement).closest('.widget-field');
1039
1040        if ($active.length ) {
1041            // Чтобы класс is-filled был актуальным
1042            $active.find('input').triggerHandler('input');
1043        }
1044    }, 250);
1045});
1046
1047creatium.init.local(function ($root) {
1048    creatium.lazy.add($root.find('.widget-field'), function ($field) {
1049        var $form = $field.closest('[data-form]');
1050
1051        var vals = $field.find('.metahtml').first().data('vals');
1052
1053        var list = [];
1054        $field.find('[data-item-text][data-item-value]').each(function () {
1055            list.push({
1056                text: $(this).attr('data-item-text'),
1057                value: $(this).attr('data-item-value') * 1 || 0,
1058            });
1059        });
1060
1061        if (!vals) return;
1062
1063        var original;
1064
1065        $field.find('.is-text').each(function () {
1066            var $text = $(this);
1067
1068            $text.find('input, textarea').on('input', function () {
1069                if ($(this).val().length) {
1070                    if (!$text.hasClass('is-filled')) $text.addClass('is-filled');
1071                } else {
1072                    if ($text.hasClass('is-filled')) $text.removeClass('is-filled');
1073                }
1074            });
1075        });
1076
1077        if (["name", "phone", "email", "count", "text", "password", "hidden"].indexOf(vals.type) >= 0) {
1078            original = $field.find('input').val();
1079
1080            $form.on('reset', function () {
1081                $field.find('input').val(original);
1082            });
1083
1084            $field.data('api-setValue', function (value) {
1085                $field.find('input').val(value);
1086            });
1087
1088            if ($field.is('[data-prefill]')) {
1089                original = $field.attr('data-prefill');
1090                $field.data('api-setValue')(original);
1091            }
1092        }
1093
1094        if (vals.type === 'textarea') {
1095            original = $field.find('textarea').val();
1096            $form.on('reset', function () {
1097                $field.find('textarea').val(original);
1098            });
1099
1100            $field.data('api-setValue', function (value) {
1101                $field.find('textarea').val(value);
1102            });
1103
1104            if ($field.is('[data-prefill]')) {
1105                original = $field.attr('data-prefill');
1106                $field.data('api-setValue')(original);
1107            }
1108        }
1109
1110        if (vals.type === 'hackable') {
1111            original = $field.find('[cr-field]').attr('data-value');
1112            $form.on('reset', function () {
1113                $field.find('[cr-field]').attr('data-value', original);
1114            });
1115
1116            var typing = $field.find('[cr-field]').attr('data-type');
1117            $field.data('api-setValue', function (value) {
1118                // Приводим значение к строке
1119                value = value.toString();
1120
1121                // А дальше к нужному типу
1122                if (typing === 'number') {
1123                    value = value * 1 || 0;
1124                } else if (typing === 'boolean') {
1125                    value = value === '1' || value === 'true';
1126                }
1127
1128                $field.find('[cr-field]').attr('data-value', value);
1129            });
1130
1131            if ($field.is('[data-prefill]')) {
1132                original = $field.attr('data-prefill');
1133                $field.data('api-setValue')(original);
1134            }
1135        }
1136
1137        if (vals.type === 'checkbox-list' || vals.type === 'checkbox-visual') {
1138            original = _.map($field.find('input'), function (el) {
1139                return $(el).prop('checked');
1140            });
1141
1142            $form.on('reset', function () {
1143                $field.find('input').each(function (index) {
1144                    $(this).prop('checked', original[index]);
1145                });
1146            });
1147
1148            $field.data('api-setValue', function (value) {
1149                $field.find('input').each(function (index) {
1150                    var item = list[index];
1151
1152                    if (value[item.text] !== undefined) {
1153                        $(this).prop('checked', value[item.text]);
1154                    }
1155                });
1156            });
1157
1158            if ($field.is('[data-prefill]')) {
1159                var prefill = {};
1160
1161                $field.attr('data-prefill').split(',').forEach(function (part) {
1162                    prefill[part.trim()] = true;
1163                });
1164
1165                $field.data('api-setValue')(prefill);
1166
1167                original = _.map($field.find('input'), function (el) {
1168                    return $(el).prop('checked');
1169                });
1170            }
1171        }
1172
1173        if (vals.type === 'checkbox-input') {
1174            original = $field.find('input').prop('checked');
1175            $form.on('reset', function () {
1176                $field.find('input').prop('checked', original);
1177            });
1178
1179            $field.data('api-setValue', function (value) {
1180                $field.find('input').prop('checked', value);
1181            });
1182
1183            if ($field.is('[data-prefill]')) {
1184                original = $field.attr('data-prefill') !== '0';
1185                $field.data('api-setValue')(original);
1186            }
1187        }
1188
1189        if (vals.type === 'privacy-checkbox') {
1190            original = $field.find('input').prop('checked');
1191            $form.on('reset', function () {
1192                $field.find('input').prop('checked', original);
1193            });
1194
1195            $field.data('api-setValue', function (value) {
1196                $field.find('input').prop('checked', value);
1197            });
1198        }
1199
1200        if (vals.type === 'radio-list' || vals.type === 'radio-visual') {
1201            original = _.map($field.find('input'), function (el) {
1202                return $(el).prop('checked');
1203            });
1204
1205            $form.on('reset', function () {
1206                $field.find('input').each(function (index) {
1207                    $(this).prop('checked', original[index]);
1208                });
1209            });
1210
1211            $field.on('change', function (event) {
1212                $field.find('input').filter(function () {
1213                    return this !== event.target;
1214                }).prop('checked', false);
1215            });
1216
1217            $field.data('api-setValue', function (value) {
1218                $field.find('input').prop('checked', false);
1219
1220                $field.find('input').each(function (index) {
1221                    var item = list[index];
1222
1223                    if (item.text === value) {
1224                        $(this).prop('checked', true);
1225                    }
1226                });
1227            });
1228
1229            if ($field.is('[data-prefill]')) {
1230                $field.data('api-setValue')($field.attr('data-prefill'));
1231                original = _.map($field.find('input'), function (el) {
1232                    return $(el).prop('checked');
1233                });
1234            }
1235        }
1236
1237        if (vals.type === 'select-menu') {
1238            $field.find('select option').eq(0).attr('value', '');
1239            $field.find('select option').slice(1).each(function (index) {
1240                $(this).attr('value', index);
1241            });
1242
1243            original = $field.find('select').val();
1244            $form.on('reset', function () {
1245                $field.find('select').val(original);
1246                $field.triggerHandler('change');
1247            });
1248
1249            $field.on('change', function (event) {
1250                $field.find('[cr-field_value]').text($field.find('select option:selected').text());
1251            });
1252
1253            $field.data('api-setValue', function (value) {
1254                if (value) {
1255                    var item = _.find(list, { text: value });
1256                    var index = list.indexOf(item);
1257
1258                    if (index >= 0) {
1259                        $field.find('select').val(index);
1260                    } else {
1261                        $field.find('select').val('');
1262                    }
1263                } else {
1264                    $field.find('select').val('');
1265                }
1266
1267                $field.triggerHandler('change');
1268            });
1269
1270            if ($field.is('[data-prefill]')) {
1271                $field.data('api-setValue')($field.attr('data-prefill'));
1272                original = $field.find('select').val();
1273            }
1274        }
1275
1276        if (vals.type === 'slider') {
1277            var $root = $field.find('[cr-field-input]');
1278            $root.find('style').insertAfter($root);
1279            $root.empty();
1280
1281        
1281    original = $root.attr('value') * 1 || 0;
1282
1283            var $input = $('<input>').val(original).appendTo($root);
1284
1285            var options = {
1286                force_edges: true,
1287                min: vals.min,
1288                max: vals.max,
1289                step: vals.step,
1290                from: original,
1291            };
1292
1293            // Задержка нужна, потому что иначе появляется Forced synchronous layouts,
1294            // и это видно во вкладке Perfomance. Если снова начнет повторяться,
1295            // можно попробовать убрать задержку, или использовать _.setTimeout
1296            // с несколькими произвольными миллисекундами
1297            window.requestAnimationFrame(function init() {
1298                if (!$.fn.ionRangeSlider) {
1299                    return setTimeout(init, 50);
1300                }
1301
1302                $input.ionRangeSlider(options);
1303
1304                if ($field.is('[data-prefill]')) {
1305                    original = $field.attr('data-prefill') * 1 || 0;
1306                    $field.data('api-setValue')(original);
1307                }
1308            });
1309
1310            $form.on('reset', function () {
1311                $input.data("ionRangeSlider").update(options);
1312            });
1313
1314            $field.data('api-setValue', function (value) {
1315                var options2 = _.clone(options);
1316                options2.from = value;
1317                $input.data("ionRangeSlider").update(options2);
1318            });
1319        }
1320
1321        if (vals.type === 'file') {
1322            var $state = $field.find('[cr-field_state]');
1323            $state.data('original-html', $state.html());
1324
1325            var $clean = $field.find('[cr-field_clean]');
1326            $clean.hide();
1327            $clean.on('click', function () {
1328                $field.find(':file').val('');
1329                $state.html($state.data('original-html'));
1330                $field.data('result', null);
1331                $clean.hide();
1332            });
1333
1334            $form.on('reset', function () {
1335                if ($field.is('[data-prefill]')) {
1336                    $field.data('api-setValue')([$field.attr('data-prefill')]);
1337                } else {
1338                    $clean.click();
1339                }
1340            });
1341
1342            $field.on('change', function handler(event) {
1343                if (!$.fn.ajaxSubmit) return setTimeout(function () {
1344                    handler(event);
1345                }, 50);
1346
1347                // на данном этапе форме не нужно знать об изменении
1348                event.stopPropagation();
1349
1350                var $fileinput = $field.find(':file');
1351
1352                var match = $fileinput.val().match(/.+[\/\\](.+)/);
1353                if (!match) return;
1354
1355                var filename = match[1];
1356
1357                // оригинал заменяем копией
1358                $fileinput.clone().insertAfter($fileinput);
1359
1360                var $fileform = $('<form>').attr({
1361                    'action': creatium.origin + '/app/' + creatium.VERSION + '/file',
1362                    'method': 'POST',
1363                    'enctype': 'multipart/form-data',
1364                });
1365
1366                var $pageinput = $('<input>').attr({
1367                    'type': 'hidden',
1368                    'name': 'ImageUploadForm[page]',
1369                    'value': creatium.page_id,
1370                });
1371
1372                $fileform.append($fileinput);
1373                $fileform.append($pageinput);
1374
1375                $fileform.appendTo('body').hide();
1376
1377                $fileform.ajaxSubmit({
1378                    dataType: 'json',
1379                    beforeSend: function() {
1380                        return $state.text(filename + ' (0%)');
1381                    },
1382                    uploadProgress: function(event, position, total, percentComplete) {
1383                        return $state.text(filename + ' (' + percentComplete + '%)');
1384                    },
1385                    success: function(result) {
1386                        $field.data('result', result);
1387                        $state.text(filename);
1388                        $clean.show();
1389
1390                        $form.trigger('change');
1391
1392                        $fileform.remove();
1393                    },
1394                    error: function(xhr) {
1395                        creatium.msg_error(creatium.l10n("Ошибка загрузки!"), xhr.status === 400 ? xhr.responseText : null);
1396
1397                        $state.html($state.data('original-html'));
1398                        $field.data('result', null);
1399
1400                        $form.trigger('change');
1401
1402                        $fileform.remove();
1403                    },
1404                });
1405            });
1406
1407            $field.data('api-setValue', function (value) {
1408                var file = value[0];
1409
1410                if (file) {
1411                    var match = file.match(/.+[\/\\](.+)/);
1412                    if (!match) file = null;
1413                }
1414
1415                if (file) {
1416                    var filename = match[1];
1417
1418                    $field.data('result', file);
1419                    $state.text(filename);
1420                    $clean.show();
1421                } else {
1422                    $state.html($state.data('original-html'));
1423                    $field.data('result', null);
1424                }
1425            });
1426
1427            if ($field.is('[data-prefill]')) {
1428                $field.data('api-setValue')([$field.attr('data-prefill')]);
1429            }
1430        }
1431    });
1432});
1433creatium.async.ready(function () {
1434    creatium.init.local(function ($root) {
1435        creatium.lazy.then($root.find('.widget-form2'), function ($widget) {
1436            var filter = function () {
1437                return $(this).closest('.widget')[0] === $widget[0];
1438            };
1439
1440            var $container = $widget.find('.swiper-container').filter(filter);
1441
1442            // если форма не пошаговая
1443            if (!$container.length) return;
1444
1445            var swiper = new Swiper($container.get(0), {
1446                autoHeight: $container.attr('data-fixheight') === 'false',
1447                autoplay: false,
1448                allowTouchMove: false,
1449                effect: $container.attr('data-animated') === 'true' ? 'slide' : 'fade',
1450                fadeEffect: { crossFade: true },
1451                touchEventsTarget: 'container',
1452                mousewheelEventsTarged: 'container',
1453                // Без этой настройки малейшее движение курсора во время клика
1454                // сбрасывает попытку отметить галочку в форме
1455                preventClicks: false,
1456                on: {
1457                    slideChangeTransitionStart: function () {
1458                        // чтобы поля обновились
1459                        $widget.trigger('change');
1460                    }
1461                },
1462            });
1463            $widget.data('api-swiper', swiper);
1464
1465            if ($widget.closest('.modal').length) {
1466                $widget.closest('.modal').on('shown.bs.modal', function () {
1467                    swiper.update();
1468                    $widget.trigger('change');
1469                })
1470            }
1471
1472            $widget.on('slidenext', function (event) {
1473                $widget.trigger('validate', [
1474                    function () {
1475                        swiper.slideNext();
1476                    }
1477                ]);
1478
1479                // если слайдер в другом слайдере, чтобы не листались оба
1480                event.stopPropagation();
1481            });
1482
1483            $widget.on('slideprev', function (event) {
1484                swiper.slidePrev();
1485
1486                // если слайдер в другом слайдере, чтобы не листались оба
1487                event.stopPropagation();
1488            });
1489
1490            // для нормальной инициации внутри модального окна
1491            creatium.lazy.add($widget, function () {
1492                swiper.update();
1493            });
1494
1495            $widget.find('.lazy').on('lazyload', _.throttle(function () {
1496                swiper.update();
1497            }, 500));
1498
1499            if (swiper.params.autoHeight) {
1500                creatium.syncInterval(function () {
1501                    if (swiper.animating || !swiper.slides.length) return;
1502
1503                    var wrapperHeight = swiper.wrapperEl.clientHeight;
1504                    var slideHeight = swiper.slides[swiper.activeIndex].clientHeight;
1505                    if (wrapperHeight !== slideHeight) swiper.update();
1506                }, 40);
1507            }
1508        });
1509    });
1510});
1511
1512creatium.init.local(function ($root) {
1513    $root.find('.widget-hamburger').each(function () {
1514        var $widget = $(this);
1515
1516        var filter = function () {
1517            return $(this).closest('.widget-hamburger')[0] === $widget[0];
1518        };
1519
1520        var $toggle = $widget.find('[cr-hamburger-toggle]').filter(filter);
1521        var $container = $widget.find('[cr-hamburger-menu]').filter(filter);
1522
1523        if ($container.hasClass('is-collapsed')) {
1524            creatium.lazy.add($widget, function ($el) {
1525                $container.show();
1526                creatium.lazy.force($container);
1527                $container.hide();
1528            });
1529        }
1530
1531        $toggle.on('click', function () {
1532            if ($container.is(':animated')) return;
1533
1534            $toggle.toggleClass('is-collapsed');
1535            $container.toggleClass('is-collapsed');
1536
1537            $toggle.toggleClass('is-expanded');
1538            $container.toggleClass('is-expanded');
1539
1540            if (scroll_fix) {
1541                $container.toggle();
1542            } else {
1543                $container.slideToggle();
1544            }
1545        });
1546
1547        // Автоскрытие гамбургера по переходу по любой ссылке
1548        // Делается в 3 шага
1549        var scroll_fix = false;
1550
1551        $(creatium).on('before-scroll-to', function () {
1552            if ($container.hasClass('is-expanded')) {
1553                // Отключаем анимацию меню
1554                scroll_fix = true;
1555
1556                // 1. Скрываем меню, чтобы высота фиксированной панели была пересчитана
1557                $toggle.click();
1558            }
1559        });
1560
1561        $(creatium).on('after-scroll-to', function () {
1562            if (scroll_fix) {
1563                // 2. Возвращаем меню, как ни в чем ни бывало
1564                $toggle.click();
1565
1566                // Включаем обратно анимацию меню
1567                scroll_fix = false;
1568
1569                // 3. Теперь скрываем меню с анимацией, красиво
1570                $toggle.click();
1571            }
1572        });
1573    })
1574});
1575
1576creatium.init.local(function ($root) {
1577    $root.find('.widget-hover').each(function () {
1578        var $widget = $(this);
1579
1580        var $hover = $widget.find('[cr-hover]').filter(function () {
1581            return $(this).closest('.widget-hover')[0] === $widget[0];
1582        });
1583
1584        $hover.on('mouseenter', function (event) {
1585            if ($(event.relatedTarget).closest($hover).length) {
1586                // Часть ховера может быть вынесена за пределы компонента,
1587                // и так мы ловим переход курсора с одной части ховера на вынесенную
1588                return;
1589            }
1590
1591            $hover.addClass('hover');
1592            $hover.addClass('animated');
1593
1594            $widget.triggerHandler('api-before-over');
1595
1596            setTimeout(function () {
1597                $hover.removeClass('animated');
1598
1599                $widget.triggerHandler('api-over');
1600            }, $hover.data('duration'));
1601        });
1602
1603        $hover.on('mouseleave', function (event) {
1604            if ($(event.relatedTarget).closest($hover).length) {
1605                // Часть ховера может быть вынесена за пределы компонента,
1606                // и так мы ловим переход курсора с одной части ховера на вынесенную
1607                return;
1608            }
1609
1610            $hover.removeClass('hover');
1611            $hover.addClass('animated');
1612
1613            $widget.triggerHandler('api-before-out');
1614
1615            setTimeout(function () {
1616                $hover.removeClass('animated');
1617
1618                $widget.triggerHandler('api-out');
1619            }, $hover.data('duration'));
1620        });
1621    })
1622});
1623
1624creatium.init.global(function () {
1625    $('.widget-html .code[data-html]').each(function () {
1626        var $code = $(this);
1627
1628        creatium.lazy.add($code, function ($el) {
1629            $el.html($el.data('html'));
1630            $el.removeAttr('data-html');
1631        });
1632    });
1633});
1634
1635creatium.init.local(function init($root) {
1636    if (!window.stackEffects) return setTimeout(function () {
1637        init($root);
1638    }, 50);
1639
1640    $root.find('.widget-image').each(function() {
1641        $(this).find('.stack-image-content').each(function () {
1642            var $imgStack, options;
1643            $imgStack = $(this);
1644            options = $imgStack.attr('stack_hover_effect');
1645            if (options) {
1646                options = JSON.parse(options);
1647                stackEffects.getInstance(options.effectType, $imgStack.get(0), {
1648                    effectType: options.effectType,
1649                    disableScale: options.disableScale,
1650                    style: options.style
1651                });
1652            }
1653            return $imgStack.removeAttr('stack_hover_effect');
1654        });
1655    });
1656});
1657creatium.init.local(function ($root) {
1658    $root.find('.widget-increasingdigits').each(function () {
1659        var searchDigitsPattern = new RegExp("([0-9]+)", "g"),
1660                digitsWrapper = "<span class='digits-wrapper'>$1</span>",
1661                $digitsContainer = $(this).find('.digits');
1662
1663            var animationDuration = parseFloat($digitsContainer.attr('data-animation-duration')) * 1000 || 0;
1664
1665            $digitsContainer.find('*').andSelf().each(function () {
1666                var textNodeId = 3;
1667
1668                $(this)
1669                    .contents()
1670                    .filter(function () {
1671                        return this.nodeType === textNodeId;
1672                    })
1673                        .each(function () {
1674                            var $digitsContainer = $(this).parent(),
1675                                wrappedTextNodeVal = this.textContent.replace(searchDigitsPattern, digitsWrapper);
1676
1677                            $(this).replaceWith(wrappedTextNodeVal);
1678
1679                            $digitsContainer.find('.digits-wrapper').each(function() {
1680                                $(this)
1681                                    .data('data-number', $(this).text())
1682                                    .text('0');
1683                            })
1684                        })
1685            })
1686
1687        creatium.lazy.add($(this), function init($el) {
1688            if (!$.fn.animateNumber) return setTimeout(function () {
1689                init($el);
1690            }, 50);
1691
1692            $el.find('.digits-wrapper').each(function () {
1693                $(this).animateNumber({ number: $(this).data('data-number') }, animationDuration);
1694            })
1695        })
1696    })
1697});
1698
1699
1700
1701creatium.init.local(function ($root) {
1702    $root.find('.widget-list').each(function () {
1703        var $widget = $(this);
1704
1705        $widget.find('.lazy-loader').one('lazyload', function () {
1706            var file = $(this).attr('src');
1707            $widget.find('li').css('background-image', 'url("' + file + '")');
1708        });
1709    })
1710});
1711
1712
1713
1714creatium.init.local(function ($root) {
1715    $root.find('.widget-pagination').each(function () {
1716        var $widget = $(this);
1717
1718        $widget.find('[href="#"]').on('click', function (event) {
1719            // Во избежание прокрутки к верху страницы
1720            event.preventDefault();
1721        });
1722    })
1723});
1724
1725
1726
1727creatium.init.local(function ($root) {
1728    $root.find('.widget-slide-share').each(function() {
1729        var $slideContainer = $(this).find('.slide');
1730        var userInputString = $slideContainer.attr('data-iframe-string');
1731
1732        if (userInputString) {
1733            var match = userInputString.match(/.*?src="(.*?)"/);
1734
1735            if (match) {
1736                var url = match[1];
1737
1738                if (url) {
1739                    $slideContainer.append('<iframe class="slide-share" src=' + url + ' allowfullscreen></iframe>');
1740                }
1741            }
1742        }
1743    })
1744});
1745
1746creatium.async.ready(function () {
1747    creatium.init.local(function ($root) {
1748        creatium.lazy.add($root.find('.widget-slider'), function ($widget) {
1749            var filter = function () {
1750                return $(this).closest('.widget')[0] === $widget[0];
1751            };
1752
1753            var $container = $widget.find('.swiper-container').filter(filter);
1754            var $next = $widget.find('[cr-slider-next]').filter(filter);
1755            var $previous = $widget.find('[cr-slider-previous]').filter(filter);
1756            var $pages = $widget.find('[cr-slider-page]').filter(filter);
1757            var $index = $widget.find('[cr-slider-index]').filter(filter);
1758
1759            var params = $container.data();
1760
1761            var $icons = $widget.find('[cr-slider-page_icon]').filter(filter).filter(function () {
1762                return $(this).find('>.svgwrap').length > 1;
1763            });
1764            $icons.find('>.svgwrap').addClass('hidden');
1765
1766            var $labels = $widget.find('[cr-slider-page_label]').filter(filter)
1767                .filter(function () {
1768                    return $(this).find('>.textable').length > 1;
1769                });
1770            $labels.find('>.textable').addClass('hidden');
1771
1772            var swiper = new Swiper($container.get(0), {
1773            nested: $widget.closest('.swiper-container').length,
1774            autoHeight: params.fixheight === false,
1775            autoplay: params.auto ? {
1776                delay: params.pause,
1777                stopOnLastSlide: !params.loop,
1778            } : false,
1779            allowTouchMove: params.touch,
1780            effect: params.animated ? 'slide' : 'fade',
1781            fadeEffect: { crossFade: true },
1782            touchEventsTarget: 'container',
1783            mousewheelEventsTarged: 'container',
1784            on: {
1785                slideChange: function () {
1786                    $pages.filter('.is-active').removeClass('is-active');
1787                    $pages.eq(swiper.activeIndex).addClass('is-active');
1788
1789                        setIcon(swiper.oldActiveIndex, swiper.activeIndex);
1790                        setImage(swiper.oldActiveIndex, swiper.activeIndex);
1791                        setLabel(swiper.oldActiveIndex, swiper.activeIndex);
1792
1793                        $index.text(swiper.activeIndex + 1);
1794
1795                        swiper.oldActiveIndex = swiper.activeIndex;
1796                    },
1797                },
1798            });
1799            $widget.data('api-swiper', swiper);
1800
1801            swiper._params = params;
1802            swiper.oldActiveIndex = swiper.activeIndex;
1803
1804            setIcon(swiper.oldActiveIndex, swiper.activeIndex);
1805
1806            function setIcon(oldIndex, newIndex) {
1807                $icons.each(function () {
1808                    var $svgwraps = $(this).children('.svgwrap');
1809                    $svgwraps.eq(oldIndex).addClass('hidden');
1810                    $svgwraps.eq(newIndex).removeClass('hidden');
1811                });
1812            }
1813
1814            setImage(swiper.oldActiveIndex, swiper.activeIndex);
1815
1816            function setImage(oldIndex, newIndex) {
1817                $icons.each(function () {
1818                    var $images = $(this).children();
1819                    $images.eq(oldIndex).addClass('hidden');
1820                    $images.eq(newIndex).removeClass('hidden');
1821                });
1822            }
1823
1824            setLabel(swiper.oldActiveIndex, swiper.activeIndex);
1825
1826            function setLabel(oldIndex, newIndex) {
1827                $labels.each(function () {
1828                    var $textables = $(this).children('.textable');
1829                    $textables.eq(oldIndex).addClass('hidden');
1830                    $textables.eq(newIndex).removeClass('hidden');
1831                });
1832            }
1833
1834            $widget.on('slidenext', function (event) {
1835                if (swiper.isEnd && params.loop) {
1836                    swiper.slideTo(0);
1837                } else {
1838                    swiper.slideNext();
1839                }
1840            });
1841
1842            $next.on('click', function () {
1843                $widget.triggerHandler('slidenext');
1844            });
1845
1846            $widget.on('slideprev', function (event) {
1847                if (swiper.isBeginning && params.loop) {
1848                    swiper.slideTo(swiper.slides.length - 1);
1849                } else {
1850                    swiper.slidePrev();
1851                }
1852            });
1853
1854            $previous.on('click', function () {
1855                $widget.triggerHandler('slideprev');
1856            });
1857
1858            $pages.on('click', function () {
1859                swiper.slideTo($(this).index());
1860            });
1861
1862            $widget.find('.lazy').on('lazyload', _.throttle(function () {
1863                swiper.update();
1864            }, 500));
1865
1866            if (swiper.params.autoHeight) {
1867                creatium.syncInterval(function () {
1868                    if (swiper.animating || !swiper.slides.length) return;
1869
1870                    var wrapperHeight = swiper.wrapperEl.clientHeight;
1871                    var slideHeight = swiper.slides[swiper.activeIndex].clientHeight;
1872                    if (wrapperHeight !== slideHeight) swiper.update();
1873                }, 40);
1874            }
1875        });
1876    });
1877});
1878
1879creatium.init.local(function ($root) {
1880    creatium.lazy.add($root.find('.widget-slider-gallery'), function init($widget) {
1881        if (!window.Swiper) return setTimeout(function () {
1882            init($widget);
1883        }, 50);
1884
1885        var filter = function () {
1886            return $(this).closest('.widget')[0] === $widget[0];
1887        };
1888
1889        var $container = $widget.find('.swiper-container').filter(filter);
1890        var $next = $widget.find('[cr-slider-next]').filter(filter);
1891        var $previous = $widget.find('[cr-slider-previous]').filter(filter);
1892        var $pages = $widget.find('[cr-slider-page]').filter(filter);
1893        var $index = $widget.find('[cr-slider-index]').filter(filter);
1894
1895        var params = $container.data();
1896
1897        var swiper = new Swiper($container.get(0), {
1898            nested: $widget.closest('.swiper-container').length,
1899            autoHeight: params.fixheight === false,
1900            autoplay: params.auto ? {
1901                delay: params.pause,
1902                stopOnLastSlide: !params.loop,
1903            } : false,
1904            allowTouchMove: params.touch,
1905            effect: params.animated ? 'slide' : 'fade',
1906            fadeEffect: { crossFade: true },
1907            touchEventsTarget: 'container',
1908            mousewheelEventsTarged: 'container',
1909            on: {
1910                slideChange: function () {
1911                    $pages.filter('.is-active').removeClass('is-active');
1912                    $pages.eq(swiper.activeIndex).addClass('is-active');
1913
1914                    $index.text(swiper.activeIndex + 1);
1915
1916                    swiper.oldActiveIndex = swiper.activeIndex;
1917                },
1918            },
1919        });
1920        $widget.data('api-swiper', swiper);
1921
1922        swiper._params = params;
1923        swiper.oldActiveIndex = swiper.activeIndex;
1924
1925        $widget.on('slidenext', function (event) {
1926            if (swiper.isEnd) {
1927                swiper.slideTo(0);
1928            } else {
1929                swiper.slideNext();
1930            }
1931        });
1932
1933        $next.on('click', function () {
1934            $widget.triggerHandler('slidenext');
1935        });
1936
1937        $widget.on('slideprev', function (event) {
1938            if (swiper.isBeginning) {
1939                swiper.slideTo(swiper.slides.length - 1);
1940            } else {
1941                swiper.slidePrev();
1942            }
1943        });
1944
1945        $previous.on('click', function () {
1946            $widget.triggerHandler('slideprev');
1947        });
1948
1949        $pages.on('click', function () {
1950            swiper.slideTo($(this).index());
1951        });
1952
1953        // для нормальной инициации внутри модального окна
1954        creatium.lazy.add($widget, function () {
1955            swiper.update();
1956        });
1957
1958        $widget.find('.lazy').on('lazyload', function () {
1959            swiper.update();
1960        });
1961    });
1962});
1963
1964/*
1965 *  @author Vikky Shostak https://koddr.me
1966 *  @copyright Copyright (c) 2016, Koddr
1967 *  @license http://opensource.org/licenses/MIT The MIT License (MIT)
1968 *  @version 3.2.9 at 12/09/2016 (22:45)
1969 *
1970 *  goodshare.js
1971 *
1972 *  Useful jQuery plugin that will help your website visitors share a link on
1973 *  social networks and microblogs. Easy to install and configuring on any of
1974 *  your website!
1975 *
1976 *  @category jQuery plugin
1977 */
1978;(function ($, window, document, undefined) {
1979  $(document).ready(function () {
1980    /*
1981     *  Variables
1982     */
1983    var metaOGDescription = $('meta[property="og:description"]').attr('content') || '';
1984    var metaOGImage = $('meta[property="og:image"]').attr('content') || '';
1985    /*
1986     *  Main function
1987     */
1988    goodshare = {
1989      init: function (_element, _options) {
1990        /*
1991         *  Default options:
1992         *
1993         *  type = vk
1994         *  url = current browser adress stroke
1995         *  title = current document <title>
1996         *  text = current document <meta property="og:description" ... />
1997         *  image = current document <meta property="og:image" ... />
1998         */
1999        var self = goodshare, options = $.extend({
2000          type: 'vk',
2001          url: location.href,
2002          title: document.title,
2003          text: metaOGDescription,
2004          image: metaOGImage
2005        }, $(_element).data(), _options);
2006        /*
2007         *  Open popup
2008         */
2009        if (self.popup(link = self[options.type](options)) !== null) return false;
2010      },
2011      /*
2012       *  Share link > Vkontakte
2013       *  @see http://vk.com
2014       */
2015      vk: function (_options) {
2016        var options = $.extend({
2017          url: location.href,
2018          title: document.title,
2019          text: metaOGDescription,
2020          image: metaOGImage
2021        }, _options);
2022        return 'http://vk.com/share.php?'
2023          + 'url=' + encodeURIComponent(options.url)
2024          + '&title=' + encodeURIComponent(options.title)
2025          + '&description=' + encodeURIComponent(options.text)
2026          + '&image=' + encodeURIComponent(options.image);
2027      },
2028      /*
2029       *  Share link > Odnoklassniki
2030       *  @see http://ok.ru
2031       */
2032      ok: function (_options) {
2033        var options = $.extend({
2034          url: location.href,
2035          title: document.title
2036        }, _options);
2037        return 'http://www.odnoklassniki.ru/dk?st.cmd=addShare&st.s=1'
2038          + '&st.comments=' + encodeURIComponent(options.title)
2039          + '&st._surl=' + encodeURIComponent(options.url);
2040      },
2041      /*
2042       *  Share link > Facebook
2043       *  @see http://facebook.com
2044       */
2045      fb: function (_options) {
2046        var options = $.extend({
2047          url: location.href,
2048          title: document.title
2049        }, _options);
2050        return 'https://facebook.com/sharer/sharer.php?'
2051          + 'u=' + encodeURIComponent(options.url);
2052      },
2053      /*
2054       *  Share link > LiveJournal
2055       *  @see http://livejournal.com
2056       */
2057      lj: function (_options) {
2058        var options = $.extend({
2059          url: location.href,
2060          title: document.title,
2061          text: metaOGDescription
2062        }, _options);
2063        return 'http://livejournal.com/update.bml?'
2064          + 'subject=' + encodeURIComponent(options.title)
2065          + '&event=' + encodeURIComponent('<a href="' + options.url + '">' + options.title + '</a> ' + options.text);
2066      },
2067      /*
2068       *  Share link > Twitter
2069       *  @see http://twitter.com
2070       */
2071      tw: function (_options) {
2072        var options = $.extend({
2073          url: location.href,
2074          title: document.title
2075        }, _options);
2076        return 'http://twitter.com/share?'
2077          + 'url=' + encodeURIComponent(options.url)
2078          + '&text=' + encodeURIComponent(options.title);
2079      },
2080      /*
2081       *  Share link > Google Plus
2082       *  @see http://plus.google.com
2083       */
2084      gp: function (_options) {
2085        var options = $.extend({
2086          url: location.href
2087        }, _options);
2088        return 'https://plus.google.com/share?'
2089          + 'url=' + encodeURIComponent(options.url);
2090      },
2091      /*
2092       *  Share link > [email protected]
2093       *  @see http://my.mail.ru
2094       */
2095      mr: function (_options) {
2096        var options = $.extend({
2097          url: location.href,
2098          title: document.title,
2099          text: metaOGDescription,
2100          image: metaOGImage
2101        }, _options);
2102        return 'http://connect.mail.ru/share?'
2103          + 'url=' + encodeURIComponent(options.url)
2104          + '&title=' + encodeURIComponent(options.title)
2105          + '&description=' + encodeURIComponent(options.text)
2106          + '&imageurl=' + encodeURIComponent(options.image);
2107      },
2108      /*
2109       *  Share link > LinkedIn
2110       *  @see http://linkedin.com
2111       */
2112      li: function (_options) {
2113        var options = $.extend({
2114          url: location.href,
2115          title: document.title,
2116          text: metaOGDescription
2117        }, _options);
2118        return 'http://www.linkedin.com/shareArticle?'
2119          + 'url=' + encodeURIComponent(options.url)
2120          + '&text=' + encodeURIComponent(options.title)
2121          + '&summary=' + encodeURIComponent(options.text)
2122          + '&mini=true';
2123      },
2124      /*
2125       *  Share link > tumblr
2126       *  @see http://tumblr.com
2127       */
2128      tm: function (_options) {
2129        var options = $.extend({
2130          url: location.href,
2131          title: document.title,
2132          text: metaOGDescription
2133        }, _options);
2134        return 'https://www.tumblr.com/widgets/share/tool?'
2135          + 'canonicalUrl=' + encodeURIComponent(options.url)
2136          + '&title=' + encodeURIComponent(options.title)
2137          + '&caption=' + encodeURIComponent(options.text)
2138          + '&posttype=link';
2139      },
2140      /*
2141       *  Share link > Blogger
2142       *  @see https://www.blogger.com
2143       */
2144      bl: function (_options) {
2145        var options = $.extend({
2146          url: location.href,
2147          title: document.title
2148        }, _options);
2149        return 'https://www.blogger.com/blog-this.g?'
2150          + 'u=' + encodeURIComponent(options.url)
2151          + '&n=' + encodeURIComponent(options.title);
2152      },
2153      /*
2154       *  Share link > Pinterest
2155       *  @see http://www.pinterest.com
2156       */
2157      pt: function (_options) {
2158        var options = $.extend({
2159          url: location.href,
2160          title: document.title,
2161          image: $('meta[property="og:image"]').attr('content')
2162        }, _options);
2163        return 'https://www.pinterest.com/pin/create/button/?'
2164          + 'url=' + encodeURIComponent(options.url)
2165          + '&media=' + encodeURIComponent(options.image)
2166          + '&description=' + encodeURIComponent(options.title);
2167      },
2168      /*
2169       *  Share link > Evernote
2170       *  @see http://www.evernote.com
2171       */
2172      en: function (_options) {
2173        var options = $.extend({
2174          url: location.href,
2175          title: document.title,
2176          text: metaOGDescription
2177        }, _options);
2178        return 'https://www.evernote.com/clip.action?'
2179          + 'url=' + encodeURIComponent(options.url)
2180          + '&title=' + encodeURIComponent(options.title)
2181          + '&body=' + encodeURIComponent(options.text + '<br/><a href="' + options.url + '">' + options.title + '</a>');
2182      },
2183      /*
2184       *  Share link > Digg
2185       *  @see http://www.digg.com
2186       */
2187      di: function (_options) {
2188        var options = $.extend({
2189          url: location.href,
2190          title: document.title
2191        }, _options);
2192        return 'http://digg.com/submit?'
2193          + 'url=' + encodeURIComponent(options.url)
2194          + '&title=' + encodeURIComponent(options.title);
2195      },
2196      /*
2197       *  Share link > Reddit
2198       *  @see http://www.reddit.com
2199       */
2200      rd: function (_options) {
2201        var options = $.extend({
2202          url: location.href,
2203          title: document.title
2204        }, _options);
2205        return 'http://www.reddit.com/submit?'
2206          + 'url=' + encodeURIComponent(options.url)
2207          + '&title=' + encodeURIComponent(options.title);
2208      },
2209      /*
2210       *  Share link > Delicious
2211       *  @see https://delicious.com
2212       */
2213      de: function (_options) {
2214        var options = $.extend({
2215          url: location.href,
2216          title: document.title
2217        }, _options);
2218        return 'https://delicious.com/save?'
2219          + 'url=' + encodeURIComponent(options.url)
2220          + '&title=' + encodeURIComponent(options.title);
2221      },
2222      /*
2223       *  Share link > StumbleUpon
2224       *  @see http://www.stumbleupon.com
2225       */
2226      su: function (_options) {
2227        var options = $.extend({
2228          url: location.href,
2229          title: document.title
2230        }, _options);
2231        return 'http://www.stumbleupon.com/submit?'
2232          + 'url=' + encodeURIComponent(options.url)
2233          + '&title=' + encodeURIComponent(options.title);
2234      },
2235      /*
2236       *  Share link > Pocket
2237       *  @see https://getpocket.com
2238       */
2239      po: function (_options) {
2240        var options = $.extend({
2241          url: location.href,
2242          title: document.title
2243        }, _options);
2244        return 'https://getpocket.com/save?'
2245          + 'url=' + encodeURIComponent(options.url)
2246          + '&title=' + encodeURIComponent(options.title);
2247      },
2248      /*
2249       *  Share link > Surfingbird
2250       *  @see http://www.surfingbird.ru
2251       */
2252      sb: function (_options) {
2253        var options = $.extend({
2254          url: location.href,
2255          title: document.title,
2256          text: metaOGDescription
2257        }, _options);
2258        return 'http://surfingbird.ru/share?'
2259          + 'url=' + encodeURIComponent(options.url)
2260          + '&title=' + encodeURIComponent(options.title)
2261          + '&description=' + encodeURIComponent(options.text);
2262      },
2263      /*
2264       *  Share link > LiveInternet
2265       *  @see http://www.liveinternet.ru
2266       */
2267      lr: function (_options) {
2268        var options = $.extend({
2269          url: location.href,
2270          title: document.title
2271        }, _options);
2272        return 'http://www.liveinternet.ru/journal_post.php?action=n_add&'
2273          + 'cnurl=' + encodeURIComponent(options.url)
2274          + '&cntitle=' + encodeURIComponent(options.title);
2275      },
2276      /*
2277       *  Share link > Buffer
2278       *  @see http://buffer.com
2279       */
2280      bf: function (_options) {
2281        var options = $.extend({
2282          url: location.href,
2283          title: document.title
2284        }, _options);
2285        return 'https://buffer.com/add?'
2286          + 'url=' + encodeURIComponent(options.url)
2287          + '&text=' + encodeURIComponent(options.title);
2288      },
2289      /*
2290       *  Share link > Instapaper
2291       *  @see https://www.instapaper.com
2292       */
2293      ip: function (_options) {
2294        var options = $.extend({
2295          url: location.href,
2296          title: document.title
2297        }, _options);
2298        return 'https://www.instapaper.com/edit?'
2299          + 'url=' + encodeURIComponent(options.url)
2300          + '&title=' + encodeURIComponent(options.title);
2301      },
2302      /*
2303       *  Share link > Readability
2304       *  @see http://www.readability.com
2305       */
2306      ra: function (_options) {
2307        var options = $.extend({
2308          url: location.href
2309        }, _options);
2310        return 'http://www.readability.com/save?'
2311          + 'url=' + encodeURIComponent(options.url);
2312      },
2313      /*
2314       *  Share link > Xing
2315       *  @see https://www.xing.com
2316       */
2317      xi: function (_options) {
2318        var options = $.extend({
2319          url: location.href
2320        }, _options);
2321        return 'https://www.xing.com/spi/shares/new?'
2322          + 'url=' + encodeURIComponent(options.url);
2323      },
2324      /*
2325       *  Share link > WordPress
2326       *  @see https://www.wordpress.com
2327       */
2328      wp: function (_options) {
2329        var options = $.extend({
2330          url: location.href,
2331          title: document.title,
2332          text: metaOGDescription,
2333          image: metaOGImage
2334        }, _options);
2335        return 'https://wordpress.com/wp-admin/press-this.php?'
2336          + 'u=' + encodeURIComponent(options.url)
2337          + '&t=' + encodeURIComponent(options.title)
2338          + '&s=' + encodeURIComponent(options.text)
2339          + '&i=' + encodeURIComponent(options.image)
2340          + '&v=2'
2341      },
2342      /*
2343       *  Share link > Baidu
2344       *  @see http://www.baidu.com
2345       */
2346      bd: function (_options) {
2347        var options = $.extend({
2348          url: location.href,
2349          title: document.title,
2350          text: metaOGDescription
2351        }, _options);
2352        return 'http://cang.baidu.com/do/add?'
2353          + 'it=' + encodeURIComponent(options.title)
2354          + '&iu=' + encodeURIComponent(options.url)
2355          + '&dc=' + encodeURIComponent(options.text)
2356          + '&fr=ien';
2357      },
2358      /*
2359       *  Share link > Renren
2360       *  @see http://www.renren.com
2361       */
2362      rr: function (_options) {
2363        var options = $.extend({
2364          url: location.href,
2365          title: document.title
2366        }, _options);
2367        return 'http://share.renren.com/share/buttonshare.do?'
2368          + 'link=' + encodeURIComponent(options.url)
2369          + '&title=' + encodeURIComponent(options.title);
2370      },
2371      /*
2372       *  Share link > Weibo
2373       *  @see http://www.weibo.com
2374       */
2375      wb: function (_options) {
2376        var options = $.extend({
2377          url: location.href,
2378          title: document.title
2379        }, _options);
2380        return 'http://service.weibo.com/share/share.php?'
2381          + 'url=' + encodeURIComponent(options.url)
2382          + '&title=' + encodeURIComponent(options.title);
2383      },
2384      /*
2385       *  Mobile > Share link > Telegram
2386       *  @see https://telegram.org/faq
2387       *  @category iOS, Android devices
2388       */
2389      tg: function (_options) {
2390        var options = $.extend({
2391          url: location.href,
2392          title: document.title
2393        }, _options);
2394        return 'tg://msg?'
2395          + 'text=' + encodeURIComponent(options.title + ' ' + options.url);
2396      },
2397      /*
2398       *  Mobile > Share link > Viber
2399       *  @see http://www.viber.com/ru/developers/share_on_viber
2400       *  @category iOS, Android devices
2401       */
2402      vi: function (_options) {
2403        var options = $.extend({
2404          url: location.href,
2405          title: document.title
2406        }, _options);
2407        return 'viber://forward?'
2408          + 'text=' + encodeURIComponent(options.title + ' ' + options.url);
2409      },
2410      /*
2411       *  Mobile > Share link > WhatsApp
2412       *  @see http://whatsapp-sharing.com
2413       *  @category iOS, Android devices
2414       */
2415      wa: function (_options) {
2416        var options = $.extend({
2417          url: location.href,
2418          title: document.title
2419        }, _options);
2420        return 'whatsapp://send?'
2421          + 'text=' + encodeURIComponent(options.title + ' ' + options.url);
2422      },
2423      /*
2424       *  Mobile > Share link > LINE
2425       *  @see https://media.line.me/howto/en/
2426       *  @category iOS, Android devices
2427       */
2428      ln: function (_options) {
2429        var options = $.extend({
2430          url: location.href,
2431          title: document.title
2432        }, _options);
2433        return 'line://msg/text/'
2434          + encodeURIComponent(options.title + ' ' + options.url);
2435      },
2436      /*
2437       *  Popup window
2438       */
2439      popup: function (url) {
2440        return window.open(url, '', 'left=' + (screen.width - 630) / 2 + ',top=' + (screen.height - 440) / 2 + ',toolbar=0,status=0,scrollbars=0,menubar=0,location=0,width=630,height=440');
2441      }
2442    };
2443    /*
2444     *  Function getCount()
2445     *  Set count to all elements with data-counter attribute.
2446     *
2447     *  @example $(document).getCount(); // Get all counters
2448     */
2449    $.fn.getCount = function () {
2450      /*
2451       *  Function roundCount()
2452       *  Return rounded and pretty value of share count.
2453       *
2454       *  @example roundCount(response.shares) // Rounded value of Facebook counter
2455       */
2456      var roundCount = function (number) {
2457        if (number > 999 && number <= 999999) var result = number / 1000 + 'k';
2458        else if (number > 999999) var result = '>1M';
2459        else var result = number;
2460        return result;
2461      };
2462      /*
2463       *  Function existCount()
2464       *  Check exist counter element.
2465       *
2466       *  @example existCount('[data-counter="fb"]') // Checked exist Facebook counter element
2467       */
2468      var existCount = function (element) {
2469        return ($(element).length > 0);
2470      };
2471      /*
2472       *  Share counter > Vkontakte
2473       *  @see http://vk.com/dev
2474       */
2475      if (existCount('[data-counter="vk"]')) {
2476        $.getJSON('https://vk.com/share.php?act=count&index=1&url=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2477        });
2478        if (!window.VK) VK = {};
2479        VK.Share = {
2480          count: function (index, count) {
2481            $('[data-counter="vk"]').text(roundCount(count));
2482          }
2483        };
2484      }
2485      ;
2486      /*
2487       *  Share counter > Facebook
2488       *  @see https://developers.facebook.com
2489       */
2490      if (existCount('[data-counter="fb"]')) {
2491        $.getJSON('https://graph.facebook.com/?id=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2492          if (response.share === undefined) $('[data-counter="fb"]').text('0');
2493          else $('[data-counter="fb"]').text(roundCount(response.share.share_count));
2494        });
2495      }
2496      ;
2497      /*
2498       *	Share counter > Odnoklassniki
2499       *	@see https://apiok.ru
2500       */
2501      if (existCount('[data-counter="ok"]')) {
2502        $.getJSON('https://connect.ok.ru/dk?st.cmd=extLike&uid=1&ref=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2503        });
2504        if (!window.ODKL) ODKL = {};
2505        ODKL.updateCount = function (index, count) {
2506          $('[data-counter="ok"]').text(roundCount(count));
2507        };
2508      }
2509      ;
2510      /*
2511       *  Share counter > Google Plus
2512       *  @see https://developers.google.com/+/
2513       */
2514      if (existCount('[data-counter="gp"]')) {
2515        $.ajax({
2516          type: 'POST',
2517          url: 'https://clients6.google.com/rpc',
2518          processData: true,
2519          contentType: 'application/json',
2520          data: JSON.stringify({
2521            'method': 'pos.plusones.get',
2522            'id': location.href,
2523            'params': {
2524              'nolog': true,
2525              'id': location.href,
2526              'source': 'widget',
2527              'userId': '@viewer',
2528              'groupId': '@self'
2529            },
2530            'jsonrpc': '2.0',
2531            'key': 'p',
2532            'apiVersion': 'v1'
2533          }),
2534          success: function (response) {
2535            $('[data-counter="gp"]').text(roundCount(response.result.metadata.globalCounts.count));
2536          }
2537        });
2538      }
2539      ;
2540      /*
2541       *  Share counter > [email protected]
2542       *  @see http://api.mail.ru
2543       */
2544      if (existCount('[data-counter="mr"]')) {
2545        $.getJSON('https://connect.mail.ru/share_count?url_list=' + encodeURIComponent(location.href) + '&callback=1&func=?', function (response) {
2546          var url = encodeURIComponent(location.href);
2547          for (var url in response) {
2548            if (response.hasOwnProperty(url)) {
2549              var count = response[url].shares;
2550              break;
2551            }
2552          }
2553          if ($.isEmptyObject(response)) $('[data-counter="mr"]').text('0');
2554          else $('[data-counter="mr"]').text(roundCount(count));
2555        });
2556      }
2557      ;
2558      /*
2559       *  Share counter > LinkedIn
2560       *  @see https://developer.linkedin.com
2561       */
2562      if (existCount('[data-counter="li"]')) {
2563        $.getJSON('https://www.linkedin.com/countserv/count/share?url=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2564          $('[data-counter="li"]').text(roundCount(response.count));
2565        });
2566      }
2567      /*
2568       *  Share counter > tumblr
2569       *  @see https://www.tumblr.com/developers
2570       */
2571      if (existCount('[data-counter="tm"]')) {
2572        $.getJSON('https://api.tumblr.com/v2/share/stats?url=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2573          $('[data-counter="tm"]').text(roundCount(response.response.note_count));
2574        });
2575      }
2576      ;
2577      /*
2578       *  Share counter > Pinterest
2579       *  @see https://developers.pinterest.com
2580       */
2581      if (existCount('[data-counter="pt"]')) {
2582        $.getJSON('https://api.pinterest.com/v1/urls/count.json?url=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2583          $('[data-counter="pt"]').text(roundCount(response.count));
2584        });
2585      }
2586      ;
2587      /*
2588       *  Share counter > Reddit
2589       *  @see https://www.reddit.com/dev/api
2590       */
2591      if (existCount('[data-counter="rd"]')) {
2592        $.getJSON('https://www.reddit.com/api/info.json?url=' + encodeURIComponent(location.href) + '&jsonp=?', function (response) {
2593          var count = response.data.children;
2594          if (count.length === 0) $('[data-counter="rd"]').text('0');
2595          else $('[data-counter="rd"]').text(roundCount(count[0].data.score));
2596        });
2597      }
2598      ;
2599      /*
2600       *  Share counter > StumbleUpon
2601       *  @see http://help.stumbleupon.com
2602       */
2603      if (existCount('[data-counter="su"]')) {
2604        $.getJSON('https://query.yahooapis.com/v1/public/yql?q='
2605          + encodeURIComponent('select * from html where url="http://www.stumbleupon.com/services/1.01/badge.getinfo?url=' + location.href + '" and xpath="*"') + '&format=json&callback=?', function (response) {
2606          var count = $.parseJSON(response.query.results.html.body);
2607          if (count.result.views === undefined) $('[data-counter="su"]').text('0');
2608          else $('[data-counter="su"]').text(roundCount(count.result.views));
2609        });
2610      }
2611      ;
2612      /*
2613       *  Share counter > Pocket
2614       *  @see https://widgets.getpocket.com/v1/button?count=horizontal&url=[URL_HERE]
2615       */
2616      if (existCount('[data-counter="po"]')) {
2617        $.getJSON('https://query.yahooapis.com/v1/public/yql?q='
2618          + encodeURIComponent('select * from html where url="https://widgets.getpocket.com/v1/button?count=horizontal&url=' + location.href + '" and xpath="*"') + '&format=json&callback=?', function (response) {
2619          $('[data-counter="po"]').text(roundCount(response.query.results.html.body.div.a.span.em.content));
2620        });
2621      }
2622      ;
2623      /*
2624       *  Share counter > Buffer
2625       *  @see https://buffer.com/developers
2626       */
2627      if (existCount('[data-counter="bf"]')) {
2628        $.getJSON('https://api.bufferapp.com/1/links/shares.json?url=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2629          $('[data-counter="bf"]').text(roundCount(response.shares));
2630        });
2631      }
2632      ;
2633      /*
2634       *  Share counter > Xing
2635       *  @see https://www.xing-share.com/app/share?op=get_share_button;counter=top;url=[URL_HERE]
2636       */
2637      if (existCount('[data-counter="xi"]')) {
2638        $.getJSON('https://query.yahooapis.com/v1/public/yql?q='
2639          + encodeURIComponent('select * from html where url="https://www.xing-share.com/app/share?op=get_share_button;counter=top;url=' + location.href + '" and xpath="*"') + '&format=json&callback=?', function (response) {
2640          $('[data-counter="xi"]').text(roundCount(response.query.results.html.body.div[0].div[0].span.content));
2641        });
2642      }
2643      ;
2644    };
2645    /*
2646     *  Init click.
2647     */
2648    $(document).on('click', '.goodshare', function (event) {
2649      event.preventDefault();
2650      goodshare.init(this);
2651    });
2652    /*
2653     *  Init share counters.
2654     */
2655    $(document).getCount();
2656  });
2657})(jQuery, window, document);
2658creatium.init.local(function ($root) {
2659    $root.find('.widget-spoiler').each(function () {
2660        var $widget = $(this);
2661
2662        var filter = function () {
2663            return $(this).closest('.widget-spoiler')[0] === $widget[0];
2664        };
2665
2666        var $toggle = $widget.find('[cr-spoiler-toggle]').filter(filter);
2667        var $container = $widget.find('[cr-spoiler-container]').filter(filter);
2668
2669        if ($container.hasClass('is-collapsed')) {
2670            creatium.lazy.add($widget, function ($el) {
2671                $container.show();
2672                creatium.lazy.force($container);
2673                $container.hide();
2674            });
2675        }
2676
2677        $widget.data('api-isCollapsed', $container.hasClass('is-collapsed'));
2678
2679        $widget.on('toggle', function (event) {
2680            // Чтобы внешние спойлеры не реагировали
2681            event.stopPropagation();
2682
2683            $widget.triggerHandler('api-before-toggle');
2684
2685            if ($widget.data('api-prevent')) {
2686                $widget.data('api-prevent', false);
2687                return;
2688            }
2689
2690            $toggle.toggleClass('is-collapsed');
2691            $container.toggleClass('is-collapsed');
2692
2693            $toggle.toggleClass('is-expanded');
2694            $container.toggleClass('is-expanded');
2695
2696            $container.stop().slideToggle().promise().always(function () {
2697                $widget.data('api-isCollapsed', !$widget.data('api-isCollapsed'));
2698
2699                $widget.triggerHandler('api-toggle');
2700            });
2701        });
2702
2703        $toggle.on('click', function (event) {
2704            $widget.trigger('toggle');
2705
2706            // На случай вложенных $toggle
2707            event.stopPropagation();
2708        });
2709    })
2710});
2711
2712creatium.init.local(function ($root) {
2713    creatium.lazy.add($root.find('.widget-stories-panel'), function ($widget) {
2714        $widget.find('[cr-stories-panel-highlight]').on('click', function handler(event) {
2715            var index = $(event.currentTarget).index();
2716
2717            var swiper = $('.modal[data-type="stories"]:visible').data('api-swiper');
2718
2719            if (swiper) swiper.slideTo(index);
2720            else setTimeout(handler.bind(this, event), 10);
2721        });
2722    });
2723});
2724creatium.init.local(function ($root) {
2725    creatium.lazy.add($root.find('.widget-tabs'), function init($widget) {
2726        if (!window.Swiper) return setTimeout(function () {
2727            init($widget);
2728        }, 50);
2729
2730        var filter = function () {
2731            return $(this).closest('.widget')[0] === $widget[0];
2732        };
2733
2734        var $container = $widget.find('.swiper-container').filter(filter);
2735        var $next = $widget.find('[cr-slider-next]').filter(filter);
2736        var $previous = $widget.find('[cr-slider-previous]').filter(filter);
2737        var $pages = $widget.find('[cr-slider-page]').filter(filter);
2738        var $index = $widget.find('[cr-slider-index]').filter(filter);
2739
2740        var params = $container.data();
2741
2742        var $icons = $widget.find('[cr-slider-page_icon]').filter(filter).filter(function () {
2743            return $(this).find('>.svgwrap').length > 1;
2744        });
2745        $icons.find('>.svgwrap').addClass('hidden');
2746
2747        var $labels = $widget.find('[cr-slider-page_label]').filter(filter)
2748            .filter(function () {
2749                return $(this).find('>.textable').length > 1;
2750            });
2751        $labels.find('>.textable').addClass('hidden');
2752
2753        var swiper = new Swiper($container.get(0), {
2754            nested: $widget.closest('.swiper-container').length,
2755            autoHeight: params.fixheight === false,
2756            autoplay: params.auto ? {
2757                delay: params.pause,
2758                stopOnLastSlide: !params.loop,
2759            } : false,
2760            allowTouchMove: params.touch,
2761            effect: params.animated ? 'slide' : 'fade',
2762            fadeEffect: { crossFade: true },
2763            touchEventsTarget: 'container',
2764            mousewheelEventsTarged: 'container',
2765            on: {
2766                slideChange: function () {
2767                    $pages.filter('.is-active').removeClass('is-active');
2768                    $pages.eq(swiper.activeIndex).addClass('is-active');
2769
2770                    setIcon(swiper.oldActiveIndex, swiper.activeIndex);
2771                    setImage(swiper.oldActiveIndex, swiper.activeIndex);
2772                    setLabel(swiper.oldActiveIndex, swiper.activeIndex);
2773
2774                    $index.text(swiper.activeIndex + 1);
2775
2776                    swiper.oldActiveIndex = swiper.activeIndex;
2777                },
2778            },
2779        });
2780        $widget.data('api-swiper', swiper);
2781
2782        swiper._params = params;
2783        swiper.oldActiveIndex = swiper.activeIndex;
2784
2785        setIcon(swiper.oldActiveIndex, swiper.activeIndex);
2786
2787        function setIcon(oldIndex, newIndex) {
2788            $icons.each(function () {
2789                var $svgwraps = $(this).children('.svgwrap');
2790                $svgwraps.eq(oldIndex).addClass('hidden');
2791                $svgwraps.eq(newIndex).removeClass('hidden');
2792            });
2793        }
2794
2795        setImage(swiper.oldActiveIndex, swiper.activeIndex);
2796
2797        function setImage(oldIndex, newIndex) {
2798            $icons.each(function () {
2799                var $images = $(this).children();
2800                $images.eq(oldIndex).addClass('hidden');
2801                $images.eq(newIndex).removeClass('hidden');
2802            });
2803        }
2804
2805        setLabel(swiper.oldActiveIndex, swiper.activeIndex);
2806
2807        function setLabel(oldIndex, newIndex) {
2808            $labels.each(function () {
2809                var $textables = $(this).children('.textable');
2810                $textables.eq(oldIndex).addClass('hidden');
2811                $textables.eq(newIndex).removeClass('hidden');
2812            });
2813        }
2814
2815        $widget.on('slidenext', function (event) {
2816            if (swiper.isEnd && params.loop) {
2817                swiper.slideTo(0);
2818            } else {
2819                swiper.slideNext();
2820            }
2821        });
2822
2823        $next.on('click', function () {
2824            $widget.triggerHandler('slidenext');
2825        });
2826
2827        $widget.on('slideprev', function (event) {
2828            if (swiper.isBeginning && params.loop) {
2829                swiper.slideTo(swiper.slides.length - 1);
2830            } else {
2831                swiper.slidePrev();
2832            }
2833        });
2834
2835        $previous.on('click', function () {
2836            $widget.triggerHandler('slideprev');
2837        });
2838
2839        $pages.on('click', function () {
2840            swiper.slideTo($(this).index());
2841        });
2842
2843        $widget.find('.lazy').on('lazyload', _.throttle(function () {
2844            swiper.update();
2845        }, 500));
2846
2847        if (swiper.params.autoHeight) {
2848            creatium.syncInterval(function () {
2849                if (swiper.animating || !swiper.slides.length) return;
2850
2851                var wrapperHeight = swiper.wrapperEl.clientHeight;
2852                var slideHeight = swiper.slides[swiper.activeIndex].clientHeight;
2853                if (wrapperHeight !== slideHeight) swiper.update();
2854            }, 40);
2855        }
2856    });
2857});
2858
2859creatium.init.local(function ($root) {
2860    $root.find('.widget-video').each(function () {
2861        var $widget = $(this);
2862
2863        var $modal = $widget.closest('.modal');
2864        $modal.on('hide', function() {
2865            var $iframeWrap = $widget.find('.video-wrapper');
2866            return $iframeWrap.attr('src', $iframeWrap.attr('src').replace('autoplay=1', 'autoplay=0'));
2867        });
2868    });
2869});
2870})($);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.