Some helper CSS animation functions
347563
function fadeOutScreen(screen) {
  var screenElement = document.querySelector(screen);

  return Velocity(screenElement, {
    opacity: 0,
  }, {
    display: "none",
    duration: 500
  });
}
210535
function(gotoEnd){
		var t = now();

		if ( gotoEnd || t >= this.options.duration + this.startTime ) {
			this.now = this.end;
			this.pos = this.state = 1;
			this.update();

			this.options.curAnim[ this.prop ] = true;

			var done = true;
			for ( var i in this.options.curAnim )
				if ( this.options.curAnim[i] !== true )
					done = false;

			if ( done ) {
				if ( this.options.display != null ) {
					// Reset the overflow
					this.elem.style.overflow = this.options.overflow;

					// Reset the display
					this.elem.style.display = this.options.display;
					if ( jQuery.css(this.elem, "display") == "none" )
						this.elem.style.display = "block";
				}

				// Hide the element if the "hide" operation was done
				if ( this.options.hide )
					jQuery(this.elem).hide();

				// Reset the properties, if the item has been hidden or shown
				if ( this.options.hide || this.options.show )
					for ( var p in this.options.curAnim )
						jQuery.attr(this.elem.style, p, this.options.orig[p]);
					
				// Execute the complete function
				this.options.complete.call( this.elem );
			}

			return false;
		} else {
			var n = t - this.startTime;
			this.state = n / this.options.duration;

			// Perform the easing function, defaults to swing
			this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
			this.now = this.start + ((this.end - this.start) * this.pos);

			// Perform the next step of the animation
			this.update();
		}

		return true;
	}
665275
function toggleCss() {
    if (!cssOpen) {
      exampleCss.classList.remove(hiddenClass);
      showCssBtn.innerHTML = hideText;
      cssOpen = true;
    } else {
      exampleCss.classList.add(hiddenClass);
      exampleScss.scrollIntoView();
      showCssBtn.innerHTML = showText;
      cssOpen = false;
    }
  }
751268
function _translate(duration, ease = '', x = false) {
    slidesDOMEl.style.cssText = getTranslationCSS(duration, ease, index, x)
  }
822050
function(element, options) {
            var defaultOptions = {
                duration: .4,
                timing: "ease",
                delay: 0,
                iteration: 1,
                direction: "normal",
                fill: "both"
            },
            style,
            animStr = this.$statics.animationString;
            if (options === undefined) {
                options = defaultOptions;
            } else {
                for (var k in defaultOptions) {
                    if (options[k] === undefined) {
                        options[k] = defaultOptions[k];
                    }
                }
            }
            style =
                this._id + " "
                + options.duration + "s "
                + options.timing + " "
                + options.delay + "s "
                + options.iteration + " "
                + options.direction + " "
                + options.fill;
            element.style[animStr] = "";
            setTimeout(
                function() {
                    element.style[animStr] = style;
                },
                1
            );
            return this;
        }
51232
function (domElt, refreshArgs) {
                // lazy processing of animation in/out string
                var animation = this._getAnimation();
                this._animating = true;
                var newSection = this._domElt.cloneNode(false);
                domElt.id = null;
                newSection.className += " not-visible";
                newSection = ariaUtilsDom.replaceHTML(newSection, this.html);
                var from = domElt;
                var to = newSection;
                ariaUtilsDom.insertAdjacentElement(from, "afterEnd", newSection);
                this.setDom(newSection);

                var animSemaphore = false;
                var cfg = {
                    // from : from,
                    to : to,
                    type : 3,
                    reverse : animation.animIn.reverse,
                    hiddenClass : 'not-visible'
                };

                var cfg2 = {
                    from : from,
                    // to : to,
                    type : 3,
                    reverse : animation.animOut.reverse,
                    hiddenClass : 'not-visible'
                };

                var anim = new ariaUtilsCssAnimations();
                var anim2 = new ariaUtilsCssAnimations();

                var animEnd = {
                    "animationend" : function () {
                        if (animSemaphore) {
                            ariaUtilsDom.removeElement(from);
                            this._animating = false;
                            this.tplCtxt.onRefreshAnimationEnd(refreshArgs);
                        } else {
                            animSemaphore = true;
                        }
                    },
                    scope : this
                };

                anim.$on(animEnd);
                anim2.$on(animEnd);

                anim.start(animation.animIn.type, cfg);
                anim2.start(animation.animOut.type, cfg2);

            }
