/*! elementor - v3.29.0 - 04-06-2025 */
"use strict";(self.webpackChunkelementorFrontend=self.webpackChunkelementorFrontend||[]).push([[457],{3905:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,n(4846),n(6211);class Counter extends elementorModules.frontend.handlers.Base{getDefaultSettings(){return{selectors:{counterNumber:".elementor-counter-number"}}}getDefaultElements(){const e=this.getSettings("selectors");return{$counterNumber:this.$element.find(e.counterNumber)}}onInit(){super.onInit(),this.intersectionObserver=elementorModules.utils.Scroll.scrollObserver({callback:e=>{if(e.isInViewport){this.intersectionObserver.unobserve(this.elements.$counterNumber[0]);const e=this.elements.$counterNumber.data(),t=e.toValue.toString().match(/\.(.*)/);t&&(e.rounding=t[1].length),this.elements.$counterNumber.numerator(e)}}}),this.intersectionObserver.observe(this.elements.$counterNumber[0])}}t.default=Counter}}]);// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function bracketFolding(pairs) {
return function(cm, start) {
var line = start.line, lineText = cm.getLine(line);
function findOpening(pair) {
var tokenType;
for (var at = start.ch, pass = 0;;) {
var found = at <= 0 ? -1 : lineText.lastIndexOf(pair[0], at - 1);
if (found == -1) {
if (pass == 1) break;
pass = 1;
at = lineText.length;
continue;
}
if (pass == 1 && found < start.ch) break;
tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
if (!/^(comment|string)/.test(tokenType)) return {ch: found + 1, tokenType: tokenType, pair: pair};
at = found - 1;
}
}
function findRange(found) {
var count = 1, lastLine = cm.lastLine(), end, startCh = found.ch, endCh
outer: for (var i = line; i <= lastLine; ++i) {
var text = cm.getLine(i), pos = i == line ? startCh : 0;
for (;;) {
var nextOpen = text.indexOf(found.pair[0], pos), nextClose = text.indexOf(found.pair[1], pos);
if (nextOpen < 0) nextOpen = text.length;
if (nextClose < 0) nextClose = text.length;
pos = Math.min(nextOpen, nextClose);
if (pos == text.length) break;
if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == found.tokenType) {
if (pos == nextOpen) ++count;
else if (!--count) { end = i; endCh = pos; break outer; }
}
++pos;
}
}
if (end == null || line == end) return null
return {from: CodeMirror.Pos(line, startCh),
to: CodeMirror.Pos(end, endCh)};
}
var found = []
for (var i = 0; i < pairs.length; i++) {
var open = findOpening(pairs[i])
if (open) found.push(open)
}
found.sort(function(a, b) { return a.ch - b.ch })
for (var i = 0; i < found.length; i++) {
var range = findRange(found[i])
if (range) return range
}
return null
}
}
CodeMirror.registerHelper("fold", "brace", bracketFolding([["{", "}"], ["[", "]"]]));
CodeMirror.registerHelper("fold", "brace-paren", bracketFolding([["{", "}"], ["[", "]"], ["(", ")"]]));
CodeMirror.registerHelper("fold", "import", function(cm, start) {
function hasImport(line) {
if (line < cm.firstLine() || line > cm.lastLine()) return null;
var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
if (start.type != "keyword" || start.string != "import") return null;
// Now find closing semicolon, return its position
for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) {
var text = cm.getLine(i), semi = text.indexOf(";");
if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)};
}
}
var startLine = start.line, has = hasImport(startLine), prev;
if (!has || hasImport(startLine - 1) || ((prev = hasImport(startLine - 2)) && prev.end.line == startLine - 1))
return null;
for (var end = has.end;;) {
var next = hasImport(end.line + 1);
if (next == null) break;
end = next.end;
}
return {from: cm.clipPos(CodeMirror.Pos(startLine, has.startCh + 1)), to: end};
});
CodeMirror.registerHelper("fold", "include", function(cm, start) {
function hasInclude(line) {
if (line < cm.firstLine() || line > cm.lastLine()) return null;
var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8;
}
var startLine = start.line, has = hasInclude(startLine);
if (has == null || hasInclude(startLine - 1) != null) return null;
for (var end = startLine;;) {
var next = hasInclude(end + 1);
if (next == null) break;
++end;
}
return {from: CodeMirror.Pos(startLine, has + 1),
to: cm.clipPos(CodeMirror.Pos(end))};
});
});
@font-face{font-family:elementskit;src:url(../fonts/elementskit.woff?fuwixw) format('woff');font-weight:400;font-style:normal}.ekit{font-family:elementskit!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ekit-logo:before{content:"\e947"}.ekit-degree-image:before{content:"\e900"}.ekit-accordion:before{content:"\e901"}.ekit-animated-flip-box:before{content:"\e902"}.ekit-animated-text:before{content:"\e903"}.ekit-brands:before{content:"\e904"}.ekit-business-hour:before{content:"\e905"}.ekit-button:before{content:"\e906"}.ekit-carousel:before{content:"\e907"}.ekit-Circle-progress:before{content:"\e908"}.ekit-contact-form:before{content:"\e909"}.ekit-countdown-timer:before{content:"\e90a"}.ekit-download-button:before{content:"\e90b"}.ekit-dropbar:before{content:"\e90c"}.ekit-elements-kit-logo:before{content:"\e90d"}.ekit-faq:before{content:"\e90e"}.ekit-full-width-scroll:before{content:"\e90f"}.ekit-google-map:before{content:"\e910"}.ekit-heading-style:before{content:"\e911"}.ekit-help-desk:before{content:"\e912"}.ekit-horizontal-timeline:before{content:"\e913"}.ekit-iframe:before{content:"\e914"}.ekit-image-comparison:before{content:"\e915"}.ekit-image-gallery:before{content:"\e916"}.ekit-image-justify:before{content:"\e917"}.ekit-image-magnifier:before{content:"\e918"}.ekit-image-masonry:before{content:"\e919"}.ekit-inline-svg:before{content:"\e91a"}.ekit-instagram:before{content:"\e91b"}.ekit-listing:before{content:"\e91c"}.ekit-music-player:before{content:"\e91d"}.ekit-news-ticker:before{content:"\e91e"}.ekit-off-canvus-menu:before{content:"\e91f"}.ekit-parallax:before{content:"\e920"}.ekit-portfolio:before{content:"\e921"}.ekit-post-banner:before{content:"\e922"}.ekit-post-carousel:before{content:"\e923"}.ekit-post-grid:before{content:"\e924"}.ekit-post-slider:before{content:"\e925"}.ekit-pricing-list:before{content:"\e926"}.ekit-pricing-table:before{content:"\e927"}.ekit-product-featured:before{content:"\e928"}.ekit-product-image:before{content:"\e929"}.ekit-product-recent:before{content:"\e92a"}.ekit-product-sale:before{content:"\e92b"}.ekit-product-top-rated:before{content:"\e92c"}.ekit-product-top-seller:before{content:"\e92d"}.ekit-progress-bar:before{content:"\e92e"}.ekit-protected-content-v2:before{content:"\e92f"}.ekit-protected-content-v3:before{content:"\e930"}.ekit-protected-content:before{content:"\e931"}.ekit-qr_code:before{content:"\e932"}.ekit-scroll-button:before{content:"\e933"}.ekit-search:before{content:"\e934"}.ekit-service:before{content:"\e935"}.ekit-slider-image:before{content:"\e936"}.ekit-social-share:before{content:"\e937"}.ekit-subscribe:before{content:"\e938"}.ekit-tab:before{content:"\e939"}.ekit-table:before{content:"\e93a"}.ekit-team-join:before{content:"\e93b"}.ekit-team-member:before{content:"\e93c"}.ekit-testimonial-carousel:before{content:"\e93d"}.ekit-testimonial-grid:before{content:"\e93e"}.ekit-testimonial-quote:before{content:"\e93f"}.ekit-testimonial-slider:before{content:"\e940"}.ekit-toggle:before{content:"\e941"}.ekit-user-login:before{content:"\e942"}.ekit-user-registration:before{content:"\e943"}.ekit-vertical-timeline:before{content:"\e944"}.ekit-video-player:before{content:"\e945"}.ekit-weather:before{content:"\e946"}.ekit-advanced-slider:before{content:"\e9c8"}.ekit-whatsapp:before{content:"\eb1e"}.ekit-image-box:before{content:"\ebd1"}.ekit-image-swap:before{content:"\eba4"}.ekit-image-hover-effect:before{content:"\ebea"}.ekit-audio-player:before{content:"\ebeb"}.ekit-category-list:before{content:"\ebec"}.ekit-fancy-heading:before{content:"\ebed"}.ekit-google-review:before{content:"\ebee"}.ekit-image-masking:before{content:"\ebef"}.ekit-image-morphing:before{content:"\ebf0"}.ekit-page-list:before{content:"\ebf1"}.ekit-post-list:before{content:"\ebf2"}.ekit-price-menu:before{content:"\ebf3"}.ekit-stylish-list:before{content:"\ebf4"}.ekit-advanced-tooltip:before{content:"\ebf5"}.ekit-avatar:before{content:"\ebf6"}.ekit-content-ticker:before{content:"\ebf7"}.ekit-coupon-code:before{content:"\ebf8"}.ekit-flip-box:before{content:"\ebf9"}.ekit-next-dark:before{content:"\ebfa"}.ekit-onepage-scroll:before{content:"\ebfb"}.ekit-pause-dark:before{content:"\ebfc"}.ekit-previous-dark:before{content:"\ebfd"}.ekit-team-carousel-slider:before{content:"\ebfe"}.ekit-volume-cross:before{content:"\ebff"}.ekit-volume-dark:before{content:"\ec00"}.ekit-volume-high-dark:before{content:"\ec01"}.ekit-volume-low-dark:before{content:"\ec02"}.ekit-volume-mute:before{content:"\ec03"}.ekit-youtube-feed:before{content:"\ec04"}.ekit-behance:before{content:"\eb4e"}.ekit-dribbble::before{content:"\eb47"}.ekit-pinterest::before{content:"\eb50"}.ekit-interactive-link::before{content:"\ec05"}.elementor-panel .elementor-element .title{padding:0 5px}.elementor-panel .elementor-element .icon{position:relative}.ekit-widget-icon{min-height:30px;display:block;font-size:28px}.ekit-widget-icon:after{content:'EKIT';position:absolute;top:3px;right:3px;color:#556068;font-size:9px;border:1px solid #dedede;font-weight:400;padding:1px 2px;line-height:10px;display:inline-block;border-radius:2px;font-family:"Open Sans",Roboto,Helvetica,Arial,sans-serif}.elementor-element-wrapper:hover .ekit-widget-icon:after{color:#d30c5c}#elementor-panel-category-elementskit .elementor-element{max-height:85px}.elementor-editor-dark-mode .ekit-widget-icon:after{color:#e0e1e3;border:1px solid #dedede45}.elementor-editor-dark-mode .elementor-element-wrapper:hover .ekit-widget-icon:after{color:#71d7f7}.elementor-control-create-meeting.elementor-control-type-button .elementor-button{padding:10px 20px;height:auto}.elementor-control-create-meeting.elementor-control-type-button .elementor-control-input-wrapper{margin:auto;text-align:center}.elementor-control-create-meeting.elementor-control-type-button.open .elementor-state-icon{position:absolute;top:9px;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);display:block;color:#fff}.elementor-control-create-meeting.elementor-control-type-button.open .elementor-button{color:#39b54a}.elementor-control-create-meeting.elementor-control-type-button .alert{position:relative;padding:.75rem 1.25rem;margin-top:1rem;border:1px solid transparent;border-radius:.25rem}.elementor-control-create-meeting.elementor-control-type-button .alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.elementor-control-create-meeting.elementor-control-type-button .alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.ekit-zoom-host-icon{font-size:20px;position:relative;top:2px;cursor:pointer}!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=1)}([function(e,t){e.exports=React},function(e,t,n){n(2),e.exports=n(3)},function(e,t,n){"use strict"},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(4),o=n.n(r),i=n(5);o()(window).on("et_builder_api_ready",function(e,t){t.registerModules(i.a)})},function(e,t){e.exports=jQuery},function(e,t,n){"use strict";var r=n(6),o=n(7);t.a=[r.a,o.a]},function(e,t,n){"use strict";var r=n(0),o=n.n(r);function i(e){return(i="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function a(e,t){for(var n=0;n {
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = void 0;
class AnchorLinks {
observer = null;
constructor($anchorLinks, classes) {
this.$anchorLinks = $anchorLinks;
this.activeAnchorClass = classes.activeAnchorItem;
this.anchorClass = classes.anchorItem;
}
getViewportHeight() {
return window.innerHeight;
}
bindEvents() {
this.onResize = this.onResize.bind(this);
window.addEventListener('resize', this.onResize);
}
initialize() {
this.viewPortHeight = this.getViewportHeight();
this.followMenuAnchors();
this.bindEvents();
}
followMenuAnchors() {
this.$anchorLinks.each((index, anchorLink) => {
if (location.pathname === anchorLink.pathname && '' !== anchorLink.hash) {
this.followMenuAnchor(jQuery(anchorLink));
}
});
}
followMenuAnchor($element) {
const $targetElement = $element.hasClass(this.anchorClass) ? $element : $element.closest(`.${this.anchorClass}`);
const anchorElement = this.getAnchorElement($element);
if (!anchorElement) {
return;
}
const options = this.getObserverOptions(anchorElement);
this.observer = this.createObserver($targetElement, $element, options);
this.observer.observe(anchorElement);
}
getAnchorElement($element) {
const anchorSelector = $element[0].hash;
try {
// `decodeURIComponent` for UTF8 characters in the hash.
const decodedSelector = decodeURIComponent(anchorSelector);
return document.querySelector(decodedSelector);
} catch (e) {
return null;
}
}
getObserverOptions(element) {
return {
root: null,
rootMargin: this.calculateRootMargin(element)
};
}
calculateRootMargin(element) {
const anchorHeight = element?.offsetHeight || 0;
const isAnchorHeightLargerThanHalfViewport = anchorHeight > this.viewPortHeight / 2;
const rootMarginBlockEnd = -1 * this.viewPortHeight / 2;
const rootMarginBlockStart = isAnchorHeightLargerThanHalfViewport ? rootMarginBlockEnd : 0;
return `${rootMarginBlockStart}px 0px ${rootMarginBlockEnd}px 0px`;
}
createObserver($targetElement, $element, options) {
return new IntersectionObserver(entries => {
entries.forEach(entry => {
$targetElement.toggleClass(this.activeAnchorClass, entry.isIntersecting);
$element.attr('aria-current', entry.isIntersecting ? 'location' : '');
});
}, options);
}
onResize() {
this.viewPortHeight = this.getViewportHeight();
if (this.observer) {
this.observer.disconnect();
}
this.followMenuAnchors();
}
}
exports["default"] = AnchorLinks;
/***/ }),
/***/ "../assets/dev/js/frontend/utils/flex-horizontal-scroll.js":
/*!*****************************************************************!*\
!*** ../assets/dev/js/frontend/utils/flex-horizontal-scroll.js ***!
\*****************************************************************/
/***/ ((__unused_webpack_module, exports) => {
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports.changeScrollStatus = changeScrollStatus;
exports.setHorizontalScrollAlignment = setHorizontalScrollAlignment;
exports.setHorizontalTitleScrollValues = setHorizontalTitleScrollValues;
function changeScrollStatus(element, event) {
if ('mousedown' === event.type) {
element.classList.add('e-scroll');
element.dataset.pageX = event.pageX;
} else {
element.classList.remove('e-scroll', 'e-scroll-active');
element.dataset.pageX = '';
}
}
// This function was written using this example https://codepen.io/thenutz/pen/VwYeYEE.
function setHorizontalTitleScrollValues(element, horizontalScrollStatus, event) {
const isActiveScroll = element.classList.contains('e-scroll'),
isHorizontalScrollActive = 'enable' === horizontalScrollStatus,
headingContentIsWiderThanWrapper = element.scrollWidth > element.clientWidth;
if (!isActiveScroll || !isHorizontalScrollActive || !headingContentIsWiderThanWrapper) {
return;
}
event.preventDefault();
const previousPositionX = parseFloat(element.dataset.pageX),
mouseMoveX = event.pageX - previousPositionX,
maximumScrollValue = 5,
stepLimit = 20;
let toScrollDistanceX = 0;
if (stepLimit < mouseMoveX) {
toScrollDistanceX = maximumScrollValue;
} else if (stepLimit * -1 > mouseMoveX) {
toScrollDistanceX = -1 * maximumScrollValue;
} else {
toScrollDistanceX = mouseMoveX;
}
element.scrollLeft = element.scrollLeft - toScrollDistanceX;
element.classList.add('e-scroll-active');
}
function setHorizontalScrollAlignment(_ref) {
let {
element,
direction,
justifyCSSVariable,
horizontalScrollStatus
} = _ref;
if (!element) {
return;
}
if (isHorizontalScroll(element, horizontalScrollStatus)) {
initialScrollPosition(element, direction, justifyCSSVariable);
} else {
element.style.setProperty(justifyCSSVariable, '');
}
}
function isHorizontalScroll(element, horizontalScrollStatus) {
return element.clientWidth < getChildrenWidth(element.children) && 'enable' === horizontalScrollStatus;
}
function getChildrenWidth(children) {
let totalWidth = 0;
const parentContainer = children[0].parentNode,
computedStyles = getComputedStyle(parentContainer),
gap = parseFloat(computedStyles.gap) || 0; // Get the gap value or default to 0 if it's not specified
for (let i = 0; i < children.length; i++) {
totalWidth += children[i].offsetWidth + gap;
}
return totalWidth;
}
function initialScrollPosition(element, direction, justifyCSSVariable) {
const isRTL = elementorFrontend.config.is_rtl;
switch (direction) {
case 'end':
element.style.setProperty(justifyCSSVariable, 'start');
element.scrollLeft = isRTL ? -1 * getChildrenWidth(element.children) : getChildrenWidth(element.children);
break;
default:
element.style.setProperty(justifyCSSVariable, 'start');
element.scrollLeft = 0;
}
}
/***/ }),
/***/ "../modules/mega-menu/assets/js/frontend/handlers/mega-menu.js":
/*!*********************************************************************!*\
!*** ../modules/mega-menu/assets/js/frontend/handlers/mega-menu.js ***!
\*********************************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js");
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = void 0;
var _utils = __webpack_require__(/*! ../utils */ "../modules/mega-menu/assets/js/frontend/utils.js");
var _anchorLink = _interopRequireDefault(__webpack_require__(/*! ../../../../../../assets/dev/js/frontend/utils/anchor-link */ "../assets/dev/js/frontend/utils/anchor-link.js"));
var _flexHorizontalScroll = __webpack_require__(/*! elementor-pro/frontend/utils/flex-horizontal-scroll */ "../assets/dev/js/frontend/utils/flex-horizontal-scroll.js");
class MegaMenu extends elementorModules.frontend.handlers.Base {
constructor() {
super(...arguments);
if (elementorFrontend.isEditMode()) {
this.lifecycleChangeListener = null;
}
this.resizeListener = null;
this.prevMouseY = null;
this.isKeyboardNavigation = false;
}
getDefaultSettings() {
return {
selectors: {
elementorWidgetWrapper: '.elementor-widget-n-menu',
widgetContainer: '.e-n-menu',
dropdownMenuToggle: '.e-n-menu-toggle',
menuWrapper: '.e-n-menu-wrapper',
headingContainer: '.e-n-menu-heading',
menuItem: '.e-n-menu-item',
tabTitle: '.e-n-menu-title',
tabTitleText: '.e-n-menu-title-text',
directTabTitle: ':scope > .elementor-widget-container > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-n-menu-item > .e-n-menu-title, :scope > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-n-menu-item > .e-n-menu-title',
tabClickableTitle: '.e-n-menu-title.e-click',
tabDropdown: '.e-n-menu-dropdown-icon',
menuContent: '.e-n-menu-content',
tabContent: '.e-n-menu-content > .e-con, .e-n-menu-heading > .e-con',
directTabContent: ':scope > .elementor-widget-container > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-n-menu-item > .e-n-menu-content > .e-con, :scope > .elementor-widget-container > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-con, :scope > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-n-menu-item > .e-n-menu-content > .e-con, :scope > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-con',
tabContentBeforeInterlacing: '> .elementor-widget-container > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-con, > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-con',
newContainerAfterRepeaterAction: '> .elementor-widget-container > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-con, > .elementor-widget-container > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-n-menu-item > .e-n-menu-content > .e-con:nth-child(2), > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-con, > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-n-menu-item > .e-n-menu-content > .e-con:nth-child(2)',
anchorLink: '.e-anchor a'
},
classes: {
active: 'e-active',
anchorItem: 'e-anchor',
activeAnchorItem: 'e-current'
},
dataAttributes: {
tabIndex: 'data-tab-index'
},
ariaAttributes: {
titleStateAttribute: 'aria-expanded',
activeTitleSelector: '[aria-expanded="true"]'
},
autoExpand: false,
autoFocus: false,
showTabFn: 'show',
hideTabFn: 'hide',
toggleSelf: false,
hidePrevious: true,
postUrl: 'post-url',
internalUrl: 'internal-url'
};
}
getDefaultElements() {
const selectors = this.getSettings('selectors');
return {
$tabContents: this.findElement(selectors.tabContent),
$widgetContainer: this.findElement(selectors.widgetContainer),
$dropdownMenuToggle: this.findElement(selectors.dropdownMenuToggle),
$menuWrapper: this.findElement(selectors.menuWrapper),
$menuContent: this.findElement(selectors.menuContent),
$headingContainer: this.findElement(selectors.headingContainer),
$menuItems: this.findElement(selectors.menuItem),
$tabTitles: this.findElement(selectors.tabTitle),
$tabDropdowns: this.findElement(selectors.tabDropdown),
$anchorLink: this.findElement(selectors.anchorLink),
$tabContentsBeforeInterlacing: this.findElement(selectors.tabContentBeforeInterlacing)
};
}
getTabTitleFilterSelector(tabIndex) {
return `[${this.getSettings('dataAttributes').tabIndex}="${tabIndex}"]`;
}
getTabIndex(tabTitleElement) {
return tabTitleElement.getAttribute(this.getSettings('dataAttributes').tabIndex);
}
setKeyboardNavigation(event) {
if ('Tab' === event.key) {
this.isKeyboardNavigation = true;
}
}
dropdownMenuHeightControllerConfig() {
const selectors = this.getSettings('selectors');
return {
elements: {
$element: this.$element,
$dropdownMenuContainer: this.$element.find(selectors.menuWrapper),
$menuToggle: this.$element.find(selectors.dropdownMenuToggle)
},
attributes: {
menuToggleState: 'aria-expanded'
},
settings: {
dropdownMenuContainerMaxHeight: 'auto',
menuHeightCssVarName: '--n-menu-dropdown-content-box-height'
}
};
}
handleContentContainerPosition() {
let $contentContainer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
this.resetContentContainersPosition();
// If no container is passed as an argument, check if there is an active container.
const activeTitleSelector = this.getSettings('ariaAttributes').activeTitleSelector,
tabIndex = this.elements.$tabDropdowns.filter(activeTitleSelector).attr('data-tab-index');
$contentContainer = $contentContainer || this.elements.$tabContents.filter(this.getTabContentFilterSelector(tabIndex));
if (!$contentContainer.length) {
return;
}
this.setContentContainerAbsolutePosition($contentContainer);
}
setContentContainerAbsolutePosition($contentContainer) {
const elementSettings = this.getElementSettings(),
isFitToContent = 'fit_to_content' === elementSettings.content_width;
if ((0, _utils.isMenuInDropdownMode)(elementSettings)) {
return;
}
if (isFitToContent) {
const direction = elementorFrontend.config.is_rtl ? 'right' : 'left',
menuItemContainerOffset = 0 < this.getMenuItemContainerAbsolutePosition($contentContainer) ? this.getMenuItemContainerAbsolutePosition($contentContainer) : 0;
$contentContainer.css(direction, menuItemContainerOffset);
}
const headingsHeight = this.elements.$headingContainer[0].getBoundingClientRect().height;
if (this.shouldPositionContentAbove($contentContainer, headingsHeight)) {
const contentContainerBoundingBox = $contentContainer[0].getBoundingClientRect();
$contentContainer.css({
width: isFitToContent ? 'max-content' : '',
'max-width': contentContainerBoundingBox.width
});
this.elements.$widgetContainer.addClass('content-above');
}
}
getMenuItemContainerAbsolutePosition($contentContainer) {
const tabIndex = $contentContainer.data('tab-index'),
$activeDropdown = this.elements.$tabDropdowns.filter(this.getTabTitleFilterSelector(tabIndex))[0],
$titleElement = $activeDropdown.closest(this.getSettings('selectors').tabTitle),
titleBoundingBox = $titleElement.getBoundingClientRect(),
contentContainerWidth = $contentContainer[0].clientWidth;
let menuItemContainerOffset = null;
switch (this.getElementSettings('content_horizontal_position')) {
case 'left':
menuItemContainerOffset = this.getLeftDirectionContainerOffset(contentContainerWidth, titleBoundingBox);
break;
case 'right':
menuItemContainerOffset = this.getRightDirectionContainerOffset(contentContainerWidth, titleBoundingBox);
break;
default:
menuItemContainerOffset = this.getCenteredContainerOffset(contentContainerWidth, titleBoundingBox);
}
return menuItemContainerOffset;
}
getCenteredContainerOffset(contentContainerWidth, titleBoundingBox) {
const menuItemContentContainerHalfWidth = contentContainerWidth / 2,
bodyWidth = elementorFrontend.elements.$body[0].clientWidth;
let titleMiddleOffset = this.adjustForScrollbarIfNeeded(titleBoundingBox.left + titleBoundingBox.width / 2);
if (elementorFrontend.config.is_rtl) {
titleMiddleOffset = bodyWidth - titleMiddleOffset;
}
let offset = titleMiddleOffset - menuItemContentContainerHalfWidth;
if (titleMiddleOffset + menuItemContentContainerHalfWidth > bodyWidth) {
offset = bodyWidth - contentContainerWidth;
} else if (menuItemContentContainerHalfWidth > titleMiddleOffset) {
offset = 0;
}
return offset;
}
getLeftDirectionContainerOffset(contentContainerWidth, titleBoundingBox) {
return elementorFrontend.config.is_rtl ? this.getRtlLeftDirectionContainerOffset(contentContainerWidth, titleBoundingBox) : this.getLtrLeftDirectionContainerOffset(contentContainerWidth, titleBoundingBox);
}
getRtlLeftDirectionContainerOffset(contentContainerWidth, titleBoundingBox) {
const bodyWidth = elementorFrontend.elements.$body[0].clientWidth,
titleLeftOffset = this.adjustForScrollbarIfNeeded(titleBoundingBox.left);
let offset = bodyWidth - titleLeftOffset - contentContainerWidth;
// If the content container doesn't fit in the viewport, align its right edge with the viewport's right edge.
if (-offset + contentContainerWidth > bodyWidth) {
offset = 0;
}
return offset;
}
getLtrLeftDirectionContainerOffset(contentContainerWidth, titleBoundingBox) {
let offset = this.adjustForScrollbarIfNeeded(titleBoundingBox.left);
offset = this.adjustStartOffsetToViewport(offset, contentContainerWidth);
return offset;
}
getRightDirectionContainerOffset(contentContainerWidth, titleBoundingBox) {
return elementorFrontend.config.is_rtl ? this.getRtlRightDirectionContainerOffset(contentContainerWidth, titleBoundingBox) : this.getLtrRightDirectionContainerOffset(contentContainerWidth, titleBoundingBox);
}
getRtlRightDirectionContainerOffset(contentContainerWidth, titleBoundingBox) {
const bodyWidth = elementorFrontend.elements.$body[0].clientWidth;
let offset = bodyWidth - this.adjustForScrollbarIfNeeded(titleBoundingBox.right);
offset = this.adjustStartOffsetToViewport(offset, contentContainerWidth);
return offset;
}
/**
* If the content container doesn't fit in the viewport, align its right edge with the viewport's right edge.
*
* @param {number} offset
* @param {number} contentContainerWidth
*/
adjustStartOffsetToViewport(offset, contentContainerWidth) {
const bodyWidth = elementorFrontend.elements.$body[0].clientWidth;
if (offset + contentContainerWidth > bodyWidth) {
offset = bodyWidth - contentContainerWidth;
}
return offset;
}
getLtrRightDirectionContainerOffset(contentContainerWidth, titleBoundingBox) {
return contentContainerWidth > titleBoundingBox.right ? 0 : titleBoundingBox.right - contentContainerWidth;
}
adjustForScrollbarIfNeeded(offset) {
if (elementorFrontend.config.is_rtl && elementorFrontend.isEditMode()) {
const scrollbarWidth = window.innerWidth - elementorFrontend.elements.$body[0].clientWidth;
offset -= scrollbarWidth;
}
return offset;
}
getMenuContainerOffset() {
const menuContainerBoundingBox = this.elements.$widgetContainer[0].getBoundingClientRect();
return elementorFrontend.config.is_rtl ? this.getMenuContainerOffsetRtl(menuContainerBoundingBox) : menuContainerBoundingBox.left;
}
getMenuContainerOffsetRtl(menuContainerBoundingBox) {
const bodyWidth = elementorFrontend.elements.$body[0].clientWidth;
let menuContainerOffset = bodyWidth - menuContainerBoundingBox.right;
if (elementorFrontend.isEditMode()) {
// In RTL mode, the editor's scrollbar is on the left side, so we need to add its width to the offset.
const scrollbarWidth = window.innerWidth - bodyWidth;
menuContainerOffset += scrollbarWidth;
}
return menuContainerOffset;
}
resetContentContainersPosition() {
this.elements.$tabContents.css({
left: '',
right: '',
bottom: '',
position: 'var(--position)',
'max-width': '',
width: 'var(--width)'
});
this.elements.$widgetContainer.removeClass('content-above');
}
getTabContentFilterSelector(tabIndex) {
return `[data-tab-index="${tabIndex}"]`;
}
isActiveTab(tabIndex) {
return 'true' === this.elements.$tabDropdowns.filter('[data-tab-index="' + tabIndex + '"]').attr(this.getSettings('ariaAttributes').titleStateAttribute);
}
activateDefaultTab() {
const settings = this.getSettings();
const defaultActiveTab = this.getEditSettings('activeItemIndex') || 1,
originalToggleMethods = {
showTabFn: settings.showTabFn,
hideTabFn: settings.hideTabFn
};
// Toggle tabs without animation to avoid jumping
this.setSettings({
showTabFn: 'show',
hideTabFn: 'hide'
});
this.changeActiveTab(defaultActiveTab);
// Return back original toggle effects
this.setSettings(originalToggleMethods);
this.elements.$widgetContainer.addClass('e-activated');
}
activateTab(tabIndex) {
const settings = this.getSettings(),
activeClass = settings.classes.active,
childMenuDropdownSelector = `.elementor-element-${this.getID()} .e-n-menu .e-n-menu .e-n-menu-dropdown-icon`,
childMenuContentSelector = `.elementor-element-${this.getID()} .e-n-menu .e-n-menu .e-n-menu-content > .e-con`,
$requestedTitle = this.elements.$tabDropdowns.filter(this.getTabTitleFilterSelector(tabIndex)).not(childMenuDropdownSelector),
animationDuration = 'show' === settings.showTabFn ? 0 : 400,
$requestedContent = this.elements.$tabContents.filter(this.getTabContentFilterSelector(tabIndex)).not(childMenuContentSelector);
this.addAnimationToContentIfNeeded(tabIndex);
$requestedContent[settings.showTabFn](animationDuration, () => this.onShowTabContent($requestedContent));
$requestedTitle.attr(this.getTitleActivationAttributes());
$requestedTitle.prev('.e-n-menu-title-container').find('a').attr(this.getTitleActivationAttributes('link'));
$requestedContent.addClass(activeClass).parent().addClass(activeClass);
$requestedContent.css({
display: 'var(--display)'
});
$requestedContent.removeAttr('display');
if (elementorFrontend.isEditMode() && !!$requestedContent.length) {
this.activeContainerWidthListener($requestedContent);
}
this.menuHeightController.reassignMenuHeight($requestedContent);
}
deactivateActiveTab() {
const settings = this.getSettings(),
activeClass = settings.classes.active,
activeTitleFilter = settings.ariaAttributes.activeTitleSelector,
activeContentFilter = '.' + activeClass,
$activeTitle = this.elements.$tabDropdowns.filter(activeTitleFilter),
$activeContent = this.elements.$tabContents.filter(activeContentFilter);
this.setTabDeactivationAttributes($activeTitle);
this.elements.$menuContent.removeClass(activeClass);
$activeContent.removeClass(activeClass);
$activeContent[settings.hideTabFn](0, () => this.onHideTabContent($activeContent));
this.removeAnimationFromContentIfNeeded();
if (elementorFrontend.isEditMode() && !!$activeContent.length) {
this.observedContainer?.unobserve($activeContent[0]);
}
this.menuHeightController.resetMenuHeight($activeContent);
this.clickInProgress = true;
}
getTitleActivationAttributes() {
let elementType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'tab';
const titleAttributes = {};
if ('tab' === elementType) {
titleAttributes['aria-expanded'] = 'true';
}
return titleAttributes;
}
setTabDeactivationAttributes($activeTitle) {
const titleStateAttribute = this.getSettings('ariaAttributes').titleStateAttribute;
$activeTitle.attr(`${titleStateAttribute}`, 'false');
}
shouldPositionContentAbove($contentContainer) {
let offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
const contentDimensions = $contentContainer[0].getBoundingClientRect();
return this.isContentShorterThanItsTopOffset(contentDimensions, offset) && this.isContentTallerThanItsBottomOffset(contentDimensions);
}
isContentShorterThanItsTopOffset(contentDimensions, offset) {
return contentDimensions.height < contentDimensions.top - offset;
}
isContentTallerThanItsBottomOffset(contentDimensions) {
return window.innerHeight - contentDimensions.top < contentDimensions.height;
}
onShowTabContent($requestedContent) {
this.handleContentContainerPosition($requestedContent);
elementorFrontend.elements.$window.trigger('elementor-pro/motion-fx/recalc');
elementorFrontend.elements.$window.trigger('elementor/nested-tabs/activate', $requestedContent);
elementorFrontend.elements.$window.trigger('elementor/bg-video/recalc');
}
onHideTabContent() {
if (this.elements.$widgetContainer.hasClass('content-above')) {
this.resetContentContainersPosition();
}
}
changeActiveTab(tabIndex) {
let fromUser = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
let byKeyboard = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
if (this.clickInProgress && elementorFrontend.isEditMode() && !byKeyboard) {
return;
}
const isActiveTab = this.isActiveTab(tabIndex);
this.deactivateActiveTab();
if (!isActiveTab || isActiveTab && !fromUser) {
this.clickInProgress = true;
this.activateTab(tabIndex);
}
setTimeout(() => {
this.clickInProgress = false;
});
}
changeActiveTabByKeyboard(event, settings) {
if (settings.widgetId.toString() !== this.getID().toString()) {
return;
}
if (!settings.titleIndex) {
this.changeActiveTab('', true, true);
return;
}
const $focusableElement = this.$element.find(`[data-focus-index="${settings.titleIndex}"]`),
isLinkElement = 'a' === $focusableElement[0].tagName.toLowerCase(),
dropdownSelector = this.getSettings('selectors.tabDropdown'),
$tabDropdown = isLinkElement ? $focusableElement.next(dropdownSelector) : $focusableElement,
tabIndex = this.getTabIndex($tabDropdown[0]);
this.changeActiveTab(tabIndex, true, true);
event.stopPropagation();
}
onTabClick(event) {
if (elementorFrontend.isEditMode()) {
event.preventDefault();
}
const hasNoDropdown = event?.currentTarget?.classList?.contains('link-only');
// Tweak for NVDA screen reader with Windows Edge.
// Ref: https://github.com/nvaccess/nvda/issues/7898
const dropdownOpensWithHover = !this.isNeedToOpenOnClick(),
blockMouseClickEvents = dropdownOpensWithHover && !this.isKeyboardNavigation;
if (hasNoDropdown || blockMouseClickEvents) {
return;
}
const selectors = this.getSettings('selectors'),
getClickedMenuId = event?.target?.closest(selectors.elementorWidgetWrapper)?.getAttribute('data-id'),
getWidgetId = this.getID().toString();
if (getClickedMenuId !== getWidgetId) {
return;
}
const clickedElement = event?.currentTarget,
dropdownElement = clickedElement?.querySelector(selectors.tabDropdown),
tabIndex = this.getTabIndex(dropdownElement);
this.changeActiveTab(tabIndex, true);
}
bindEvents() {
this.elements.$tabTitles.on(this.getTabEvents());
this.elements.$dropdownMenuToggle.on('click', this.onClickToggleDropdownMenu.bind(this));
this.elements.$tabContents.on(this.getContentEvents());
this.elements.$menuContent.on(this.getContentEvents());
this.elements.$headingContainer.on(this.getHeadingEvents());
elementorFrontend.addListenerOnce(this.getModelCID(), 'scroll', elementorFrontend.debounce(this.menuHeightController.reassignMobileMenuHeight.bind(this.menuHeightController), 250));
elementorFrontend.elements.$window.on('elementor/nested-tabs/activate', this.reInitSwipers);
elementorFrontend.elements.$window.on('elementor/nested-elements/activate-by-keyboard', this.changeActiveTabByKeyboard.bind(this));
elementorFrontend.elements.$window.on('elementor/mega-menu/dropdown-toggle-by-keyboard', this.onClickToggleDropdownMenuByKeyboard.bind(this));
elementorFrontend.elements.$window.on('resize', this.resizeEventHandler.bind(this));
if (elementorFrontend.isEditMode()) {
this.addChildLifeCycleEventListeners();
elementorFrontend.elements.$window.on('elementor/dynamic/url_change', this.changeMegaMenuTitleContainerTag.bind(this));
}
elementorFrontend.elements.$window.on('elementor/nested-container/atomic-repeater', this.linkContainer.bind(this));
}
unbindEvents() {
this.elements.$tabTitles.off();
this.elements.$menuContent.off();
this.elements.$tabContents.off();
this.elements.$headingContainer.off();
elementorFrontend.elements.$window.off('resize');
if (elementorFrontend.isEditMode()) {
this.removeChildLifeCycleEventListeners();
elementorFrontend.elements.$window.on('elementor/dynamic/url_change', this.changeMegaMenuTitleContainerTag.bind(this));
}
elementorFrontend.elements.$window.off('elementor/nested-tabs/activate', this.reInitSwipers);
elementorFrontend.elements.$window.off('elementor/nested-elements/activate-by-keyboard', this.changeActiveTabByKeyboard.bind(this));
elementorFrontend.elements.$window.off('elementor/mega-menu/dropdown-toggle-by-keyboard', this.onClickToggleDropdownMenuByKeyboard.bind(this));
elementorFrontend.elements.$window.off('resize', this.resizeEventHandler.bind(this));
elementorFrontend.elements.$window.off('elementor/nested-container/atomic-repeater', this.linkContainer.bind(this));
}
/**
* Fixes issues where Swipers that have been initialized while a tab is not visible are not properly rendered
* and when switching to the tab the swiper will not respect any of the chosen `autoplay` related settings.
*
* This is triggered when switching to a nested tab, looks for Swipers in the tab content and reinitializes them.
*
* @param {Object} event - Incoming event.
* @param {Object} content - Active nested tab dom element.
*/
reInitSwipers(event, content) {
const swiperElements = content.querySelectorAll('.swiper');
for (const element of swiperElements) {
if (!element.swiper) {
return;
}
element.swiper.initialized = false;
element.swiper.init();
}
}
resizeEventHandler() {
this.resizeListener = this.handleContentContainerPosition();
this.setLayoutType();
this.setTouchMode();
this.menuHeightController.reassignMobileMenuHeight();
this.setScrollPosition();
const activeTitleSelector = this.getSettings('ariaAttributes').activeTitleSelector,
tabIndex = this.elements.$tabDropdowns.filter(activeTitleSelector).attr('data-tab-index'),
childMenuContentSelector = `.elementor-element-${this.getID()} .e-n-menu .e-n-menu .e-n-menu-content > .e-con`,
$requestedContent = this.elements.$tabContents.filter(this.getTabContentFilterSelector(tabIndex)).not(childMenuContentSelector);
this.menuHeightController.resetMenuHeight($requestedContent);
this.menuHeightController.reassignMenuHeight($requestedContent);
}
/**
* Add Child Lifecycle Event Listeners
*
* This method adds event listeners for the elementor/editor/element-rendered and elementor/editor/element-destroyed
* events. These events are fired when an element is rendered or destroyed in the editor. The callback functions
* check if the rendered/destroyed element is nested in this mega-menu instance, and if it is, triggers the
* recalculation of the mega-menu's content containers position.
*/
addChildLifeCycleEventListeners() {
this.lifecycleChangeListener = this.handleContentContainerChildrenChanges.bind(this);
window.addEventListener('elementor/editor/element-rendered', this.lifecycleChangeListener);
window.addEventListener('elementor/editor/element-destroyed', this.lifecycleChangeListener);
}
removeChildLifeCycleEventListeners() {
window.removeEventListener('elementor/editor/element-rendered', this.lifecycleChangeListener);
window.removeEventListener('elementor/editor/element-destroyed', this.lifecycleChangeListener);
}
handleContentContainerChildrenChanges(event) {
if (!this.isNestedElementRenderedInContentContainer(event.detail.elementView)) {
return;
}
this.handleContentContainerPosition();
}
isNestedElementRenderedInContentContainer(elementView) {
const elementContainer = elementView?.getContainer();
if (!elementContainer) {
return false;
}
const elementAncestors = elementContainer.getParentAncestry();
return elementAncestors.some(parent => this.getID().toString() === parent.model.get('id').toString());
}
getTabEvents() {
const tabEvents = {
click: this.onTabClick.bind(this)
};
return this.isNeedToOpenOnClick() ? tabEvents : this.replaceClickWithHover(tabEvents);
}
getContentEvents() {
return this.isNeedToOpenOnClick() ? {} : {
mouseleave: this.onMouseLeave.bind(this),
mousemove: this.trackMousePosition.bind(this)
};
}
isNeedToOpenOnClick() {
const elementSettings = this.getElementSettings();
return this.isEdit || this.isMobileDevice() || 'hover' !== elementSettings.open_on || 'dropdown' === elementSettings.item_layout;
}
isMobileDevice() {
const mobileDevices = ['mobile', 'mobile_extra', 'tablet', 'tablet_extra'];
return mobileDevices.includes(elementorFrontend.getCurrentDeviceMode());
}
replaceClickWithHover(tabEvents) {
tabEvents.mouseenter = this.onMouseTitleEnter.bind(this);
tabEvents.mouseleave = this.onMouseLeave.bind(this);
tabEvents.keyup = this.setKeyboardNavigation.bind(this);
return tabEvents;
}
onMouseTitleEnter(event) {
event.preventDefault();
const settings = this.getSettings(),
currentTarget = event?.currentTarget,
currentTargetWidgetId = currentTarget?.closest(settings.selectors.elementorWidgetWrapper)?.getAttribute('data-id'),
widgetId = this.$element[0].getAttribute('data-id');
if (widgetId !== currentTargetWidgetId) {
return;
}
const titleStateAttribute = settings.ariaAttributes.titleStateAttribute,
dropdownSelector = settings.selectors.tabDropdown,
activeDropdownElement = currentTarget?.querySelector(dropdownSelector),
isActiveTabTitle = 'true' === activeDropdownElement?.getAttribute(titleStateAttribute);
if (isActiveTabTitle) {
return;
}
const tabIndex = activeDropdownElement?.getAttribute('data-tab-index');
this.changeActiveTab(tabIndex, true);
}
onClickToggleDropdownMenu(show) {
this.elements.$widgetContainer.attr('data-layout', 'dropdown');
const titleStateAttribute = this.getSettings('ariaAttributes').titleStateAttribute,
isDropdownVisible = 'true' === this.elements.$dropdownMenuToggle.attr(titleStateAttribute);
if ('boolean' !== typeof show) {
show = !isDropdownVisible;
}
const activeTabTitleValue = show ? 'true' : 'false';
this.elements.$dropdownMenuToggle.attr(titleStateAttribute, activeTabTitleValue);
elementorFrontend.utils.events.dispatch(window, 'elementor-pro/mega-menu/dropdown-open');
this.menuHeightController.reassignMobileMenuHeight();
}
onClickOutsideDropdownMenu(event) {
if (!this.isNeedToOpenOnClick()) {
return;
}
const settings = this.getSettings(),
selectors = settings.selectors,
widgetWrapper = `.elementor-element-${this.getID()}`,
activeClass = settings.classes.active,
activeContentFilter = `> .e-con.${activeClass}`,
$activeContent = this.elements.$menuContent.find(activeContentFilter),
isMenuDropdownsClosed = 0 === $activeContent.length,
isElementRemovedFromDOM = elementorFrontend.isEditMode() && !document.body.contains(event?.target),
isClickedInsideCurrentMenu = !!event?.target?.closest(`${widgetWrapper} ${selectors.widgetContainer}`),
isMenuContentWrapperClicked = event?.target?.classList?.contains(selectors.menuContent.replace('.', ''));
if (isMenuContentWrapperClicked) {
this.deactivateActiveTab();
return;
}
if (isMenuDropdownsClosed || isClickedInsideCurrentMenu || isElementRemovedFromDOM) {
return;
}
this.deactivateActiveTab();
}
onClickToggleDropdownMenuByKeyboard(event, settings) {
if (settings.widgetId.toString() !== this.getID().toString()) {
return;
}
this.onClickToggleDropdownMenu(settings.show);
}
addAnimationToContentIfNeeded(tabIndex) {
const openAnimation = this.getElementSettings('open_animation');
if ('none' === openAnimation || '' === openAnimation) {
return;
}
const $requestedContent = this.elements.$tabContents.filter(this.getTabContentFilterSelector(tabIndex));
$requestedContent.addClass(`animated ${openAnimation}`);
}
removeAnimationFromContentIfNeeded() {
const openAnimation = this.getElementSettings('open_animation');
if ('none' === openAnimation || '' === openAnimation) {
return;
}
this.elements.$tabContents.removeClass(`animated ${openAnimation}`);
}
/**
* Store the current Y-coordinate of the mouse cursor.
*
* @param {Event} event - The mouse event object.
*/
trackMousePosition(event) {
this.prevMouseY = event?.clientY;
}
/**
* Check if the menu content is currently hovered.
*
* @return {boolean} - True if menu content is hovered, otherwise false.
*/
isMenuContentHovered() {
const settings = this.getSettings(),
$widget = this.$element;
return $widget.find(`${settings.selectors.menuContent}:hover`).length > 0;
}
isCursorInBetweenMenuTitleAndContent(event) {
const settings = this.getSettings();
const selectors = settings.selectors;
const currentElement = event?.currentTarget;
const activeContent = currentElement?.closest(selectors.menuItem)?.querySelector(selectors.menuContent);
const isMouseLeavingTabTitle = currentElement.classList?.contains(selectors.tabTitle.replace('.', ''));
const hasActiveTabTitle = activeContent?.classList?.contains(settings.classes.active);
if (!isMouseLeavingTabTitle || !hasActiveTabTitle) {
return false;
}
const titleBoundingClientRect = currentElement.getBoundingClientRect();
const contentBoundingClientRect = activeContent.getBoundingClientRect();
const mouseY = event.clientY;
const isTitleAboveContent = titleBoundingClientRect.bottom <= contentBoundingClientRect.top;
return isTitleAboveContent ? mouseY >= titleBoundingClientRect.bottom && mouseY < contentBoundingClientRect.top : mouseY <= titleBoundingClientRect.top && mouseY > contentBoundingClientRect.bottom;
}
/**
* Determines whether the cursor moved sideways or downwards.
*
* @param {Event} event - The mouse event object.
* @return {boolean} - True if the cursor moved sideways or downwards, otherwise false.
*/
didCursorMoveSidewaysOrDown(event) {
// Detects if the Y-coordinate of the mouse has not decreased (i.e., either remained the same or increased).
return this.prevMouseY !== null && event?.clientY >= this.prevMouseY;
}
/**
* Check whether the dropdown menu should remain open based on hover and cursor movement.
*
* @param {boolean} isMouseLeavingTabContent - True if the mouse is leaving the tab content.
* @param {Event} event - The mouse event object.
* @return {boolean} - True if dropdown should be considered as hovered, otherwise false.
*/
isHoveredDropdownMenu(isMouseLeavingTabContent, event) {
// If the mouse is leaving the tab content and it moved sideways or downwards, close the dropdown.
if (isMouseLeavingTabContent && this.didCursorMoveSidewaysOrDown(event)) {
return false;
}
// Otherwise, return true if the menu content is hovered.
return this.isMenuContentHovered();
}
/**
* Handle the event when the mouse leaves the dropdown.
*
* @param {Event} event - The mouse event object.
*/
onMouseLeave(event) {
event.preventDefault();
const isMouseLeavingTabContent = event?.currentTarget?.classList?.contains('e-con');
if (!this.isHoveredDropdownMenu(isMouseLeavingTabContent, event) && !this.isCursorInBetweenMenuTitleAndContent(event)) {
this.deactivateActiveTab();
}
}
onInit() {
this.menuHeightController = new elementorProFrontend.utils.DropdownMenuHeightController(this.dropdownMenuHeightControllerConfig());
super.onInit(...arguments);
if (this.getSettings('autoExpand')) {
this.activateDefaultTab();
}
(0, _flexHorizontalScroll.setHorizontalScrollAlignment)(this.getHorizontalScrollingSettings());
this.setTouchMode();
if (!elementorFrontend.isEditMode()) {
const classes = this.getSettings('classes');
this.anchorLinks = new _anchorLink.default(this.elements.$anchorLink, classes);
this.anchorLinks.initialize();
elementorFrontend.elements.$window.on('elementor/dynamic/url_change', this.changeMegaMenuTitleContainerTag.bind(this));
}
this.menuToggleVisibilityListener(this.elements.$dropdownMenuToggle);
this.setScrollPosition();
this.onClickOutsideDropdownMenu = this.onClickOutsideDropdownMenu.bind(this);
document.addEventListener('click', this.onClickOutsideDropdownMenu);
this.clickInProgress = false;
}
onDestroy() {
document.removeEventListener('click', this.onClickOutsideDropdownMenu);
elementorFrontend.elements.$window.off('elementor/dynamic/url_change');
}
setScrollPosition() {
const settingsObject = {
element: this.elements.$headingContainer[0],
direction: this.getItemPosition(),
justifyCSSVariable: '--n-menu-heading-justify-content',
horizontalScrollStatus: this.getHorizontalScrollSetting()
};
(0, _flexHorizontalScroll.setHorizontalScrollAlignment)(settingsObject);
}
getPropsThatTriggerContentPositionCalculations() {
return ['content_horizontal_position', 'content_position', 'item_position_horizontal', 'content_width', 'item_layout'];
}
activeContainerWidthListener($activeContainer) {
let previousWidth = 0;
this.observedContainer = new ResizeObserver(activeContainer => {
const currentWidth = activeContainer[0].borderBoxSize?.[0].inlineSize;
if (!!currentWidth && currentWidth !== previousWidth) {
previousWidth = currentWidth;
if (0 !== previousWidth) {
this.handleContentContainerPosition();
}
}
});
this.observedContainer.observe($activeContainer[0]);
}
menuToggleVisibilityListener($menuToggle) {
let previousWidth;
this.observedContainer = new ResizeObserver(menuToggle => {
const currentWidth = menuToggle[0].borderBoxSize?.[0].inlineSize;
if (currentWidth !== previousWidth) {
previousWidth = currentWidth;
this.setLayoutType();
}
});
this.observedContainer.observe($menuToggle[0]);
}
onElementChange(propertyName) {
if (this.getPropsThatTriggerContentPositionCalculations().includes(propertyName)) {
this.handleContentContainerPosition();
}
this.setLayoutType();
}
onEditSettingsChange(propertyName, value) {
const settings = this.getSettings();
if (settings.autoFocus && 'activeItemIndex' === propertyName) {
this.changeActiveTab(value, false);
}
this.setLayoutType();
}
/**
* Sets the layout type as a data attribute, so that it can be use for the responsive or dropdown menu styling.
*
* Originally this styling was handled by the distinction between the heading and the content styling elements.
* Since we removed the title duplication, we needed another way to distinguish between the horizontal and the dropdown styling.
*/
setLayoutType() {
const layoutType = 'none' === this.elements.$dropdownMenuToggle.css('display') ? 'horizontal' : 'dropdown';
this.elements.$widgetContainer.attr('data-layout', layoutType);
}
getHeadingEvents() {
const navigationWrapper = this.elements.$headingContainer[0];
return {
mousedown: this.changeScrollStatusAndDispatch.bind(this, navigationWrapper),
mouseup: this.changeScrollStatusAndDispatch.bind(this, navigationWrapper),
mouseleave: this.changeScrollStatusAndDispatch.bind(this, navigationWrapper),
mousemove: this.setHorizontalTitleScrollValuesAndDispatch.bind(this, navigationWrapper)
};
}
getHorizontalScrollSetting() {
const currentDevice = elementorFrontend.getCurrentDeviceMode();
return elementorFrontend.utils.controls.getResponsiveControlValue(this.getElementSettings(), 'horizontal_scroll', '', currentDevice);
}
getItemPosition() {
const currentDevice = elementorFrontend.getCurrentDeviceMode();
return elementorFrontend.utils.controls.getResponsiveControlValue(this.getElementSettings(), 'item_position_horizontal', '', currentDevice);
}
changeScrollStatusAndDispatch(navigationWrapper, event) {
(0, _flexHorizontalScroll.changeScrollStatus)(navigationWrapper, event);
elementorFrontend.elements.$window.trigger('elementor-pro/mega-menu/heading-mouse-event');
}
setHorizontalTitleScrollValuesAndDispatch(navigationWrapper, event) {
(0, _flexHorizontalScroll.setHorizontalTitleScrollValues)(navigationWrapper, this.getHorizontalScrollSetting(), event);
elementorFrontend.elements.$window.trigger('elementor-pro/mega-menu/heading-mouse-event');
}
linkContainer(event) {
const {
container
} = event.detail,
id = container.model.get('id'),
currentId = String(this.$element.data('id')),
view = container.view.$el;
if (id === currentId) {
this.updateIndexValues(view);
this.updateListeners(view);
}
}
updateIndexValues(view) {
const {
selectors: {
directTabTitle,
directTabContent
}
} = this.getDefaultSettings(),
currentMenu = view[0],
tabsContents = currentMenu.querySelectorAll(directTabContent),
tabTitles = currentMenu.querySelectorAll(directTabTitle),
settings = this.getSettings(),
itemIdBase = tabTitles[0].getAttribute('id').slice(0, -1);
tabTitles.forEach((element, index) => {
const newIndex = index + 1,
updatedTabID = itemIdBase + newIndex,
updatedContainerID = updatedTabID.replace('e-n-menu-title-', 'e-n-menu-content-'),
updatedTabDropdownID = updatedTabID.replace('e-n-menu-title-', 'e-n-menu-dropdown-icon-');
element.setAttribute('id', updatedTabID);
element.querySelector(settings.selectors.tabDropdown)?.setAttribute('data-tab-index', newIndex);
element.querySelector(settings.selectors.tabDropdown)?.setAttribute('id', updatedTabDropdownID);
element.querySelector(settings.selectors.tabDropdown)?.setAttribute('aria-controls', updatedContainerID);
element.querySelector(settings.selectors.tabTitleText)?.setAttribute('data-binding-index', newIndex);
tabsContents[index]?.setAttribute('aria-labelledby', updatedTabDropdownID);
tabsContents[index]?.setAttribute('data-tab-index', newIndex);
tabsContents[index]?.setAttribute('id', updatedContainerID);
});
}
updateListeners(view) {
const {
selectors: {
tabClickableTitle,
tabDropdown,
tabContent,
tabTitle
}
} = this.getSettings(),
$tabTitles = view.find(tabTitle),
$tabClickableTitle = view.find(tabClickableTitle);
this.elements.$tabTitles = view.find(tabClickableTitle);
this.elements.$tabDropdowns = view.find(tabDropdown);
this.elements.$tabContents = view.find(tabContent);
$tabTitles.off();
$tabClickableTitle.on(this.getTabEvents());
this.clickInProgress = false;
}
/**
* Toggle the container tag of the mega menu title.
* Needs to be places in pro Mega Menu frontend handler
*
* @param {Event} event
* @return {undefined}
*/
changeMegaMenuTitleContainerTag(event) {
const {
element,
actionName,
value
} = event.detail,
elementParent = element.parentNode,
closestMenuItemTitle = elementParent.parentNode,
newElement = this.maybeCreateNewElement(elementParent, value),
elementToUpdate = this.maybeReplaceMenuItemTitleContent(elementParent, newElement, closestMenuItemTitle),
currentUrl = element.dataset?.currentUrl || null;
this.maybeUpdateNewElementsHref(value, elementToUpdate);
this.eCurrentClassHandler(actionName, closestMenuItemTitle, currentUrl === value);
return undefined;
}
maybeReplaceMenuItemTitleContent(elementParent, newElement, closestMenuItemTitle) {
if (!newElement) {
return elementParent;
}
Array.from(elementParent.attributes).forEach(attr => {
newElement.setAttribute(attr.name, attr.value);
});
if ('A' === newElement.tagName) {
newElement.classList.add('e-link', 'e-focus');
} else if ('DIV' === newElement.tagName) {
newElement.classList.remove('e-link', 'e-focus');
}
newElement.innerHTML = elementParent.innerHTML;
closestMenuItemTitle.replaceChild(newElement, elementParent);
return newElement;
}
maybeCreateNewElement(elementParent, value) {
if (!value) {
return document.createElement('div');
}
if (value && 'DIV' === elementParent.tagName) {
return document.createElement('a');
}
}
maybeUpdateNewElementsHref(value, newElement) {
if (value) {
newElement.setAttribute('href', value);
} else {
newElement.removeAttribute('href');
}
}
eCurrentClassHandler(actionName, closestMenuItemTitle, isCurrentUrl) {
const settings = this.getSettings(),
{
classes: {
activeAnchorItem: eCurrentClassName
},
postUrl,
internalUrl
} = settings;
switch (actionName) {
case postUrl:
closestMenuItemTitle.classList.add(eCurrentClassName);
break;
case internalUrl:
if (isCurrentUrl) {
closestMenuItemTitle.classList.add(eCurrentClassName);
} else {
closestMenuItemTitle.classList.remove(eCurrentClassName);
}
break;
default:
if (closestMenuItemTitle.classList.contains(eCurrentClassName) && postUrl !== actionName) {
closestMenuItemTitle.classList.remove(eCurrentClassName);
}
break;
}
}
setTouchMode() {
const widgetSelector = this.getSettings('selectors').widgetContainer;
if (elementorFrontend.isEditMode() || 'resize' === event?.type) {
const responsiveDevices = ['mobile', 'mobile_extra', 'tablet', 'tablet_extra'],
currentDevice = elementorFrontend.getCurrentDeviceMode();
if (-1 !== responsiveDevices.indexOf(currentDevice)) {
this.$element.find(widgetSelector).attr('data-touch-mode', 'true');
return;
}
} else if ('ontouchstart' in window) {
this.$element.find(widgetSelector).attr('data-touch-mode', 'true');
return;
}
this.$element.find(widgetSelector).attr('data-touch-mode', 'false');
}
getTabsDirection() {
const currentDevice = elementorFrontend.getCurrentDeviceMode();
return elementorFrontend.utils.controls.getResponsiveControlValue(this.getElementSettings(), 'tabs_justify_horizontal', '', currentDevice);
}
getHorizontalScrollingSettings() {
return {
element: this.elements.$headingContainer[0],
direction: this.getTabsDirection(),
justifyCSSVariable: '--n-tabs-heading-justify-content',
horizontalScrollStatus: this.getHorizontalScrollSetting()
};
}
}
exports["default"] = MegaMenu;
/***/ }),
/***/ "../modules/mega-menu/assets/js/frontend/utils.js":
/*!********************************************************!*\
!*** ../modules/mega-menu/assets/js/frontend/utils.js ***!
\********************************************************/
/***/ ((__unused_webpack_module, exports) => {
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports.isMenuInDropdownMode = isMenuInDropdownMode;
function isMenuInDropdownMode(elementSettings) {
if ('dropdown' === elementSettings.item_layout) {
return true;
}
const activeBreakpointsList = elementorFrontend.breakpoints.getActiveBreakpointsList({
withDesktop: true
}),
breakpointIndex = activeBreakpointsList.indexOf(elementSettings.breakpoint_selector),
currentDeviceModeIndex = activeBreakpointsList.indexOf(elementorFrontend.getCurrentDeviceMode());
return currentDeviceModeIndex <= breakpointIndex;
}
/***/ })
}]);
//# sourceMappingURL=mega-menu.1344912ff0c40681bb13.bundle.js.map
{"content":[{"id":"sjbwygw","elType":"section","settings":{"custom_height":{"unit":"vh","size":"0"},"background_background":"classic","background_image":{"id":1536,"url":"https:\/\/library.elementor.com\/wp-content\/uploads\/2017\/05\/gunijiuucgy-denys-nevozhai.png"},"background_size":"cover","padding":{"unit":"px","top":"300","right":"0","bottom":"300","left":"0","isLinked":false},"padding_tablet":{"unit":"px","top":"150","right":"150","bottom":"150","left":"150","isLinked":true},"padding_mobile":{"unit":"px","top":"120","right":"30","bottom":"120","left":"30","isLinked":false},"content_width":{"unit":"px","size":"500"}},"elements":[{"id":"thpgnbl","elType":"column","settings":{"_inline_size":null,"_column_size":100,"background_background":"classic","background_color":"#fea709","margin":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"padding":{"unit":"px","top":"80","right":"80","bottom":"80","left":"80","isLinked":true},"margin_mobile":{"unit":"px","top":"0","right":"0","bottom":"0","left":"0","isLinked":true},"padding_tablet":{"unit":"px","top":"70","right":"70","bottom":"70","left":"70","isLinked":true},"padding_mobile":{"unit":"px","top":"50","right":"30","bottom":"50","left":"30","isLinked":false}},"elements":[{"id":"tjwxrku","elType":"widget","settings":{"title":"Luxury Travel","align":"center","title_color":"#ffffff","typography_typography":"custom","typography_font_size":{"unit":"px","size":"85"},"typography_font_family":"Roboto","header_size":"h1","typography_font_size_tablet":{"unit":"px","size":"80"},"typography_font_size_mobile":{"unit":"px","size":"55"},"typography_text_transform":"uppercase","typography_letter_spacing":{"unit":"px","size":2.1}},"elements":[],"widgetType":"heading"},{"id":"ngdocaw","elType":"widget","settings":{"title":"Explore over 200 destinations","align":"center","title_color":"#ffffff","typography_typography":"custom","typography_font_size":{"unit":"px","size":"25"},"typography_font_family":"Roboto","typography_font_weight":"500","header_size":"h3","typography_font_size_tablet":{"unit":"px","size":"23"},"typography_font_size_mobile":{"unit":"px","size":"17"}},"elements":[],"widgetType":"heading"}],"isInner":false}],"isInner":false},{"id":"hnffjwy","elType":"section","settings":{"padding":{"unit":"px","top":"80","right":"0","bottom":"100","left":"0","isLinked":false},"gap":"no","padding_tablet":{"unit":"px","top":"60","right":"25","bottom":"60","left":"25","isLinked":false},"padding_mobile":{"unit":"px","top":"50","right":"30","bottom":"50","left":"30","isLinked":false},"content_width":{"unit":"px","size":"1040"}},"elements":[{"id":"fmepfke","elType":"column","settings":{"_inline_size":null,"_column_size":100},"elements":[{"id":"fntowbu","elType":"widget","settings":{"title":"Top destinations, amazing offers","align":"center","title_color":"#3a3a3a","typography_typography":"custom","typography_font_size":{"unit":"px","size":"40"},"typography_font_family":"Roboto","_padding":{"unit":"px","top":"0","right":"0","bottom":"60","left":"0","isLinked":false},"typography_font_size_tablet":{"unit":"px","size":"35"},"typography_font_size_mobile":{"unit":"px","size":"30"},"typography_line_height_mobile":{"unit":"em","size":"1.3"},"_padding_tablet":{"unit":"px","top":"0","right":"0","bottom":"40","left":"0","isLinked":false},"_padding_mobile":{"unit":"px","top":"0","right":"0","bottom":"30","left":"0","isLinked":false},"header_size":"h3"},"elements":[],"widgetType":"heading"},{"id":"jlmobyu","elType":"section","settings":{"gap":"wide","structure":"30"},"elements":[{"id":"werccid","elType":"column","settings":{"_inline_size":null,"_column_size":33,"background_background":"classic","border_border":"solid","border_width":{"unit":"px","top":"1","right":"1","bottom":"1","left":"1","isLinked":true},"border_color":"#636363","margin":{"unit":"%","top":"0","right":"6","bottom":"0","left":"0","isLinked":false},"padding":{"unit":"px","top":"5","right":"5","bottom":"5","left":"5","isLinked":true},"margin_mobile":{"unit":"px","top":"0","right":"0","bottom":"0","left":"0","isLinked":true}},"elements":[{"id":"gverkyx","elType":"widget","settings":{"image":{"id":1537,"url":"https:\/\/library.elementor.com\/wp-content\/uploads\/2017\/05\/d.png"},"space":{"unit":"%","size":"100"},"image_size":"full"},"elements":[],"widgetType":"image"},{"id":"iopebqt","elType":"widget","settings":{"title":"London $555","align":"center","title_color":"#3a3a3a","typography_typography":"custom","typography_font_size":{"unit":"px","size":"30"},"typography_font_family":"Roboto","typography_font_size_tablet":{"unit":"px","size":"25"},"header_size":"h4"},"elements":[],"widgetType":"heading"},{"id":"pfwxzrb","elType":"widget","settings":{"editor":"
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamco.<\/p>","align":"center","text_color":"#636363","typography_typography":"custom","typography_font_size":{"unit":"px","size":"16"},"typography_font_family":"Roboto","typography_font_weight":"400","typography_line_height":{"unit":"em","size":"1.6"},"_padding":{"unit":"%","top":"0","right":"12","bottom":"0","left":"12","isLinked":false},"typography_font_size_tablet":{"unit":"px","size":"14"},"_margin_tablet":{"unit":"px","top":"-10","right":"0","bottom":"0","left":"0","isLinked":false},"_padding_tablet":{"unit":"px","top":"0","right":"5","bottom":"0","left":"5","isLinked":false}},"elements":[],"widgetType":"text-editor"},{"id":"jbkzlwi","elType":"widget","settings":{"text":"View offer","align":"justify","typography_typography":"custom","typography_font_size":{"unit":"px","size":"23"},"typography_font_family":"Roboto","typography_font_weight":"900","typography_text_transform":"lowercase","typography_letter_spacing":{"unit":"px","size":"2"},"background_color":"#fea709","border_radius":{"unit":"px","top":"0","right":"0","bottom":"0","left":"0","isLinked":true},"text_padding":{"unit":"px","top":"17","right":"17","bottom":"17","left":"17","isLinked":true},"typography_font_size_tablet":{"unit":"px","size":"18"},"button_background_hover_color":"#3cc6d5"},"elements":[],"widgetType":"button"}],"isInner":true},{"id":"siyactb","elType":"column","settings":{"_inline_size":null,"_column_size":33,"background_background":"classic","border_border":"solid","border_width":{"unit":"px","top":"1","right":"1","bottom":"1","left":"1","isLinked":true},"border_color":"#636363","margin":{"unit":"%","top":"0","right":"3","bottom":"0","left":"3","isLinked":false},"padding":{"unit":"px","top":"5","right":"5","bottom":"5","left":"5","isLinked":true},"margin_mobile":{"unit":"px","top":"30","right":"0","bottom":"30","left":"0","isLinked":false}},"elements":[{"id":"ljemyep","elType":"widget","settings":{"image":{"id":1538,"url":"https:\/\/library.elementor.com\/wp-content\/uploads\/2017\/05\/dc.png"},"space":{"unit":"%","size":"100"}},"elements":[],"widgetType":"image"},{"id":"sbdtbsc","elType":"widget","settings":{"title":"India $1285","align":"center","title_color":"#3a3a3a","typography_typography":"custom","typography_font_size":{"unit":"px","size":"30"},"typography_font_family":"Roboto","typography_font_size_tablet":{"unit":"px","size":"25"},"header_size":"h4"},"elements":[],"widgetType":"heading"},{"id":"vebvjfh","elType":"widget","settings":{"editor":"
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus ullamcorper mattis.<\/p>","align":"center","text_color":"#636363","typography_typography":"custom","typography_font_size":{"unit":"px","size":"16"},"typography_font_family":"Roboto","typography_font_weight":"400","typography_line_height":{"unit":"em","size":"1.6"},"_padding":{"unit":"%","top":"0","right":"12","bottom":"0","left":"12","isLinked":false},"typography_font_size_tablet":{"unit":"px","size":"14"},"_margin_tablet":{"unit":"px","top":"-10","right":"0","bottom":"0","left":"0","isLinked":false},"_padding_tablet":{"unit":"px","top":"0","right":"5","bottom":"0","left":"5","isLinked":false}},"elements":[],"widgetType":"text-editor"},{"id":"tolgbxb","elType":"widget","settings":{"text":"View offer","align":"justify","typography_typography":"custom","typography_font_size":{"unit":"px","size":"23"},"typography_font_family":"Roboto","typography_font_weight":"900","typography_text_transform":"lowercase","typography_letter_spacing":{"unit":"px","size":"2"},"background_color":"#fea709","border_radius":{"unit":"px","top":"0","right":"0","bottom":"0","left":"0","isLinked":true},"text_padding":{"unit":"px","top":"17","right":"17","bottom":"17","left":"17","isLinked":true},"typography_font_size_tablet":{"unit":"px","size":"18"},"button_background_hover_color":"#3cc6d5"},"elements":[],"widgetType":"button"}],"isInner":true},{"id":"fsizeug","elType":"column","settings":{"_inline_size":null,"_column_size":33,"background_background":"classic","border_border":"solid","border_width":{"unit":"px","top":"1","right":"1","bottom":"1","left":"1","isLinked":true},"border_color":"#636363","margin":{"unit":"%","top":"0","right":"0","bottom":"0","left":"6","isLinked":false},"padding":{"unit":"px","top":"5","right":"5","bottom":"5","left":"5","isLinked":true},"margin_mobile":{"unit":"px","top":"0","right":"0","bottom":"0","left":"0","isLinked":true}},"elements":[{"id":"sfpsjhw","elType":"widget","settings":{"image":{"id":1539,"url":"https:\/\/library.elementor.com\/wp-content\/uploads\/2017\/05\/dss.png"},"space":{"unit":"%","size":"100"}},"elements":[],"widgetType":"image"},{"id":"izkhuly","elType":"widget","settings":{"title":"Paris $495","align":"center","title_color":"#3a3a3a","typography_typography":"custom","typography_font_size":{"unit":"px","size":"30"},"typography_font_family":"Roboto","typography_font_size_tablet":{"unit":"px","size":"25"},"header_size":"h4"},"elements":[],"widgetType":"heading"},{"id":"jjzjhgz","elType":"widget","settings":{"editor":"
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus mattis.<\/p>","align":"center","text_color":"#636363","typography_typography":"custom","typography_font_size":{"unit":"px","size":"16"},"typography_font_family":"Roboto","typography_font_weight":"400","typography_line_height":{"unit":"em","size":"1.6"},"_padding":{"unit":"%","top":"0","right":"12","bottom":"0","left":"12","isLinked":false},"typography_font_size_tablet":{"unit":"px","size":"14"},"_margin_tablet":{"unit":"px","top":"-10","right":"0","bottom":"0","left":"0","isLinked":false},"_padding_tablet":{"unit":"px","top":"0","right":"5","bottom":"0","left":"05","isLinked":false}},"elements":[],"widgetType":"text-editor"},{"id":"uftiafw","elType":"widget","settings":{"text":"View offer","align":"justify","typography_typography":"custom","typography_font_size":{"unit":"px","size":"23"},"typography_font_family":"Roboto","typography_font_weight":"900","typography_text_transform":"lowercase","typography_letter_spacing":{"unit":"px","size":"2"},"background_color":"#fea709","border_radius":{"unit":"px","top":"0","right":"0","bottom":"0","left":"0","isLinked":true},"text_padding":{"unit":"px","top":"17","right":"17","bottom":"17","left":"17","isLinked":true},"typography_font_size_tablet":{"unit":"px","size":"18"},"button_background_hover_color":"#3cc6d5"},"elements":[],"widgetType":"button"}],"isInner":true}],"isInner":true}],"isInner":false}],"isInner":false},{"id":"bxwymfb","elType":"section","settings":{"gap":"no","background_background":"classic","background_color":"#eaf2fb","padding":{"unit":"px","top":"100","right":"0","bottom":"100","left":"0","isLinked":false},"padding_tablet":{"unit":"px","top":"0","right":"0","bottom":"0","left":"0","isLinked":false}},"elements":[{"id":"fxwzbdi","elType":"column","settings":{"_inline_size":null,"_column_size":100},"elements":[{"id":"uwovhjl","elType":"section","settings":{"gap":"no","content_position":"middle","structure":"20"},"elements":[{"id":"zoacnkm","elType":"column","settings":{"_inline_size":null,"_column_size":50,"background_background":"gradient","background_color":"#ffffff","background_color_b":"#3cc6d5","background_gradient_type":"radial"},"elements":[{"id":"zlrzxwb","elType":"widget","settings":{"image":{"id":1540,"url":"https:\/\/library.elementor.com\/wp-content\/uploads\/2017\/05\/PR-011-SI-22_03_12-293.png"},"_padding":{"unit":"px","top":"80","right":"0","bottom":"0","left":"0","isLinked":false},"_margin_mobile":{"unit":"px","top":"0","right":"17","bottom":"0","left":"17","isLinked":false},"image_size":"full"},"elements":[],"widgetType":"image"}],"isInner":true},{"id":"disfvjt","elType":"column","settings":{"_inline_size":null,"_column_size":50,"padding":{"unit":"%","top":"0","right":"10","bottom":"0","left":"10","isLinked":false},"padding_mobile":{"unit":"px","top":"60","right":"35","bottom":"60","left":"35","isLinked":false}},"elements":[{"id":"rmykxrc","elType":"widget","settings":{"title":"The best deals","align":"left","title_color":"#3a3a3a","typography_typography":"custom","typography_font_size":{"unit":"px","size":"30"},"typography_font_family":"Roboto","header_size":"h4","align_mobile":"center","typography_font_size_tablet":{"unit":"px","size":"25"},"typography_font_size_mobile":{"unit":"px","size":"30"}},"elements":[],"widgetType":"heading"},{"id":"xzamcve","elType":"widget","settings":{"editor":"
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec venenatis velit metus. Morbi non augue non sapien ullamcorper volutpat id a libero. Curabitur maximus vel est ac suscipit. Pellentesque imperdiet ultricies interdum. Etiam metus tortor, elementum et nisl vitae, tristique scelerisque odio. Duis eget consequat nisi. Fusce vel metus consequat, volutpat arcu ut, egestas mauris.<\/p>","align":"left","text_color":"#636363","typography_typography":"custom","typography_font_size":{"unit":"px","size":"16"},"typography_font_family":"Roboto","typography_font_weight":"400","typography_line_height":{"unit":"em","size":"1.6"},"_padding":{"unit":"px","top":"0","right":"0","bottom":"0","left":"0","isLinked":true},"align_mobile":"center","typography_font_size_tablet":{"unit":"px","size":"15"},"typography_font_size_mobile":{"unit":"px","size":"16"},"_margin_tablet":{"unit":"px","top":"-10","right":"0","bottom":"0","left":"0","isLinked":false},"_margin_mobile":{"unit":"px","top":"0","right":"0","bottom":"0","left":"0","isLinked":true}},"elements":[],"widgetType":"text-editor"}],"isInner":true}],"isInner":true},{"id":"kclrovt","elType":"section","settings":{"gap":"no","content_position":"middle","structure":"20","reverse_order_mobile":"reverse-mobile"},"elements":[{"id":"lhsvqha","elType":"column","settings":{"_inline_size":null,"_column_size":50,"padding":{"unit":"%","top":"0","right":"10","bottom":"0","left":"10","isLinked":false},"padding_mobile":{"unit":"px","top":"60","right":"35","bottom":"60","left":"35","isLinked":false}},"elements":[{"id":"ieedfbb","elType":"widget","settings":{"title":"Family oriented","align":"left","title_color":"#3a3a3a","typography_typography":"custom","typography_font_size":{"unit":"px","size":"30"},"typography_font_family":"Roboto","header_size":"h4","align_mobile":"center","typography_font_size_tablet":{"unit":"px","size":"25"},"typography_font_size_mobile":{"unit":"px","size":"30"}},"elements":[],"widgetType":"heading"},{"id":"jppofkb","elType":"widget","settings":{"editor":"
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec venenatis velit metus. Morbi non augue non sapien ullamcorper volutpat id a libero. Curabitur maximus vel est ac suscipit. Pellentesque imperdiet ultricies interdum. Etiam metus tortor, elementum et nisl vitae, tristique scelerisque odio.<\/p>","align":"left","text_color":"#636363","typography_typography":"custom","typography_font_size":{"unit":"px","size":"16"},"typography_font_family":"Roboto","typography_font_weight":"400","typography_line_height":{"unit":"em","size":"1.6"},"_padding":{"unit":"px","top":"0","right":"0","bottom":"0","left":"0","isLinked":true},"align_mobile":"center","typography_font_size_tablet":{"unit":"px","size":"15"},"typography_font_size_mobile":{"unit":"px","size":"16"},"_margin_tablet":{"unit":"px","top":"-10","right":"0","bottom":"0","left":"0","isLinked":false},"_margin_mobile":{"unit":"px","top":"0","right":"0","bottom":"0","left":"0","isLinked":true}},"elements":[],"widgetType":"text-editor"}],"isInner":true},{"id":"xsfjvuq","elType":"column","settings":{"_inline_size":null,"_column_size":50,"background_background":"gradient","background_color":"#ffffff","background_color_b":"#fea709","background_gradient_type":"radial"},"elements":[{"id":"pqknonw","elType":"widget","settings":{"image":{"id":1541,"url":"https:\/\/library.elementor.com\/wp-content\/uploads\/2017\/05\/PR-021-SI-01_05_12-539.png"},"_padding":{"unit":"px","top":"80","right":"0","bottom":"0","left":"0","isLinked":false},"_margin_tablet":{"unit":"px","top":"0","right":"28","bottom":"0","left":"28","isLinked":false}},"elements":[],"widgetType":"image"}],"isInner":true}],"isInner":true}],"isInner":false}],"isInner":false},{"id":"resepim","elType":"section","settings":{"background_background":"classic","background_image":{"id":1542,"url":"https:\/\/library.elementor.com\/wp-content\/uploads\/2017\/05\/2.png"},"background_size":"cover","padding":{"unit":"px","top":"100","right":"0","bottom":"100","left":"0","isLinked":false},"padding_mobile":{"unit":"px","top":"10","right":"0","bottom":"10","left":"0","isLinked":false},"content_width":{"unit":"px","size":"550"}},"elements":[{"id":"lmgtkxe","elType":"column","settings":{"_inline_size":null,"_column_size":100,"background_background":"classic","background_color":"rgba(255,255,255,0.81)","margin":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"padding":{"unit":"px","top":"70","right":"70","bottom":"70","left":"70","isLinked":true},"margin_mobile":{"unit":"px","top":"30","right":"30","bottom":"30","left":"30","isLinked":true},"padding_tablet":{"unit":"px","top":"80","right":"80","bottom":"80","left":"80","isLinked":true},"padding_mobile":{"unit":"px","top":"40","right":"40","bottom":"40","left":"40","isLinked":true}},"elements":[{"id":"skmwlej","elType":"widget","settings":{"title":"Book today","align":"center","title_color":"#3a3a3a","typography_typography":"custom","typography_font_size":{"unit":"px","size":"60"},"typography_font_family":"Roboto","_padding":{"unit":"px","top":"0","right":"0","bottom":"0","left":"0","isLinked":true},"typography_font_size_mobile":{"unit":"px","size":"43"}},"elements":[],"widgetType":"heading"},{"id":"lsjcoal","elType":"widget","settings":{"weight":{"unit":"px","size":"7"},"color":"#fea709","width":{"unit":"%","size":"20"},"align":"center"},"elements":[],"widgetType":"divider"},{"id":"vwakzcq","elType":"widget","settings":{"editor":"
Totally customizable multi-city trips\u00a0& instant\u00a0price and book<\/p>","align":"center","text_color":"#3a3a3a","typography_typography":"custom","typography_font_size":{"unit":"px","size":"25"},"typography_font_family":"Roboto","typography_font_weight":"400","typography_line_height":{"unit":"em","size":"1.4"},"_padding":{"unit":"px","top":"10","right":"10","bottom":"10","left":"10","isLinked":true},"typography_font_size_tablet":{"unit":"px","size":"22"},"typography_font_size_mobile":{"unit":"px","size":"21"},"_padding_tablet":{"unit":"px","top":"0","right":"40","bottom":"0","left":"40","isLinked":false},"_padding_mobile":{"unit":"px","top":"3","right":"10","bottom":"3","left":"10","isLinked":false}},"elements":[],"widgetType":"text-editor"},{"id":"yilbvlk","elType":"widget","settings":{"text":"View offer","align":"center","typography_typography":"custom","typography_font_size":{"unit":"px","size":"25"},"typography_font_family":"Roboto","typography_font_weight":"900","typography_text_transform":"lowercase","typography_letter_spacing":{"unit":"px","size":"2"},"background_color":"#fea709","border_radius":{"unit":"px","top":"0","right":"0","bottom":"0","left":"0","isLinked":true},"text_padding":{"unit":"px","top":"17","right":"50","bottom":"17","left":"50","isLinked":false},"align_mobile":"justify","typography_font_size_mobile":{"unit":"px","size":"18"},"button_background_hover_color":"#3cc6d5"},"elements":[],"widgetType":"button"}],"isInner":false}],"isInner":false}],"page_settings":[]}