text: /*
   * ngDialog - easy modals and popup windows
   * http://github.com/likeastore/ngDialog
   * (c) 2013-2015 MIT License, https://likeastore.com
   */
  
   
  
  (function() {
  
     
      'use strict';
  
      var m = angular.module('ngDialog', []);
  
      var $el = angular.element;
      var isDef = angular.isDefined;
      var style = (document.body || document.documentElement).style;
      var animationEndSupport = isDef(style.animation) || isDef(style.WebkitAnimation) || isDef(style.MozAnimation) || isDef(style.MsAnimation) || isDef(style.OAnimation);
      var animationEndEvent = 'animationend webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend';
      var focusableElementSelector = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]';
      var forceBodyReload = false;
      var scope;
  
      m.provider('ngDialog', function () {
          var defaults = this.defaults = {
              className: 'ngdialog-theme-default',
              plain: false,
              showClose: true,
              closeByDocument: true,
              closeByEscape: true,
              closeByNavigation: false,
              appendTo: false,
              preCloseCallback: false,
              overlay: true,
              cache: true,
              trapFocus: true,
              preserveFocus: true,
              ariaAuto: true,
              ariaRole: null,
              ariaLabelledById: null,
              ariaLabelledBySelector: null,
              ariaDescribedById: null,
              ariaDescribedBySelector: null
          };
  
          this.setForceBodyReload = function (_useIt) {
              forceBodyReload = _useIt || false;
          };
  
          this.setDefaults = function (newDefaults) {
              angular.extend(defaults, newDefaults);
          };
  
          var globalID = 0, dialogsCount = 0, closeByDocumentHandler, defers = {};
  
          this.$get = ['$document', '$templateCache', '$compile', '$q', '$http', '$rootScope', '$timeout', '$window', '$controller',
              function ($document, $templateCache, $compile, $q, $http, $rootScope, $timeout, $window, $controller) {
                  var $body = $document.find('body');
                  if (forceBodyReload) {
                      $rootScope.$on('$locationChangeSuccess', function () {
                          $body = $document.find('body');
                      });
                  }
  
                  var privateMethods = {
                      onDocumentKeydown: function (event) {
                          if (event.keyCode === 27) {
                              publicMethods.close('$escape');
                          }
                      },
  
                      activate: function($dialog) {
                          var options = $dialog.data('$ngDialogOptions');
  
                          if (options.trapFocus) {
                              $dialog.on('keydown', privateMethods.onTrapFocusKeydown);
  
                              // Catch rogue changes (eg. after unfocusing everything by clicking a non-focusable element)
                              $body.on('keydown', privateMethods.onTrapFocusKeydown);
                          }
                      },
  
                      deactivate: function($dialog) {
                          $dialog.off('keydown', privateMethods.onTrapFocusKeydown);
                          $body.off('keydown', privateMethods.onTrapFocusKeydown);
                      },
  
                      deactivateAll: function($all) {
                          angular.forEach(function(el) {
                              var $dialog = angular.element(el);
                              privateMethods.deactivate($dialog);
                          });
                      },
  
                      setBodyPadding: function (width) {
                          var originalBodyPadding = parseInt(($body.css('padding-right') || 0), 10);
                          $body.css('padding-right', (originalBodyPadding + width) + 'px');
                          $body.data('ng-dialog-original-padding', originalBodyPadding);
                      },
  
                      resetBodyPadding: function () {
                          var originalBodyPadding = $body.data('ng-dialog-original-padding');
                          if (originalBodyPadding) {
                              $body.css('padding-right', originalBodyPadding + 'px');
                          } else {
                              $body.css('padding-right', '');
                          }
                      },
  
                      performCloseDialog: function ($dialog, value) {
                          var id = $dialog.attr('id');
  
                          if (typeof $window.Hammer !== 'undefined') {
                              var hammerTime = scope.hammerTime;
                              hammerTime.off('tap', closeByDocumentHandler);
                              hammerTime.destroy && hammerTime.destroy();
                              delete scope.hammerTime;
                          } else {
                              $dialog.unbind('click');
                          }
  
                          if (dialogsCount === 1) {
                              $body.unbind('keydown');
                          }
  
                          if (!$dialog.hasClass("ngdialog-closing")){
                              dialogsCount -= 1;
                          }
  
                          var previousFocus = $dialog.data('$ngDialogPreviousFocus');
                          if (previousFocus) {
                              previousFocus.focus();
                          }
  
                          $rootScope.$broadcast('ngDialog.closing', $dialog);
                          dialogsCount = dialogsCount < 0 ? 0: dialogsCount;
                          if (animationEndSupport) {
                              scope.$destroy();
                              $dialog.unbind(animationEndEvent).bind(animationEndEvent, function () {
                                  $dialog.remove();
                                  if (dialogsCount === 0) {
                                      $body.removeClass('ngdialog-open');
                                      privateMethods.resetBodyPadding();
                                  }
                                  $rootScope.$broadcast('ngDialog.closed', $dialog);
                              }).addClass('ngdialog-closing');
                          } else {
                              scope.$destroy();
                              $dialog.remove();
                              if (dialogsCount === 0) {
                                  $body.removeClass('ngdialog-open');
                                  privateMethods.resetBodyPadding();
                              }
                              $rootScope.$broadcast('ngDialog.closed', $dialog);
                          }
                          if (defers[id]) {
                              defers[id].resolve({
                                  id: id,
                                  value: value,
                                  $dialog: $dialog,
                                  remainingDialogs: dialogsCount
                              });
                              delete defers[id];
                          }
                      },
  
                      closeDialog: function ($dialog, value) {
                          var preCloseCallback = $dialog.data('$ngDialogPreCloseCallback');
  
                          if (preCloseCallback && angular.isFunction(preCloseCallback)) {
  
                              var preCloseCallbackResult = preCloseCallback.call($dialog, value);
  
                              if (angular.isObject(preCloseCallbackResult)) {
                                  if (preCloseCallbackResult.closePromise) {
                                      preCloseCallbackResult.closePromise.then(function () {
                                          privateMethods.performCloseDialog($dialog, value);
                                      });
                                  } else {
                                      preCloseCallbackResult.then(function () {
                                          privateMethods.performCloseDialog($dialog, value);
                                      }, function () {
                                          return;
                                      });
                                  }
                              } else if (preCloseCallbackResult !== false) {
                                  privateMethods.performCloseDialog($dialog, value);
                              }
                          } else {
                              privateMethods.performCloseDialog($dialog, value);
                          }
                      },
  
                      onTrapFocusKeydown: function(ev) {
                          var el = angular.element(ev.currentTarget);
                          var $dialog;
  
                          if (el.hasClass('ngdialog')) {
                              $dialog = el;
                          } else {
                              $dialog = privateMethods.getActiveDialog();
  
                              if ($dialog === null) {
                                  return;
                              }
                          }
  
                          var isTab = (ev.keyCode === 9);
                          var backward = (ev.shiftKey === true);
  
                          if (isTab) {
                              privateMethods.handleTab($dialog, ev, backward);
                          }
                      },
  
                      handleTab: function($dialog, ev, backward) {
                          var focusableElements = privateMethods.getFocusableElements($dialog);
  
                          if (focusableElements.length === 0) {
                              if (document.activeElement) {
                                  document.activeElement.blur();
                              }
                              return;
                          }
  
                          var currentFocus = document.activeElement;
                          var focusIndex = Array.prototype.indexOf.call(focusableElements, currentFocus);
  
                          var isFocusIndexUnknown = (focusIndex === -1);
                          var isFirstElementFocused = (focusIndex === 0);
                          var isLastElementFocused = (focusIndex === focusableElements.length - 1);
  
                          var cancelEvent = false;
  
                          if (backward) {
                              if (isFocusIndexUnknown || isFirstElementFocused) {
                                  focusableElements[focusableElements.length - 1].focus();
                                  cancelEvent = true;
                              }
                          } else {
                              if (isFocusIndexUnknown || isLastElementFocused) {
                                  focusableElements[0].focus();
                                  cancelEvent = true;
                              }
                          }
  
                          if (cancelEvent) {
                              ev.preventDefault();
                              ev.stopPropagation();
                          }
                      },
  
                      autoFocus: function($dialog) {
                          var dialogEl = $dialog[0];
  
                          // Browser's (Chrome 40, Forefix 37, IE 11) don't appear to honor autofocus on the dialog, but we should
                          var autoFocusEl = dialogEl.querySelector('*[autofocus]');
                          if (autoFocusEl !== null) {
                              autoFocusEl.focus();
  
                              if (document.activeElement === autoFocusEl) {
                                  return;
                              }
  
                              // Autofocus element might was display: none, so let's continue
                          }
  
                          var focusableElements = privateMethods.getFocusableElements($dialog);
  
                          if (focusableElements.length > 0) {
                              focusableElements[0].focus();
                              return;
                          }
  
                          // We need to focus something for the screen readers to notice the dialog
                          var contentElements = privateMethods.filterVisibleElements(dialogEl.querySelectorAll('h1,h2,h3,h4,h5,h6,p,span'));
  
                          if (contentElements.length > 0) {
                              var contentElement = contentElements[0];
                              $el(contentElement).attr('tabindex', '0');
                              contentElement.focus();
                          }
                      },
  
                      getFocusableElements : function($dialog) {
                          var dialogEl = $dialog[0];
  
                          var rawElements = dialogEl.querySelectorAll(focusableElementSelector);
  
                          return privateMethods.filterVisibleElements(rawElements);
                      },
  
                      filterVisibleElements: function(els) {
                          var visibleFocusableElements = [];
  
                          for (var i=0; i<els.length; i++) {
                              var el = els[i];
  
                              if (el.offsetWidth > 0 || el.offsetHeight > 0) {
                                  visibleFocusableElements.push(el);
                              }
                          }
  
                          return visibleFocusableElements;
                      },
  
                      getActiveDialog: function() {
                          var dialogs = document.querySelectorAll('.ngdialog');
  
                          if (dialogs.length === 0) {
                              return null;
                          }
  
                          // TODO: This might be incorrect if there are a mix of open dialogs with different 'appendTo' values
                          return $el(dialogs[dialogs.length - 1]);
                      },
  
                      applyAriaAttributes: function($dialog, options) {
  
                          if (options.ariaAuto) {
                              if (!options.ariaRole) {
                                  var detectedRole = (privateMethods.getFocusableElements($dialog).length > 0) ?
                                      'dialog' :
                                      'alertdialog';
  
                                  options.ariaRole = detectedRole;
                              }
  
                              if (!options.ariaLabelledBySelector) {
                                  options.ariaLabelledBySelector = 'h1,h2,h3,h4,h5,h6';
                              }
  
                              if (!options.ariaDescribedBySelector) {
                                  options.ariaDescribedBySelector = 'article,section,p';
                              }
                          }
  
                          if (options.ariaRole) {
                              $dialog.attr('role', options.ariaRole);
                          }
  
                          privateMethods.applyAriaAttribute(
                              $dialog, 'aria-labelledby', options.ariaLabelledById, options.ariaLabelledBySelector);
  
                          privateMethods.applyAriaAttribute(
                              $dialog, 'aria-describedby', options.ariaDescribedById, options.ariaDescribedBySelector);
                      },
  
                      applyAriaAttribute: function($dialog, attr, id, selector) {
                          if (id) {
                              $dialog.attr(attr, id);
                          }
  
                          if (selector) {
                              var dialogId = $dialog.attr('id');
  
                              var firstMatch = $dialog[0].querySelector(selector);
  
                              if (!firstMatch) {
                                  return;
                              }
  
                              var generatedId = dialogId + '-' + attr;
  
                              $el(firstMatch).attr('id', generatedId);
  
                              $dialog.attr(attr, generatedId);
  
                              return generatedId;
                          }
                      }
                  };
  
                  var publicMethods = {
  
                      /*
                       * @param {Object} options:
                       * - template {String} - id of ng-template, url for partial, plain string (if enabled)
                       * - plain {Boolean} - enable plain string templates, default false
                       * - scope {Object}
                       * - controller {String}
                       * - className {String} - dialog theme class
                       * - showClose {Boolean} - show close button, default true
                       * - closeByEscape {Boolean} - default true
                       * - closeByDocument {Boolean} - default true
                       * - preCloseCallback {String|Function} - user supplied function name/function called before closing dialog (if set)
                       *
                       * @return {Object} dialog
                       */
                      open: function (opts) {
                          var self = this;
                          var options = angular.copy(defaults);
  
                          opts = opts || {};
                          angular.extend(options, opts);
  
                          globalID += 1;
  
                          self.latestID = 'ngdialog' + globalID;
  
                          var defer;
                          defers[self.latestID] = defer = $q.defer();
  
                          scope = angular.isObject(options.scope) ? options.scope.$new() : $rootScope.$new();
                          var $dialog, $dialogParent;
  
                          $q.when(loadTemplate(options.template || options.templateUrl)).then(function (template) {
  
                              $templateCache.put(options.template || options.templateUrl, template);
  
                              if (options.showClose) {
                                  template += '<div class="ngdialog-close"></div>';
                              }
  
                              self.$result = $dialog = $el('<div id="ngdialog' + globalID + '" class="ngdialog"></div>');
                              $dialog.html((options.overlay ?
                                  '<div class="ngdialog-overlay"></div><div class="ngdialog-content" role="document">' + template + '</div>' :
                                  '<div class="ngdialog-content" role="document">' + template + '</div>'));
  
                              $dialog.data('$ngDialogOptions', options);
  
                              if (options.data && angular.isString(options.data)) {
                                  var firstLetter = options.data.replace(/^\s*/, '')[0];
                                  scope.ngDialogData = (firstLetter === '{' || firstLetter === '[') ? angular.fromJson(options.data) : options.data;
                              } else if (options.data && angular.isObject(options.data)) {
                                  scope.ngDialogData = options.data;
                              }
  
                              if (options.controller && (angular.isString(options.controller) || angular.isArray(options.controller) || angular.isFunction(options.controller))) {
                                  var controllerInstance = $controller(options.controller, {
                                      $scope: scope,
                                      $element: $dialog
                                  });
                                  $dialog.data('$ngDialogControllerController', controllerInstance);
                              }
  
                              if (options.className) {
                                  $dialog.addClass(options.className);
                              }
  
                              if (options.appendTo && angular.isString(options.appendTo)) {
                                  $dialogParent = angular.element(document.querySelector(options.appendTo));
                              } else {
                                  $dialogParent = $body;
                              }
  
                              privateMethods.applyAriaAttributes($dialog, options);
  
                              if (options.preCloseCallback) {
                                  var preCloseCallback;
  
                                  if (angular.isFunction(options.preCloseCallback)) {
                                      preCloseCallback = options.preCloseCallback;
                                  } else if (angular.isString(options.preCloseCallback)) {
                                      if (scope) {
                                          if (angular.isFunction(scope[options.preCloseCallback])) {
                                              preCloseCallback = scope[options.preCloseCallback];
                                          } else if (scope.$parent && angular.isFunction(scope.$parent[options.preCloseCallback])) {
                                              preCloseCallback = scope.$parent[options.preCloseCallback];
                                          } else if ($rootScope && angular.isFunction($rootScope[options.preCloseCallback])) {
                                              preCloseCallback = $rootScope[options.preCloseCallback];
                                          }
                                      }
                                  }
  
                                  if (preCloseCallback) {
                                      $dialog.data('$ngDialogPreCloseCallback', preCloseCallback);
                                  }
                              }
  
                              scope.closeThisDialog = function (value) {
                                  privateMethods.closeDialog($dialog, value);
                              };
  
                              $timeout(function () {
                                  var $activeDialogs = document.querySelectorAll('.ngdialog');
                                  privateMethods.deactivateAll($activeDialogs);
  
                                  $compile($dialog)(scope);
                                  var widthDiffs = $window.innerWidth - $body.prop('clientWidth');
                                  $body.addClass('ngdialog-open');
                                  var scrollBarWidth = widthDiffs - ($window.innerWidth - $body.prop('clientWidth'));
                                  if (scrollBarWidth > 0) {
                                      privateMethods.setBodyPadding(scrollBarWidth);
                                  }
                                  $dialogParent.append($dialog);
  
                                  privateMethods.activate($dialog);
  
                                  if (options.trapFocus) {
                                      privateMethods.autoFocus($dialog);
                                  }
  
                                  if (options.name) {
                                      $rootScope.$broadcast('ngDialog.opened', {dialog: $dialog, name: options.name});
                                  } else {
                                      $rootScope.$broadcast('ngDialog.opened', $dialog);
                                  }
                              });
  
                              if (options.closeByEscape) {
                                  $body.bind('keydown', privateMethods.onDocumentKeydown);
                              }
  
                              if (options.closeByNavigation) {
                                  $rootScope.$on('$locationChangeSuccess', function () {
                                      privateMethods.closeDialog($dialog);
                                  });
                              }
  
                              if (options.preserveFocus) {
                                  $dialog.data('$ngDialogPreviousFocus', document.activeElement);
                              }
  
                              closeByDocumentHandler = function (event) {
                                  var isOverlay = options.closeByDocument ? $el(event.target).hasClass('ngdialog-overlay') : false;
                                  var isCloseBtn = $el(event.target).hasClass('ngdialog-close');
  
                                  if (isOverlay || isCloseBtn) {
                                      publicMethods.close($dialog.attr('id'), isCloseBtn ? '$closeButton' : '$document');
                                  }
                              };
  
                              if (typeof $window.Hammer !== 'undefined') {
                                  var hammerTime = scope.hammerTime = $window.Hammer($dialog[0]);
                                  hammerTime.on('tap', closeByDocumentHandler);
                              } else {
                                  $dialog.bind('click', closeByDocumentHandler);
                              }
  
                              dialogsCount += 1;
  
                              return publicMethods;
                          });
  
                          return {
                              id: 'ngdialog' + globalID,
                              closePromise: defer.promise,
                              close: function (value) {
                                  privateMethods.closeDialog($dialog, value);
                              }
                          };
  
                          function loadTemplateUrl (tmpl, config) {
                              return $http.get(tmpl, (config || {})).then(function(res) {
                                  return res.data || '';
                              });
                          }
  
                          function loadTemplate (tmpl) {
                              if (!tmpl) {
                                  return 'Empty template';
                              }
  
                              if (angular.isString(tmpl) && options.plain) {
                                  return tmpl;
                              }
  
                              if (typeof options.cache === 'boolean' && !options.cache) {
                                  return loadTemplateUrl(tmpl, {cache: false});
                              }
  
                              return $templateCache.get(tmpl) || loadTemplateUrl(tmpl, {cache: true});
                          }
                      },
  
                      /*
                       * @param {Object} options:
                       * - template {String} - id of ng-template, url for partial, plain string (if enabled)
                       * - plain {Boolean} - enable plain string templates, default false
                       * - name {String}
                       * - scope {Object}
                       * - controller {String}
                       * - className {String} - dialog theme class
                       * - showClose {Boolean} - show close button, default true
                       * - closeByEscape {Boolean} - default false
                       * - closeByDocument {Boolean} - default false
                       * - preCloseCallback {String|Function} - user supplied function name/function called before closing dialog (if set); not called on confirm
                       *
                       * @return {Object} dialog
                       */
                      openConfirm: function (opts) {
                          var defer = $q.defer();
  
                          var options = {
                              closeByEscape: false,
                              closeByDocument: false
                          };
                          angular.extend(options, opts);
  
                          options.scope = angular.isObject(options.scope) ? options.scope.$new() : $rootScope.$new();
                          options.scope.confirm = function (value) {
                              defer.resolve(value);
                              var $dialog = $el(document.getElementById(openResult.id));
                              privateMethods.performCloseDialog($dialog, value);
                          };
  
                          var openResult = publicMethods.open(options);
                          openResult.closePromise.then(function (data) {
                              if (data) {
                                  return defer.reject(data.value);
                              }
                              return defer.reject();
                          });
  
                          return defer.promise;
                      },
  
                      /*
                       * @param {String} id
                       * @return {Object} dialog
                       */
                      close: function (id, value) {
                          var $dialog = $el(document.getElementById(id));
  
                          if ($dialog.length) {
                              privateMethods.closeDialog($dialog, value);
                          } else {
                              publicMethods.closeAll(value);
                          }
  
                          return publicMethods;
                      },
  
                      closeAll: function (value) {
                          var $all = document.querySelectorAll('.ngdialog');
  
                          // Reverse order to ensure focus restorationi works as expected
                          for (var i=$all.length; i>-1; i--) {
                              var dialog = $all[i];
                              privateMethods.closeDialog($el(dialog), value);
                          }
                      },
  
                      getDefaults: function () {
                          return defaults;
                      }
                  };
  
                  return publicMethods;
              }];
      });
  
      m.directive('ngDialog', ['ngDialog', function (ngDialog) {
          return {
              restrict: 'A',
              scope : {
                  ngDialogScope : '='
              },
              link: function (scope, elem, attrs) {
                  elem.on('click', function (e) {
                      e.preventDefault();
  
                      var ngDialogScope = angular.isDefined(scope.ngDialogScope) ? scope.ngDialogScope : 'noScope';
                      angular.isDefined(attrs.ngDialogClosePrevious) && ngDialog.close(attrs.ngDialogClosePrevious);
  
                      var defaults = ngDialog.getDefaults();
  
                      ngDialog.open({
                          template: attrs.ngDialog,
                          className: attrs.ngDialogClass || defaults.className,
                          controller: attrs.ngDialogController,
                          scope: ngDialogScope,
                          data: attrs.ngDialogData,
                          showClose: attrs.ngDialogShowClose === 'false' ? false : (attrs.ngDialogShowClose === 'true' ? true : defaults.showClose),
                          closeByDocument: attrs.ngDialogCloseByDocument === 'false' ? false : (attrs.ngDialogCloseByDocument === 'true' ? true : defaults.closeByDocument),
                          closeByEscape: attrs.ngDialogCloseByEscape === 'false' ? false : (attrs.ngDialogCloseByEscape === 'true' ? true : defaults.closeByEscape),
                          preCloseCallback: attrs.ngDialogPreCloseCallback || defaults.preCloseCallback
                      });
                  });
              }
          };
      }]);
  
      return m;
  })();
  