1299713
function animateSelection(element, fromSelection, toSelection) {

  resetAnimations(element);

  // Calculate the animation timings.
  const items = element.items;
  const keyframes = element.selectionAnimationKeyframes;
  element[playingAnimationSymbol] = true;
  const timings = mixin.helpers.effectTimingsForSelectionAnimation(element, fromSelection, toSelection);

  // Figure out which item will be the one *after* the one we're selecting.
  const itemCount = items.length;
  const selectionWraps = element.selectionWraps;
  const selectionIndex = FractionalSelectionMixin.helpers.selectionParts(toSelection, itemCount, selectionWraps).index;
  const totalSteps = stepsToIndex(itemCount, selectionWraps, fromSelection, toSelection);
  const forward = totalSteps >= 0;
  let nextUpIndex = selectionIndex + (forward ? 1 : - 1);
  if (selectionWraps) {
    nextUpIndex = FractionalSelectionMixin.helpers.wrappedSelection(nextUpIndex, itemCount);
  } else if (!isItemIndexInBounds(element, nextUpIndex)) {
    nextUpIndex = null; // At start/end of list; don't have a next item to show.
  }

  // Play the animations using those timings.
  let lastAnimationDetails;
  timings.forEach((timing, index) => {
    const item = items[index];
    if (timing) {
      showItem(item, true);
      const animation = item.animate(keyframes, timing);
      element[animationSymbol][index] = animation;
      if (index === nextUpIndex) {
        // This item will be animated, so will already be in the desired state
        // after the animation completes.
        nextUpIndex = null;
      }
      if (timing.endDelay !== 0) {
        // This is the animation for the item that will be left selected.
        // We want to clean up when this animation completes.
        lastAnimationDetails = { animation, index, timing, forward };
      }
    } else {
      // This item doesn't participate in the animation.
      showItem(item, false);
    }
  });

  if (lastAnimationDetails != null) {
    // Arrange for clean-up work to be performed.
    lastAnimationDetails.nextUpIndex = nextUpIndex;
    lastAnimationDetails.animation.onfinish = event => selectionAnimationFinished(element, lastAnimationDetails);
    element[lastAnimationSymbol] = lastAnimationDetails.animation;
  } else {
    // Shouldn't happen -- we should always have at least one animation.
    element[playingAnimationSymbol] = false;
  }
}
400177
function widthChangeFormFun() {
    this.createFromDivs();
    $('#' + this.options.id + '_grid').css('display', 'none');
    $('#' + this.options.id + '_form').css('display', 'block');
    this.showType = 'form';
    if (typeof this.options.afterCreate == 'function') {
        this.options.afterCreate.call(this);
    }
}
700449
function() {
            var self            = this,
                transformName   = '',
                effectsIn       = self.config.animation.effectsIn || self.config.animation.effects,
                effectsOut      = self.config.animation.effectsOut || self.config.animation.effects;

            self.callActions('beforeParseEffects', arguments);

            self.effectsIn      = new mixitup.StyleData();
            self.effectsOut     = new mixitup.StyleData();
            self.transformIn    = [];
            self.transformOut   = [];

            self.effectsIn.opacity = self.effectsOut.opacity = 1;

            self.parseEffect('fade', effectsIn, self.effectsIn, self.transformIn);
            self.parseEffect('fade', effectsOut, self.effectsOut, self.transformOut, true);

            for (transformName in mixitup.transformDefaults) {
                if (!(mixitup.transformDefaults[transformName] instanceof mixitup.TransformData)) {
                    continue;
                }

                self.parseEffect(transformName, effectsIn, self.effectsIn, self.transformIn);
                self.parseEffect(transformName, effectsOut, self.effectsOut, self.transformOut, true);
            }

            self.parseEffect('stagger', effectsIn, self.effectsIn, self.transformIn);
            self.parseEffect('stagger', effectsOut, self.effectsOut, self.transformOut, true);

            self.callActions('afterParseEffects', arguments);
        }
