text: 'use strict';
  
  const animation = require('./animation-1ef5a673.js');
  
  /**
   * baseAnimation
   * Base class which is extended by the various types. Each
   * type will provide their own animations for open and close
   * and registers itself with Menu.
   */
  const baseAnimation = () => {
      // https://material.io/guidelines/motion/movement.html#movement-movement-in-out-of-screen-bounds
      // https://material.io/guidelines/motion/duration-easing.html#duration-easing-natural-easing-curves
      // "Apply the sharp curve to items temporarily leaving the screen that may return
      // from the same exit point. When they return, use the deceleration curve. On mobile,
      // this transition typically occurs over 300ms" -- MD Motion Guide
      return animation.createAnimation()
          .easing('cubic-bezier(0.0, 0.0, 0.2, 1)') // Deceleration curve (Entering the screen)
          .duration(300);
  };
  
  /**
   * Menu Overlay Type
   * The menu slides over the content. The content
   * itself, which is under the menu, does not move.
   */
  const menuOverlayAnimation = (menu) => {
      let closedX;
      let openedX;
      const BOX_SHADOW_WIDTH = 8;
      const width = menu.width + BOX_SHADOW_WIDTH;
      const menuAnimation = animation.createAnimation();
      const backdropAnimation = animation.createAnimation();
      if (menu.isEndSide) {
          // right side
          closedX = width + 'px';
          openedX = '0px';
      }
      else {
          // left side
          closedX = -width + 'px';
          openedX = '0px';
      }
      menuAnimation
          .addElement(menu.menuInnerEl)
          .fromTo('transform', `translateX(${closedX})`, `translateX(${openedX})`);
      backdropAnimation
          .addElement(menu.backdropEl)
          .fromTo('opacity', 0.01, 0.32);
      return baseAnimation().addAnimation([menuAnimation, backdropAnimation]);
  };
  
  /**
   * Menu Push Type
   * The content slides over to reveal the menu underneath.
   * The menu itself also slides over to reveal its bad self.
   */
  const menuPushAnimation = (menu) => {
      let contentOpenedX;
      let menuClosedX;
      const width = menu.width;
      if (menu.isEndSide) {
          contentOpenedX = -width + 'px';
          menuClosedX = width + 'px';
      }
      else {
          contentOpenedX = width + 'px';
          menuClosedX = -width + 'px';
      }
      const menuAnimation = animation.createAnimation()
          .addElement(menu.menuInnerEl)
          .fromTo('transform', `translateX(${menuClosedX})`, 'translateX(0px)');
      const contentAnimation = animation.createAnimation()
          .addElement(menu.contentEl)
          .fromTo('transform', 'translateX(0px)', `translateX(${contentOpenedX})`);
      const backdropAnimation = animation.createAnimation()
          .addElement(menu.backdropEl)
          .fromTo('opacity', 0.01, 0.32);
      return baseAnimation().addAnimation([menuAnimation, backdropAnimation, contentAnimation]);
  };
  
  /**
   * Menu Reveal Type
   * The content slides over to reveal the menu underneath.
   * The menu itself, which is under the content, does not move.
   */
  const menuRevealAnimation = (menu) => {
      const openedX = (menu.width * (menu.isEndSide ? -1 : 1)) + 'px';
      const contentOpen = animation.createAnimation()
          .addElement(menu.contentEl) // REVIEW
          .fromTo('transform', 'translateX(0px)', `translateX(${openedX})`);
      return baseAnimation().addAnimation(contentOpen);
  };
  
  const createMenuController = () => {
      const menuAnimations = new Map();
      const menus = [];
      const open = async (menu) => {
          const menuEl = await get(menu);
          if (menuEl) {
              return menuEl.open();
          }
          return false;
      };
      const close = async (menu) => {
          const menuEl = await (menu !== undefined ? get(menu) : getOpen());
          if (menuEl !== undefined) {
              return menuEl.close();
          }
          return false;
      };
      const toggle = async (menu) => {
          const menuEl = await get(menu);
          if (menuEl) {
              return menuEl.toggle();
          }
          return false;
      };
      const enable = async (shouldEnable, menu) => {
          const menuEl = await get(menu);
          if (menuEl) {
              menuEl.disabled = !shouldEnable;
          }
          return menuEl;
      };
      const swipeGesture = async (shouldEnable, menu) => {
          const menuEl = await get(menu);
          if (menuEl) {
              menuEl.swipeGesture = shouldEnable;
          }
          return menuEl;
      };
      const isOpen = async (menu) => {
          if (menu != null) {
              const menuEl = await get(menu);
              return (menuEl !== undefined && menuEl.isOpen());
          }
          else {
              const menuEl = await getOpen();
              return menuEl !== undefined;
          }
      };
      const isEnabled = async (menu) => {
          const menuEl = await get(menu);
          if (menuEl) {
              return !menuEl.disabled;
          }
          return false;
      };
      const get = async (menu) => {
          await waitUntilReady();
          if (menu === 'start' || menu === 'end') {
              // there could be more than one menu on the same side
              // so first try to get the enabled one
              const menuRef = find(m => m.side === menu && !m.disabled);
              if (menuRef) {
                  return menuRef;
              }
              // didn't find a menu side that is enabled
              // so try to get the first menu side found
              return find(m => m.side === menu);
          }
          else if (menu != null) {
              // the menuId was not left or right
              // so try to get the menu by its "id"
              return find(m => m.menuId === menu);
          }
          // return the first enabled menu
          const menuEl = find(m => !m.disabled);
          if (menuEl) {
              return menuEl;
          }
          // get the first menu in the array, if one exists
          return menus.length > 0 ? menus[0].el : undefined;
      };
      /**
       * Get the instance of the opened menu. Returns `null` if a menu is not found.
       */
      const getOpen = async () => {
          await waitUntilReady();
          return _getOpenSync();
      };
      /**
       * Get all menu instances.
       */
      const getMenus = async () => {
          await waitUntilReady();
          return getMenusSync();
      };
      /**
       * Get whether or not a menu is animating. Returns `true` if any
       * menu is currently animating.
       */
      const isAnimating = async () => {
          await waitUntilReady();
          return isAnimatingSync();
      };
      const registerAnimation = (name, animation) => {
          menuAnimations.set(name, animation);
      };
      const _register = (menu) => {
          if (menus.indexOf(menu) < 0) {
              if (!menu.disabled) {
                  _setActiveMenu(menu);
              }
              menus.push(menu);
          }
      };
      const _unregister = (menu) => {
          const index = menus.indexOf(menu);
          if (index > -1) {
              menus.splice(index, 1);
          }
      };
      const _setActiveMenu = (menu) => {
          // if this menu should be enabled
          // then find all the other menus on this same side
          // and automatically disable other same side menus
          const side = menu.side;
          menus
              .filter(m => m.side === side && m !== menu)
              .forEach(m => m.disabled = true);
      };
      const _setOpen = async (menu, shouldOpen, animated) => {
          if (isAnimatingSync()) {
              return false;
          }
          if (shouldOpen) {
              const openedMenu = await getOpen();
              if (openedMenu && menu.el !== openedMenu) {
                  await openedMenu.setOpen(false, false);
              }
          }
          return menu._setOpen(shouldOpen, animated);
      };
      const _createAnimation = (type, menuCmp) => {
          const animationBuilder = menuAnimations.get(type);
          if (!animationBuilder) {
              throw new Error('animation not registered');
          }
          const animation = animationBuilder(menuCmp);
          return animation;
      };
      const _getOpenSync = () => {
          return find(m => m._isOpen);
      };
      const getMenusSync = () => {
          return menus.map(menu => menu.el);
      };
      const isAnimatingSync = () => {
          return menus.some(menu => menu.isAnimating);
      };
      const find = (predicate) => {
          const instance = menus.find(predicate);
          if (instance !== undefined) {
              return instance.el;
          }
          return undefined;
      };
      const waitUntilReady = () => {
          return Promise.all(Array.from(document.querySelectorAll('ion-menu'))
              .map(menu => menu.componentOnReady()));
      };
      registerAnimation('reveal', menuRevealAnimation);
      registerAnimation('push', menuPushAnimation);
      registerAnimation('overlay', menuOverlayAnimation);
      return {
          registerAnimation,
          get,
          getMenus,
          getOpen,
          isEnabled,
          swipeGesture,
          isAnimating,
          isOpen,
          enable,
          toggle,
          close,
          open,
          _getOpenSync,
          _createAnimation,
          _register,
          _unregister,
          _setOpen,
          _setActiveMenu,
      };
  };
  const menuController = /*@__PURE__*/ createMenuController();
  
  exports.menuController = menuController;
  