text: (function(UI) {
  
      "use strict";
  
      var active = false, activeCount = 0, $html = UI.$html, body;
  
      UI.$win.on("resize orientationchange", UI.Utils.debounce(function(){
          UI.$('.uk-modal.uk-open').each(function(){
              UI.$(this).data('modal').resize();
          });
      }, 150));
  
      UI.component('modal', {
  
          defaults: {
              keyboard: true,
              bgclose: true,
              minScrollHeight: 150,
              center: false,
              modal: true
          },
  
          scrollable: false,
          transition: false,
          hasTransitioned: true,
  
          init: function() {
  
              if (!body) body = UI.$('body');
  
              if (!this.element.length) return;
  
              var $this = this;
  
              this.paddingdir = "padding-" + (UI.langdirection == 'left' ? "right":"left");
              this.dialog     = this.find(".uk-modal-dialog");
  
              this.active     = false;
  
              // Update ARIA
              this.element.attr('aria-hidden', this.element.hasClass("uk-open"));
  
              this.on("click", ".uk-modal-close", function(e) {
                  e.preventDefault();
                  $this.hide();
              }).on("click", function(e) {
  
                  var target = UI.$(e.target);
  
                  if (target[0] == $this.element[0] && $this.options.bgclose) {
                      $this.hide();
                  }
              });
  
              UI.domObserve(this.element, function(e) {
                  $this.resize();
              });
          },
  
          toggle: function() {
              return this[this.isActive() ? "hide" : "show"]();
          },
  
          show: function() {
  
              if (!this.element.length) return;
  
              var $this = this;
  
              if (this.isActive()) return;
  
              if (this.options.modal && active) {
                  active.hide(true);
              }
  
              this.element.removeClass("uk-open").show();
              this.resize();
  
              if (this.options.modal) {
                  active = this;
              }
  
              this.active = true;
  
              activeCount++;
  
              if (UI.support.transition) {
                  this.hasTransitioned = false;
                  this.element.one(UI.support.transition.end, function(){
                      $this.hasTransitioned = true;
                  }).addClass("uk-open");
              } else {
                  this.element.addClass("uk-open");
              }
  
              $html.addClass("uk-modal-page").height(); // force browser engine redraw
  
              // Update ARIA
              this.element.attr('aria-hidden', 'false');
  
              this.element.trigger("show.uk.modal");
  
              UI.Utils.checkDisplay(this.dialog, true);
  
              return this;
          },
  
          hide: function(force) {
  
              if (!force && UI.support.transition && this.hasTransitioned) {
  
                  var $this = this;
  
                  this.one(UI.support.transition.end, function() {
                      $this._hide();
                  }).removeClass("uk-open");
  
              } else {
  
                  this._hide();
              }
  
              return this;
          },
  
          resize: function() {
  
              var bodywidth  = body.width();
  
              this.scrollbarwidth = window.innerWidth - bodywidth;
  
              body.css(this.paddingdir, this.scrollbarwidth);
  
              this.element.css('overflow-y', this.scrollbarwidth ? 'scroll' : 'auto');
  
              if (!this.updateScrollable() && this.options.center) {
  
                  var dh  = this.dialog.outerHeight(),
                  pad = parseInt(this.dialog.css('margin-top'), 10) + parseInt(this.dialog.css('margin-bottom'), 10);
  
                  if ((dh + pad) < window.innerHeight) {
                      this.dialog.css({'top': (window.innerHeight/2 - dh/2) - pad });
                  } else {
                      this.dialog.css({'top': ''});
                  }
              }
          },
  
          updateScrollable: function() {
  
              // has scrollable?
              var scrollable = this.dialog.find('.uk-overflow-container:visible:first');
  
              if (scrollable.length) {
  
                  scrollable.css('height', 0);
  
                  var offset = Math.abs(parseInt(this.dialog.css('margin-top'), 10)),
                  dh     = this.dialog.outerHeight(),
                  wh     = window.innerHeight,
                  h      = wh - 2*(offset < 20 ? 20:offset) - dh;
  
                  scrollable.css({
                      'max-height': (h < this.options.minScrollHeight ? '':h),
                      'height':''
                  });
  
                  return true;
              }
  
              return false;
          },
  
          _hide: function() {
  
              this.active = false;
              if (activeCount > 0) activeCount--;
              else activeCount = 0;
  
              this.element.hide().removeClass('uk-open');
  
              // Update ARIA
              this.element.attr('aria-hidden', 'true');
  
              if (!activeCount) {
                  $html.removeClass('uk-modal-page');
                  body.css(this.paddingdir, "");
              }
  
              if(active===this) active = false;
  
              this.trigger('hide.uk.modal');
          },
  
          isActive: function() {
              return this.active;
          }
  
      });
  
      UI.component('modalTrigger', {
  
          boot: function() {
  
              // init code
              UI.$html.on("click.modal.uikit", "[data-uk-modal]", function(e) {
  
                  var ele = UI.$(this);
  
                  if (ele.is("a")) {
                      e.preventDefault();
                  }
  
                  if (!ele.data("modalTrigger")) {
                      var modal = UI.modalTrigger(ele, UI.Utils.options(ele.attr("data-uk-modal")));
                      modal.show();
                  }
  
              });
  
              // close modal on esc button
              UI.$html.on('keydown.modal.uikit', function (e) {
  
                  if (active && e.keyCode === 27 && active.options.keyboard) { // ESC
                      e.preventDefault();
                      active.hide();
                  }
              });
          },
  
          init: function() {
  
              var $this = this;
  
              this.options = UI.$.extend({
                  "target": $this.element.is("a") ? $this.element.attr("href") : false
              }, this.options);
  
              this.modal = UI.modal(this.options.target, this.options);
  
              this.on("click", function(e) {
                  e.preventDefault();
                  $this.show();
              });
  
              //methods
              this.proxy(this.modal, "show hide isActive");
          }
      });
  
      UI.modal.dialog = function(content, options) {
  
          var modal = UI.modal(UI.$(UI.modal.dialog.template).appendTo("body"), options);
  
          modal.on("hide.uk.modal", function(){
              if (modal.persist) {
                  modal.persist.appendTo(modal.persist.data("modalPersistParent"));
                  modal.persist = false;
              }
              modal.element.remove();
          });
  
          setContent(content, modal);
  
          return modal;
      };
  
      UI.modal.dialog.template = '<div class="uk-modal"><div class="uk-modal-dialog" style="min-height:0;"></div></div>';
  
      UI.modal.alert = function(content, options) {
  
          options = UI.$.extend(true, {bgclose:false, keyboard:false, modal:false, labels:UI.modal.labels}, options);
  
          var modal = UI.modal.dialog(([
              '<div class="uk-margin uk-modal-content">'+String(content)+'</div>',
              '<div class="uk-modal-footer uk-text-right"><button class="uk-button uk-button-primary uk-modal-close">'+options.labels.Ok+'</button></div>'
          ]).join(""), options);
  
          modal.on('show.uk.modal', function(){
              setTimeout(function(){
                  modal.element.find('button:first').focus();
              }, 50);
          });
  
          return modal.show();
      };
  
      UI.modal.confirm = function(content, onconfirm, oncancel) {
  
          var options = arguments.length > 1 && arguments[arguments.length-1] ? arguments[arguments.length-1] : {};
  
          onconfirm = UI.$.isFunction(onconfirm) ? onconfirm : function(){};
          oncancel  = UI.$.isFunction(oncancel) ? oncancel : function(){};
          options   = UI.$.extend(true, {bgclose:false, keyboard:false, modal:false, labels:UI.modal.labels}, UI.$.isFunction(options) ? {}:options);
  
          var modal = UI.modal.dialog(([
              '<div class="uk-margin uk-modal-content">'+String(content)+'</div>',
              '<div class="uk-modal-footer uk-text-right"><button class="uk-button js-modal-confirm-cancel">'+options.labels.Cancel+'</button> <button class="uk-button uk-button-primary js-modal-confirm">'+options.labels.Ok+'</button></div>'
          ]).join(""), options);
  
          modal.element.find(".js-modal-confirm, .js-modal-confirm-cancel").on("click", function(){
              UI.$(this).is('.js-modal-confirm') ? onconfirm() : oncancel();
              modal.hide();
          });
  
          modal.on('show.uk.modal', function(){
              setTimeout(function(){
                  modal.element.find('.js-modal-confirm').focus();
              }, 50);
          });
  
          return modal.show();
      };
  
      UI.modal.prompt = function(text, value, onsubmit, options) {
  
          onsubmit = UI.$.isFunction(onsubmit) ? onsubmit : function(value){};
          options  = UI.$.extend(true, {bgclose:false, keyboard:false, modal:false, labels:UI.modal.labels}, options);
  
          var modal = UI.modal.dialog(([
              text ? '<div class="uk-modal-content uk-form">'+String(text)+'</div>':'',
              '<div class="uk-margin-small-top uk-modal-content uk-form"><p><input type="text" class="uk-width-1-1"></p></div>',
              '<div class="uk-modal-footer uk-text-right"><button class="uk-button uk-modal-close">'+options.labels.Cancel+'</button> <button class="uk-button uk-button-primary js-modal-ok">'+options.labels.Ok+'</button></div>'
          ]).join(""), options),
  
          input = modal.element.find("input[type='text']").val(value || '').on('keyup', function(e){
              if (e.keyCode == 13) {
                  modal.element.find(".js-modal-ok").trigger('click');
              }
          });
  
          modal.element.find(".js-modal-ok").on("click", function(){
              if (onsubmit(input.val())!==false){
                  modal.hide();
              }
          });
  
          modal.on('show.uk.modal', function(){
              setTimeout(function(){
                  input.focus();
              }, 50);
          });
  
          return modal.show();
      };
  
      UI.modal.blockUI = function(content, options) {
  
          var modal = UI.modal.dialog(([
              '<div class="uk-margin uk-modal-content">'+String(content || '<div class="uk-text-center">...</div>')+'</div>'
          ]).join(""), UI.$.extend({bgclose:false, keyboard:false, modal:false}, options));
  
          modal.content = modal.element.find('.uk-modal-content:first');
  
          return modal.show();
      };
  
  
      UI.modal.labels = {
          'Ok': 'Ok',
          'Cancel': 'Cancel'
      };
  
  
      // helper functions
      function setContent(content, modal){
  
          if(!modal) return;
  
          if (typeof content === 'object') {
  
              // convert DOM object to a jQuery object
              content = content instanceof jQuery ? content : UI.$(content);
  
              if(content.parent().length) {
                  modal.persist = content;
                  modal.persist.data("modalPersistParent", content.parent());
              }
          }else if (typeof content === 'string' || typeof content === 'number') {
                  // just insert the data as innerHTML
                  content = UI.$('<div></div>').html(content);
          }else {
                  // unsupported data type!
                  content = UI.$('<div></div>').html('UIkit.modal Error: Unsupported data type: ' + typeof content);
          }
  
          content.appendTo(modal.element.find('.uk-modal-dialog'));
  
          return modal;
      }
  
  })(UIkit);
  