247142
function _animate(handle, runAnimation, enabledElement, targetLocation) {
  if (!runAnimation.value) {
    return;
  }

  // Pixels / second
  const distanceRemaining = Math.abs(handle.y - targetLocation.y);
  const linearDistEachFrame = distanceRemaining / 10;

  if (distanceRemaining < 1) {
    handle.y = targetLocation.y;
    runAnimation.value = false;

    return;
  }

  if (handle.y > targetLocation.y) {
    handle.y -= linearDistEachFrame;
  } else if (handle.y < targetLocation.y) {
    handle.y += linearDistEachFrame;
  }

  // Update the image
  external.cornerstone.updateImage(enabledElement.element);

  // Request a new frame
  external.cornerstone.requestAnimationFrame(function() {
    _animate(handle, runAnimation, enabledElement, targetLocation);
  });
}
386065
function _animateFunc(func, element, duration, opts) {
  opts = Object.assign({}, opts);
  var tween;
  return new Promise(function(resolve, reject, onCancel) {
    opts.onComplete = resolve;
    tween = func(element, duration, opts);
    onCancel &&
      onCancel(function() {
        tween.kill();
      });
  });
}
963910
function(css) {
  css = css
    // remove comments
    .replace(/\/\*[^\0]*?\*\//g, '')
    // trim space before characters
    .replace(/\s+({|})/g, '$1')
    // trim space after characters
    .replace(/(;|,|:|{|}|^)\s+/g, '$1')
    // trim combinators
    .replace(/\s+(>|\+|~)\s+/g, '$1')
    // remove escaped newlines and spaces
    .replace(/\\\r?\n\s+/g, '')
    // remove trailing semicolons in rules
    .replace(/;(})/g, '$1');

  return css;
}
9531
function () {
        if (this.element && this._container && this._outline) {
            var items = this.element.querySelectorAll('.u-menu-item');

            // Remove all transition delays; menu items fade out concurrently.
            for (var i = 0; i < items.length; i++) {
                items[i].style.transitionDelay = null;
            }

            // Measure the inner element.
            var rect = this.element.getBoundingClientRect();
            var height = rect.height;
            var width = rect.width;

            if(!width){
                var left = rect.left;
                var right = rect.right;
                width = right - left;
            }

            if(!height){
                var top = rect.top;
                var bottom = rect.bottom;
                height = bottom - top;
            }

            // Turn on animation, and apply the final clip. Also make invisible.
            // This triggers the transitions.
            u.addClass(this.element, 'is-animating');
            this._applyClip(height, width);
            u.removeClass(this._container, 'is-visible');

            // Clean up after the animation is complete.
            this._addAnimationEndListener();
        }
    }
