/*!
 * # Fomantic-UI - Sidebar
 * https://github.com/fomantic/Fomantic-UI/
 *
 *
 * Released under the MIT license
 * https://opensource.org/licenses/MIT
 *
 */

(function ($, window, document) {
    'use strict';

    function isFunction(obj) {
        return typeof obj === 'function' && typeof obj.nodeType !== 'number';
    }

    window = window !== undefined && window.Math === Math
        ? window
        : globalThis;

    $.fn.sidebar = function (...args) {
        const $allModules = $(this);
        const $window = $(window);
        const $document = $(document);
        const $body = $('body');
        const $html = $('html');
        const $head = $('head');

        let time = Date.now();
        let performance = [];

        const parameters = args[0];
        const methodInvoked = typeof parameters === 'string';
        const queryArguments = args.slice(1);
        const contextCheck = function (context, win) {
            let $context;
            if ([window, document].includes(context)) {
                $context = $body;
            } else {
                $context = $(win.document).find(context);
                if ($context.length === 0) {
                    $context = win.frameElement ? contextCheck(context, win.parent) : $body;
                }
            }

            return $context;
        };
        let returnedValue;

        $allModules.each(function () {
            const settings = $.isPlainObject(parameters)
                ? $.extend(true, {}, $.fn.sidebar.settings, parameters)
                : $.extend({}, $.fn.sidebar.settings);

            const selector = settings.selector;
            const className = settings.className;
            const namespace = settings.namespace;
            const regExp = settings.regExp;
            const error = settings.error;

            const eventNamespace = '.' + namespace;
            const moduleNamespace = 'module-' + namespace;

            const $module = $(this);
            let $context = contextCheck(settings.context, window);
            const isBody = $context[0] === $body[0];

            let $sidebars = $module.children(selector.sidebar);
            let $fixed = $context.children(selector.fixed);
            let $pusher = $context.children(selector.pusher);
            let $style;

            const element = this;
            let instance = $module.data(moduleNamespace);

            let elementNamespace;
            let id;
            let currentScroll;
            let initialBodyMargin = '';
            let initialBodyMarginInt = 0;
            let tempBodyMargin = 0;
            let hadScrollbar = false;

            const module = {

                initialize: function () {
                    module.debug('Initializing sidebar', parameters);

                    module.create.id();

                    // avoids locking rendering if initialized in onReady
                    if (settings.delaySetup) {
                        requestAnimationFrame(module.setup.layout);
                    } else {
                        module.setup.layout();
                    }

                    requestAnimationFrame(function () {
                        module.setup.cache();
                    });

                    module.instantiate();
                },

                instantiate: function () {
                    module.verbose('Storing instance of module', module);
                    instance = module;
                    $module
                        .data(moduleNamespace, module);
                },

                create: {
                    id: function () {
                        id = (Math.random().toString(16) + '000000000').slice(2, 10);
                        elementNamespace = '.' + id;
                        module.verbose('Creating unique id for element', id);
                    },
                },

                destroy: function () {
                    module.verbose('Destroying previous module for', $module);
                    $module
                        .off(eventNamespace)
                        .removeData(moduleNamespace);
                    // bound by uuid
                    $context.off(elementNamespace);
                    $window.off(elementNamespace);
                    $document.off(elementNamespace);
                },

                event: {
                    clickaway: function (event) {
                        if (settings.closable) {
                            const clickedInPusher = $pusher.find(event.target).length > 0 || $pusher.is(event.target);
                            const clickedContext = $context.is(event.target);
                            if (clickedInPusher) {
                                module.verbose('User clicked on dimmed page');
                                module.hide();
                            }
                            if (clickedContext) {
                                module.verbose('User clicked on dimmable context (scaled out page)');
                                module.hide();
                            }
                        }
                    },
                    touch: function (event) {
                        // event.stopPropagation();
                    },
                    containScroll: function (event) {
                        if (element.scrollTop <= 0) {
                            element.scrollTop = 1;
                        }
                        if ((element.scrollTop + element.offsetHeight) >= element.scrollHeight) {
                            element.scrollTop = element.scrollHeight - element.offsetHeight - 1;
                        }
                    },
                    scroll: function (event) {
                        if ($(event.target).closest(selector.sidebar).length === 0) {
                            event.preventDefault();
                        }
                    },
                },

                bind: {
                    clickaway: function () {
                        module.verbose('Adding clickaway events to context', $context);
                        $context
                            .on('click' + elementNamespace, module.event.clickaway)
                            .on('touchend' + elementNamespace, module.event.clickaway);
                    },
                    scrollLock: function () {
                        if (settings.scrollLock) {
                            module.debug('Disabling page scroll');
                            hadScrollbar = module.has.scrollbar();
                            if (hadScrollbar) {
                                module.save.bodyMargin();
                                module.set.bodyMargin();
                            }
                            $context.addClass(className.locked);
                        }
                        module.verbose('Adding events to contain sidebar scroll');
                        $document
                            .on('touchmove' + elementNamespace, module.event.touch);
                        $module
                            .on('scroll' + eventNamespace, module.event.containScroll);
                    },
                },
                unbind: {
                    clickaway: function () {
                        module.verbose('Removing clickaway events from context', $context);
                        $context.off(elementNamespace);
                    },
                    scrollLock: function () {
                        module.verbose('Removing scroll lock from page');
                        if (hadScrollbar) {
                            module.restore.bodyMargin();
                        }
                        $context.removeClass(className.locked);
                        $document.off(elementNamespace);
                        $module.off('scroll' + eventNamespace);
                    },
                },

                add: {
                    inlineCSS: function () {
                        const width = module.cache.width || $module.outerWidth();
                        const height = module.cache.height || $module.outerHeight();
                        const isRTL = module.is.rtl();
                        const direction = module.get.direction();
                        const distance = {
                            left: width,
                            right: -width,
                            top: height,
                            bottom: -height,
                        };
                        let style;

                        if (isRTL) {
                            module.verbose('RTL detected, flipping widths');
                            distance.left = -width;
                            distance.right = width;
                        }

                        style = '<style>';

                        if (direction === 'left' || direction === 'right') {
                            module.debug('Adding CSS rules for animation distance', width);
                            style += ''
                                + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
                                + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
                                + '           transform: translate3d(' + distance[direction] + 'px, 0, 0);'
                                + ' }';
                        } else if (direction === 'top' || direction === 'bottom') {
                            style += ''
                                + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
                                + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
                                + '           transform: translate3d(0, ' + distance[direction] + 'px, 0);'
                                + ' }';
                        }

                        style += '</style>';
                        $style = $(style)
                            .appendTo($head);
                        module.debug('Adding sizing css to head', $style);
                    },
                },

                refresh: function () {
                    module.verbose('Refreshing selector cache');
                    $context = contextCheck(settings.context, window);
                    module.refreshSidebars();
                    $pusher = $context.children(selector.pusher);
                    $fixed = $context.children(selector.fixed);
                    module.clear.cache();
                },

                refreshSidebars: function () {
                    module.verbose('Refreshing other sidebars');
                    $sidebars = $context.children(selector.sidebar);
                },

                repaint: function () {
                    module.verbose('Forcing repaint event');
                    element.style.display = 'none';
                    const ignored = element.offsetHeight;
                    element.scrollTop = element.scrollTop; // eslint-disable-line no-self-assign
                    element.style.display = '';
                },

                setup: {
                    cache: function () {
                        module.cache = {
                            width: $module.outerWidth(),
                            height: $module.outerHeight(),
                        };
                    },
                    layout: function () {
                        if ($context.children(selector.pusher).length === 0) {
                            module.debug('Adding wrapper element for sidebar');
                            module.error(error.pusher);
                            $pusher = $('<div class="pusher" />');
                            $context
                                .children()
                                .not(selector.omitted)
                                .not($sidebars)
                                .wrapAll($pusher);
                            module.refresh();
                        }
                        if ($module.nextAll(selector.pusher).length === 0 || $module.nextAll(selector.pusher)[0] !== $pusher[0]) {
                            module.debug('Moved sidebar to correct parent element');
                            module.error(error.movedSidebar, element);
                            $module.detach().prependTo($context);
                            module.refresh();
                        }
                        module.clear.cache();
                        module.set.pushable();
                        module.set.direction();
                    },
                },

                attachEvents: function (selector, event) {
                    const $toggle = $(selector);
                    event = isFunction(module[event])
                        ? module[event]
                        : module.toggle;
                    if ($toggle.length > 0) {
                        module.debug('Attaching sidebar events to element', selector, event);
                        $toggle
                            .on('click' + eventNamespace, event);
                    } else {
                        module.error(error.notFound, selector);
                    }
                },
                can: {
                    leftBodyScrollbar: function () {
                        if (module.cache.leftBodyScrollbar === undefined) {
                            module.cache.leftBodyScrollbar = module.is.rtl() && ((module.is.iframe && !module.is.firefox()) || module.is.safari());
                        }

                        return module.cache.leftBodyScrollbar;
                    },
                },
                save: {
                    bodyMargin: function () {
                        initialBodyMargin = $context.css((isBody ? 'margin-' : 'padding-') + (module.can.leftBodyScrollbar() ? 'left' : 'right'));
                        initialBodyMarginInt = Number.parseInt(initialBodyMargin.replace(/[^\d.]/g, ''), 10);
                        const bodyScrollbarWidth = isBody ? window.innerWidth - document.documentElement.clientWidth : $context[0].offsetWidth - $context[0].clientWidth;
                        tempBodyMargin = initialBodyMarginInt + bodyScrollbarWidth;
                    },
                },
                show: function (callback) {
                    callback = isFunction(callback)
                        ? callback
                        : function () {};
                    if (module.is.hidden()) {
                        if (settings.onShow.call(element) === false) {
                            module.verbose('Show callback returned false cancelling show');

                            return;
                        }
                        if (settings.overlay) {
                            module.error(error.overlay);
                            settings.transition = 'overlay';
                        }
                        module.refresh();
                        if (module.othersActive()) {
                            module.debug('Other sidebars currently visible');
                            if (settings.exclusive) {
                                // if not overlay, queue animation after hide
                                if (settings.transition !== 'overlay') {
                                    module.hideOthers(module.show);

                                    return;
                                }

                                module.hideOthers();
                            } else {
                                settings.transition = 'overlay';
                            }
                        }
                        module.set.dimmerStyles();
                        module.pushPage(function () {
                            callback.call(element);
                            settings.onVisible.call(element);
                        });
                        settings.onChange.call(element);
                    } else {
                        module.debug('Sidebar is already visible');
                    }
                },

                hide: function (callback) {
                    callback = isFunction(callback)
                        ? callback
                        : function () {};
                    if ((module.is.visible() || module.is.animating()) && settings.onHide.call(element) !== false) {
                        module.debug('Hiding sidebar', callback);
                        module.refreshSidebars();
                        module.pullPage(function () {
                            callback.call(element);
                            settings.onHidden.call(element);
                        });
                        settings.onChange.call(element);
                    }
                },

                othersAnimating: function () {
                    return $sidebars.not($module).filter('.' + className.animating).length > 0;
                },
                othersVisible: function () {
                    return $sidebars.not($module).filter('.' + className.visible).length > 0;
                },
                othersActive: function () {
                    return module.othersVisible() || module.othersAnimating();
                },

                hideOthers: function (callback = function () {}) {
                    const $otherSidebars = $sidebars.not($module).filter('.' + className.visible);
                    const sidebarCount = $otherSidebars.length;
                    let callbackCount = 0;
                    $otherSidebars
                        .sidebar('hide', function () {
                            callbackCount++;
                            if (callbackCount === sidebarCount && isFunction(callback)) {
                                callback();
                            }
                        });
                },

                toggle: function () {
                    module.verbose('Determining toggled direction');
                    if (module.is.hidden()) {
                        module.show();
                    } else {
                        module.hide();
                    }
                },

                pushPage: function (callback) {
                    const transition = module.get.transition();
                    const $transition = transition === 'overlay' || module.othersActive()
                        ? $module
                        : $pusher;
                    callback = isFunction(callback)
                        ? callback
                        : function () {};
                    if (settings.returnScroll) {
                        currentScroll = (isBody ? $window : $context).scrollTop();
                    }
                    if (settings.transition === 'scale down') {
                        module.scrollToTop();
                    }
                    module.bind.scrollLock();
                    module.set.transition(transition);
                    module.repaint();
                    const animate = function () {
                        module.bind.clickaway();
                        module.add.inlineCSS();
                        module.set.animating();
                        module.set.visible();
                    };
                    const dim = function () {
                        module.set.dimmed();
                    };
                    const transitionEnd = function (event) {
                        if (event.target === $transition[0]) {
                            $transition.off('transitionend' + elementNamespace, transitionEnd);
                            module.remove.animating();
                            callback.call(element);
                        }
                    };
                    $transition.off('transitionend' + elementNamespace);
                    $transition.on('transitionend' + elementNamespace, transitionEnd);
                    requestAnimationFrame(animate);
                    if (settings.dimPage && !module.othersVisible()) {
                        requestAnimationFrame(dim);
                    }
                },

                pullPage: function (callback) {
                    const transition = module.get.transition();
                    const $transition = transition === 'overlay' || module.othersActive()
                        ? $module
                        : $pusher;
                    callback = isFunction(callback)
                        ? callback
                        : function () {};
                    module.verbose('Removing context push state', module.get.direction());

                    module.unbind.clickaway();
                    module.unbind.scrollLock();

                    const animate = function () {
                        module.set.transition(transition);
                        module.set.animating();
                        if (settings.dimPage && !module.othersVisible()) {
                            module.set.closing();
                        }
                        module.remove.visible();
                    };
                    const transitionEnd = function (event) {
                        if (event.target === $transition[0]) {
                            $transition.off('transitionend' + elementNamespace, transitionEnd);
                            module.remove.animating();
                            module.remove.closing();
                            module.remove.transition();
                            module.remove.inlineCSS();
                            if (transition === 'scale down' || settings.returnScroll) {
                                module.scrollBack();
                            }
                            if (settings.dimPage && !module.othersVisible()) {
                                $pusher.removeClass(className.dimmed);
                            }
                            callback.call(element);
                        }
                    };
                    $transition.off('transitionend' + elementNamespace);
                    $transition.on('transitionend' + elementNamespace, transitionEnd);
                    requestAnimationFrame(animate);
                },

                scrollToTop: function () {
                    module.verbose('Scrolling to top of page to avoid animation issues');
                    $module.scrollTop(0);
                    (isBody ? $window : $context)[0].scrollTo(0, 0);
                },

                scrollBack: function () {
                    module.verbose('Scrolling back to original page position');
                    (isBody ? $window : $context)[0].scrollTo(0, currentScroll);
                },

                clear: {
                    cache: function () {
                        module.verbose('Clearing cached dimensions');
                        module.cache = {};
                    },
                },

                set: {
                    bodyMargin: function () {
                        const position = module.can.leftBodyScrollbar() ? 'left' : 'right';
                        $context.css((isBody ? 'margin-' : 'padding-') + position, tempBodyMargin + 'px');
                        $context.find(selector.bodyFixed.replace('right', position)).each(function () {
                            const el = $(this);
                            const attribute = el.css('position') === 'fixed' ? 'padding-' + position : position;
                            el.css(attribute, 'calc(' + el.css(attribute) + ' + ' + tempBodyMargin + 'px)');
                        });
                    },
                    dimmerStyles: function () {
                        if (settings.blurring) {
                            $pusher.addClass(className.blurring);
                        } else {
                            $pusher.removeClass(className.blurring);
                        }
                    },

                    // container
                    pushed: function () {
                        $context.addClass(className.pushed);
                    },
                    pushable: function () {
                        $context.addClass(className.pushable);
                    },

                    // pusher
                    dimmed: function () {
                        $pusher.addClass(className.dimmed);
                    },

                    // sidebar
                    active: function () {
                        $module.addClass(className.active);
                    },
                    animating: function () {
                        $module.addClass(className.animating);
                    },
                    closing: function () {
                        $pusher.addClass(className.closing);
                    },
                    transition: function (transition = module.get.transition()) {
                        $module.addClass(transition);
                    },
                    direction: function (direction = module.get.direction()) {
                        $module.addClass(className[direction]);
                    },
                    visible: function () {
                        $module.addClass(className.visible);
                    },
                    overlay: function () {
                        $module.addClass(className.overlay);
                    },
                },
                remove: {

                    inlineCSS: function () {
                        module.debug('Removing inline css styles', $style);
                        if ($style && $style.length > 0) {
                            $style.remove();
                        }
                    },

                    // context
                    pushed: function () {
                        $context.removeClass(className.pushed);
                    },
                    pushable: function () {
                        $context.removeClass(className.pushable);
                    },

                    // sidebar
                    active: function () {
                        $module.removeClass(className.active);
                    },
                    animating: function () {
                        $module.removeClass(className.animating);
                    },
                    closing: function () {
                        $pusher.removeClass(className.closing);
                    },
                    transition: function (transition = module.get.transition()) {
                        $module.removeClass(transition);
                    },
                    direction: function (direction = module.get.direction()) {
                        $module.removeClass(className[direction]);
                    },
                    visible: function () {
                        $module.removeClass(className.visible);
                    },
                    overlay: function () {
                        $module.removeClass(className.overlay);
                    },
                },
                restore: {
                    bodyMargin: function () {
                        const position = module.can.leftBodyScrollbar() ? 'left' : 'right';
                        $context.css((isBody ? 'margin-' : 'padding-') + position, initialBodyMarginInt === 0 ? '' : initialBodyMargin);
                        $context.find(selector.bodyFixed.replace('right', position)).each(function () {
                            const el = $(this);
                            const attribute = el.css('position') === 'fixed' ? 'padding-' + position : position;
                            el.css(attribute, '');
                        });
                    },
                },
                get: {
                    direction: function () {
                        if ($module.hasClass(className.top)) {
                            return className.top;
                        }
                        if ($module.hasClass(className.right)) {
                            return className.right;
                        }
                        if ($module.hasClass(className.bottom)) {
                            return className.bottom;
                        }

                        return className.left;
                    },
                    transition: function () {
                        const direction = module.get.direction();
                        const transition = module.is.mobile()
                            ? (settings.mobileTransition === 'auto'
                                ? settings.defaultTransition.mobile[direction]
                                : settings.mobileTransition)
                            : (settings.transition === 'auto'
                                ? settings.defaultTransition.computer[direction]
                                : settings.transition);
                        module.verbose('Determined transition', transition);

                        return transition;
                    },
                },
                has: {
                    scrollbar: function () {
                        return isBody || $context.css('overflow-y') !== 'hidden';
                    },
                },
                is: {
                    safari: function () {
                        if (module.cache.isSafari === undefined) {
                            module.cache.isSafari = /constructor/i.test(window.HTMLElement) || !!window.ApplePaySession;
                        }

                        return module.cache.isSafari;
                    },
                    firefox: function () {
                        if (module.cache.isFirefox === undefined) {
                            module.cache.isFirefox = !!window.InstallTrigger;
                        }

                        return module.cache.isFirefox;
                    },
                    iframe: function () {
                        return !(window.self === window.top);
                    },
                    mobile: function () {
                        const userAgent = navigator.userAgent;
                        const isMobile = userAgent.match(regExp.mobile);
                        if (isMobile) {
                            module.verbose('Browser was found to be mobile', userAgent);

                            return true;
                        }

                        module.verbose('Browser is not mobile, using regular transition', userAgent);

                        return false;
                    },
                    hidden: function () {
                        return !module.is.visible();
                    },
                    visible: function () {
                        return $module.hasClass(className.visible);
                    },
                    // alias
                    open: function () {
                        return module.is.visible();
                    },
                    closed: function () {
                        return module.is.hidden();
                    },
                    vertical: function () {
                        return $module.hasClass(className.top);
                    },
                    animating: function () {
                        return $context.hasClass(className.animating);
                    },
                    rtl: function () {
                        if (module.cache.isRTL === undefined) {
                            module.cache.isRTL = $module.attr('dir') === 'rtl' || $module.css('direction') === 'rtl' || $body.attr('dir') === 'rtl' || $body.css('direction') === 'rtl' || $context.attr('dir') === 'rtl' || $context.css('direction') === 'rtl';
                        }

                        return module.cache.isRTL;
                    },
                },

                setting: function (name, value) {
                    module.debug('Changing setting', name, value);
                    if ($.isPlainObject(name)) {
                        $.extend(true, settings, name);
                    } else if (value !== undefined) {
                        if ($.isPlainObject(settings[name])) {
                            $.extend(true, settings[name], value);
                        } else {
                            settings[name] = value;
                        }
                    } else {
                        return settings[name];
                    }
                },
                internal: function (name, value) {
                    if ($.isPlainObject(name)) {
                        $.extend(true, module, name);
                    } else if (value !== undefined) {
                        module[name] = value;
                    } else {
                        return module[name];
                    }
                },
                debug: function (...args) {
                    if (!settings.silent && settings.debug) {
                        if (settings.performance) {
                            module.performance.log(args);
                        } else {
                            module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
                            module.debug.apply(console, args);
                        }
                    }
                },
                verbose: function (...args) {
                    if (!settings.silent && settings.verbose && settings.debug) {
                        if (settings.performance) {
                            module.performance.log(args);
                        } else {
                            module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
                            module.verbose.apply(console, args);
                        }
                    }
                },
                error: function (...args) {
                    if (!settings.silent) {
                        module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
                        module.error.apply(console, args);
                    }
                },
                performance: {
                    log: function (message) {
                        let currentTime;
                        let executionTime;
                        let previousTime;
                        if (settings.performance) {
                            currentTime = Date.now();
                            previousTime = time || currentTime;
                            executionTime = currentTime - previousTime;
                            time = currentTime;
                            performance.push({
                                Name: message[0],
                                Arguments: message.slice(1),
                                Element: element,
                                'Execution Time': executionTime,
                            });
                        }
                        clearTimeout(module.performance.timer);
                        module.performance.timer = setTimeout(function () {
                            module.performance.display();
                        }, 500);
                    },
                    display: function () {
                        let title = settings.name + ':';
                        let totalTime = 0;
                        time = false;
                        clearTimeout(module.performance.timer);
                        $.each(performance, function (index, data) {
                            totalTime += data['Execution Time'];
                        });
                        title += ' ' + totalTime + 'ms';
                        if (performance.length > 0) {
                            console.groupCollapsed(title);
                            console.table(performance);
                            console.groupEnd();
                        }
                        performance = [];
                    },
                },
                invoke: function (query, passedArguments = queryArguments, context = element) {
                    let object = instance;
                    let maxDepth;
                    let found;
                    let response;
                    if (typeof query === 'string' && object !== undefined) {
                        query = query.split(/[ .]/);
                        maxDepth = query.length - 1;
                        $.each(query, function (depth, value) {
                            const camelCaseValue = depth !== maxDepth
                                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
                                : query;
                            if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
                                object = object[camelCaseValue];
                            } else if (object[camelCaseValue] !== undefined) {
                                found = object[camelCaseValue];

                                return false;
                            } else if ($.isPlainObject(object[value]) && (depth !== maxDepth)) {
                                object = object[value];
                            } else if (object[value] !== undefined) {
                                found = object[value];

                                return false;
                            } else {
                                module.error(error.method, query);

                                return false;
                            }
                        });
                    }
                    if (isFunction(found)) {
                        response = found.apply(context, passedArguments);
                    } else if (found !== undefined) {
                        response = found;
                    }
                    if (Array.isArray(returnedValue)) {
                        returnedValue.push(response);
                    } else if (returnedValue !== undefined) {
                        returnedValue = [returnedValue, response];
                    } else if (response !== undefined) {
                        returnedValue = response;
                    }

                    return found;
                },
            };

            if (methodInvoked) {
                if (instance === undefined) {
                    module.initialize();
                }
                module.invoke(parameters);
            } else {
                if (instance !== undefined) {
                    module.invoke('destroy');
                }
                module.initialize();
            }
        });

        return returnedValue !== undefined
            ? returnedValue
            : this;
    };

    $.fn.sidebar.settings = {

        name: 'Sidebar',
        namespace: 'sidebar',

        silent: false,
        debug: false,
        verbose: false,
        performance: true,

        transition: 'auto',
        mobileTransition: 'auto',

        defaultTransition: {
            computer: {
                left: 'uncover',
                right: 'uncover',
                top: 'overlay',
                bottom: 'overlay',
            },
            mobile: {
                left: 'uncover',
                right: 'uncover',
                top: 'overlay',
                bottom: 'overlay',
            },
        },

        context: 'body',
        exclusive: false,
        closable: true,
        dimPage: true,
        scrollLock: false,
        returnScroll: false,
        delaySetup: false,

        onChange: function () {},
        onShow: function () {},
        onHide: function () {},

        onHidden: function () {},
        onVisible: function () {},

        className: {
            active: 'active',
            animating: 'animating',
            blurring: 'blurring',
            closing: 'closing',
            dimmed: 'dimmed',
            locked: 'locked',
            pushable: 'pushable',
            pushed: 'pushed',
            right: 'right',
            top: 'top',
            left: 'left',
            bottom: 'bottom',
            visible: 'visible',
        },

        selector: {
            bodyFixed: '> .ui.fixed.menu, > .ui.right.toast-container, > .ui.right.sidebar, > .ui.fixed.nag, > .ui.fixed.nag > .close',
            fixed: '.fixed',
            omitted: 'script, link, style, .ui.modal, .ui.dimmer, .ui.nag, .ui.fixed',
            pusher: '.pusher',
            sidebar: '.ui.sidebar',
        },

        regExp: {
            mobile: /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/g,
        },

        error: {
            method: 'The method you called is not defined.',
            pusher: 'Had to add pusher element. For optimal performance make sure body content is inside a pusher element',
            movedSidebar: 'Had to move sidebar. For optimal performance make sure sidebar and pusher are direct children of your body tag',
            overlay: 'The overlay setting is no longer supported, use animation: overlay',
            notFound: 'There were no elements that matched the specified selector',
        },

    };
})(jQuery, window, document);