415879
function() {
      var editor = $('<div></div>').addClass('kelmu-editor').css('z-order', '60000');
      editor.css('position', 'absolute').css('top', '10px').css('left', (container.children('div').last().outerWidth() + 100) + 'px');
      editor.css('border-radius', '5px').css('box-shadow', '3px 3px 5px #888888').css('background-color', '#FFFAE5');
      editor.css('padding', '10').css('cursor', 'move').draggable();
      editor.appendTo(container);

      editor.append($('<h3>Annotation editor</h3>').css('margin', '5px 0px'));

      // *********************************************************************************************************

      var statusView = $('<div></div>').text('Step 1, substep 1 of 1').addClass('kelmu-editor-status');
      statusView.appendTo(editor);

      // *********************************************************************************************************

      var generalButtons = $('<div></div>').addClass('kelmu-editor-general-buttons');
      generalButtons.appendTo(editor);

      $('<button></button>').text('Settings').addClass('btn').appendTo(generalButtons).click(function(e) {
        e.preventDefault();
        container.find('.kelmu-editor-pane').remove();
        editor.css('height', '');
        editor.css('width', '');
        window.kelmu.data[id].selectedElementNumber = -1;
        window.kelmu.data[id].previousSelectedElementNumber = -1;

        var settingsPanel = $('<div></div>').addClass('kelmu-editor-pane').appendTo(editor);

        addComponent('Length (ms)', settingsPanel, 'kelmu-editor-animation-length', window.kelmu.data[id].settings.animationLength, 'text');

        var helpShown = false;

        var pickerFunction = function() {

          if (!helpShown) {
            alert('Move the mouse cursor on top of the button and\nkeep moving the cursor until it gets a green border.');
            helpShown = true;
          }

          buttonPickerEnabled = true;
          element.find('a, button').css('border', '');
          if (!buttonPickerCreated) {
            createButtonPicker();
          }
        };

        addComponent('Begin button', settingsPanel, 'kelmu-editor-begin-button', window.kelmu.data[id].settings.begin, 'text');
        $('<br>').appendTo(settingsPanel);
        $('<button></button>').text('Point Begin button').appendTo(settingsPanel).click(function(e) {
          e.preventDefault();
          buttonToPick = 'begin';
          pickerFunction();
        });
        $('<br>').appendTo(settingsPanel);

        addComponent('Undo button', settingsPanel, 'kelmu-editor-undo-button', window.kelmu.data[id].settings.undo, 'text');
        $('<br>').appendTo(settingsPanel);
        $('<button></button>').text('Point Undo button').appendTo(settingsPanel).click(function(e) {
          e.preventDefault();
          buttonToPick = 'undo';
          pickerFunction();
        });
        $('<br>').appendTo(settingsPanel);

        addComponent('Step button', settingsPanel, 'kelmu-editor-step-button', window.kelmu.data[id].settings.step, 'text');
        $('<br>').appendTo(settingsPanel);
        $('<button></button>').text('Point Step button').appendTo(settingsPanel).click(function(e) {
          e.preventDefault();
          buttonToPick = 'step';
          pickerFunction();
        });
        $('<br>').appendTo(settingsPanel);

        addComponent('Redo button', settingsPanel, 'kelmu-editor-redo-button', window.kelmu.data[id].settings.redo, 'text');
        $('<br>').appendTo(settingsPanel);
        $('<button></button>').text('Point Redo button').appendTo(settingsPanel).click(function(e) {
          e.preventDefault();
          buttonToPick = 'redo';
          pickerFunction();
        });
        $('<br>').appendTo(settingsPanel);

        $('<button></button>').text('Save settings').appendTo($('<p></p>').appendTo(settingsPanel)).click(function(e) {
          e.preventDefault();

          window.kelmu.data[id].settings.animationLength = parseInt(settingsPanel.find('.kelmu-editor-animation-length').val(), 10);
          window.kelmu.data[id].settings.undo = settingsPanel.find('.kelmu-editor-undo-button').val();
          window.kelmu.data[id].settings.step = settingsPanel.find('.kelmu-editor-step-button').val();
          window.kelmu.data[id].settings.redo = settingsPanel.find('.kelmu-editor-redo-button').val();
          window.kelmu.data[id].settings.begin = settingsPanel.find('.kelmu-editor-begin-button').val();

          buttonPickerEnabled = false;

          window.kelmu.data[id].actions.update();
          updateView(true, true);
          window.kelmu.data[id].actions.initButtons();

          alert('Settings saved.');

        });

      });

      $('<button></button>').text('Import').addClass('btn').appendTo(generalButtons).click(function(e) {
        e.preventDefault();
        container.find('.kelmu-editor-pane').remove();
        editor.css('height', '');
        editor.css('width', '');
        window.kelmu.data[id].selectedElementNumber = -1;
        window.kelmu.data[id].previousSelectedElementNumber = -1;

        var importPanel = $('<div></div>').addClass('kelmu-editor-pane').appendTo(editor);
        var helpLabel = $('<p></p>').css('font-size', '11px').appendTo(importPanel);
        helpLabel.text('Copy and paste the definition below.');
        var textarea = $('<textarea></textarea>').appendTo(importPanel);
        textarea.css('font-size', '10px').css('min-height', '200px');
        $('<button></button>').text('Import').appendTo($('<p></p>').appendTo(importPanel)).click(function(e) {
          e.preventDefault();

          var text = textarea.val().trim();
          if (text.indexOf('kelmuCb(') >= 0) {
            text = text.substring(8, text.length - 1);
          }

          try {
            var parsed = JSON.parse(text);
            if (parsed[id] && parsed[id].settings && parsed[id].definitions) {
              window.kelmu.data[id].settings = parsed[id].settings;
              window.kelmu.data[id].definitions = parsed[id].definitions;
              alert('Definitions succesfully imported.');
              window.kelmu.data[id].actions.update();
              updateView(true, true);
              window.kelmu.data[id].actions.initButtons();
            } else {
              alert('Definition for ' + id + ' was not found or it is incomplete!');
            }
          } catch (error) {
            alert('Malformed definition!');
          }

        });
      });

      $('<button></button>').text('Export').addClass('btn').appendTo(generalButtons).click(function(e) {
        e.preventDefault();
        container.find('.kelmu-editor-pane').remove();
        editor.css('height', '');
        editor.css('width', '');
        window.kelmu.data[id].selectedElementNumber = -1;
        window.kelmu.data[id].previousSelectedElementNumber = -1;

        var exportedData = {};
        exportedData[id] = { definitions: window.kelmu.data[id].definitions, settings: window.kelmu.data[id].settings };

        var exportPanel = $('<div></div>').addClass('kelmu-editor-pane').appendTo(editor);
        var helpLabel = $('<p></p>').css('font-size', '11px').appendTo(exportPanel);
        helpLabel.text('Copy and paste the following definition in a file with extension .jsonp');
        var textarea = $('<textarea></textarea>').appendTo(exportPanel);
        textarea.css('font-size', '10px').css('min-height', '200px');
        textarea.val('kelmuCb(' + JSON.stringify(exportedData) + ')');
      });

      // *********************************************************************************************************

      var buttons = $('<div></div>').addClass('kelmu-editor-move-buttons');
      buttons.appendTo(editor);

      // Previous substep
      $('<button></button>').text('<').addClass('btn').appendTo(buttons).click(function(e) {
        e.preventDefault();
        if (window.kelmu.data[id].subStepNumber > 0) {
          window.kelmu.data[id].actions.setSubstep(window.kelmu.data[id].subStepNumber - 1);
        }
        window.kelmu.data[id].selectedElementNumber = -1;
        updateView(true, false);
      });

      // Next substep
      $('<button></button>').text('>').addClass('btn').appendTo(buttons).click(function(e) {
        e.preventDefault();
        if (window.kelmu.data[id].subStepNumber < (window.kelmu.data[id].definitions['step' + window.kelmu.data[id].stepNumber] || []).length - 1) {
          window.kelmu.data[id].actions.setSubstep(window.kelmu.data[id].subStepNumber + 1);
        }
        window.kelmu.data[id].selectedElementNumber = -1;
        updateView(true, false);
      });

      // New substep
      $('<button></button>').text('+Substep').addClass('btn').appendTo(buttons).click(function(e) {
        e.preventDefault();

        if (!window.kelmu.data[id].definitions['step' + window.kelmu.data[id].stepNumber]) {
          // Create new definition block for the substep
          window.kelmu.data[id].definitions['step' + window.kelmu.data[id].stepNumber] = [[]];
        }

        window.kelmu.data[id].definitions['step' + window.kelmu.data[id].stepNumber].splice(window.kelmu.data[id].subStepNumber + 1, 0, []);
        window.kelmu.data[id].actions.setSubstep(window.kelmu.data[id].subStepNumber + 1);
        window.kelmu.data[id].selectedElementNumber = -1;
        updateView(true, false);
        notifyModifications();
      });

      // Remove substep
      $('<button></button>').text('-Substep').addClass('btn').appendTo(buttons).click(function(e) {
        e.preventDefault();
        if ((window.kelmu.data[id].definitions['step' + window.kelmu.data[id].stepNumber] || []).length > 1) {
          if (confirm('Do you really want to remove this substep?')) {
            // Remove the definition block and make sure that the substep in the editor exists
            window.kelmu.data[id].definitions['step' + window.kelmu.data[id].stepNumber].splice(window.kelmu.data[id].subStepNumber, 1);
            window.kelmu.data[id].actions.setSubstep(Math.max(window.kelmu.data[id].subStepNumber - 1, 0));
          }

          window.kelmu.data[id].selectedElementNumber = -1;
          updateView(true, false);
          notifyModifications();
        } else {
          alert('You cannot remove the only substep!');
        }
      });

      // *********************************************************************************************************

      var newButtons = $('<div></div>').addClass('kelmu-editor-new-buttons');
      newButtons.appendTo(editor);

      var createNewButton = function(name, defaults, values) {
        return $('<button></button>').text(name).addClass('btn').appendTo(newButtons).click(function(e) {
          e.preventDefault();
          var data = window.kelmu.data[id];

          // Create new definition array for this step if it doesn't exist
          if (!data.definitions['step' + data.stepNumber]) {
            data.definitions['step' + data.stepNumber] = [[]];
          }

          data.definitions['step' + data.stepNumber][data.subStepNumber].push($.extend({}, values, defaults));
          data.selectedElementNumber = data.definitions['step' + data.stepNumber][data.subStepNumber].length - 1;
          data.actions.update();
          updateView(true, true);
          notifyModifications();
        });
      };

      // New text annotation
      createNewButton('+Text', window.kelmu.defaults.text, {
        text: 'New text',
        width: 400,
        height: 80,
        left: 10,
        top: 10
      }).appendTo(newButtons);

      // New arrow
      createNewButton('+Arrow', window.kelmu.defaults.arrow, {
        y1: 10,
        x1: 10,
        y2: 60,
        x2: 60
      }).appendTo(newButtons);

      // New line annotation
      createNewButton('+Line', window.kelmu.defaults.line, {
        y1: 10,
        x1: 10,
        y2: 60,
        x2: 60
      }).appendTo(newButtons);

      // New button
      createNewButton('+Button', window.kelmu.defaults.button, {}).appendTo(newButtons);

      // New action event
      createNewButton('+Action', window.kelmu.defaults.action, {}).appendTo(newButtons);

      // New sound
      createNewButton('+Sound', window.kelmu.defaults.sound, {}).click(function(e) {
        e.preventDefault();
        container.find('.kelmu-sound-control').show();
      }).appendTo(newButtons);

      // *********************************************************************************************************
      var componentPanel = $('<div></div>').addClass('kelmu-editor-components');
      componentPanel.appendTo(editor);

      // *********************************************************************************************************

      return editor;

    }
1013922
function(variables) {
        var animation = false,
        animationstring = 'animation',
        keyframeprefix = '',
        domPrefixes = ["Webkit", "Moz", "O", "ms", "Khtml"],
        pfx = '',
        elm = document.querySelector("body");

        if( elm.style.animationName !== undefined ) { animation = true; }
        if( animation === false ) {
            for( var i = 0; i < domPrefixes.length; i++ ) {
                if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
                    pfx = domPrefixes[ i ];
                    animationstring = pfx + 'Animation';
                    keyframeprefix = '-' + pfx.toLowerCase() + '-';
                    animation = true;
                    break;
                }
            }
        }
        variables.keyframesPrefix = keyframeprefix;
        variables.animationString = animationstring;
        variables.aliases = {
            transform: keyframeprefix + "transform"
        };
        variables.count = 1;
    }
31306
function onShow(scope, element, opts) {
      sanitizeAndConfigure(opts);

      if (opts.menuContentEl[0]) {
        // Inherit the theme from the target element.
        $mdTheming.inherit(opts.menuContentEl, opts.target);
      } else {
        $log.warn(
          '$mdMenu: Menu elements should always contain a `md-menu-content` element,' +
          'otherwise interactivity features will not work properly.',
          element
        );
      }

      // Register various listeners to move menu on resize/orientation change
      opts.cleanupResizing = startRepositioningOnResize();
      opts.hideBackdrop = showBackdrop(scope, element, opts);

      // Return the promise for when our menu is done animating in
      return showMenu()
        .then(function(response) {
          opts.alreadyOpen = true;
          opts.cleanupInteraction = activateInteraction();
          opts.cleanupBackdrop = setupBackdrop();

          // Since the menu finished its animation, mark the menu as clickable.
          element.addClass('md-clickable');

          return response;
        });

      /**
       * Place the menu into the DOM and call positioning related functions
       */
      function showMenu() {
        opts.parent.append(element);
        element[0].style.display = '';

        return $q(function(resolve) {
          var position = calculateMenuPosition(element, opts);

          element.removeClass('md-leave');

          // Animate the menu scaling, and opacity [from its position origin (default == top-left)]
          // to normal scale.
          $animateCss(element, {
            addClass: 'md-active',
            from: animator.toCss(position),
            to: animator.toCss({transform: ''})
          })
          .start()
          .then(resolve);

        });
      }

      /**
       * Check for valid opts and set some sane defaults
       */
      function sanitizeAndConfigure() {
        if (!opts.target) {
          throw Error(
            '$mdMenu.show() expected a target to animate from in options.target'
          );
        }
        angular.extend(opts, {
          alreadyOpen: false,
          isRemoved: false,
          target: angular.element(opts.target), // make sure it's not a naked DOM node
          parent: angular.element(opts.parent),
          menuContentEl: angular.element(element[0].querySelector('md-menu-content'))
        });
      }

      /**
       * Configure various resize listeners for screen changes
       */
      function startRepositioningOnResize() {

        var repositionMenu = (function(target, options) {
          return $$rAF.throttle(function() {
            if (opts.isRemoved) return;
            var position = calculateMenuPosition(target, options);

            target.css(animator.toCss(position));
          });
        })(element, opts);

        $window.addEventListener('resize', repositionMenu);
        $window.addEventListener('orientationchange', repositionMenu);

        return function stopRepositioningOnResize() {

          // Disable resizing handlers
          $window.removeEventListener('resize', repositionMenu);
          $window.removeEventListener('orientationchange', repositionMenu);

        };
      }

      /**
       * Sets up the backdrop and listens for click elements.
       * Once the backdrop will be clicked, the menu will automatically close.
       * @returns {!Function} Function to remove the backdrop.
       */
      function setupBackdrop() {
        if (!opts.backdrop) return angular.noop;

        opts.backdrop.on('click', onBackdropClick);

        return function() {
          opts.backdrop.off('click', onBackdropClick);
        };
      }

      /**
       * Function to be called whenever the backdrop is clicked.
       * @param {!MouseEvent} event
       */
      function onBackdropClick(event) {
        event.preventDefault();
        event.stopPropagation();

        scope.$apply(function() {
          opts.mdMenuCtrl.close(true, { closeAll: true });
        });
      }

      /**
       * Activate interaction on the menu. Resolves the focus target and closes the menu on
       * escape or option click.
       * @returns {!Function} Function to deactivate the interaction listeners.
       */
      function activateInteraction() {
        if (!opts.menuContentEl[0]) return angular.noop;

        // Wire up keyboard listeners.
        // - Close on escape,
        // - focus next item on down arrow,
        // - focus prev item on up
        opts.menuContentEl.on('keydown', onMenuKeyDown);
        opts.menuContentEl[0].addEventListener('click', captureClickListener, true);

        // kick off initial focus in the menu on the first enabled element
        var focusTarget = opts.menuContentEl[0]
          .querySelector(prefixer.buildSelector(['md-menu-focus-target', 'md-autofocus']));

        if (!focusTarget) {
          var childrenLen = opts.menuContentEl[0].children.length;
          for (var childIndex = 0; childIndex < childrenLen; childIndex++) {
            var child = opts.menuContentEl[0].children[childIndex];
            focusTarget = child.querySelector('.md-button:not([disabled])');
            if (focusTarget) {
              break;
            }
            if (child.firstElementChild && !child.firstElementChild.disabled) {
              focusTarget = child.firstElementChild;
              break;
            }
          }
        }

        focusTarget && focusTarget.focus();

        return function cleanupInteraction() {
          opts.menuContentEl.off('keydown', onMenuKeyDown);
          opts.menuContentEl[0].removeEventListener('click', captureClickListener, true);
        };

        // ************************************
        // internal functions
        // ************************************

        function onMenuKeyDown(ev) {
          var handled;
          switch (ev.keyCode) {
            case $mdConstant.KEY_CODE.ESCAPE:
              opts.mdMenuCtrl.close(false, { closeAll: true });
              handled = true;
              break;
            case $mdConstant.KEY_CODE.TAB:
              opts.mdMenuCtrl.close(false, { closeAll: true });
              // Don't prevent default or stop propagation on this event as we want tab
              // to move the focus to the next focusable element on the page.
              handled = false;
              break;
            case $mdConstant.KEY_CODE.UP_ARROW:
              if (!focusMenuItem(ev, opts.menuContentEl, opts, -1) && !opts.nestLevel) {
                opts.mdMenuCtrl.triggerContainerProxy(ev);
              }
              handled = true;
              break;
            case $mdConstant.KEY_CODE.DOWN_ARROW:
              if (!focusMenuItem(ev, opts.menuContentEl, opts, 1) && !opts.nestLevel) {
                opts.mdMenuCtrl.triggerContainerProxy(ev);
              }
              handled = true;
              break;
            case $mdConstant.KEY_CODE.LEFT_ARROW:
              if (opts.nestLevel) {
                opts.mdMenuCtrl.close();
              } else {
                opts.mdMenuCtrl.triggerContainerProxy(ev);
              }
              handled = true;
              break;
            case $mdConstant.KEY_CODE.RIGHT_ARROW:
              var parentMenu = $mdUtil.getClosest(ev.target, 'MD-MENU');
              if (parentMenu && parentMenu != opts.parent[0]) {
                ev.target.click();
              } else {
                opts.mdMenuCtrl.triggerContainerProxy(ev);
              }
              handled = true;
              break;
          }
          if (handled) {
            ev.preventDefault();
            ev.stopImmediatePropagation();
          }
        }

        function onBackdropClick(e) {
          e.preventDefault();
          e.stopPropagation();
          scope.$apply(function() {
            opts.mdMenuCtrl.close(true, { closeAll: true });
          });
        }

        // Close menu on menu item click, if said menu-item is not disabled
        function captureClickListener(e) {
          var target = e.target;
          // Traverse up the event until we get to the menuContentEl to see if
          // there is an ng-click and that the ng-click is not disabled
          do {
            if (target == opts.menuContentEl[0]) return;
            if ((hasAnyAttribute(target, ['ng-click', 'ng-href', 'ui-sref']) ||
                target.nodeName == 'BUTTON' || target.nodeName == 'MD-BUTTON') && !hasAnyAttribute(target, ['md-prevent-menu-close'])) {
              var closestMenu = $mdUtil.getClosest(target, 'MD-MENU');
              if (!target.hasAttribute('disabled') && (!closestMenu || closestMenu == opts.parent[0])) {
                close();
              }
              break;
            }
          } while (target = target.parentNode);

          function close() {
            scope.$apply(function() {
              opts.mdMenuCtrl.close(true, { closeAll: true });
            });
          }

          function hasAnyAttribute(target, attrs) {
            if (!target) return false;

            for (var i = 0, attr; attr = attrs[i]; ++i) {
              if (prefixer.hasAttribute(target, attr)) {
                return true;
              }
            }

            return false;
          }
        }

      }
    }
475966
function getTransition(properties, duration, easing, delay) {
    // Get the CSS properties needed.
    var props = getProperties(properties);

    // Account for aliases (`in` => `ease-in`).
    if ($.cssEase[easing]) { easing = $.cssEase[easing]; }

    // Build the duration/easing/delay attributes for it.
    var attribs = '' + toMS(duration) + ' ' + easing;
    if (parseInt(delay, 10) > 0) { attribs += ' ' + toMS(delay); }

    // For more properties, add them this way:
    // "margin 200ms ease, padding 200ms ease, ..."
    var transitions = [];
    $.each(props, function(i, name) {
      transitions.push(name + ' ' + attribs);
    });

    return transitions.join(', ');
  }