Your IP : 18.219.32.237


Current Path : /usr/local/mgr5/skins/orion/devel/
Upload File :
Current File : //usr/local/mgr5/skins/orion/devel/app-extform.js

/**
 * namespace APP
 */
var App = App || {};


/**
 * Init method of application
 */
App.init = function() {
  'use strict';
  App.mgr();

  //core methods here
  function nextEventBind(e, data) {
    var event = data.event,
        cb = data.cb,
        tData = data.tData;
    if (typeof cb === 'function') {
      EventMgr.one(event, cb, tData);
    }
  }

  EventMgr.bind('nextEventBind', nextEventBind);
};


/**
 * Global vars
 */
App.Global = function() {
  'use strict';
  var HeaderMoving = false,
      bannerHtml = null,
      warning = [],
      anychartXML = null,
      selid,
      scrollTop,
      targetId = '',
      msg = {};

  return {
    HeaderMoving: HeaderMoving,
    bannerHtml: bannerHtml,
    warning: warning,
    anychartXML: anychartXML,
    selid: selid,
    scrollTop: scrollTop,
    msg: msg,
    targetId: targetId
  };
}();

'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

/**
 * Module with utilits
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 */
/*global App:true*/
App.u = App.Common = function (window, $, EventMgr) {
  'use strict';

  var init = function init() {
    EventMgr.on($(window.document), linkSelector, 'keydown', linkKeyDownHandler);
  },
      ENTERKEY = 13,
      SPACE = 32,
      linkSelector = 'a',
      getQueryString = function getQueryString(queryObj, noesc) {
    var j = 0,
        paramString = '',
        curValue,
        keyVar;
    for (keyVar in queryObj) {
      if (keyVar !== '') {
        if (j !== 0) {
          paramString += '&';
        }
        curValue = queryObj[keyVar];
        //encode params
        if (noesc) {
          paramString += keyVar + '=' + curValue;
        } else {
          paramString += keyVar + '=' + encodeURIComponent(curValue);
        }
        j++;
      }
    }
    return paramString;
  },

  //parse url to object
  //@todo unit test
  parseParams = function parseParams(paramString) {
    if (paramString !== undefined && paramString !== null) {
      paramString = paramString.replace(/^\?/, '');
      var paramStirngArray = paramString.split('&'),
          paramStirngObj = {},
          re = /=(.+)?/,
          tmp;
      for (var i = 0; i < paramStirngArray.length; i++) {
        tmp = paramStirngArray[i].split(re);
        paramStirngObj[tmp[0]] = tmp[1] ? tmp[1] : '';
      }
      return paramStirngObj;
    } else {
      return {};
    }
  },

  //@todo unit test
  serializeForAttr = function serializeForAttr(obj) {
    var keyVar,
        paramStr = '',
        i = 0;
    /* jslint forin:true */
    for (keyVar in obj) {
      i++;
      if (i !== 1) {
        paramStr += '&';
      }
      paramStr += keyVar + '=' + encodeURIComponent(obj[keyVar]);
    }
    return paramStr;
  },


  //from here
  // http://www.jonefox.com/blog/2009/05/21/internet-explorer-and-the-innerhtml-property/
  replaceHtml = function replaceHtml(el, html) {
    if (el) {
      var oldEl = typeof el === 'string' ? document.getElementById(el) : el,
          newEl = document.createElement(oldEl.nodeName);
      //Preserve any properties we care about (id and class in this example)
      newEl.id = oldEl.id;
      newEl.className = oldEl.className;
      //set the new HTML and insert back into the DOM
      newEl.innerHTML = html;
      if (oldEl.parentNode) {
        oldEl.parentNode.replaceChild(newEl, oldEl);
      } else {
        oldEl.innerHTML = html;
      }
      //return a reference to the new element in case we need it
      oldEl = null;
      return newEl;
    }
  },
      linkKeyDownHandler = function linkKeyDownHandler(e) {
    var codeKey = e.which || e.keyCode;
    if (ENTERKEY === codeKey || SPACE === codeKey) {
      $(this).trigger('click');
      e.preventDefault();
    }
  },
      wordWrap = function wordWrap(str, wordLen) {
    if (!str) {
      return str;
    }
    wordLen = wordLen || 100;
    var wArr = str.split(' '),
        length = wArr.length,
        cWord,
        cWordLen,
        newWord,
        wordLenReg = new RegExp('(.{' + wordLen + '})', 'g');
    for (var i = 0; i < length; i++) {
      if (wArr[i].length > wordLen) {
        cWord = wArr[i].split(wordLenReg);
        cWordLen = cWord.length;
        newWord = '';
        for (var j = 0; j < cWordLen; j++) {
          if (cWord[j] !== '') {
            newWord += cWord[j] + '<br>';
          }
        }
        str = str.replace(wArr[i], newWord);
        //replace \n to <br/>
        str = str.replace(/\n/g, '<br/>');
      }
    }
    return str;
  },
      injectCss = function injectCss(url) {
    var link = document.createElement('link');
    link.setAttribute('rel', 'stylesheet');
    link.setAttribute('type', 'text/css');
    link.setAttribute('href', url);
    document.getElementsByTagName('head')[0].appendChild(link);
  },
      required = function required(file, callback, param) {
    var script = document.getElementsByTagName('script')[0],
        newjs = document.createElement('script');

    newjs.onreadystatechange = function () {
      if (newjs.readyState === 'loaded' || newjs.readyState === 'complete') {
        newjs.onreadystatechange = null;
        if (App.u.isFunction(callback)) {
          callback(param);
          param = null;
          file = null;
        }
      }
    };

    newjs.onload = function () {
      if (App.u.isFunction(callback)) {
        callback(param);
        param = null;
        file = null;
      }
    };

    newjs.src = file;
    script.parentNode.insertBefore(newjs, script);
  },
      noMoreId = {},
      noMoreCheckTimeId,
      noMoreThan = function noMoreThan(id, timeOut, func) {
    var time = new Date().getTime(),
        dTime;
    timeOut = timeOut ? timeOut : 100;
    if (!noMoreId[id]) {
      noMoreId[id] = {
        q: false,
        lastRun: time,
        timeOut: timeOut
      };
      runFunc(func, time, id);
    } else {
      dTime = time - noMoreId[id].lastRun;
      //check for timeout
      if (dTime > timeOut) {
        runFunc(func, time, id);
        clearTimeout(noMoreCheckTimeId);
        //to queue
      } else {
        noMoreId[id].q = true;
        clearTimeout(noMoreCheckTimeId);
        //todo closure
        noMoreCheckTimeId = setTimeout(function () {
          checkLastCall(func, time, id);
        }, timeOut * 2);
      }
    }
  },
      checkLastCall = function checkLastCall(func, time, id) {
    if (noMoreId[id].q === true) {
      runFunc(func, time, id);
    }
  },
      runFunc = function runFunc(func, time, id) {
    if (typeof func === 'function') {
      func();
      noMoreId[id].lastRun = time;
      noMoreId[id].q = false;
    }
  },
      clone = function clone(obj) {
    // Handle the 3 simple types, and null or undefined
    if (null === obj || 'object' !== (typeof obj === 'undefined' ? 'undefined' : _typeof(obj))) {
      return obj;
    }
    var copy;
    // Handle Date
    if (obj instanceof Date) {
      copy = new Date();
      copy.setTime(obj.getTime());
      return copy;
    }

    // Handle Array
    if (obj instanceof Array) {
      copy = [];
      for (var i = 0, len = obj.length; i < len; i++) {
        copy[i] = clone(obj[i]);
      }
      return copy;
    }

    // Handle Object
    if (obj instanceof Object) {
      copy = {};
      for (var attr in obj) {
        if (obj.hasOwnProperty(attr)) {
          copy[attr] = clone(obj[attr]);
        }
      }
      return copy;
    }

    throw new Error("Unable to copy obj! Its type isn't supported.");
  },
      msg = {},
      storage = { breadcrumb: {}, dashboard: {} },

  /**
   * Cache jQuery Selector for static elems
   */
  selectorCache = function () {
    var selectors = {};
    return function (selector) {
      if (selectors[selector]) {
        return selectors.selector;
      }
      selectors.selector = $(selector);
      return selectors.selector;
    };
  }(),

  //check for string
  isString = function isString(string) {
    return typeof string === 'string';
  },

  //check for function
  isFunction = function isFunction(func) {
    return typeof func === 'function';
  },

  //check for type Number
  isNumber = function isNumber(num) {
    return typeof num === 'number';
  },

  //escape regexp expression
  escapeRegExp = function escapeRegExp(str) {
    return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
  },

  //escape qoute & double quote
  escapeQuote = function escapeQuote(str) {
    return String(str).replace(/"/g, '&quot;');
  },
      getCaretPosition = function getCaretPosition(obj) {
    obj.focus();
    if (obj.selectionStart) {
      return obj.selectionStart;
    } else if (document.selection) {
      var sel = document.selection.createRange();
      var clone = sel.duplicate();
      sel.collapse(true);
      clone.moveToElementText(obj);
      clone.setEndPoint('EndToEnd', sel);
      return clone.text.length;
    }
    return 0;
  },
      CSSEscape = function CSSEscape(value) {
    var string = String(value);
    var length = string.length;
    var index = -1;
    var codeUnit;
    var result = '';
    var firstCodeUnit = string.charCodeAt(0);
    while (++index < length) {
      codeUnit = string.charCodeAt(index);
      // Note: there’s no need to special-case astral symbols, surrogate
      // pairs, or lone surrogates.
      // If the character is NULL (U+0000), then throw an
      // `InvalidCharacterError` exception and terminate these steps.
      if (codeUnit == 0x0000) {
        throw new InvalidCharacterError('Invalid character: the input contains U+0000.');
      }
      if (
      // If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
      // U+007F, […]
      codeUnit >= 0x0001 && codeUnit <= 0x001F || codeUnit == 0x007F ||
      // If the character is the first character and is in the range [0-9]
      // (U+0030 to U+0039), […]
      index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039 ||
      // If the character is the second character and is in the range [0-9]
      // (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
      index == 1 && codeUnit >= 0x0030 && codeUnit <= 0x0039 && firstCodeUnit == 0x002D) {
        // http://dev.w3.org/csswg/cssom/#escape-a-character-as-code-point
        result += '\\' + codeUnit.toString(16) + ' ';
        continue;
      }
      // If the character is not handled by one of the above rules and is
      // greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
      // is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
      // U+005A), or [a-z] (U+0061 to U+007A), […]
      if (codeUnit >= 0x0080 || codeUnit == 0x002D || codeUnit == 0x005F || codeUnit >= 0x0030 && codeUnit <= 0x0039 || codeUnit >= 0x0041 && codeUnit <= 0x005A || codeUnit >= 0x0061 && codeUnit <= 0x007A) {
        // the character itself
        result += string.charAt(index);
        continue;
      }
      // Otherwise, the escaped character.
      // http://dev.w3.org/csswg/cssom/#escape-a-character
      result += '\\' + string.charAt(index);
    }
    return result;
  },
      insertStringAfterCaret = function insertStringAfterCaret(elem, textToInsert, removeLine) {
    if (!elem || !textToInsert) {
      return;
    }
    elem.focus();
    var val = elem.value,
        end = val.length === 0 ? 0 : getCaretPosition(elem),
        start = removeLine ? val.lastIndexOf('\n', end - 1) + 1 : end,
        before = val.substring(0, start),
        after = val.substring(end);
    elem.value = before + textToInsert + after;
    var r,
        index = (before + textToInsert).length;
    if (elem.setSelectionRange) {
      elem.setSelectionRange(index, index);
    } else {
      r = elem.createTextRange();
      r.collapse(true);
      r.select(index, index);
    }
  },
      formatDateTime = function formatDateTime(timestamp) {
    var date = new Date(timestamp);
    return date.getFullYear() + '-' + ('0' + (date.getMonth() + 1)).slice(-2) + '-' + ('0' + date.getDate()).slice(-2) + ' ' + ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2) + ':' + ('0' + date.getSeconds()).slice(-2);
  },
      parseDate = function parseDate(timeString) {
    var cArr = String(timeString).split(' ');
    if (cArr.length === 2) {
      var dArr = cArr[0].split('-'),
          tArr = cArr[1].split(':');
      if (dArr.length === 3 && tArr.length === 3) {
        return new Date(dArr[0], parseInt(dArr[1], 10) - 1, dArr[2], tArr[0], tArr[1], tArr[2]);
      }
    }
    return new Date();
  },

  //check file size function
  checkFileSize = function checkFileSize(tabId, name) {
    var inputFile = name ? $('#' + name + '-' + tabId) : $('#form-wrapper-' + tabId + ' input[type="file"]'),
        msg = null,
        field = null;
    inputFile.each(function () {
      var maxSize = this.getAttribute('data-max-size'),
          msgSize = this.getAttribute('data-maxsize-msg');
      field = this;
      if (this.files && maxSize) {
        maxSize -= 0;
        for (var i = 0, l = this.files.length; i < l; i++) {
          if (this.files[i].size > maxSize) {
            msg = String(pageInfo.messages.fileMaxSize).replace('__VALUE__', msgSize);
            return false;
          }
        }
      }
    });
    return {
      msg: msg,
      field: field
    };
  },
      openInNewWindow = function openInNewWindow(url, param) {
    var newwindow = window.open('', param);
    if (newwindow) {
      newwindow.openner = null;
      newwindow.location = url;
    }
  },
      removeParam = function removeParam(form, param) {
    var len = form.length,
        i,
        name;
    for (i = 0; i < len; i++) {
      name = form[i].name;
      delete param[name];
    }
    return param;
  },

  /**
   *  Устанавливаем позиционирование выпадающего списка на форме
   */
  setOptionListPosition = function setOptionListPosition(prefixId, id) {
    var elemHeight, elem, bodyHeight, elemTop, formTop, form, tabId;
    bodyHeight = window.document.body.offsetHeight;
    //calculate position for list options
    elem = $(prefixId + id);
    elem[0].style.top = '';
    elemTop = elem.offset().top;
    elemHeight = elem[0].offsetHeight;
    if (bodyHeight - elemTop < elemHeight) {
      tabId = elem[0].getAttribute('data-tabid');
      form = $('#form-scroll-' + tabId);
      if (form.length === 0) {
        //if it filter
        form = $('#tcw-' + tabId);
      }
      formTop = form.offset().top;
      if (formTop > elemTop - elemHeight - 19) {
        elem[0].style.top = '-' + elemHeight / 2 + 'px';
      } else {
        elem[0].style.top = '-' + elemHeight + 'px';
      }
    }
  },


  /**
   * Получить предыдущую html ноду
   * @param {HTMLElement} node - html node
   * @return {null | HTMLElement}
   */
  getPreviousNode = function getPreviousNode(node) {
    var el = node;
    var previousSibling = null;
    if (el) {
      while (!previousSibling && el) {
        el = el.previousSibling;
        if (el.nodeType === 1) {
          previousSibling = el;
        }
      }
    }

    return previousSibling;
  },


  /**
   * Check on refresh menu flag in response
   */
  checkRefreshMenu = function checkRefreshMenu(data) {
    if (data.refreshMenu) {
      EventMgr.trigger('favoriteMenuUpdateDone');
    }
  };

  return {
    init: init,
    setOptionListPosition: setOptionListPosition,
    parseParams: parseParams,
    replaceHtml: replaceHtml,
    serializeForAttr: serializeForAttr,
    wordWrap: wordWrap,
    required: required,
    noMoreThan: noMoreThan,
    checkRefreshMenu: checkRefreshMenu,
    clone: clone,
    injectCss: injectCss,
    msg: msg,
    removeParam: removeParam,
    storage: storage,
    selectorCache: selectorCache,
    isNumber: isNumber,
    isString: isString,
    isFunction: isFunction,
    getQueryString: getQueryString,
    escapeRegExp: escapeRegExp,
    insertStringAfterCaret: insertStringAfterCaret,
    getCaretPosition: getCaretPosition,
    escapeQuote: escapeQuote,
    formatDateTime: formatDateTime,
    parseDate: parseDate,
    checkFileSize: checkFileSize,
    openInNewWindow: openInNewWindow,
    CSSEscape: CSSEscape,
    getPreviousNode: getPreviousNode
  };
}(window, $, EventMgr);
//# sourceMappingURL=App.Common.js.map

'use strict';

/**
 * Модуль для работы с DOM
 *  App.Dom
 * @param {object} window global object
 * @return {{addClass: function, removeClass: function,
 * toggleClass: function, byId: function, hasClass: function
 * }}
 *
 */
App.Dom = function (window) {
  'use strict';

  var doc = document,
      testAPIelem = doc.createElement('div');

  /**
   * getElementById wrapper
   * @param {String} id value of id
   * @return {?null|object}
   */
  function byId(id) {
    if (typeof id !== 'string') {
      return null;
    }
    return doc.getElementById(id);
  }

  /**
   * add class to HTMLNode
   * @param {HTMLNode} elem HTML node
   * @param {string} className name of adding class
   * @type {Function}
   */
  var addClass = testAPIelem.classList ? function (elem, className) {
    if (!elem) {
      return;
    }
    if (typeof className !== 'string') {
      return;
    }
    elem.classList.add(className);
  } : function (elem, className) {
    if (!elem) {
      return;
    }
    if (typeof className !== 'string') {
      return;
    }
    if (!elem.className.match(className)) {
      elem.className += ' ' + className;
    }
  };

  /**
   * remove class
   * @param {HTMLNode} elem HTML node
   * @param {string} className name of removing class
   * @type {Function}
   */
  var removeClass = testAPIelem.classList ? function (elem, className) {
    if (!elem) {
      return;
    }
    if (typeof className !== 'string') {
      return;
    }
    elem.classList.remove(className);
  } : function (elem, className) {
    if (!elem) {
      return;
    }
    if (typeof className !== 'string') {
      return;
    }
    var regex = new RegExp(className, 'g');
    elem.className += elem.className.replace(regex, '');
  };

  /**
   * toggle class
   * @param {HTMLNode} elem HTML node
   * @param {string} className name of toggling class
   * @type {Function}
   * @return {undefined}
   */
  var toogleClass = testAPIelem.classList ? function (elem, className) {
    if (!elem) {
      return;
    }
    if (typeof className !== 'string') {
      return;
    }
    elem.classList.toggle(className);
  } : function (elem, className) {
    if (!elem) {
      return;
    }
    if (typeof className !== 'string') {
      return;
    }
    var classes = elem.className;
    if (classes.match(className)) {
      var regex = new RegExp(className, 'g');
      elem.className += classes.replace(regex, '');
    } else {
      elem.className += ' ' + className;
    }
  };

  /**
   * check for has class
   * @param {HTMLNode} elem HTML node
   * @param {string} className name of checking class
   * @type {Function}
   * @return {boolean|undefined}
   */
  var hasClass = testAPIelem.classList ? function (elem, className) {
    if (!elem) {
      return;
    }
    if (typeof className !== 'string') {
      return;
    }
    return elem.classList.contains(className);
  } : function (elem, className) {
    if (!elem) {
      return;
    }
    if (typeof className !== 'string') {
      return;
    }
    var classes = elem.className;
    return classes.match(className);
  };
  return {
    init: function init() {},
    byId: byId,
    addClass: addClass,
    removeClass: removeClass,
    toogleClass: toogleClass,
    hasClass: hasClass
  };
}(window);
//# sourceMappingURL=App.Dom.js.map

'use strict';

/**
 * Модуль утилит для манипуляции с формой
 * @param {object} window глобальный объект
 * @param {object} $ jQuery глобальный объект
 * @param {object} App объект приложения
 */
App.FormUtils = function (window, $, App) {

  function changeReadOnly(elems, set) {
    if (!elems || elems.length === 0) {
      return;
    }
    if (set) {
      elems.find('.b-myselect,' + ' .b-radio,' + ' .b-checkbox__control,' + ' .l-slider__wr,' + ' .b-input_for_slider,' + ' .b-mselect').addClass('readonly').removeClass('mselect-av');
    } else {
      elems.find('.b-myselect, .b-radio,' + ' .b-checkbox__control,' + ' .l-slider__wr,' + ' .b-input_for_slider,' + ' .b-mselect').removeClass('readonly').addClass('mselect-av');
    }
    elems.find('.b-input, .b-textarea').attr('readonly', set);
  }

  var api = {
    changeReadOnly: changeReadOnly
  };

  return api;
}(window, $, App);
//# sourceMappingURL=App.FormUtils.js.map

'use strict';

/**
 * Модуль обработки скрытия полей на форме
 * @param {object} window глобальный объект
 * @param {object} $ jQuery глобальный объект
 * @param {object} EventMgr менеджер событий
 * @param {object} formUtils утилиты для манипуляции с формой
 * @param {object} commonUtils общие утилиты
 */
App.FormDependFields = function (window, $, EventMgr, formUtils, commonUtils) {
  /** селектор контролов управляющих скрытием полей  */
  var dependFieldSlistSelector = '.control-field input[type="hidden"],' + ' .control-field .b-input,' + ' .control-field .b-input_type_file,' + ' .control-field .b-textarea';

  /**
   * Получаем ссылку на ноду формы
   * @return {object} jQuery объект
   */
  function $content() {
    return commonUtils.selectorCache('.i-form-wr');
  }

  //hide/show field by select, radio and checkbox
  /**
   * Обработчик скрытия зависимых полей от данного контрола
   */
  function dependFieldsSlistHandler() {
    var handlerValue = this.getAttribute('data-handler-val');
    var name = this.getAttribute('name');
    var type = this.getAttribute('type');
    var tabId = this.getAttribute('data-tabid');
    var rowIsHidden = false,
        shadowShowElems = void 0,
        shadowHideElems = void 0,
        HideElems = void 0,
        shadowedRow = void 0;
    if (!name) {
      return;
    }
    //show hidden fields by "hide"
    shadowHideElems = $('.hidden-shadow-' + name);
    HideElems = $('.hidden-' + name);
    //unshadow shadow elems
    formUtils.changeReadOnly(shadowHideElems, false);
    shadowHideElems.removeClass('hidden-shadow-' + name);
    HideElems.removeClass('hidden-' + name);
    //hide field by else
    $('.showed-' + name).addClass('depended-hidden-s').addClass('l-form__row_hidden_yes').removeClass('showed-' + name);
    //check row if already shadowed by else or 1st start
    shadowedRow = $('.depended-shadow-s');
    if (!shadowedRow.hasClass('row-shadow')) {
      shadowedRow.addClass('row-shadow');
      formUtils.changeReadOnly(shadowedRow, true);
    }
    //shadow field by else
    shadowShowElems = $('.showed-shadow-' + name).removeClass('showed-shadow-' + name).addClass('depended-shadow-s').addClass('row-shadow');
    //add readonly from shadow
    formUtils.changeReadOnly(shadowShowElems, true);

    rowIsHidden = $(this).parents('.l-form__row, .filter-item').hasClass('l-form__row_hidden_yes');
    // если поле не скрыто, то оно учавствует в скрытие полей
    if (!rowIsHidden) {
      //for text and native hidden
      if (type === 'text' || type === 'textarea' || !handlerValue) {
        var value = this.value;
        if (value === '') {
          //hide field by "hide" (empty = "yes")
          $('#frm-' + tabId + ' [data-hide-' + name + '-' + hash('empty-yes') + ' = "yes"]').addClass('hidden-' + name).addClass('l-form__row_hidden_yes');
          //shadow field by "hide" (empty = "yes")
          shadowHideElems = $('#frm-' + tabId + ' [data-shadow-' + name + '-' + hash('empty-yes') + ' = "yes"]').addClass('hidden-shadow-' + name).addClass('row-shadow');
          formUtils.changeReadOnly(shadowHideElems, true);
        } else {
          //hide fields by "hide" (empty = no)
          $('#frm-' + tabId + ' [data-hide-' + name + '-' + hash('empty-no') + ' = "yes"]').addClass('hidden-' + name).addClass('l-form__row_hidden_yes');
          //shadow fields by "hide" (empty = no)
          shadowHideElems = $('#frm-' + tabId + ' [data-shadow-' + name + '-' + hash('empty-no') + ' = "yes"]').addClass('hidden-shadow-' + name).addClass('row-shadow');
          formUtils.changeReadOnly(shadowHideElems, true);
        }
        // для селектов и радиобаттонов
      } else {
        //show field by "show"
        $('#frm-' + tabId + ' [data-show-' + name + '-' + handlerValue + ' = "yes"]').addClass('showed-' + name).removeClass('depended-hidden-s').removeClass('l-form__row_hidden_yes');
        //unshadow field by "show"
        shadowShowElems = $('#frm-' + tabId + ' [data-show-shadow-' + name + '-' + handlerValue + ' = "yes"]').addClass('showed-shadow-' + name).removeClass('depended-shadow-s').removeClass('row-shadow');
        formUtils.changeReadOnly(shadowShowElems, false);
        //hide field by "hide"
        $('#frm-' + tabId + ' [data-hide-' + name + '-' + handlerValue + ' = "yes"]').addClass('hidden-' + name).addClass('l-form__row_hidden_yes');
        //shadow field by "hide"
        shadowHideElems = $('#frm-' + tabId + ' [data-shadow-' + name + '-' + handlerValue + ' = "yes"]').addClass('hidden-shadow-' + name).addClass('row-shadow');
        formUtils.changeReadOnly(shadowHideElems, true);
      }
    }
  }

  /**
   * Вызываем обработчик if/else скрытия полей
   * @param {string} tabId id таба
   */
  function dependSlistHandlerRun(tabId) {
    $('#cont-' + tabId + ' tr:not(".row-error") .control-field' + ' input[type="hidden"],' + ' #cont-' + tabId + ' tr:not(".row-error") .control-field' + ' input[type="text"],' + ' #cont-' + tabId + ' tr:not(".row-error") .control-field' + ' input[type="password"],' + ' #cont-' + tabId + ' tr:not(".row-error") .control-field' + ' .b-input_type_file,' + ' #cont-' + tabId + ' .control-field.filter-item input[type="hidden"],' + ' #cont-' + tabId + ' .control-field .b-textarea,' + ' #cont-' + tabId + ' .control-field.filter-item input[type="text"]').each(function () {
      dependFieldsSlistHandler.apply(this);
    });
  }

  /**
   * Hide page if no visible fields
   * @param {String} tabId
   */
  function checkEmptyPage(tabId) {
    $('#form-wrapper-' + tabId + ' .b-form-page').each(function () {
      var id = this.getAttribute('id');
      if ($('#' + id + ' .l-form__row:not(.l-form__row_hidden_yes):not(.depended-hidden-s)').length > 0) {
        this.style.display = '';
      } else {
        this.style.display = 'none';
      }
    });
  }

  /**
   * Handler for changed control fields
   *
   * every contol field runs hide/show function from up to down from
   * @param {object} e event object
   * @param {object} data
   * @this {object} HTML node
   */
  function firstDependFieldsSlistHandler(e, data) {
    //проверяем на тип boolean для проверки на setvalue=once/final 
    var tabId = !!data && typeof data !== 'boolean' ? data.tabId : this.getAttribute('data-tabid');
    // сбрасываем все правила скрытия
    $('#cont-' + tabId + ' .l-form__row_hidden_yes').removeClass('l-form__row_hidden_yes');
    $('#cont-' + tabId + ' .row-shadow').removeClass('row-shadow');

    dependSlistHandlerRun(tabId);

    checkEmptyPage(tabId);

    EventMgr.trigger('updFormHeight', { tabId: tabId });
    EventMgr.trigger('reloadSlider', { tabId: tabId });
    EventMgr.trigger('upPrefixField', { tabId: tabId });
  }

  function init() {
    EventMgr.bind('appendForm,appendReport,appendedFilter,initFuncRun', firstDependFieldsSlistHandler);
    EventMgr.on($content(), dependFieldSlistSelector, 'change', firstDependFieldsSlistHandler);
  }

  var api = {
    init: init
  };

  return api;
}(window, $, EventMgr, App.FormUtils, App.Common);
//# sourceMappingURL=App.FormDependFields.js.map

'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

/**
 * Form module
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 *  @param {object} ScrollHandler Scrollbar library
 */
App.Forms = function (window, $, EventMgr, App, ScrollHandler) {
  'use strict';

  function init() {
    EventMgr.on($content(), headerFormSelector, 'click', collapsedForm);
    EventMgr.on($content(), unlimitBtnSelector, 'click', insertUnlimValue);
    //zoom
    EventMgr.on($content(), zoomBtnSelector, 'click', zoomHandler);
    EventMgr.on($content(), zoomTextareaSelector, 'change', syncZoomValue);
    EventMgr.on($content(), zoomTextareaSelector, 'keyup', addLineBreakToZoomField);
    EventMgr.on($content(), zoomTextareaELSelector, 'keyup', syncZoomValue);
    EventMgr.on($content(), passwdBtnSelector, 'click', genPassword);
    EventMgr.on($content(), showpwdBtnSelector, 'click', showPassword);
    EventMgr.on($content(), calendarBtnSelector, 'click', calendarHandler);
    //checkbox
    EventMgr.on($content(), checkboxChangeSelector, 'change', changeElHandler);
    EventMgr.on($content(), checkboxSelector, 'click', changeCheckboxValue);
    //radio
    EventMgr.on($content(), radiobuttonSelector, 'click', changeRadioValue);
    EventMgr.on($content(), descRadioSelector, 'click', radioLabelClickHandler);
    EventMgr.on($content(), radiobuttonSelector, 'keydown', radioBtnKeyDownHandler);

    EventMgr.on($content(), bandShowSelector, 'click', bandShowHandler);
    EventMgr.on($content(), dependSlistSelector, 'change', dependSlistHandler);
    EventMgr.on($content(), setvalueSelector, 'change', setValueHandler);
    EventMgr.on($content(), setvalueBtnSelector, 'click', setValueHandler);
    EventMgr.on($content(), resetBtnSelector, 'click', resetHandler);
    EventMgr.on($content(), userexpLinkSelector, 'click', levelUp);
    EventMgr.on($content(), nestedreportSelector, 'click', nestedReportHandler);
    EventMgr.on($content(), fakePasswdSelector, 'change', fakePasswdCopy);
    EventMgr.bind('forceSetValues', forceSetValues);
    EventMgr.bind('appendForm,appendReport,appendedFilter,forceDepend', firstDependSlistHandler);
    EventMgr.bind('loadPage', loadPassList);
    EventMgr.bind('appendForm,appendReport,switchTabForm,setFocus', setFocus);
    EventMgr.bind('appendForm', scrollToSelectedBranch);
    EventMgr.bind('formSetValues', formSetValues);
    EventMgr.bind('syncInputToZoom', syncInputWithZoom);
    EventMgr.on($content(), passwdField, 'change', checkPass);
    EventMgr.on($content(), inputTypeTextSelector, 'keydown', submitFormByEnter);
    EventMgr.on($content(), checkBoxSelectTextareaRadioFormSelector, 'keydown', submitFormByCtrlEnter);
    EventMgr.on($content(), passwdField, 'keyup', checkPass);
    EventMgr.on($content(), novalueSelector, 'change', changeNovalueFieldHandler);
    EventMgr.on($content(), formBtnSelector, 'keydown', formBtnKeyDownHandler);
    EventMgr.on($content(), descLabelCheckboxSelector, 'click', checkboxDescClickHandler);
    EventMgr.bind('gotPasswdList', gotPasswdListHandler);
    EventMgr.on($content(), treeHitarea, 'click', treeCollpasedControl);
    EventMgr.on($content(), treeLabelSelector, 'click', treeSelectedControl);
    EventMgr.on($content(), treeMultiLabelSelector, 'click', treeMultiSelectedControl);
    EventMgr.on($content(), treeCommonLabelSelector, 'dblclick', treeCollpasedControlWrapper);
    EventMgr.on($content(), fakeFileInput, 'click', fakeFileInputHandler);
    EventMgr.on($content(), FileInput, 'change', fileInputChangeHandler);
    EventMgr.on($content(), treeReszieConrtolSelector, 'mousedown', treeResizeControl);
    EventMgr.on($content(), confirmField, 'keyup, change', checkConfirmField);
    EventMgr.on($content(), quoteSelector, 'click', quoteHandler);
    //clear tab cache
    EventMgr.bind('closeTabEvent,appendForm,appendFilter,appendReport', cleanTabCache);
    EventMgr.bind('appendForm', prefixFieldSetUp);
    EventMgr.bind('upPrefixField', prefixFieldSetUp);
    EventMgr.on($content(), formListRow, 'click', formListRowClickHandler);
    EventMgr.bind('focusOnErrorField', focusOnErrorField);
    EventMgr.on($content(), '.b-textarea_responsive_yes', 'keyup', textareaResize);
    EventMgr.bind('appendForm', checkTitleWidth);
    EventMgr.on($content(), ticketBtnUp, 'click', ticketMoveUpHandler);
    EventMgr.on($content(), ticketBtnDown, 'click', ticketMoveDownHandler);
    EventMgr.on($content(), ticketCollapse, 'click', ticketCollapseHandler);
  }

  var appDom = App.Dom;

  var CACHE = {};

  function cleanTabCache(e, data) {
    var tabId = data.tabId;
    if (CACHE[tabId]) {
      delete CACHE[tabId];
    }
  }

  function $content() {
    return App.Common.selectorCache('.i-form-wr');
  }

  var pageInfo = window.pageInfo,
      quoteSelector = '.b-quote',
      treeReszieConrtolSelector = '.b-resizer',
      fakeFileInput = '.b-input-file-fake',
      FileInput = '.b-input_type_file',
      treeHitarea = '.tree-wrapper .tree-hitarea',
      treeLabelSelector = '.b-tree_type_default .tree-handler',
      treeCommonLabelSelector = '.tree-wrapper .tree-handler',
      treeMultiLabelSelector = '.b-tree_type_multiple .tree-handler',
      fakePasswdSelector = 'input.fakePasswd',
      novalueSelector = 'input[data-novalue], textarea[data-novalue]',
      passwdField = '.b-form-passwd-field, .b-form-passwd-field + input',
      userexpLinkSelector = 'div.userexperience',


  //wrapper for zoom textarea
  zoomTextareaSelector = '.b-textarea_for_zoom',

  //zoom field in inline-edit
  zoomTextareaELSelector = '.edit-field-form .b-textarea_for_zoom',


  //wrapper for body

  //wrapper for radiobutton
  radiobuttonSelector = '.b-radio:not(".readonly")' + ' .b-radio__control',

  //wrapper for checkboxes
  checkboxSelector = '.b-checkbox__control',

  //wrapper for headers of form page
  headerFormSelector = '.b-form-page__title',
      bandShowSelector = '.band-content .band_show_button',

  //wrapper for unlim btn from form
  unlimitBtnSelector = '.b-input-btn_type_unlimit',

  //zoom button
  zoomBtnSelector = '.b-input-btn_type_zoom',

  //password button
  passwdBtnSelector = '.b-input-btn_type_passwd',

  //calendar button
  calendarBtnSelector = '.b-input-btn_type_calendar',

  //show passwd button
  showpwdBtnSelector = '.b-input-btn_type_showpwd',

  //checkbox onchange
  checkboxChangeSelector = 'input[type="checkbox"].onchange',


  //wrapper for control field select and radio
  dependSlistSelector = '.depend.b-myselect input[type="hidden"],' + ' .depend.b-select-ac input[type="hidden"],' + ' .depend.b-radio input[type="hidden"]',
      setvalueSelector = '.setvalue input[type="hidden"],' + ' .b-select-ac_setvalues_yes input[type="hidden"],' + ' .setvalue input[type="text"],' + ' .setvalue input[type="password"],' + ' .setvalue .b-textarea',
      setvalueBtnSelector = '.i-button_type_setvalues',
      resetBtnSelector = '.i-button_type_reset',
      formBtnSelector = '.i-button, .b-checkbox__control',
      inputTypeTextSelector = '.l-form__wrapper .i-input-control,' + ' .filter-wrapper .i-input-control',
      checkBoxSelectTextareaRadioFormSelector = '.l-form__wrapper' + ' .b-radio__control,' + ' .l-form__wrapper .b-textarea,' + ' .l-form__wrapper .b-myselect__select-value,' + ' .filter-wrapper .b-myselect__select-value,' + ' .l-form__wrapper .b-checkbox__control,' + ' .l-form__wrapper .b-mselect__view-value',
      nestedreportSelector = '.data-wrapper.nestedreport',
      descRadioSelector = '.b-label__visible_for_radio, .b-radio-img__row',
      descLabelCheckboxSelector = ' .l-form__row_type_checkbox .b-label__visible',
      confirmField = '.b-form-confirm-field, .b-form-passwd-field',
      ticketBtnUp = '.i-ticket__btn-move_up',
      ticketBtnDown = '.i-ticket__btn-move_down',
      ticketCollapse = '.i-ticket__btn-collapse',
      formListRow = '.b-form-list__row, .b-form-blocks__block';

  function $activeTab() {
    return $('.tab-content_st_active');
  }

  //check for title overwidth & set hint overwidth
  function checkTitleWidth(e, data) {
    $('#cont-' + data.tabId).find('.b-title_type-form').each(function () {
      var width = this.offsetWidth,
          scrollWidth = this.scrollWidth - 1;
      if (width < scrollWidth) {
        this.className += ' overwidth';
        this.removeAttribute('data-hint');
      }
    });
  }

  function quoteHandler(e) {
    e.preventDefault();
    var content = '',
        selection;
    if (typeof window.getSelection !== 'undefined') {
      var sel = window.getSelection();
      content = sel.toString();
    } else if (typeof document.selection !== 'undefined') {
      if (document.selection.type === 'Text') {
        selection = document.selection.createRange();
        content = selection.text;
      }
    }
    if (content === '') {
      return;
    }
    var lines = content.split('\n'),
        l = lines.length;
    content = '';
    for (var i = 0; i < l; i++) {
      content += '> ' + lines[i];
      if (i !== l - 1) {
        content += '\n';
      }
    }
    var targetId = this.getAttribute('data-target'),
        elem = App.Dom.byId(targetId);
    if (elem) {
      App.u.insertStringAfterCaret(elem, content);
    }
  }

  function fakeFileInputHandler() {
    var id = this.getAttribute('data-source');
    $('#' + id).trigger('click');
  }

  function checkFileSize(tabId, name) {
    var fileSizeRes = App.u.checkFileSize(tabId, name);
    if (fileSizeRes.msg) {
      EventMgr.trigger('errMsgValid', {
        self: fileSizeRes.field,
        err: fileSizeRes.msg,
        number: 0
      });
    } else {
      EventMgr.trigger('okMsgValid', {
        self: fileSizeRes.field,
        number: 0,
        notOk: true
      });
    }
  }

  function fileInputChangeHandler() {
    var id = this.id,
        tabId = this.getAttribute('data-tabid'),
        fElemInput = App.Dom.byId('f-' + id),
        value = this.value,
        startIndex = value.indexOf('\\') >= 0 ? value.lastIndexOf('\\') : value.lastIndexOf('/'),
        filename = '',
        stateWrapper = App.Dom.byId('b-input-file__wr-' + tabId);
    if (this.files) {
      var filesList = this.files,
          l = filesList.length;
      for (var i = 0; i < l; i++) {
        if (i !== 0) {
          filename += ', ';
        }
        filename += filesList[i].name;
      }
      App.Dom.addClass(stateWrapper, 'b-input-file__wr_state_selected');
      //check file size
      checkFileSize(tabId, this.getAttribute('name'));
    } else {
      filename = value.substring(startIndex);
      if (filename.indexOf('\\') === 0 || filename.indexOf('/') === 0) {
        filename = filename.substring(1);
      }
      App.Dom.removeClass(stateWrapper, 'b-input-file__wr_state_selected');
    }
    filename = window.filterXSS(filename);
    fElemInput.innerHTML = filename;
    fElemInput.setAttribute('data-hint', filename);
  }
  //tree resizer
  var treeResizeObj = {};
  //tree resize drag
  function treeResizeControl(e) {
    var id = this.getAttribute('data-id'),
        tabId = this.getAttribute('data-tabid'),
        elem = App.Dom.byId(id),
        moveTrigger = this.getAttribute('data-move-trigger') || false,
        offsetTop = parseInt(this.offsetTop, 10),
        $tip = $('.b-tip_name_textarea_resize');
    //hide tip if it showing
    if ($tip.length) {
      $tip.find('.b-tip__close').trigger('click');
    }
    treeResizeObj.height = parseInt(elem.style.height, 10);
    if (!treeResizeObj.height) {
      treeResizeObj.height = elem.offsetHeight;
    }
    treeResizeObj.elem = elem;
    treeResizeObj.id = id;
    treeResizeObj.tabId = tabId;
    treeResizeObj.moveTrigger = moveTrigger;

    e = e || window.event;
    if (e.touches) {
      treeResizeObj.shiftY = e.touches[0].pageY;
      treeResizeObj.top = e.touches[0].pageY - offsetTop;
      document.ontouchmove = treeResizeMove;
      document.ontouchend = treeResizeDrop;
      document.ontouchcancel = treeResizeDrop;
    } else {
      treeResizeObj.shiftY = e.clientY;
      treeResizeObj.top = e.clientY - offsetTop;
      document.onmousemove = treeResizeMove;
      document.onmouseup = treeResizeDrop;
    }
    document.body.style.cursor = 'n-resize';
  }
  var treeResizerTimeId = 1;
  // tree resize move
  function treeResizeMove(e) {
    var diffY;
    if (e.touches) {
      diffY = e.touches[0].pageY - treeResizeObj.shiftY;
    } else {
      diffY = e.clientY - treeResizeObj.shiftY;
    }
    if (treeResizeObj.elem) {
      treeResizeObj.elem.style.height = treeResizeObj.height + diffY + 'px';
    }
    if (treeResizeObj.moveTrigger) {
      clearTimeout(treeResizerTimeId);
      treeResizerTimeId = setTimeout(function () {
        EventMgr.trigger(treeResizeObj.moveTrigger, {
          id: treeResizeObj.id, tabId: treeResizeObj.tabId });
      }, 100);
    }
    e.preventDefault();
  }
  // tree resize drop
  function treeResizeDrop(e) {
    if (e.touches) {
      document.ontouchmove = null;
      document.ontouchend = null;
      document.ontouchcancel = null;
    } else {
      document.onmousemove = null;
      document.onmouseup = null;
    }
    EventMgr.trigger('updFormHeight', { tabId: treeResizeObj.tabId });
    document.body.style.cursor = '';
    $(treeResizeObj.elem).removeClass('b-textarea_responsive_yes');
    e.preventDefault();
  }
  //dblclick handler
  function treeCollpasedControlWrapper(e) {
    e.preventDefault();
    var $self = $(this);
    $self.prev().trigger('click');
  }

  function treeCollpasedControl() {
    var parent = this.parentNode,
        className = parent.className,
        name,
        params,
        url,
        self,
        tabId,
        root,
        elem,
        img,
        src,
        id;
    self = $(this);
    root = self.parents('.tree-inner');
    tabId = root.attr('data-tabid');
    id = root.attr('id');
    //added class collapsed
    if (className.match(/t-opened/)) {
      className = className.replace(/t-opened/g, '');
      className += ' collapsed';
      //remove collapsed
    } else if (className.match(/collapsed/)) {
      //just open
      if (className.match(/loaded/)) {
        className = className.replace(/collapsed/g, '');
        className += ' t-opened';
        //load children
      } else if (!className.match(/loading/)) {
        name = App.Dom.byId(id + '-value').name;
        params = $('#frm-' + tabId).serializeObject();
        url = pageInfo.url;
        /* jslint camelcase:false */
        params.sv_field = name;
        params.sv_tree = 'yes';
        /* jslint camelcase:true */
        elem = self.siblings('.tree-handler');
        img = self.siblings('.tree-handler').children('.icon').children('img');
        src = img.attr('src');
        img.attr('src', pageInfo.theme + 'img/loader.gif');
        params[name] = elem.attr('data-val');
        //elem.parent().addClass('loading');
        className += ' loading';
        //get text node
        /* jshint camelcase: false */
        params.sv_text = $(elem).find('.tree-label').text();
        EventMgr.trigger('ajaxRequest', {
          url: url,
          param: params,
          trfunc: 'formGetTreeBranch',
          invar: {
            tabId: tabId,
            name: name,
            elem: elem,
            src: src,
            img: img,
            id: 'cont-' + id },
          type: 'get', outtype: 'json', queue: 'noqueue' });
      }
    }
    parent.className = className;
    EventMgr.trigger('updateScroll', { id: 'cont-' + id });
  }

  function treeSelectedControl(e) {
    var $self = $(this),
        id = $self.parents('.tree-inner').attr('id');
    //remove other selection
    $selectedTreeElem(id).removeClass('selected');
    var input = App.Dom.byId(id + '-value');
    input.value = this.getAttribute('data-val');
    $(input).trigger('change');
    this.className += ' selected';
  }

  function $selectedTreeElem(id) {
    return $('#' + id + ' .tree-handler.selected');
  }

  function treeMultiSelectedControl(e) {
    var $self = $(this),
        id = $self.parents('.tree-inner').attr('id'),
        value = '';
    //remove other selection
    var input = App.Dom.byId(id + '-value');
    if (e.ctrlKey || e.metaKey) {
      //unselected
      if ($self.hasClass('selected')) {
        $self.removeClass('selected');
        //add selection
      } else {
        $self.addClass('selected');
      }
      $selectedTreeElem(id).each(function (index) {
        if (index !== 0) {
          value += ',';
        }
        value += this.getAttribute('data-val');
      });
    } else {
      $selectedTreeElem(id).removeClass('selected');
      value = this.getAttribute('data-val');
      this.className += ' selected';
    }
    input.value = value;
    $(input).trigger('change');
  }

  function scrollToSelectedBranch() {
    setTimeout(function () {
      $('.tree-wrapper .selected').each(function () {
        var id = $(this).parents('.tree-wrapper').attr('id');
        EventMgr.trigger('scrollTo', { id: id, offsetTop: this.offsetTop });
      });
    }, 100);
  }

  function resetHandler() {
    var tabId = this.getAttribute('data-tabid'),
        form = App.Dom.byId('frm-' + tabId);
    form.reset();
  }

  function changeNovalueFieldHandler() {
    if (this.getAttribute('data-novalue')) {
      this.setAttribute('data-novalue', 'no');
      if (this.placeholder) {
        this.placeholder = '';
      }
    }
  }
  //submit form by ENTER keyup under text and password fields
  function submitFormByEnter(e) {
    e = e || window.event;
    var codeKey = e.which || e.keyCode,
        tabId;
    if (codeKey === ENTERKEY) {
      //sometime form submit native...
      e.preventDefault();
      var $self = $(this);
      tabId = this.getAttribute('data-tabid');
      $self.trigger('change');
      $self.trigger('blur');
      clickButtonTrigger(tabId);
    }
  }
  //submit form by ENTER + CTRL under textarea, select, radio, checkbox
  function submitFormByCtrlEnter(e) {
    e = e || window.event;
    var codeKey = e.which || e.keyCode,
        tabId;
    if (codeKey === ENTERKEY && (e.ctrlKey || e.metaKey)) {
      e.preventDefault();
      $(this).trigger('blur');
      tabId = this.getAttribute('data-tabid');
      clickButtonTrigger(tabId);
    }
  }
  /**
   * Ищем кнопку типа ok для отправки формы, сперва ищем дефлотную(default="yes"), затем (type=ok), (type=next), кнопку фильтра()
   */
  function clickButtonTrigger(tabId) {
    // ищем кнопку default, кнопку ok, потом первую попавшусю
    var $defaultButton = $('#cont-' + tabId + ' .i-button_default_yes');
    var $okButton = $('#cont-' + tabId + ' .b-button_act_ok');
    var $nextButton = $('#cont-' + tabId + ' .b-button_act_next');
    var $filterButton = $('#frm-' + tabId + ' .b-button__filter-set');

    setTimeout(function () {
      var $button;
      if ($defaultButton[0]) {
        $button = $defaultButton;
      } else if ($okButton[0]) {
        $button = $okButton;
      } else if ($nextButton[0]) {
        $button = $nextButton;
      } else if ($filterButton) {
        $button = $filterButton;
      }
      $button.first().trigger('click');
    }, 1);
  }

  function loadPassList() {
    var url,
        data = getLocalStorage('mgr5-passwdlist'),
        version = getLocalStorage('mgr5-passwd-ver'),
        newVersion = false;

    if (pageInfo.version !== version) {
      setLocalStorage('mgr5-passwd-ver', pageInfo.version);
      newVersion = true;
    }

    if (data && data !== '' && !newVersion) {
      passwdlist = data;
    } else {
      url = '/manimg/common/passwd.list';
      EventMgr.trigger('ajaxRequest', {
        url: url, param: {}, trfunc: 'gotPasswdList',
        outtype: 'html', type: 'get' });
    }
  }

  function getLocalStorage(itemId) {
    if (typeof localStorage !== 'undefined') {
      return localStorage.getItem(itemId);
    } else {
      return false;
    }
  }

  function setLocalStorage(itemId, data) {
    if (typeof localStorage !== 'undefined') {
      localStorage.setItem(itemId, data);
    } else {
      return false;
    }
  }

  var passwdlist = '';

  function gotPasswdListHandler(e, data) {
    passwdlist = '\n' + data + '\n';
    setLocalStorage('mgr5-passwdlist', passwdlist);
  }

  //The following function returns the logarithm of y with base x (ie. logx y):
  function getBaseLog(x, y) {
    return Math.log(y) / Math.log(x);
  }

  var passType = { 0: 'short', 1: 'weak', 2: 'good', 3: 'strong' };

  function checkConfirmField(e) {
    var self, tabId;
    if (this.getAttribute('data-check-field')) {
      tabId = this.getAttribute('data-tabid');
      self = App.Dom.byId(this.getAttribute('data-check-field') + '-' + tabId);
    } else {
      self = this;
    }
    var confirmId = self.getAttribute('data-confirm-field'),
        parentId = self.getAttribute('data-parent'),
        confirmField = App.Dom.byId(confirmId),
        messageElem = App.Dom.byId('check-confirm-' + parentId),
        isChanged = false,
        showConfirmMsg = false;
    if (App.Dom.hasClass(messageElem, 'b-form-confirm-message_show_true')) {
      showConfirmMsg = true;
    }
    if (!!confirmField && self.value !== confirmField.value) {
      if (!showConfirmMsg) {
        App.Dom.addClass(messageElem, 'b-form-confirm-message_show_true');
        isChanged = true;
      }
    } else {
      if (showConfirmMsg) {
        App.Dom.removeClass(messageElem, 'b-form-confirm-message_show_true');
        isChanged = true;
      }
    }
    if (isChanged) {
      EventMgr.trigger('updateScroll', { id: 'form-scroll-' + tabId });
    }
  }

  function checkPass() {
    var strength,
        value = App.u.escapeRegExp($.trim(this.value)),
        name = this.getAttribute('data-parent'),
        regexp = new RegExp('\n' + value + '\n', 'i'),
        tabId = this.getAttribute('data-tabid'),
        id = 'checkpass-indicator-wrapper-' + name,
        wr = App.Dom.byId(id),
        isChanged = false;
    if (wr) {
      if (this.value !== '') {
        if (passwdlist.match(regexp)) {
          strength = 0;
        } else {
          strength = checkPassStrength(this.value);
        }
        if (wr.className !== passType[strength] + ' showed') {
          wr.className = passType[strength] + ' showed';
          isChanged = true;
        }
      } else {
        if (wr.className !== '') {
          wr.className = '';
          isChanged = true;
        }
      }
    }
    if (isChanged) {
      EventMgr.trigger('updateScroll', { id: 'form-scroll-' + tabId });
    }
  }

  function checkPassStrength(value) {
    var len = value.length,
        str = value.split(''),
        uniq = 0,
        special = 0,
        repeatTypes = 0,
        varCase = 0,
        symbArr = {},
        strType = [],
        ind,
        i,
        lvl = 0;

    for (i = 0; i < len; i++) {
      //count uniq symbols
      if (!symbArr[str[i]]) {
        uniq++;
      }
      symbArr[str[i]] = true;
      //count special symbols
      if (str[i].match(/[!@#$%^&*?_~{}"'()|\\+\[\]]\s/)) {
        special++;
        strType.push('sn');
        //count lowcase
      } else if (str[i].match(/[a-z]/)) {
        strType.push('ll');
        //count uppercase
      } else if (str[i].match(/[A-Z]/)) {
        strType.push('lu');
        //count number
      } else if (str[i].match(/\d/)) {
        strType.push('dn');
        //any cyrillic symbol = 2 special
      } else {
        special++;
        special++;
        strType.push('sn');
      }
      if (i !== 0) {
        //check for repeat types symbol
        if (strType[i].substr(0, 1) === strType[i - 1].substr(0, 1)) {
          repeatTypes++;
        }
        //check for diffirent case
        if (strType[i].substr(1, 1) !== strType[i - 1].substr(1, 1)) {
          varCase++;
        }
      }
    }

    ind = (len + Math.sqrt(0.5 * special + varCase) - Math.sqrt(repeatTypes)) * getBaseLog(len, uniq);
    if (ind < 3) {
      lvl = 0;
      //weak
    } else if (ind >= 3 && ind < 6) {
      lvl = 1;
      //good
    } else if (ind >= 6 && ind < 9) {
      lvl = 2;
      //hard
    } else if (ind >= 9) {
      lvl = 3;
    } else {
      lvl = 0;
    }
    return lvl;
  }
  //handler for level up link
  function levelUp(e) {
    e.preventDefault();
    var exp = this.getAttribute('data-level'),
        tabId = getActiveTabId(),
        form = $('#frm-' + tabId),
        param = form.serializeObject(),
        $mixedContols = form.find('.i-control-mixed');
    param.userexperience = exp;

    if ($mixedContols.length !== 0) {
      param = App.u.removeParam($mixedContols, param);
    }
    if (param.snext) {
      delete param.snext;
    }
    if (param.sback) {
      delete param.sback;
    }
    EventMgr.trigger('reloadTab', { tabId: tabId, param: param });
  }

  function nestedReportHandler(e) {
    e.preventDefault();
    var elid = this.getAttribute('data-elid'),
        $self = $(this),
        index = $self.parents('td').index(),
        th = $self.parents('table').find('th')[index],
        colname = th.getAttribute('data-colname'),
        nested = th.getAttribute('data-nestedreport'),
        parent = getActiveTabId(),
        plid = App.Dom.byId(parent + '-plid'),
        form = $('#frm-' + parent),
        param = form.serializeObject();
    elid = elid || $self.find('.b-list__table-col-content').first().html();
    param.func = nested;
    param.elid = elid;
    param.colname = colname;
    if (plid !== null) {
      param.plid = plid.value;
    }
    EventMgr.trigger('ajaxRequest', {
      param: param,
      invar: { parent: parent },
      type: 'get',
      outtype: 'json',
      trfunc: 'ajaxResponse',
      queue: 'nested-' + parent,
      failfunc: 'failCommonAjaxResponse' });
    EventMgr.trigger('tabLoading', { tabId: parent });
  }

  var isIE = '\v' === 'v';

  function scrollToFormRow($focusedField, tabId, animate) {
    setTimeout(function () {
      var formRow = $focusedField.closest('.l-form__row'),
          offsetTop = formRow[0] ? formRow[0].offsetTop : 0,
          $page = $focusedField.closest('.b-form-page'),
          formScrollEl = App.Dom.byId('form-scroll-' + tabId),
          heightViewPort = formScrollEl ? parseInt(formScrollEl.style.height, 10) : 0;
      if ($page[0]) {
        offsetTop += $page[0].offsetTop;
      }

      EventMgr.trigger('scrollTo', {
        id: 'form-scroll-' + tabId,
        offsetTop: offsetTop,
        animate: animate });
    }, 100);
  }

  function focusOnErrorField(e, data) {
    var $focusField = $('.row-error .b-input, .row-error .b-textarea, .row-error .b-checkbox__control'),
        tabId = data.tabId,
        $page;
    if ($focusField.length > 0) {
      $page = $focusField.closest('.b-form-page');
      if ($page.hasClass('b-form-page_st_collapsed')) {
        $page.find('.i-form-page__title').trigger('click');
      }

      $focusField.focus();
      scrollToFormRow($focusField, tabId, true);
    }
  }

  function setFocus(e, data) {
    if (isIE || window.pageInfo.mobile) {
      return;
    }
    var tabId = data.tabId,
        form = document.getElementById('frm-' + tabId);
    if (form === null) {
      return;
    }
    var len = form.length,
        elem = null,
        curElem,
        name,
        r1,
        readonly,
        forceFocused = $('#form-wrapper-' + tabId + ' .b-form__focus-field');
    //force focused field by attr focus="yes"
    if (forceFocused.length > 0) {
      forceFocused.focus();
      scrollToFormRow(forceFocused, tabId, false);
      return;
    }
    //find out accessable field
    for (var i = 0; i < len; i++) {
      elem = form[i];
      //for select
      if (elem.type === 'hidden' && elem.getAttribute('data-type') === 'select') {
        curElem = $(elem).parent();
        if (!curElem.hasClass('readonly') && curElem.width() !== 0) {
          name = elem.getAttribute('name');
          $('#_' + name + '-' + tabId + ' .b-myselect__select-value').focus();
          window.scrollToTopLeft();
          return;
        }
        //for radio
      } else if (elem.type === 'hidden' && elem.getAttribute('data-type') === 'radio') {
        curElem = $(elem).parent();
        if (!curElem.hasClass('readonly') && curElem.width() !== 0) {
          name = elem.getAttribute('name');
          $('.tab-content_st_active div[data-id="' + name + '"][tabindex="0"]').focus();
          window.scrollToTopLeft();
          return;
        }
      } else if (elem.type === 'hidden' && elem.getAttribute('data-type') === 'checkbox') {
        name = elem.getAttribute('name');
        $('#' + tabId + '-' + name).focus();
        window.scrollToTopLeft();
        return;
      }
      r1 = elem.getAttribute('readonly');
      readonly = r1 !== null;
      if (elem.type !== 'hidden' && !readonly && elem.offsetWidth !== 0) {
        elem.focus();
        window.scrollToTopLeft();
        return;
      }
    }
    form = null;
    elem = null;
  }

  function AttrIsSupported(element, attr) {
    var elem = document.createElement(element);
    return attr in elem;
  }
  /**
   * forceSetValues
   * @param {object} e event object
   * @param {object} data object with data
   */
  function forceSetValues(e, data) {
    var tabId = data.tabId,
        url = pageInfo.url,
        name = data.name,
        params = $('#frm-' + tabId).serializeObject();
    /* jslint camelcase:false */
    params.sv_field = name;
    /* jslint camelcase:true */
    EventMgr.trigger('ajaxRequest', {
      url: url,
      param: params,
      trfunc: 'formSetValues',
      invar: { tabId: tabId },
      type: 'get',
      outtype: 'json',
      queue: 'multiload' });
  }

  /**
   * Callback setvalues field changed
   * send request for new values
   * @param {object} e  event object
   * @param {boolean} sv  setvalues once flag
   * @return {boolean}
   * @this {object} HTML node
   */
  var lastTargetElemId = 'default_value';
  function setValueHandler(e, sv, srcId) {
    var self = this;
    setTimeout(function () {
      EventMgr.trigger('preSetValues', [self, 100]);
      //check for loop
      var elemId = self.getAttribute('id'),
          $self = $(self),
          flags = $self.getFlags();
      if ($self.hasClass('b-textarea_for_zoom')) {
        return true;
      }
      if (lastTargetElemId === srcId) {
        return true;
      }
      lastTargetElemId = elemId;
      //check for setvalues once
      if (sv) {
        return true;
      }
      //var tabId = $activeTab().attr('data-tabid'),
      var tabId = self.getAttribute('data-tabid'),
          $form = $('#frm-' + tabId),
          params = $form.serializeObject(),
          addParams = {},
          url = pageInfo.url,
          once = App.Dom.hasClass(self.parentNode, 'sv_nochange'),
          blocking = App.Dom.hasClass(self.parentNode, 'sv_blocking') || flags.blocking,
          name = self.getAttribute('data-name') ? self.getAttribute('data-name') : self.name,
          id = self.getAttribute('data-id'),
          isShowcaseForm = $form.hasClass('b-form_showcase_yes'),
          hasFile = $form.hasClass('withfiles'),
          skipFile = App.Dom.hasClass(self.parentNode, 'sv_skipfiles'),
          $noSetValues = $form.find('.i-nosetvalues');

      if ($noSetValues.length !== 0) {
        params = App.u.removeParam($noSetValues, params);
      }

      //check for button id
      if (id && id !== 'undefined') {
        id = id.split('=', 2);
        if (id[1]) {
          params[id[0]] = id[1];
          addParams[id[0]] = id[1];
        }
      }

      /* jshint camelcase: false */
      params.sv_field = name;
      var options = {
        url: url,
        param: params,
        failfunc: 'failFormAjaxResponse',
        trfunc: 'formSetValues',
        invar: { tabId: tabId, once: once, blocking: blocking },
        type: 'post',
        outtype: 'json',
        queue: 'multiload' };
      //if form has input@type=file
      if (hasFile && !skipFile) {
        /* jshint camelcase: false */
        options.invar.blocking = true;
        addParams.sv_field = name;
        addParams.sfrom = 'ajax';
        EventMgr.trigger('setBrandSettings', {
          options: options,
          tabId: tabId,
          param: params,
          addParams: addParams
        });
      } else {
        /* jslint camelcase:true */
        EventMgr.trigger('ajaxRequest', options);
        if (blocking) {
          EventMgr.trigger('tabLoading', { tabId: tabId });
        }
      }
    }, 0);
  }
  /**
   * Проверяем на изменение значения мультиселекта
   */
  function isMultiSelectValuesChanged(stringVal, arrVal) {
    //check for empty value - only slist rerender
    if (arrVal === '') {
      return true;
    }
    if (typeof stringVal === 'string') {
      if (typeof arrVal === 'string') {
        arrVal = arrVal.split(',');
      } else if (typeof arrVal.join !== 'function') {
        return false;
      }
      var oldValues = stringVal.split(','),
          l = oldValues.length;
      oldValues.sort();
      arrVal.sort();
      if (oldValues.length !== arrVal.length) {
        return true;
      }
      while (l--) {
        if (oldValues[l] !== arrVal[l]) {
          return true;
        }
      }
      return false;
    }
    return false;
  }

  /**
   * Setvalues handler
   * change values in fields from response
   * @param {object} e event object
   * @param {object} data object with data
   **/
  function formSetValues(e, data) {
    //check for auth
    if (data.ok && data.reload) {
      window.location.reload();
    }
    var tabId = data.tabId,
        form = App.Dom.byId('frm-' + tabId),
        once = data.once,
        blocking = data.blocking,
        readonlyArray = [];
    if (blocking) {
      EventMgr.trigger('tabLoadingHide', { tabId: tabId });
    }
    if (form === null || data.error) {
      return;
    }
    var setvalues = data.setvalues,
        elem = '',
        keyVar,
        tagName,
        value,
        changed,
        dType,
        type,
        liAct,
        elemId;
    if ((typeof setvalues === 'undefined' ? 'undefined' : _typeof(setvalues)) === 'object') {
      /* jslint forin:true */
      for (keyVar in setvalues) {
        elem = form.elements[keyVar];
        //check for bad words
        if (keyVar === 'item' || keyVar === 'length') {
          continue;
        }
        if (elem) {
          tagName = elem.tagName;
          value = setvalues[keyVar];
          changed = true;
          if (value === null) {
            continue;
          }
          if (tagName === 'INPUT') {
            type = elem.getAttribute('type');
            if (elem.value !== value) {
              //input@type=text
              if (type === 'text' || type === 'password') {
                changed = elem.value !== value.value;
                elem.value = value.value;
                if (value.prefix) {
                  var $prefixNode = $(elem).parent().find('.i-input__prefix');
                  if ($prefixNode.length) {
                    $prefixNode.html(value.prefix);
                    EventMgr.trigger('upPrefixField', { tabId: tabId });
                  }
                }
                //slider logic
                if (value.min !== undefined || value.max !== undefined || value.step !== undefined) {
                  var id = elem.id,
                      $sliderNode = $('#' + id + '-slider');
                  if (value.min !== undefined) {
                    $sliderNode.attr('data-min', value.min);
                  }
                  if (value.max !== undefined) {
                    $sliderNode.attr('data-max', value.max);
                  }
                  if (value.step !== undefined) {
                    $sliderNode.attr('data-step', value.step);
                  }
                  EventMgr.trigger('reloadSlider', { tabId: tabId });
                }
                //mask logic
                if (value.mask !== undefined) {
                  EventMgr.trigger('inputMaskChangeBySetvalues', { elem: elem, mask: value.mask, value: value.value });
                }
              } else if (type === 'file') {
                //reset file value
                if (value.value === '') {
                  var $elem = $(elem);
                  $elem.replaceWith($elem.val('').clone(true));
                  $(form.elements[keyVar]).trigger('change');
                }
              } else if (type === 'hidden') {
                // #17927 setvalues[keyVar].slist
                changed = elem.value !== value.value || setvalues[keyVar].slist;
                if (changed) {
                  elemId = elem.getAttribute('id');
                  dType = elem.getAttribute('data-type');
                  //select
                  if (dType === 'select') {
                    //replace slist values
                    if (value.slist) {
                      $('ul#' + tabId + '-' + elem.name).html(renderSlistElem(setvalues[keyVar].slist));
                      //clean slist cache for searching
                      EventMgr.trigger('cleanSlistCache', {
                        tabId: tabId,
                        id: tabId + '-' + elem.name });
                      //check for search in list
                      if (setvalues[keyVar].slist && setvalues[keyVar].slist.length > 10) {
                        var $mySelect = $('#_' + elem.name + '-' + tabId);
                        if (!$mySelect.hasClass('sb-select')) {
                          $mySelect.addClass('sb-select');
                        }
                      }
                      EventMgr.trigger('forceDepend', { tabId: tabId });
                      if (setvalues[keyVar].slist && setvalues[keyVar].slist.length !== 0) {
                        //set active item
                        if (setvalues[keyVar].value !== '') {
                          liAct = $('#' + tabId + '-' + keyVar + ' li[data-val="' + setvalues[keyVar].value + '"]');
                        } else {
                          liAct = $('#' + tabId + '-' + keyVar + ' li[data-val="' + elem.value + '"]');
                          if (liAct.length === 0) {
                            liAct = $('ul#' + tabId + '-' + elem.name + ' li:first');
                          }
                        }
                      } else {
                        //set null msg
                        $('#_' + keyVar + '-' + tabId + ' .b-myselect__select-value').html(setvalues.nullmsg);
                      }
                    } else {
                      // case without slist
                      //set active item
                      liAct = $('#' + tabId + '-' + keyVar + ' li[data-val="' + value.value + '"]');
                    }
                    //set value for select
                    if (liAct.length > 0) {
                      var $selectElem = $('#_' + keyVar + '-' + tabId),
                          isReadonly = $selectElem.hasClass('readonly');
                      //check for readonly
                      if (isReadonly) {
                        $selectElem.removeClass('readonly');
                      }
                      liAct.trigger('click', [once, elemId]);
                      if (isReadonly) {
                        $selectElem.addClass('readonly');
                      }
                    }
                    //radio
                  } else if (dType === 'radio') {
                    if (value.slist && App.Tabs.tabs[tabId] && App.Tabs.tabs[tabId].formSource && App.Tabs.tabs[tabId].formSource[keyVar]) {
                      var sourceElem = App.Tabs.tabs[tabId].formSource[keyVar],
                          radioHtml = '';
                      sourceElem.slist = value.slist;
                      if (value.value) {
                        sourceElem.value = value.value;
                        //set first value
                      } else if (sourceElem.slist[0]) {
                        sourceElem.value = sourceElem.slist[0].key;
                      }
                      radioHtml = templates.formItemRadio(sourceElem);
                      $('#' + tabId + '-' + keyVar + '-radio').replaceWith(radioHtml);
                    }
                    if (!value.slist) {
                      $('#' + 'frm-' + tabId + ' .' + keyVar + '-' + tabId + '-' + window.hash(value.value)).trigger('click', [once, elemId]);
                    }
                    // checkbox
                  } else if (dType === 'checkbox') {
                    $('#' + tabId + '-' + keyVar).trigger('click', [[once, true]]);
                    // multiselect
                  } else if (dType === 'multiple') {
                    // replace value.value with value
                    var mvalue = value.value !== undefined ? value.value : value;
                    changed = isMultiSelectValuesChanged(elem.value, mvalue);
                    // вызываем при изменение значений или наличие slist
                    if (changed || value.slist) {
                      var id = elem.getAttribute('data-id');
                      EventMgr.trigger('selectValues', {
                        id: id, sElems: setvalues[keyVar] });
                    }
                    // input@type=hidden
                  } else if (dType === 'tree') {
                    $('#' + keyVar + '-' + tabId + ' li[data-val="' + setvalues[keyVar].value + '"]').trigger('click', [once, true]);
                  } else {
                    elem.value = value.value;
                  }
                }
              }
              if (changed) {
                elemId = elem.getAttribute('id');
                $(elem).trigger('change', [once, elemId]);
              }
            }
          } else {
            changed = elem.value !== value.value;
            elem.value = value.value;
            if (changed) {
              elemId = elem.getAttribute('id');
              $(elem).trigger('change', [once, elemId]);
              if (elem.classList && elem.classList.contains('b-text-editor')) {
                EventMgr.trigger('TinyMCE_setContent', { content: elem.value, id: elemId });
              }
            }
          }
          //set readonly
          if (value.readonly) {
            var readonly = value.readonly === 'yes';
            //changeReadOnly($(elem).closest('.l-form__row'), readonly);
            //add to array and set after all
            readonlyArray.push({ elem: elem, readonly: readonly });
          }
        } else {
          //textdata
          elem = App.Dom.byId(tabId + '-' + keyVar);
          if (elem) {
            type = elem.getAttribute('data-type');
            if (type === 'img') {
              elem.src = setvalues[keyVar].value;
              //ticket
            } else if (type === 'ticket') {
              var newTicketHtml = templates.formItemTicketMsg(setvalues[keyVar]);
              if (newTicketHtml) {
                $(newTicketHtml).appendTo(elem);
              }
              //              EventMgr.trigger('setFocus', { tabId: tabId });
              //list
            } else if (type === 'list') {
              setvalues[keyVar].id = tabId;
              setvalues[keyVar].type = 'form';
              if (setvalues[keyVar].view === 'blocklist') {
                elem.innerHTML = templates.formListBlocksContent(setvalues[keyVar]);
              } else {
                elem.innerHTML = templates.formListContent(setvalues[keyVar]);
              }
            } else if (type === 'listfilter') {
              setvalues[keyVar].id = tabId;
              elem.innerHTML = templates.formListFilter(setvalues[keyVar]);
              //buttons
            } else if (type === 'buttons') {
              var buttons = setvalues[keyVar],
                  l = setvalues[keyVar].length;
              for (var i = 0; i < l; i++) {
                //check for same buttons
                if (data.__formModel && data.__formModel.__buttons[i] && buttons[i].name !== data.__formModel.__buttons[i].name) {
                  var parent = $('#' + tabId + '-buttons .b-button').first().attr('data-parent');
                  elem.innerHTML = templates.buttons({
                    buttons: buttons,
                    id: tabId,
                    parent: parent,
                    type: 'form',
                    cancelBtnClass: ''
                  });
                  //update form model
                  EventMgr.trigger('updateModel', {
                    tabId: tabId,
                    name: '__buttons',
                    value: buttons
                  });
                  break;
                }
              }
              if (l === 0) {
                elem.innerHTML = '';
                //update form model
                EventMgr.trigger('updateModel', {
                  tabId: tabId,
                  name: '__buttons',
                  value: buttons
                });
              }
            } else if (type === 'link') {
              //unescape &amp; -> &
              var hrefLink = String(setvalues[keyVar].value).replace(/&amp;/g, '&');
              elem.href = hrefLink;
              elem.setAttribute('data-url', App.u.escapeQuote(hrefLink));
            } else if (type === 'datetime') {
              var d = App.u.parseDate(setvalues[keyVar].value),
                  dt = new Date().getTime() - d.getTime();
              elem.setAttribute('data-difftime', dt);
            } else if (type === 'textdata') {
              elem = App.Dom.byId(tabId + '-' + keyVar + '-inner');
              elem.innerHTML = window.htmlDecode(setvalues[keyVar].value);
              // EventMgr.trigger('updateScroll', { id: tabId + '-' + keyVar });
            } else {
              elem.innerHTML = window.htmlDecode(setvalues[keyVar].value);
            }
            EventMgr.trigger('updateScroll', { id: 'form-scroll-' + tabId });
          } else {
            //for frame
            elem = App.Dom.byId(keyVar + '-' + tabId);
            if (elem && elem.getAttribute('data-type') === 'frame') {
              elem.setAttribute('src', setvalues[keyVar].value);
            }
          }
        }
      }
    }
    //set readonly
    for (var i = 0, l = readonlyArray.length; i < l; i++) {
      App.FormUtils.changeReadOnly($(readonlyArray[i].elem).closest('.l-form__row'), readonlyArray[i].readonly);
    }
    EventMgr.trigger('setValuesDone', { tabId: tabId });
  }

  function renderSlistElem(elems) {
    var elemHTML = templates.formItemSelectList({ slist: elems, value: '' });
    return elemHTML;
  }
  //remove space and insert line break when press SPACE in zoom field
  function addLineBreakToZoomField(e) {
    var codeKey = e.which || e.keyCode;
    if (codeKey === SPACE) {
      e.preventDefault();
      var allText = this.value,
          currentPos = getCaret(this),
          beforeText = allText.substr(0, currentPos),
          afterText = allText.substr(currentPos);

      this.value = beforeText.replace(/((\s*\S+)*)\s*/, '$1') + '\n' + afterText.replace(/((\s*\S+)*)\s*/, '$1');
      setCaretPosition(this, beforeText.length);
    }
  }
  //from
  // http://stackoverflow.com/questions/11779140/how-to-push-cursor-to-the-next-line-when-user-hits-ctrl-enter
  function getCaret(el) {
    if (el.selectionStart) {
      return el.selectionStart;
    } else if (document.selection) {
      el.focus();

      var r = document.selection.createRange();
      if (r === null) {
        return 0;
      }

      var re = el.createTextRange(),
          rc = re.duplicate();
      re.moveToBookmark(r.getBookmark());
      rc.setEndPoint('EndToStart', re);

      return rc.text.length;
    }
    return 0;
  }

  function setCaretPosition(elem, caretPos) {
    if (elem !== null) {
      if (elem.createTextRange) {
        var range = elem.createTextRange();
        range.move('character', caretPos);
        range.select();
      } else {
        if (elem.selectionStart) {
          elem.focus();
          elem.setSelectionRange(caretPos, caretPos);
        } else {
          elem.focus();
        }
      }
    }
  }

  //sync value zoom textarea and input
  function syncZoomValue(e) {
    var self = $(this),
        controlField = self.attr('data-control-field'),
        tabId = $activeTab().attr('data-tabid'),
        input = $('#cont-' + tabId + ' input[name="' + controlField + '"],' + ' #editinlist-wrapper-' + tabId + ' input[name="' + controlField + '"]'),
        value = self.val().replace(/\n+/g, ' ').replace(/(^\s*|\s*$)/g, '').replace(/\s+/g, ' ');
    input.val(value).trigger('change');
  }

  function syncInputWithZoom(e, data) {
    var tabId = data.tabId,
        input = data.self,
        controlField,
        textarea,
        value;
    if (input && App.Dom.hasClass(input, 'testzoom')) {
      controlField = input.name;
      textarea = $('#cont-' + tabId + ' .b-textarea[name="zoom-' + controlField + '"],' + ' #editinlist-wrapper-' + tabId + ' .b-textarea[name="zoom-' + controlField + '"]');
      value = input.value.replace(/(^\s*|\s*$)/g, '').replace(/\s+/g, '\n');
      if (textarea.length > 0) {
        textarea[0].value = value;
      }
    }
  }
  //calendar handler
  function calendarHandler(e) {
    var self = $(this),
        calendarFieldName = self.attr('data-control-field'),
        type = self.attr('data-type'),
        activeTab = $activeTab().attr('data-tabid'),
        calendarField = App.Dom.byId(calendarFieldName + '-' + activeTab),
        syncFieldName,
        syncField;
    if (calendarField) {
      syncFieldName = calendarField.getAttribute('data-syncfield');
      if (syncFieldName) {
        syncField = App.Dom.byId(syncFieldName + '-' + activeTab);
      }
    }
    //not good
    if (calendarField !== null) {
      if (type === 'month') {
        App.Calendar.showMonth(calendarField, syncField, e);
      } else {
        App.Calendar.show(calendarField, syncField, e);
      }
    }
  }
  //zoom handler
  function zoomHandler() {
    var self = $(this),
        controlField = self.attr('data-control-field'),
        row = self.parents('.l-form__row'),
        tabId = $activeTab().attr('data-tabid'),
        input = $('#cont-' + tabId + ' input[name="' + controlField + '"],' + ' #editinlist-wrapper-' + tabId + ' input[name="' + controlField + '"]'),
        textarea = $('#cont-' + tabId + ' .b-textarea[name="zoom-' + controlField + '"],' + ' #editinlist-wrapper-' + tabId + ' .b-textarea[name="zoom-' + controlField + '"]'),
        value;
    if (row.hasClass('zoom')) {
      //state = 'zoom';
      row.removeClass('zoom');
      value = textarea[0].value.replace(/\n+/g, ' ').replace(/(^\s*|\s*$)/g, '').replace(/\s+/g, ' ');
      input.val(value);
    } else {
      // state = 'unzoom';
      row.addClass('zoom');
      value = input.val().replace(/(^\s*|\s*$)/g, '').replace(/\s+/g, '\n');
      textarea[0].value = value;
    }
    EventMgr.trigger('updFormHeight', { tabId: tabId });
    EventMgr.trigger('updateFixedField', { tabId: tabId });
  }
  //toggle password field type text/password
  function showPassword() {
    var pwdFieldName = this.getAttribute('data-control-field'),
        tabId = this.getAttribute('data-tabid'),
        pwdField = App.Dom.byId(pwdFieldName + '-' + tabId);
    if (pwdField) {
      var type = pwdField.getAttribute('type');
      if (type === 'text') {
        pwdField.setAttribute('type', 'password');
        $(this).removeClass('b-input-btn_pwd_liketext');
      } else if (type === 'password') {
        pwdField.setAttribute('type', 'text');
        $(this).addClass('b-input-btn_pwd_liketext');
      }
    }
  }

  function fakePasswdCopy() {
    var parentId = this.getAttribute('data-parent'),
        parent = App.Dom.byId(parentId);
    if (parent !== null) {
      parent.value = this.value;
      $(parent).trigger('change');
    }
  }
  //password generation
  function genPassword() {
    var pwdFieldName = this.getAttribute('data-control-field'),
        pwdField = $('.tab-content_st_active input[name="' + pwdFieldName + '"]'),
        current = pwdField.val(),
        confFieldName = pwdField.attr('data-check-field'),
        pwdLen = pageInfo.pwgenlen || 8,
        pwdChar = pageInfo.pwgencharacters || '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        confField = $('.tab-content_st_active' + ' input[name="' + confFieldName + '"][type="password"]'),
        n = 0,
        rn,
        nnn = 0,
        tabId = $activeTab().attr('data-tabid'),
        pwdFake,
        confirmFake;
    if (pwdField.attr('readonly')) {
      return;
    }
    if (pwdFieldName) {
      $('.b-input-btn_type_showpwd[data-control-field="' + pwdFieldName + '"]').remove();
    }
    pwdFake = App.Dom.byId(pwdFieldName + '-' + tabId + '-fake');
    confirmFake = App.Dom.byId(confFieldName + '-' + tabId + '-fake');

    if (pwdFake && pwdFake.offsetWidth === 0) {
      pwdFake.style.display = 'block';
      if (confirmFake) {
        confirmFake.style.display = 'block';
      }
      pwdField.hide();
      if (confField) {
        confField.hide();
      }
    }
    var lowerCase = pwdChar.match(/[a-z]/g),
        upperCase = pwdChar.match(/[A-Z]/g),
        number = pwdChar.match(/\d/g),
        special = pwdChar.match(/[!,@,#,$,%,^,&,*,?,_,~]/g),
        pwgenchar = {},
        typesPull = [],
        i,
        nn = 0,
        letters = 0;
    if (lowerCase || upperCase) {
      nn++;
      typesPull.push('l');
    }
    if (lowerCase) {
      lowerCase = lowerCase.join('');
      if (!upperCase) {
        pwgenchar.l = lowerCase;
      } else {
        pwgenchar.lc = lowerCase;
      }
      letters++;
    }
    if (upperCase) {
      upperCase = upperCase.join('');
      if (!lowerCase) {
        pwgenchar.l = upperCase;
      } else {
        pwgenchar.uc = upperCase;
      }

      letters++;
    }
    if (number) {
      number = number.join('');
      pwgenchar.d = number;
      typesPull.push('d');
      nn++;
    }
    if (special) {
      special = special.join('');
      pwgenchar.s = special;
      typesPull.push('s');
      nn++;
    }
    for (i = 0; i < pwdLen - nn; i++) {
      if (nnn === nn) {
        nnn = 0;
      }
      typesPull.push(typesPull[nnn]);
      nnn++;
    }
    rn = Math.floor(Math.random() * pwdLen + 1) % nn;
    typesPull = shiftArray(typesPull, rn);
    var elemObj = {
      passwdField: pwdField,
      confirmField: confField,
      passwdFake: pwdFake,
      confirmFake: confirmFake,
      pwdLen: pwdLen,
      //pwdChar : pwdChar,
      typesPull: typesPull,
      pwgenchar: pwgenchar,
      letters: letters
    };
    genPasswd(current, n, elemObj, 'lc');
  }

  //last to one
  function shiftArray(arr, n) {
    var elem,
        len = arr.length - 1;
    while (n--) {
      elem = arr[0];
      arr.splice(0, 1);
      arr[len] = elem;
    }
    return arr;
  }

  function genPasswd(current, n, elemObj, prevCase) {
    current = current.substr(0, n);
    var pwd = '',
        curCase = prevCase,
        curType,
        typesPull = elemObj.typesPull,
        pwgenchar = elemObj.pwgenchar,
        letters = elemObj.letters;

    for (var i = n; i < elemObj.pwdLen; i++) {
      curType = typesPull[i];
      if (curType === 'l' && letters === 2) {

        if (curCase === 'lc') {
          curCase = 'uc';
        } else {
          curCase = 'lc';
        }
        curType = curCase;
        if (i === n) {
          prevCase = curCase;
        }
      }
      pwd += pwgenchar[curType].substr(Math.floor(Math.random() * pwgenchar[curType].length), 1);
    }
    n++;
    current += pwd;
    elemObj.passwdField.val(current);
    elemObj.confirmField.val(current);
    elemObj.passwdFake.value = current;
    if (elemObj.confirmFake) {
      setTimeout(function () {
        elemObj.confirmFake.value = current;
      }, 1);
    }
    if (n < elemObj.pwdLen) {
      setTimeout(function () {
        genPasswd(current, n, elemObj, prevCase);
      }, 35);
    } else {
      $(elemObj.passwdField).trigger('change');
      $(elemObj.passwdFake).trigger('change');
      $(elemObj.confirmField).trigger('change');
    }
  }

  function getActiveTabId() {
    return $('.tab-content_st_active').attr('data-tabid') || false;
  }

  var UPKEY = 38,
      DOWNKEY = 40,
      LEFTKEY = 37,
      RIGHTKEY = 39,
      ENTERKEY = 13,
      TABKEY = 9,
      ESCKEY = 27,
      SPACE = 32;
  //trigger click if ENTER||SPACE KEYDOWN by element
  function formBtnKeyDownHandler(e) {
    e = e || window.event;
    var codeKey = e.which || e.keyCode;
    if (codeKey === ENTERKEY || codeKey === SPACE) {
      e.preventDefault();
      $(this).trigger('click');
    }
  }

  function radioBtnKeyDownHandler(e) {
    e = e || window.event;
    var codeKey = e.which || e.keyCode,
        name,
        id,
        tabId,
        radios;
    if (codeKey === UPKEY && !e.ctrlKey) {
      e.preventDefault();
      name = this.getAttribute('data-id');
      id = this.getAttribute('data-handler-val');
      radios = $(this).closest('.b-radio').find('div[data-id="' + name + '"]');
      var prev = null;
      radios.each(function () {
        var curId = this.getAttribute('data-handler-val');
        if (curId === id && prev !== null) {
          this.setAttribute('tabindex', '');
          prev.setAttribute('tabindex', '0');
          changeRadioValue.apply(prev);
          prev.focus();
          window.scrollToTopLeft();
          return false;
        }
        prev = this;
      });
    } else if (codeKey === DOWNKEY && !e.ctrlKey) {
      e.preventDefault();
      name = this.getAttribute('data-id');
      id = this.getAttribute('data-handler-val');
      radios = $(this).closest('.b-radio').find('div[data-id="' + name + '"]');
      var next = false;
      radios.each(function () {
        if (next) {
          this.setAttribute('tabindex', '0');
          changeRadioValue.apply(this);
          this.focus();
          return false;
        }
        var curId = this.getAttribute('data-handler-val');
        if (curId === id) {
          this.setAttribute('tabindex', '');
          next = true;
        }
      });
    }
  }

  function radioLabelClickHandler() {
    var rClass = this.getAttribute('data-r-class'),
        targetElem = $('.' + rClass);
    targetElem.trigger('click');
  }
  function checkboxDescClickHandler(e, sv) {
    var tabId = this.getAttribute('data-tabid'),
        id = this.getAttribute('data-id'),
        targetElem = $('.b-checkbox__control[data-tabid="' + tabId + '"]' + '[data-id="' + id + '"]');
    targetElem.trigger('click', [sv]);
  }
  //set radio value
  function changeRadioValue(e, sv) {
    var self = $(this),
        id = this.getAttribute('data-id'),
        val = this.getAttribute('data-val'),
        handlerVal = this.getAttribute('data-handler-val');

    if (self.hasClass('checked')) {
      return false;
    } else {
      $('.' + id).removeClass('checked').attr('tabindex', '');
      self.addClass('checked');
      this.setAttribute('tabindex', '0');
      this.focus();
      $('#' + id).val(val).attr('data-handler-val', handlerVal).trigger('change', [sv]);
    }
  }
  /**
   * Callback checkbox click event
   * check/uncheck checkbox
   * @param  {object} e event object
   * @param {boolean} setvalues flag once
   * @return {boolean}
   * @this {object} HTML node
   */
  function changeCheckboxValue(e, param) {
    var $self = $(this),
        id = this.getAttribute('data-id'),
        elem;
    param = param || [];
    if ($self.hasClass('readonly') && !param[1]) {
      return false;
    }
    if ($self.hasClass('checked')) {
      $self.removeClass('checked');
      elem = $('input[name=' + id + ']').val('off').attr('data-handler-val', hash('off'));
    } else {
      $self.addClass('checked');
      elem = $('input[name=' + id + ']').val('on').attr('data-handler-val', hash('on'));
    }
    elem.trigger('change', [param[0]]);
  }

  function collapsedForm(e) {
    //dangerously
    var TIMEOUT = 300;
    e = e || window.event;
    //check for dashboard block reload click
    if (e && e.target) {
      if ($(e.target).hasClass('dashblock-reload')) {
        return;
      }
    }
    if (!App.Global.HeaderMoving) {
      var self = $(this),
          parent = self.parent(),
          elemSlide = parent.next(),
          elemParent = parent.parent(),
          tabId = elemParent.attr('data-tabid'),
          name = parent.attr('data-name'),
          type = parent.attr('data-type'),
          $stateElem = parent.find('.b-triangle'),
          collapsed = elemParent.hasClass('b-form-page_st_collapsed');
      if (collapsed) {
        elemSlide.slideDown(TIMEOUT);
        elemParent.removeClass('b-form-page_st_collapsed');
        $stateElem.attr('data-state', 'expanded');
      } else {
        elemSlide.slideUp(TIMEOUT);
        $stateElem.attr('data-state', 'collapsed');
        setTimeout(function () {
          elemParent.addClass('b-form-page_st_collapsed');
          elemParent = null;
        }, TIMEOUT - 20);
      }
      //form page
      if (type !== 'dashboard-block') {
        EventMgr.trigger('saveFormPageState', {
          tabId: tabId,
          name: name,
          collapsed: collapsed
        });
        setTimeout(function () {
          EventMgr.trigger('updFormHeight', { tabId: tabId });
          EventMgr.trigger('updateScroll', {});
          tabId = null;
        }, TIMEOUT);
      } else {
        //dashboard block
        setTimeout(function () {
          EventMgr.trigger('updateScroll', {});
        }, TIMEOUT);
        var position = self.parents('.b-dashboard_cell').attr('data-pos'),
            display = collapsed ? 'max' : 'min',
            block = self.parent().attr('data-name');
        var param = {
          func: 'dashboard.save', out: 'xml',
          block: block, display: display, position: position };
        var url = pageInfo.url;
        EventMgr.trigger('ajaxRequest', {
          url: url, param: param,
          trfunc: 'DoNothing', queue: 'noqueue' });
        if (!collapsed) {
          setTimeout(function () {
            EventMgr.trigger('updateScroll', {});
          }, TIMEOUT);
        } else {
          setTimeout(function () {
            EventMgr.trigger('updateScroll', {});
            EventMgr.trigger('upDashTableList', { tabId: 'block-' + block });
            block = null;
          }, 10);
        }
      }
    } else {
      App.Global.HeaderMoving = false;
    }
    e.preventDefault();
  }

  function insertUnlimValue() {
    var parId = this.getAttribute('data-control-field'),
        tabId = getActiveTabId(),
        parentEl = App.Dom.byId(parId + '-' + tabId),
        value = parentEl.getAttribute('data-unlimit');
    if (parentEl !== null) {
      parentEl.value = value;
      //for setvalues
      $(parentEl).trigger('change');
    }
  }

  function changeElHandler(e) {
    var showAttr = this.getAttribute('show'),
        show = showAttr.split(','),
        len = show.length,
        checked = this.getAttribute('checked'),
        className = 'hideEl';
    while (len--) {
      $('formItem' + show[len]).toggleClass(className);
    }
  }
  //hide/show depend items in select and radio
  function dependSlistHandler(e) {
    var value = this.value,
        name = this.getAttribute('name'),
        type = this.getAttribute('data-type'),
        tabId = this.getAttribute('data-tabid'),
        elem,
        selectElem,
        showElem;
    //hide select options
    $('#frm-' + tabId + ' div[data-depend="' + name + '"] .dependelem.b-myselect__select-li_show_yes').removeClass('b-myselect__select-li_show_yes');
    $('#frm-' + tabId + ' div[data-depend="' + name + '"] .dependelem[data-dependkey="' + value + '"]').addClass('b-myselect__select-li_show_yes');

    //uncheck radio
    selectElem = $('#frm-' + tabId + ' div[data-depend="' + name + '"] .b-myselect__select-li_show_yes .b-radio__control.checked');
    if (selectElem.length === 0) {
      $('#frm-' + tabId + ' div[data-depend="' + name + '"] .b-radio__control').removeClass('checked');
      elem = $('#frm-' + tabId + ' div[data-depend="' + name + '"] .b-myselect__select-li_show_yes .b-radio__control')[0];
      if (elem) {
        changeRadioValue.apply(elem);
      }
    }
    //check for more one depend select
    var $dependSelect = $('#frm-' + tabId + ' div[data-depend="' + name + '"]');
    if ($dependSelect.length > 1) {
      $dependSelect.each(function () {
        var showElem = $(this).find('.dependelem[data-dependkey="' + value + '"].b-myselect__select-li_show_yes');
        dependSelectCheckForOprion(showElem, name, tabId, $(this));
      });
    } else {
      //unselect option
      showElem = $('#frm-' + tabId + ' div[data-depend="' + name + '"] ' + 'li.dependelem[data-dependkey="' + value + '"].b-myselect__select-li_show_yes');
      dependSelectCheckForOprion(showElem, name, tabId);
    }
    //unselect multiselect
    if ($dependSelect.length) {
      $dependSelect.each(function () {
        if (appDom.hasClass(this, 'b-mselect')) {
          EventMgr.trigger('mselectUnselectByDepend', { self: this });
        }
      });
    }
    EventMgr.trigger('updateScroll', { id: 'form-scroll-' + tabId });
  }

  /**
   * Проверяем на наличия опций у зависимого селекта, если их нет скрываем поле
   */
  function dependSelectCheckForOprion(showElem, name, tabId, $self) {
    var $elem = $self || $('#frm-' + tabId + ' div[data-depend="' + name + '"]');
    if (showElem.length === 0) {
      $elem.closest('.l-form__row').css('display', 'none');
    } else {
      $elem.closest('.l-form__row').css('display', '');
    }
  }

  //show depend items in append form
  function firstDependSlistHandler(e, data) {
    var tabId = data.tabId;
    $('#cont-' + tabId + ' tr:not(".row-error") .depend.b-myselect ' + 'input[type="hidden"],' + ' #cont-' + tabId + ' .depend.b-radio input[type="hidden"],' + ' #cont-' + tabId + ' .depend.b-select-ac input[type="hidden"]').each(function () {
      dependSlistHandler.apply(this);
    });
    EventMgr.trigger('updFormHeight', { tabId: tabId });
    EventMgr.trigger('reloadSlider', { tabId: tabId });
  }

  function bandShowHandler(e) {
    var id = this.getAttribute('data-id'),
        self = $(this),
        toggleClass = 'data-table-hidden';
    if (self.hasClass(toggleClass)) {
      self.removeClass(toggleClass);
      $('#' + id).slideDown(300);
    } else {
      self.addClass(toggleClass);
      $('#' + id).slideUp(300);
    }
    setTimeout(function () {
      EventMgr.trigger('updateScroll', {});
    }, 350);
  }

  /**
   * setUp padding for input with prefix
   * @param {object} e
   * @param {object} data
   */
  function prefixFieldSetUp(e, data) {
    var tabId = data.tabId;
    setTimeout(function () {
      $('#cont-' + tabId + ' .i-input__prefix').each(function () {
        var elemWidth = this.offsetWidth,
            input = App.Common.getPreviousNode(this),
            inputWidth,
            PADDING = 7,
            BORDER = 1;
        if (input) {
          inputWidth = input.offsetWidth;
          input.style.width = inputWidth - elemWidth - (PADDING + BORDER * 2) + 'px';
          input.style.paddingLeft = elemWidth + 'px';
        }
      });
    }, 1);
  }

  //click for row in form list
  function formListRowClickHandler(e) {
    //check for loop
    if (e.target) {
      var $target = $(e.target);
      if ($target.hasClass('i-button') || $target.prop('tagName') === 'A' || $target.hasClass('b-checkbox__control')) {
        return;
      }
    }
    var $self = $(this),
        buttons = $self.find('.i-button_default_yes'),
        checkbox = $self.find('.i-checkbox_type_default');

    if (buttons.length === 1) {
      buttons.trigger('click');
    } else if (checkbox.length === 1) {
      checkbox.trigger('click');
    }
  }

  //
  function textareaResize(e) {
    var lastHeight = parseInt(this.style.height, 10),
        scrollHeight,
        maxHeight = (this.getAttribute('data-max-rows') - 0) * 12,
        BTNBOXHEIGHT = 62,
        id = this.getAttribute('id'),
        tabId = this.getAttribute('data-tabid');
    this.style.height = 'auto';
    scrollHeight = this.scrollHeight - 0;
    if (maxHeight < scrollHeight) {
      $(this).removeClass('b-textarea_responsive_yes');
    }
    this.style.height = scrollHeight + 'px';
    if (lastHeight !== scrollHeight) {

      EventMgr.trigger('updFormHeight', {
        tabId: tabId });
      //scroll textarea for visible area
      var textareaBotPos = $(this).offset().top + scrollHeight + BTNBOXHEIGHT,
          windowHeight = window.innerHeight;
      if (textareaBotPos > windowHeight) {
        var $self = $(this),
            offsetTop = $self.closest('.l-form__row')[0] ? $self.closest('.l-form__row')[0].offsetTop : 0,
            $page = $self.closest('.b-form-page'),
            formScrollEl = App.Dom.byId('form-scroll-' + tabId),
            heightViewPort = formScrollEl ? parseInt(formScrollEl.style.height, 10) : 0;
        if ($page[0]) {
          offsetTop += $page[0].offsetTop;
        }
        offsetTop -= heightViewPort - (scrollHeight + BTNBOXHEIGHT + this.offsetTop);
        EventMgr.trigger('scrollTo', {
          id: 'form-scroll-' + tabId,
          offsetTop: offsetTop,
          raw: false
        });
      }
    }
  }

  function ticketMoveUpHandler(e) {
    var tabId = this.getAttribute('data-tabid'),
        $self = $(this),
        $row = $self.closest('.l-form__row'),
        offsetTop = 0;
    if ($row[0]) {
      offsetTop = $row[0].offsetTop;
      EventMgr.trigger('scrollTo', {
        id: 'form-scroll-' + tabId,
        offsetTop: offsetTop,
        animate: true
      });
    }
  }

  function ticketMoveDownHandler(e) {
    var tabId = this.getAttribute('data-tabid'),
        $self = $(this),
        $row = $self.closest('.l-form__row'),
        $form = $self.closest('.l-form__wrapper'),
        offsetTop = 0,
        height = 0,
        formHeight = 0,
        MAGICNUMBER2 = 120,
        //min height item for work
    MAGICNUMBER = 160; //btn box height
    if ($row[0] && $form[0]) {
      offsetTop = $row[0].offsetTop;
      height = $row[0].offsetHeight;
      if (height < 120) {
        return;
      }
      formHeight = $form[0].offsetHeight;
      EventMgr.trigger('scrollTo', {
        id: 'form-scroll-' + tabId,
        offsetTop: offsetTop + height - formHeight + MAGICNUMBER,
        animate: true
      });
    }
  }

  function ticketCollapseHandler(e) {
    e.preventDefault();
    var $self = $(this),
        tabId = $self.closest('.tab-content').attr('data-tabid');
    if ($self.hasClass('mbar-showall')) {
      $self.removeClass('mbar-showall').addClass('mbar-hideall');
      $self.closest('.b-ticket__table-row_is_collapsible').removeClass('b-ticket__table-row_is_collapsed');
    } else {
      $self.removeClass('mbar-hideall').addClass('mbar-showall');
      $self.closest('.b-ticket__table-row_is_collapsible').addClass('b-ticket__table-row_is_collapsed');
    }
    EventMgr.trigger('updFormHeight', { tabId: tabId });
  }

  return {
    init: init,
    checkPassStrength: checkPassStrength,
    CACHE: CACHE
  };
}(window, $, EventMgr, App, ScrollHandler);
//# sourceMappingURL=App.Forms.js.map

'use strict';

/**
 * Wizard Module
 * Control wizard steps
 * @param {object} window global object
 * @param {object|function} $ jQuery
 * @param {object} EventMgr Event manager
 */
/*global App:true*/
App.Wizards = function (window, $, EventMgr) {
  'use strict';

  /**
   * Event in appendForm for check wizard steps
   * @param {object} e
   * @param {object} data
   */

  function wizardLoad(e, data) {
    var tabId = data.tabId;
    setTimeout(function () {
      EventMgr.trigger('bindHorizScrollControl', {
        leftBtn: '#cont-' + tabId + ' .i-wizard__triangle_dir_left',
        rightBtn: '#cont-' + tabId + ' .i-wizard__triangle_dir_right',
        actElem: '#cont-' + tabId + ' .i-wizard__step-num_st_active',
        innerBox: '#cont-' + tabId + ' .i-wizard__inner',
        id: tabId
      });
    }, 50);
  }

  /**
   * Init function
   * Bind to needed events
   */
  function init() {
    EventMgr.bind('appendForm', wizardLoad);
  }

  var api = {
    init: init
  };

  return api;
}(window, $, EventMgr);
//# sourceMappingURL=App.Wizards.js.map

'use strict';

/**
 * ScrollController
 * requires ScrollHandler!!!
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 *  @param {object} ScrollHandler Scrollbar library
 */
App.ScrollController = function (window, $, EventMgr, App, ScrollHandler) {
  'use strict';

  var init = function init() {
    EventMgr.bind('menuTypeChanged', updateScroll);
    EventMgr.obind($window(), 'resize', updateScroll);
    EventMgr.bind('updateScroll', updateScroll);
    EventMgr.bind('loadPage', attachScrollMenu);
    EventMgr.bind('appendForm,appendedFilter', attachScrollTabtoForm);
    EventMgr.bind('appendToolbarAce', attachScrollToToolbarAce);
    EventMgr.bind('appendReport', attachScrollTabtoForm);
    EventMgr.bind('appendList', attachScrollTabtoList);
    EventMgr.bind('appendMapDone', attachScrollTabtoRack);
    EventMgr.bind('loadLoginForm', attachScrolltoLoginForm);
    EventMgr.bind('appendDashboard', attachScrollTabtoDB);
    EventMgr.bind('appendDashList', attachScrolltoBlockDB);
    EventMgr.bind('closeTabEvent', detachScroll);
    EventMgr.bind('scrollTo', scrollTo);
  },
      $window = function $window() {
    return $(window);
  },
      updateScroll = function updateScroll(e, data) {
    if (data && data.id) {
      ScrollHandler.update(data.id);
    } else {
      ScrollHandler.update();
    }
    data = null;
  },
      detachScroll = function detachScroll(e, data) {
    ScrollHandler.detach(data.tabId);
    data = null;
  },
      attachScrollMenu = function attachScrollMenu() {
    setTimeout(function () {
      ScrollHandler.attach('menu-items-wr', 'menu-items', 'tab0');
    }, 10);
  },
      attachScrolltoBlockDB = function attachScrolltoBlockDB(e, data) {
    var blockId = data.tabId,
        cont = blockId + '-scrollwrapper',
        obj = 'lt-' + blockId;
    ScrollHandler.attach(cont, obj, blockId, true, true);
    data = null;
  },

  //вешаем сколл на форму
  attachScrollTabtoForm = function attachScrollTabtoForm(e, data) {
    setTimeout(function () {
      var tabId = data.tabId;
      ScrollHandler.attach('form-scroll-' + tabId, 'form-scroll-in-' + tabId, tabId, true);
      $('#frm-' + tabId + ' .band-table').each(function () {
        var id = this.id;
        ScrollHandler.attach(id, 'lt-' + id, tabId, true, true);
      });
      $('#frm-' + tabId + ' .b-form-list_view_table').each(function () {
        var id = this.id;
        ScrollHandler.attach(id, 'inner-' + id, tabId, true, true);
      });
      // for select
      $('#frm-' + tabId + ' .b-myselect__select-ul').each(function () {
        var id = this.getAttribute('id');
        ScrollHandler.attach('cont-' + id, id, tabId, true);
      });
      // for multiselect
      $('#frm-' + tabId + ' .b-mselect__ul-choose').each(function () {
        var id = this.getAttribute('data-id');
        ScrollHandler.attach(id + '-ms-list', id + '-ms-list-ul', tabId, true);
      });
      // for multiselect
      $('#frm-' + tabId + ' .b-mselect__view-value').each(function () {
        var id = this.getAttribute('data-id');
        ScrollHandler.attach(this.id, id + '-ms-view', tabId, true);
      });
      //for tree
      $('#frm-' + tabId + ' .tree-inner').each(function () {
        var id = this.getAttribute('id');
        ScrollHandler.attach('cont-' + id, id, tabId, true, true);
      });

      //for select autocomplite
      $('#frm-' + tabId + ' .b-select-ac__list').each(function () {
        var id = this.getAttribute('id');
        ScrollHandler.attach('cont-' + id, id, tabId, true);
      });
      // $('#frm-' + tabId + ' .b-textdata').each(function() {
      //   var id = this.getAttribute('id');
      //   ScrollHandler.attach(id, id + '-inner', tabId, true, true);
      // });
      tabId = null;
      data = null;
    }, 50);
  },
      attachScrollToToolbarAce = function attachScrollToToolbarAce(e, data) {
    var tabId = data.tabId;
    $('#frm-' + tabId + ' .b-myselect__select-ul').each(function () {
      var id = this.getAttribute('id');
      ScrollHandler.attach('cont-' + id, id, tabId, true);
    });
  },
      attachScrollTabtoDB = function attachScrollTabtoDB(e, data) {
    var tabId = 'tab0';
    ScrollHandler.attach('cont-' + tabId, 'incont-' + tabId, 'tab0', true);
    tabId = null;
  },
      attachScrolltoLoginForm = function attachScrolltoLoginForm(e, data) {
    $('.b-myselect__select-ul').each(function () {
      var id = this.getAttribute('id');
      ScrollHandler.attach('cont-' + id, id, 'tab1', true);
      id = null;
    });
  },
      attachScrollTabtoList = function attachScrollTabtoList(e, data) {
    var tabId = data.tabId;
    ScrollHandler.attach('ltwr-' + tabId, 'lt-' + tabId, tabId, true);
    ScrollHandler.attach('cont-' + tabId + '-pager-slist', tabId + '-pager-slist', tabId, true);
    tabId = null;
  },
      attachScrollTabtoRack = function attachScrollTabtoRack(e, data) {
    if (data.map.type === 'rack') {
      var tabId = data.tabId;
      ScrollHandler.attach(tabId + '-map', 'b-rack-' + tabId, tabId, true);
    }
  },
      scrollTo = function scrollTo(e, data) {
    var offsetTop = data.offsetTop,
        id = data.id,
        raw = data.raw,
        animate = data.animate;
    ScrollHandler.scrollTo(id, offsetTop, raw, animate);
  };

  return {
    init: init
  };
}(window, $, EventMgr, App, ScrollHandler);
//# sourceMappingURL=App.ScrollController.js.map

'use strict';

/**
 * ajax helper module
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 */
App.AjaxHelper = function (window, $, EventMgr) {
  'use strict';

  var init = function init() {
    EventMgr.bind('ajaxRequest', ajaxRequest);
    EventMgr.bind('ajaxRequestAbort', ajaxRequestAbort);
  },
      CACHE = {},
      ajaxRequestAbort = function ajaxRequestAbort(e, data) {
    var id = data.id;
    if (CACHE[id] && CACHE[id].xhr.abort) {
      CACHE[id].erMsg = 'Request canceled By User';
      CACHE[id].xhr.abort();
    }
  },
      addRequestHook = function addRequestHook(cb) {
    if (typeof cb === 'function') {
      requestHooks.push(cb);
    }
  },
      addResponseHook = function addResponseHook(cb) {
    if (typeof cb === 'function') {
      responseHooks.push(cb);
    }
  },
      requestHooks = [],
      responseHooks = [],
      applyRequestHooks = function applyRequestHooks(data) {
    for (var i = 0, l = requestHooks.length; i < l; i++) {
      requestHooks[i].apply(this, [data]);
    }
  },
      applyResponseHooks = function applyResponseHooks(data) {
    for (var i = 0, l = responseHooks.length; i < l; i++) {
      responseHooks[i].apply(this, [data]);
    }
  },
      ajaxRequest = function ajaxRequest(e, dataSource) {
    applyRequestHooks(dataSource);
    var cUrl = dataSource.url || pageInfo.url,
        param = dataSource.param || {},
        formData = dataSource.formData || {},
        inVar = dataSource.invar || {},
        trFunc = dataSource.trfunc || 'ajaxResponse',
        failFunc = dataSource.failfunc || false,
        type = dataSource.type || 'get',
        outType = dataSource.outtype || 'html',
        queueName = dataSource.queue || 'queue',
        noesc = !!dataSource.noesc,
        reqType = dataSource.reqType || 'jquery',
        progressCb = dataSource.progressCb || function () {},
        rp = dataSource.rp || [],
        id = dataSource.id;
    inVar.__dataSource = dataSource;
    if (queueName === 'noqueue') {
      queueName = new Date().getTime();
    }
    param.sfrom = 'ajax';
    param.operafake = new Date().getTime();
    var paramString = getQueryString(param, noesc);

    if (reqType === 'jquery') {
      EventMgr.trigger('getAjaxRequest', {});
      var ajaxParams = {
        url: cUrl,
        type: type,
        dataType: 'html',
        data: paramString,
        headers: { 'ISP-Client': 'Web-interface' },
        //data : param,
        async: true,
        success: success,
        xhrFields: { withCredentials: true },
        error: error
      };
      if (type === 'jsonp') {
        ajaxParams.jsonp = 'callback';
        ajaxParams.dataType = 'jsonp';
        ajaxParams.crossDomain = true;
      }
      $.ajaxq(queueName, ajaxParams);
    } else {
      //progress upload
      var xhr = new XMLHttpRequest();
      xhr.upload.addEventListener('progress', progressCb, false);
      xhr.open('POST', cUrl);
      //set header for long request
      xhr.setRequestHeader('ISP-Client', 'Web-interface');
      xhr.onreadystatechange = function () {
        if (this.readyState === 4) {
          if (this.status === 200) {
            delete CACHE[id];
            success(this.responseText);
          } else {
            error(this, this.statusText, this.statusText);
          }
        }
      };
      formData.append('sfrom', 'ajax');
      CACHE[id] = { xhr: xhr };
      xhr.send(formData);
    }
    /* jshint latedef: false*/
    function success(data) {
      if (type !== 'jsonp') {
        data = data.replace(/\\'/g, "'");
        data = data.replace(/^<![\w\s\"-\/]*>/g, '');
        if (!data) {
          //wtf?
          console.log('empty response');
          EventMgr.trigger('ajaxError', {});
          return;
        }
      }

      if (outType === 'json' && type !== 'jsonp') {
        //remove non-printable characters
        data = data.replace(/[\x00-\x08\x0B-\x0C\x0E-\x1F]/g, '');
        try {
          data = jQuery.parseJSON(data);
        } catch (e) {
          //error
          console.log('jsonParseError', dataSource, failFunc);
          dataSource.erType = 'json';
          if (failFunc) {
            EventMgr.trigger(failFunc, dataSource);
          }
          //EventMgr.trigger('ajaxError', {});
          return;
        }
      }
      if (outType !== 'html') {
        data.sourceParamString = paramString;
        //add props in returned object
        $.extend(data, inVar);
        data.selfUrl = pageInfo.url + '?' + data.urlparam;
        //remove some param from response
        if (rp.length) {
          data = removeParams(data, rp);
        }
      }

      if (trFunc !== 'DoNothing') {
        EventMgr.trigger(trFunc, data);
      }
      EventMgr.trigger('giveAjaxRequest', {});
    }
    /* jshint latedef: false*/
    function error(jqXHR, textStatus, errorThrown) {
      //check for long request
      if ((errorThrown === 'Service Unavailable' || jqXHR.status === 503) && !dataSource.ignore503) {
        //go to new url while request not end
        var longUrl = jqXHR.responseText;
        dataSource.url = pageInfo.host + '/' + longUrl;
        dataSource.reqType = 'jquery';
        EventMgr.trigger('ajaxRequest', dataSource);
      } else if (trFunc === 'ajaxResponse' && inVar.exType === 'dashboard') {
        inVar.error = true;
        inVar.shithappend = true;
        EventMgr.trigger('ajaxResponse', inVar);
      } else if (failFunc) {
        var regex = /<div class="fatal-error-desc">(.*?)<\/div>/ig,
            errText = String(jqXHR.responseText).match(regex);
        if (errText && errText[0]) {
          dataSource.erMsg = errText[0];
        }
        if (CACHE[dataSource.id] && App.u.isString(CACHE[dataSource.id].erMsg)) {
          dataSource.erMsg = CACHE[dataSource.id].erMsg;
        }
        EventMgr.trigger(failFunc, dataSource);
        delete CACHE[dataSource.id];
      }
      console.log(textStatus);
    }
  },
      removeParams = function removeParams(data, rp) {
    var l = rp.length;
    while (l--) {
      data[rp[l]] = null;
    }
    return data;
  },

  //join with &
  getQueryString = function getQueryString(queryObj, noesc) {
    var j = 0,
        paramString = '',
        curValue,
        keyVar;
    for (keyVar in queryObj) {
      if (keyVar !== '') {
        if (j !== 0) {
          paramString += '&';
        }
        curValue = queryObj[keyVar];
        //encode params
        if (noesc) {
          paramString += keyVar + '=' + curValue;
        } else {
          paramString += keyVar + '=' + encodeURIComponent(curValue);
        }
        j++;
      }
    }
    return paramString;
  };
  return {
    init: init,
    addRequestHook: addRequestHook,
    addResponseHook: addResponseHook
  };
}(window, $, EventMgr);
//# sourceMappingURL=App.AjaxHelper.js.map

'use strict';

/**
 * Valid checker module
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 */
App.ValidChecker = function (window, $, EventMgr, App) {
  var init = function init() {
    EventMgr.bind('checkValue', checkValue);
    EventMgr.bind('validatorResponse', managerValidator);
  },
      checkValue = function checkValue(e, data) {
    var nameValid = data.name,
        self = data.self,
        paramValid = data.param,
        number = data.number,
        value = data.value,
        prefix = data.prefix,
        fieldName = data.fieldname,
        funcName = data.funcname,
        convert = data.convert;
    //ajax request
    var param = {
      func: 'check.' + nameValid,
      value: value,
      name: fieldName,
      funcname: funcName };
    if (paramValid) {
      param.args = paramValid;
    }
    if (prefix) {
      param.prefix = prefix;
    }
    if (convert) {
      param.tconvert = convert;
    }
    EventMgr.trigger('ajaxRequest', {
      url: pageInfo.url,
      param: param,
      invar: {
        self: self,
        namevalid: nameValid,
        ovalue: self.value,
        vvalue: value,
        multi: data.multi,
        number: number },
      trfunc: 'validatorResponse',
      outtype: 'json',
      queue: 'multiload' });
  },
      managerValidator = function managerValidator(e, data) {
    var self = data.self,
        nameValid = data.namevalid,
        ovalue = data.ovalue,
        value = data.value,
        number = data.number,
        vvalue = data.vvalue;
    if (data.ermsg) {
      validatorErrors[nameValid] = data.ermsg;
      if (ovalue === self.value && self.offsetWidth !== 0 || self.nextSibling !== null && self.nextSibling.nodeName.toLowerCase() === 'textarea' && self.nextSibling.offsetWidth !== 0 && ovalue === self.value) {
        EventMgr.trigger('errMsgValid', {
          type: nameValid,
          self: self,
          err: data.ermsg,
          number: number });
      } else {
        EventMgr.trigger('okMsgValid', {
          type: nameValid,
          self: self,
          number: number });
      }
    } else {
      if (ovalue === self.value) {
        //single valid
        EventMgr.trigger('okMsgValid', {
          type: nameValid,
          self: self,
          number: number,
          multi: data.multi,
          value: value,
          ovalue: ovalue,
          vvalue: vvalue });
      } else {
        //multivalid
        EventMgr.trigger('okMsgValid', {
          type: nameValid,
          self: self,
          multi: data.multi,
          number: number,
          value: value,
          ovalue: ovalue,
          vvalue: vvalue });
      }
    }
  },
      validatorErrors = {};

  return {
    init: init
  };
}(window, $, EventMgr, App);
//# sourceMappingURL=App.ValidChecker.js.map

'use strict';

/**
 * Slider module
 * @param {object} window global object
 * @param {object|function} $ jQuery
 * @param {object} EventMgr Event manager
 * @param {object} App Application
 */
/*global App:true*/
App.Slider = function (window, $, EventMgr, App) {
  'use strict';

  var init = function init() {
    EventMgr.on($content(), sliderSelector, 'mousedown', drag);
    EventMgr.on($content(), sliderWrapperSelector, 'mousedown', sliderToPoint);
    EventMgr.bind('appendForm', start);
    EventMgr.bind('appendEditInList', startEditInList);
    EventMgr.bind('reloadSlider', start);
    EventMgr.on($content(), sliderInputSelector, 'change', sliderMove);
    EventMgr.on($content(), sliderInputSelector, 'keydown', sliderKeyDownHandler);
    EventMgr.on($content(), sliderInputSelector, 'keyup', deleteSliderHandler);
    EventMgr.on($content(), sliderSelector, 'ontouchstart', drag);
  },
      $content = function $content() {
    return $('#main-wrapper');
  },
      sliderSelector = '.l-slider__wr:not(".readonly") .b-slider__el',
      sliderInputSelector = '.b-input_for_slider:not(".readonly")',
      sliderWrapperSelector = '.l-slider__wr:not(".readonly")',
      max = 0,
      min = 0,
      self = null,
      maxleft = 0,
      shiftX = 0,
      width = 0,
      intId = null,
      tabId = '',
      inputId = null,
      step = 0,


  //flag for change input value
  fromInput = false,
      calcValue = function calcValue(np) {
    var bound = max - min,
        delta = bound / maxleft,
        initDelta = min % step,
        value = Math.round(np * delta) + parseInt(min, 10),
        el = App.Dom.byId(inputId),
        elSlider = App.Dom.byId(inputId + '-slider'),
        ldf = value % step,
        rdf = step - ldf;
    if (ldf > rdf) {
      value += rdf;
    } else {
      value -= ldf;
    }
    value += initDelta;
    //check bounds
    if (value > max) {
      value = max;
    } else if (value < min) {
      value = min;
    }
    if (el !== null) {
      el.value = value;
    }
    if (elSlider) {
      elSlider.setAttribute('data-value', value);
    }
    EventMgr.trigger('changeSliderValue', { tabId: tabId });
  },
      getDataSlider = function getDataSlider() {
    tabId = self.getAttribute('data-tabid');
    inputId = self.getAttribute('data-id');
    min = self.getAttribute('data-min');
    step = parseInt(self.getAttribute('data-step'), 10);
    if (!step) {
      step = 1;
    }
    max = self.getAttribute('data-max');
    width = $(self).parent().width();
    maxleft = width - 9;
  },
      setPosition = function setPosition(newPosition) {
    var np = 0;
    if (newPosition <= maxleft && newPosition >= 0) {
      np = newPosition;
    } else if (newPosition > maxleft) {
      fromInput = false;
      np = maxleft;
    } else {
      fromInput = false;
      np = 0;
    }
    self.style.left = np + 'px';
    if (!fromInput) {
      calcValue(np);
    }
    fromInput = false;
    return false;
  },
      start = function start(e, data) {
    tabId = data.tabId;
    $('#incont-' + tabId + ' .b-slider__el').each(function () {
      self = this;
      fromInput = true;
      getDataSlider();
      if (width !== 0) {
        var value = this.getAttribute('data-value'),
            bound = max - min,
            delta = bound / maxleft,
            np = value / delta - min / delta;
        setPosition(np);
      }
    });
  },
      startEditInList = function startEditInList(e, data) {
    tabId = data.tabId;
    $('#editinlist-wrapper-' + tabId + ' .b-slider__el').each(function () {
      self = this;
      fromInput = true;
      getDataSlider();
      var value = this.getAttribute('data-value'),
          bound = max - min,
          delta = bound / maxleft,
          np = value / delta - min / delta;
      setPosition(np);
    });
  },
      sliderMove = function sliderMove(e, sv) {
    e = e || window.event;
    var f = this.value.substr(0, 1) === '-' ? '-' : '';
    this.value = f + this.value.replace(/\D/g, '');
    fromInput = true;
    var id = this.getAttribute('id');
    self = App.Dom.byId(id + '-slider');
    getDataSlider();
    var value = App.Dom.byId(inputId).value,
        ldf = value % step,
        rdf = step - ldf,
        bound = max - min,
        delta = bound / maxleft,
        initDelta = min % step,
        np,
        elSlider = App.Dom.byId(inputId + '-slider');
    value -= 0;
    if (ldf > rdf) {
      value += rdf;
    } else {
      value -= ldf;
    }
    value += initDelta;
    this.value = value;
    np = value / delta - min / delta;

    if (np > maxleft) {
      fromInput = false;
    }
    setPosition(np);
    blockEvent(e);

    if (elSlider) {
      elSlider.setAttribute('data-value', value);
    }

    EventMgr.trigger('changeSliderValue', { tabId: tabId });
    return false;
  },
      sliderKeyDownHandler = function sliderKeyDownHandler(e) {
    e = e || window.event;
    var codeKey = e.which || e.keyCode,
        id;
    if (codeKey === 38 || codeKey === 40) {
      id = this.getAttribute('id');
      self = $('a#' + id + '-slider')[0];
      getDataSlider();
      blockEvent(e);
    }
    if (codeKey === 38 && !e.ctrlKey) {
      clearInterval(intId);
      sliderMoveForKeyDown(true);
      intId = setInterval(function () {
        sliderMoveForKeyDown(true);
      }, 100);
      blockEvent(e);
    } else if (codeKey === 40 && !e.ctrlKey) {
      clearInterval(intId);
      sliderMoveForKeyDown(false);
      intId = setInterval(function () {
        sliderMoveForKeyDown(false);
      }, 100);
      blockEvent(e);
    }
  },
      deleteSliderHandler = function deleteSliderHandler() {
    var f = this.value.substr(0, 1) === '-' ? '-' : '';
    this.value = f + this.value.replace(/\D/g, '');
    clearInterval(intId);
  },
      sliderMoveForKeyDown = function sliderMoveForKeyDown(up) {
    var input = App.Dom.byId(inputId),
        value = input.value;
    if (up) {
      value = parseInt(value, 10) + step;
    } else {
      if (value === max) {
        value -= 3;
      } else {
        value -= step;
      }
    }
    input.value = value;
    EventMgr.trigger('changeSliderValue', { tabId: tabId });
    $('#' + inputId).trigger('change');
  },
      sliderToPoint = function sliderToPoint(e) {
    e = e || window.event;
    self = $(this).children('.b-slider__el')[0];
    getDataSlider();
    shiftX = e.clientX - $(this).offset().left - 7;
    setPosition(shiftX);
    $('#' + inputId).trigger('change');
  },
      drag = function drag(e) {
    $(this).trigger('focus');
    e = e || window.event;
    if (e.touches) {
      shiftX = e.touches[0].pageX - parseInt(this.style.left, 10);
      document.ontouchmove = move;
      document.ontouchend = drop;
      document.ontouchcancel = drop;
    } else {
      shiftX = e.clientX - parseInt(this.style.left, 10);
      document.onmousemove = move;
      document.onmouseup = drop;
    }
    self = this;
    getDataSlider();
    blockEvent(e);
    return false;
  },

  //Handler for move
  move = function move(e) {
    e = e || window.event;
    if (e.touches) {
      setPosition(e.touches[0].pageX - shiftX);
    } else {
      setPosition(e.clientX - shiftX);
    }
    blockEvent(e);
    return false;
  },

  //Handler for mouseup, unbind mousemove and mouseup
  drop = function drop(e) {
    $(this).trigger('blur');
    e = e || window.event;
    document.onmousemove = null;
    document.onmouseup = null;
    document.ontouchmove = null;
    document.ontouchend = null;
    document.ontouchcancel = null;
    $('#' + inputId).trigger('change');
    blockEvent(e);
  };

  return {
    init: init
  };
}(window, $, EventMgr, App);
//# sourceMappingURL=App.Slider.js.map

'use strict';

/**
  Select Autocomplete
  provide select with options autocomplete
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 *  @param {object} ScrollHandler Scrollbar library
 *  @return {object}
 **/
App.SelectAutoComplete = function (window, $, EventMgr, App, ScrollHandler) {
  'use strict';

  var inputSelector = '.b-select-ac__input',
      chooseListItem = '.i-select-ac__list-item',
      keys = {
    '38': 'UPKEY',
    '40': 'DOWNKEY',
    '37': 'LEFTKEY',
    '39': 'RIGHTKEY',
    '13': 'ENTERKEY',
    '9': 'TABKEY'
  };

  function $content() {
    var content;
    return function () {
      if (!content || content.length === 0) {
        content = $('#main-wrapper');
      }
      return content;
    }();
  }

  function $body() {
    var content;
    return function () {
      if (!content || content.length === 0) {
        content = $('body');
      }
      return content;
    }();
  }

  function init() {
    EventMgr.on($content(), inputSelector, 'keyup', keyUpHandler);
    EventMgr.on($content(), inputSelector, 'keydown', tabUpHandler);
    EventMgr.on($content(), inputSelector, 'blur', checkValue);
    EventMgr.on($content(), inputSelector, 'click', getDefaultOptions);
    EventMgr.on($content(), inputSelector, 'click', preventDefault);
    EventMgr.bind('selectAutoCompleteResponse', makeChooseList);
    EventMgr.on($content(), chooseListItem, 'click', chooseListItemHandler);
  }

  var timer, lastValue;

  function preventDefault(e) {
    e.preventDefault();
    e.stopPropagation();
  }

  function getChooseList(elem, firstRun) {
    var name = elem.getAttribute('data-name'),
        tabId = elem.getAttribute('data-tabid'),
        url = window.pageInfo.url,
        param = $('#frm-' + tabId).serializeObject(),
        value = elem.value;
    param[name] = elem.value;
    /* jslint camelcase: false */
    param.sv_field = name;
    param.sv_autocomplete = 'yes';
    /* jslint camelcase: true */
    if (value !== lastValue || firstRun) {
      EventMgr.trigger('ajaxRequest', {
        url: url,
        param: param,
        trfunc: 'selectAutoCompleteResponse',
        invar: { tabId: tabId, sourceField: name, value: value },
        type: 'post', outtype: 'json', queue: 'noqueue' });
    }
    lastValue = value;
  }

  function getDefaultOptions() {
    // close others list
    $body().trigger('click');
    var elem = this;
    getChooseList(elem, true);
  }

  /**
   * KeyUp handler
   * get choose list or set value from choose list
   * @param {object} e
   * @this {Node}
   */
  function keyUpHandler(e) {
    e = e || window.event;
    var codeKey = e.which || e.keyCode;
    if (keys[codeKey]) {
      keyChooseListItem(e, keys[codeKey], this);
      return;
    }
    var elem = this;
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(function () {
      getChooseList(elem);
    }, 200);
  }

  /**
   * Choose value by up/down key
   * @param {Object} e Event object
   * @param {String} key Name of key
   * @param {HTMLElement} elem
   * @param {Boolean} dontPrevent Don't prevent default action
   */
  function keyChooseListItem(e, key, elem, dontPrevent) {
    var name = elem.getAttribute('data-name'),
        tabId = elem.getAttribute('data-tabid'),
        $selected = $('#b-select-ac-list__' + name + '-' + tabId + ' .b-select-ac__list-item_selected_yes');
    if ($selected.length === 0) {
      $selected = $('#b-select-ac-list__' + name + '-' + tabId + ' .i-select-ac__list-item:first');
      if ($selected.length === 0) {
        return;
      } else {
        $selected.addClass('b-select-ac__list-item_selected_yes');
        chooseListItemHandler.apply($selected[0], [e, true, dontPrevent]);
        return;
      }
    }

    if (key === 'UPKEY') {
      var prev = $selected.prev();
      if (prev.length !== 0) {
        $selected.removeClass('b-select-ac__list-item_selected_yes');
        prev.addClass('b-select-ac__list-item_selected_yes');
        chooseListItemHandler.apply(prev[0], [e, true, dontPrevent]);
      }
    } else if (key === 'DOWNKEY') {
      var next = $selected.next();
      if (next.length !== 0) {
        $selected.removeClass('b-select-ac__list-item_selected_yes');
        next.addClass('b-select-ac__list-item_selected_yes');
        chooseListItemHandler.apply(next[0], [e, true, dontPrevent]);
      }
    } else if (key === 'ENTERKEY') {
      chooseListItemHandler.apply($selected[0], [e, false, dontPrevent]);
    } else if (key === 'TABKEY') {
      //choose only when selected 1st elem
      if ($selected.index() === 0) {
        chooseListItemHandler.apply($selected[0], [e, true, dontPrevent]);
      }
    }
  }
  var chooseListStorage = {},
      VALUESCACHE = {};

  /**
   * Build choose list from response
   * @param {Object} e
   * @param {Object} data
   * @return {Boolean}
   */
  function makeChooseList(e, data) {
    var tabId = data.tabId,
        fieldName = data.sourceField,
        commonId = fieldName + '-' + tabId,
        listElem = App.Dom.byId('b-select-ac-list__' + commonId),
        listElemWrapperId = 'cont-b-select-ac-list__' + commonId,
        listElemWrapper = App.Dom.byId(listElemWrapperId),
        chooseList = data.setvalues[fieldName],
        defValue = data.value,
        l,
        html = '',
        value,
        re,
        options = {},
        id = new Date().getTime(),
        focusedElem = document.activeElement;
    //show only if element is focused
    if (focusedElem) {
      if (focusedElem.getAttribute('data-name') !== fieldName) {
        return false;
      }
    }

    //trigger setvalues if somebody add other field values
    if (data[data.sourceField]) {
      data[data.sourceField] = null;
      EventMgr.trigger('formSetValues', data);
    }

    if (chooseList && chooseList.slist) {
      l = chooseList.slist.length;
      for (var i = 0; i < l; i++) {
        value = chooseList.slist[i].value;
        if (typeof value === 'string') {
          re = new RegExp('(' + App.u.escapeRegExp(defValue) + ')', 'i');
          value = value.replace(re, '<span class="b-select-ac__font-normal">$1</span>');
          html += '<li data-id="' + i + '" data-lid="' + id + '"' + ' class="b-select-ac__list-item i-select-ac__list-item">' + value + '</li>';
          options[String(i)] = {
            key: chooseList.slist[i].key,
            value: chooseList.slist[i].value
          };
        }
      }
      chooseListStorage[String(id)] = {
        options: options
      };
      listElem.innerHTML = html;
    } else {
      listElem.innerHTML = '<li class="b-select-ac__list-item i-select-ac__list-item ' + 'b-select-ac__list-item_notfound_yes" data-lid="' + id + '">' + pageInfo.notfound + '</li>';
    }
    if (listElemWrapper.style.display !== 'block') {
      listElemWrapper.style.display = 'block';
      $body().on('click.closeChooseList', $.proxy(closeChooseList, listElem));
    } else {
      $body().off('click.closeChooseList');
      $body().on('click.closeChooseList', $.proxy(closeChooseList, listElem));
    }
    EventMgr.trigger('updateScroll', listElemWrapperId);
    App.Common.setOptionListPosition('#opt-', commonId);
  }

  function setValue(opt) {
    opt = opt || {};
    var inputValue = App.Dom.byId(opt.id),
        inputKey = App.Dom.byId('key-' + opt.id);
    if (inputValue) {
      inputValue.value = opt.value;
    }
    if (inputKey) {
      inputKey.value = opt.key;
      $(inputKey).trigger('change');
      VALUESCACHE[opt.id] = {
        key: opt.key,
        value: opt.value
      };
    }
  }

  /**
   * Set choosen value to element
   * @param {Object} e
   * @param {Boolean|Undefined} dontclose Don't close flag
   * @param {Boolean|Undefined} dontPrevent Don't prevent default action
   * @this {Node}
   */
  function chooseListItemHandler(e, dontclose, dontPrevent) {
    if (!dontPrevent) {
      e.preventDefault();
    }
    var elem = this,
        id = elem.getAttribute('data-id'),
        lid = elem.getAttribute('data-lid'),
        parentNode = elem.parentNode,
        inputId = parentNode.getAttribute('data-id');
    if (chooseListStorage[lid] && chooseListStorage[lid].options) {
      if (chooseListStorage[lid].options[id] !== undefined) {
        setValue({
          id: inputId,
          key: chooseListStorage[lid].options[id].key,
          value: chooseListStorage[lid].options[id].value
        });
      }
    }
    if (!dontclose) {
      closeChooseList.apply(parentNode, [{}, true]);
    }
  }
  function tabUpHandler(e) {
    e = e || window.event;
    var codeKey = e.which || e.keyCode;
    if (keys[codeKey] === 'TABKEY') {
      if (this.value !== '') {
        keyChooseListItem(e, 'TABKEY', this, true);
      }
      //close list
      $body().trigger('click');
    }
  }
  /**
   * check congruence for value & key
   */
  function checkValue(e, force) {
    var id = this.getAttribute('id'),
        optListWrapper = App.Dom.byId('cont-b-select-ac-list__' + id),
        optList = App.Dom.byId('b-select-ac-list__' + id);
    if (force || optListWrapper && optListWrapper.style.display === 'none' || $(optList).find('.b-select-ac__list-item_notfound_yes').length) {
      var inputKey = App.Dom.byId('key-' + id);
      if (VALUESCACHE[id] && inputKey && VALUESCACHE[id].key === inputKey.value) {
        if (this.value !== '') {
          this.value = VALUESCACHE[id].value;
        } else {
          setValue({ id: id, key: '', value: '' });
        }
      } else {
        this.value = '';
      }
    }
  }

  /**
   * check fullmatch value & options
   */
  function checkFullmatch(options, value) {
    var fullmatch = false,
        fullmatchKey;
    if (options && value !== undefined) {
      var l = options.length;
      for (var key in options) {
        if (options.hasOwnProperty(key)) {
          fullmatchKey = key;
          if (options[key].value === value) {
            fullmatch = true;
            break;
          }
        }
      }
    }
    return {
      yes: fullmatch,
      key: options[fullmatchKey].key
    };
  }
  /**
   * close Choose list
   * @param {Boolean|Undefined} chosen
   * @param {Object} e
   * @this {Node}
   */
  function closeChooseList(e, chosen) {
    var listItem = $(this).find('.i-select-ac__list-item');
    var listElemWrapper = this.parentNode;

    if (listItem[0] && !chosen) {
      var lid = listItem[0].getAttribute('data-lid'),
          id = this.getAttribute('data-id');
      if (id && chooseListStorage && chooseListStorage[lid]) {
        var inputValue = App.Dom.byId(id),
            fullmatch = checkFullmatch(chooseListStorage[lid].options, inputValue.value);
        //if (chooseListStorage[lid].fullmatchKey !== false) {
        if (fullmatch.yes) {
          //set valuesCache
          setValue({
            id: id,
            key: fullmatch.key,
            value: inputValue.value
          });
        } else {
          //check for valid value in value field
          checkValue.apply(inputValue, [{}, true]);
        }
      }
    }
    listElemWrapper.style.display = 'none';
    this.innerHTML = '';
    $body().off('click');
    chooseListStorage = {};
  }

  var api = {
    init: init
  };

  return api;
}(window, $, EventMgr, App, ScrollHandler);
//# sourceMappingURL=App.SelectAutoComplete.js.map

'use strict';

/**
 * Модуль обрабатывает ссылки на документацию
 *
 */
var App = App || {};
App.Help = function (window, $, EventMgr) {
  'use strict';

  var init = function init() {
    EventMgr.on($mainWrapper(), helpLinkSelector, 'click', showHelp);
  },
      $mainWrapper = function $mainWrapper() {
    return $('#main-wrapper');
  },
      helpLinkSelector = '.help',
      showHelp = function showHelp(e) {
    var type = this.getAttribute('data-help-type'),
        helpChain = this.getAttribute('data-help'),
        func = $('.tab-content_st_active').attr('data-func'),
        url;
    e = e || window.event;
    e.preventDefault();
    if (type - 0 === 2 || type === 'default') {
      window.open(pageInfo.url + '?func=help&topic=' + func + '&path=' + helpChain + '&newwindow=yes');
    } else if (type === 'external') {
      url = this.getAttribute('data-help-func');
      App.u.openInNewWindow(url);
    }
  };
  return {
    init: init
  };
}(window, $, EventMgr);
//# sourceMappingURL=App.Help.js.map

'use strict';

/**
 * Модуль отвечает за отображение хинтов
 * @param {object} window global object
 * @param {object|function} $ jQuery
 * @param {object} EventMgr Event manager
 * @param {object} App Application
 */
/*global App:true*/
App.Hint = function (window, $, EventMgr, App) {
  'use strict';

  var init = function init() {
    EventMgr.on($mainWrapper(), hintItemSelector, 'mouseover', hintShowHandler);
    EventMgr.on($mainWrapper(), '.i-text-content', 'mouseover', hintInListShowHandler);
    EventMgr.on($mainWrapper(), hintActiveItemSelector, 'mouseover', hintActiveShowHandler);
    EventMgr.bind('hintActiveShowHandler', hintActiveShowHandler);
    EventMgr.on($mainWrapper(), hintMenuItemSelector, 'mouseover', hintShowHandler);
    EventMgr.on($mainWrapper(), hintItemSelector, 'mouseout', hintHideHandler);
    EventMgr.on($mainWrapper(), '.i-text-content', 'mouseout', hintHideHandler);
    EventMgr.on($mainWrapper(), previewItemSelector, 'mouseover', previewShowHandler);
    EventMgr.on($mainWrapper(), previewItemSelector, 'mouseout', hintHideHandler);
    EventMgr.on($mainWrapper(), hintActiveItemSelector, 'mouseout', hintHideHandler);
    EventMgr.on($mainWrapper(), hintMenuItemSelector, 'mouseout', hintHideHandler);
    EventMgr.on($mainWrapper(), hintBoxSelector, 'mouseover', hintShow);
    EventMgr.on($mainWrapper(), hintBoxSelector, 'mouseout', hintHide);
    EventMgr.on($body(), tipCloseSelector, 'click', closeTipByCross);
    //EventMgr.on($body(), tipCloseCrossSelector, 'click', closeTipByCross);
    EventMgr.bind('showHintMap', showHintMap);
    EventMgr.bind('forceShowHint', forceShowHint);
    EventMgr.bind('hideHint', hintHide);
    EventMgr.bind('stopShowHint', stopShowHint);
    EventMgr.bind('tabLoading', hintHide);
    EventMgr.bind('closeTabEvent', hintHide);
    EventMgr.bind('ajaxResponseHint', updateHint);
    EventMgr.on('.force-hint-flag', '.force-hint', 'focus', showForceHint);
    EventMgr.on('.force-hint-flag', '.force-hint', 'blur', forcehintHide);
    EventMgr.bind('verticalScroll', checkPosition);
    EventMgr.bind('showTips', showTips);
    EventMgr.bind('loadPage', checkTipsForDesktop);
    EventMgr.bind('updateTipPosition', updateTipPosition);
  },
      $mainWrapper = function $mainWrapper() {
    return App.u.selectorCache('#main-wrapper');
  },
      $body = function $body() {
    return App.u.selectorCache('#main-wrapper');
  },
      hintItemSelector = '.hint',
      tipCloseSelector = '.b-tip',
      tipCloseCrossSelector = '.b-tip__close',
      pageInfo = window.pageInfo,
      previewItemSelector = '#modal1-img li',
      hintActiveItemSelector = '.acthint',
      $hintBoxFn = function $hintBoxFn() {
    return $('#hint');
  },
      $hintBoxInnerFn = function $hintBoxInnerFn() {
    return $('#hint-inner');
  },
      hintBoxSelector = '#hint',

  //$ elem inner hint
  $$hintBoxInner,
      $$hintBox,
      hintMenuItemSelector = '.overwidth',
      timer,
      hideTimer,
      lastSelf,

  /**
   * Force show hint when form elem in focus
   * @param {object} e
   * @this HTML Node
   */
  showForceHint = function showForceHint(e) {
    clearTimeout(hideTimer);
    var $srcElem = $(this),
        hintField = $srcElem.parents('.i-form__item').find('.field-help'),
        self = hintField;
    if (hintField.length > 0 && hintGetContent(self, false)) {
      setTimeout(function () {
        setHintPosition(self, true);
        hintShow(undefined, true);
      }, 1);
    }
    lastSelf = $srcElem;
  },
      forcehintHide = function forcehintHide() {
    $$hintBox = $$hintBox || $hintBoxFn();
    $$hintBox.css('visibility', '').removeClass('active');
  },
      checkPosition = function checkPosition() {
    if ($$hintBox.hasClass('active')) {
      if (lastSelf && lastSelf.hasClass('force-hint')) {
        var hintField = lastSelf.parents('.l-form__row').find('.field-help');
        if (hintField.offset().top < 142) {
          forcehintHide();
        } else {
          setHintPosition(hintField, true);
        }
      }
    }
  },


  //prevent show hint
  stopShowHint = function stopShowHint() {
    clearTimeout(timer);
  },

  /**
   * Hint handler for DCMap
   * get props of element and show it as list
   * @param {object} e
   */
  showHintMap = function showHintMap(e) {
    var data = e.originalEvent.detail.props,
        self = $(e.originalEvent.detail.elem),
        hint = '<ul>',
        msg = data.msg,
        key,
        $$hintBoxInner = $$hintBoxInner || $hintBoxInnerFn();
    for (key in data) {
      if (msg[key]) {
        hint += '<li>' + '<label class="b-hint-line__label">' + msg[key] + ':</label>' + ' ' + data[key] + '</li>';
      }
    }
    hint += '</ul>';
    $$hintBoxInner.html(hint);

    //@todo least 200ms mouseover don't show hint

    timer = setTimeout(function () {
      hintShow(self);
    }, 500);
    lastSelf = null;
  },

  /**
   * Show hint like preview for development mode
   * @param {object} e
   * @this {object} HTML Node
   */
  previewShowHandler = function previewShowHandler(e) {
    var self = $(this),
        imgName = this.getAttribute('data-val'),
        text,
        style,
        src;
    $$hintBoxInner = $$hintBoxInner || $hintBoxInnerFn();
    if (!imgName) {
      return;
    }
    src = 'src="/manimg/common/img/' + imgName + '.png"';
    style = 'style="min-height: 16px; min-width: 16px;"';
    text = '<img class="preview-icon" ' + style + ' ' + src + ' ></img>';
    $$hintBoxInner.html(text);
    //check for shadow

    setHintPosition(self, false);

    //@todo least 200ms mouseover don't show hint
    timer = setTimeout(function () {
      hintShow();
    }, 500);
  },

  /**
   * show hint for element with custom hint
   * @param {object} e
   * @param {object} data
   */
  forceShowHint = function forceShowHint(e, data) {
    var elem = data.elem,
        hint = data.hint,
        self = $(elem);
    $$hintBoxInner = $$hintBoxInner || $hintBoxInnerFn();
    $$hintBoxInner.html(hint);
    setHintPosition(self, false);
    hintShow();
    lastSelf = null;
  },

  /**
   * Get hint content for view
   * find out hint content in elem attribute
   * @param {object} self jQuery object of element
   * @param {boolean} active Flag for active hint
   * @return {boolean}
   */
  hintGetContent = function hintGetContent(self, active) {
    var state,
        text,
        shadow,
        row,
        mn,
        overwidth = false;
    $$hintBoxInner = $$hintBoxInner || $hintBoxInnerFn();
    //get hint content
    state = self[0].getAttribute('data-state');
    if (state) {
      text = self[0].getAttribute('data-hint-' + state);
      if (!text) {
        text = self[0].getAttribute('data-hint');
      }
    } else {
      text = self[0].getAttribute('data-hint');
    }
    mn = self[0].getAttribute('data-hint-mn');
    if (active) {
      text = pageInfo.loading;
    }
    if (!text) {
      if (self.hasClass('overwidth')) {
        text = self[0].innerText || self[0].firstChild.nodeValue || self.html();
        overwidth = true;
      } else {
        return false;
      }
    }
    //filtred text
    text = window.filterXSS(text);
    shadow = self.hasClass('shadow');
    if (shadow) {
      row = self.parents('tr.row-shadow');
      if (!row.length) {
        text = text.replace(/<span class=['"]hint-.*/g, '');
      }
    }

    $$hintBoxInner.html(text);
    if (mn) {
      if (!String(mn).match('hint')) {
        mn = 'hint_' + mn;
      }
      $$hintBoxInner.attr('data-mn', mn);
    } else {
      $$hintBoxInner.attr('data-mn', null);
    }
    lastSelf = null;
    return true;
  },

  /**
   * Show hint handler
   * call function for show hint
   * @param {object} e
   * @param {boolean} active Flag for active hint
   * @this HTML Node
   */
  hintShowHandler = function hintShowHandler(e, active) {
    var self = $(this);
    if (hintGetContent(self, active)) {
      setHintPosition(self, false);
      //@todo least 200ms mouseover don't show hint
      timer = setTimeout(function () {
        hintShow();
      }, 500);
    }
    lastSelf = null;
    //if hint on parent
    if (e.stopPropagation) {
      e.stopPropagation();
    }
  },
      hintInListShowHandler = function hintInListShowHandler(e) {
    if (this.className.match(/overwidth/)) {
      hintShowHandler.apply(this, [e]);
    } else {
      var width = this.offsetWidth,
          scrollWidth = this.scrollWidth - 1;
      if (width < scrollWidth) {
        this.className += ' overwidth';
        hintShowHandler.apply(this, [e]);
      }
    }
  },


  /**
   * Set position for hint
   * detect best position for view hint
   * @param {object} self jQuery object of element
   * @param {boolean} fixed flag for fixed position of hint (for form items)
   */
  setHintPosition = function setHintPosition(self, fixed, box, boxInner, forceRight, forceBottom) {
    var PADDING = 15,
        heightTail = 10,
        marginElem = 3,
        N3 = 7,
        N4 = 30,
        $hintBoxInner,
        $hintBox;
    if (box && boxInner) {
      $hintBoxInner = boxInner;
      $hintBox = box;
    } else {
      if (!$$hintBox || !$$hintBoxInner) {
        $$hintBoxInner = $hintBoxInnerFn();
        $$hintBox = $hintBoxFn();
      }
      $hintBoxInner = $$hintBoxInner;
      $hintBox = $$hintBox;
    }
    //calculate hint position
    var heightHintBox = $hintBoxInner[0].offsetHeight,
        widthElem = self.width(),
        heightElem,
        selfOffset = self.offset(),

    //top position of element
    topElem = selfOffset.top,

    //left position of element
    leftElem = selfOffset.left,
        docWidth = $('body').width(),
        left,
        top,
        topFlag = false,
        rightFlag = false,
        LEFT_BORDER;
    //check for svg elem
    if (widthElem === 0 && self && self[0]) {
      widthElem = self[0].getBoundingClientRect().width;
    }
    $hintBoxInner.removeClass('b-hint__inner_right_fixed' + ' b-hint__inner_right' + ' b-hint__inner_top' + ' b-hint__inner_top_right' + ' b-hint__inner_left');
    //top of element hinting
    if (!fixed) {
      top = topElem - heightHintBox - heightTail - marginElem - PADDING;
      left = leftElem + widthElem / 2 - N3;
      LEFT_BORDER = 300;
    } else {
      top = topElem - PADDING;
      left = leftElem + widthElem + marginElem + heightTail;
      LEFT_BORDER = 250;
    }
    //check for left border
    if (docWidth - left < LEFT_BORDER || forceRight) {
      $hintBoxInner.addClass('b-hint__inner_right');
      var right = docWidth - leftElem - N4;
      rightFlag = true;
      $hintBox.css('right', right + 'px');
      $hintBox.css('left', '');
      if (fixed) {
        top = topElem - heightHintBox - heightTail - marginElem - PADDING;
      }
    } else {
      if (fixed) {
        $hintBoxInner.addClass('b-hint__inner_right_fixed');
      }
      $hintBoxInner.addClass('b-hint__inner_left');
      $hintBox.css('left', left + 'px');
      $hintBox.css('right', '');
    }
    //check for top border
    if (heightHintBox > top || forceBottom) {
      heightElem = self.outerHeight();
      //check for svg elem
      if (heightElem === 0 && self && self[0]) {
        heightElem = self[0].getBoundingClientRect().height;
      }
      top = self.offset().top + heightElem + heightTail - PADDING;
      if (rightFlag) {
        $hintBoxInner.addClass('b-hint__inner_top_right');
      } else {
        $hintBoxInner.addClass('b-hint__inner_top');
      }
    }
    $hintBox.css('top', top + 'px');
  },
      currentHintId,

  /**
   * Active hint handler
   * get request for content hint
   * @param {object} e
   * @this {object}
   */
  hintActiveShowHandler = function hintActiveShowHandler(e) {
    var _this = this;
    if (e.originalEvent.detail.elem) {
      _this = e.originalEvent.detail.elem;
    }
    var self = $(_this),
        tabId = $('.tab-content_st_active').attr('data-tabid'),
        elid = self.parents('tr').attr('data-elid') || _this.getAttribute('data-elid'),
        pName = _this.getAttribute('data-name'),
        value = _this.getAttribute('data-value'),
        hintfunc = _this.getAttribute('data-hintfunc');
    //for acthint in col
    if (!pName) {
      var index = self.closest('td').index(),
          th = self.closest('table').find('th')[index],
          pName = th.getAttribute('data-colname');
    }
    if (hintfunc) {
      currentHintId = tabId + value + elid + pName;
      var params = {
        func: hintfunc,
        elid: elid,
        type: pName
      };
      EventMgr.trigger('ajaxRequest', {
        url: pageInfo.url,
        param: params,
        invar: {
          hintTabId: tabId,
          hintElid: elid,
          hintPName: pName,
          hintValue: value,
          self: self },
        type: 'get',
        outtype: 'json',
        trfunc: 'ajaxResponseHint',
        queue: 'actHint' + tabId,
        failfunc: 'failCommonAjaxResponse' });
    } else {
      currentHintId = tabId + value + elid + pName;
      EventMgr.trigger('getActiveHint', {
        tabId: tabId,
        elid: elid,
        pName: pName,
        value: value,
        self: self });
    }

    hintShowHandler.apply(_this, [{}, true]);
    e.preventDefault();
    e.stopPropagation();
  },

  /**
   * Update hint content when got response of active hint
   * @param {object} e
   * @param {object} data
   */
  updateHint = function updateHint(e, data) {
    var elid = data.hintElid,
        tabId = data.hintTabId,
        pName = data.hintPName,
        value = data.hintValue,
        self = data.self,
        id = tabId + value + elid + pName,
        textValue;
    if (currentHintId === id) {
      if (!data.hint || data.hint === '') {
        textValue = 'Oops..';
      } else {
        textValue = window.htmlDecode(data.hint);
      }
      textValue = window.filterXSS(textValue);
      $$hintBoxInner.html(textValue);
      setHintPosition(self, false);
    }
  },

  /**
   * Show HTML Node of hint
   * @param {object} self jQuery object of element
   * @param {boolean} force Force show hint flag
   */
  hintShow = function hintShow(self, force) {
    $$hintBoxInner = $$hintBoxInner || $hintBoxInnerFn();
    $$hintBox = $$hintBox || $hintBoxFn();
    //check for hint show by self
    if (self !== undefined && typeof self.width === 'function') {
      setHintPosition(self, false);
    }
    $$hintBox.addClass('active');
    if (force) {
      $$hintBox.css('visibility', 'visible');
    } else {
      $$hintBox.css('visibility', '');
    }
    clearTimeout(timer);
  },
      hintHideHandler = function hintHideHandler(e) {
    hintHide();
    clearTimeout(timer);
  },

  /**
   * Hide HTML Node of hint
   */
  hintHide = function hintHide() {
    $$hintBox = $$hintBox || $hintBoxFn();
    $$hintBox.removeClass('active');
    $$hintBox.find('.hint-cont').html();
    currentHintId = '';
    clearTimeout(timer);
  },
      renderTip = function renderTip(tipObject, inTab) {
    var html = templates.tip(tipObject);
    if (inTab) {
      $('.tab-content_st_active').append(html);
    } else {
      $body().append(html);
    }
    return $('.b-tip_name_' + tipObject.name);
  },
      actTip,

  /**
   * show Tips
   * @param {object} e
   * @param {object} data
   *
   * find target element by classname i-tip-target_st_NAME
   * */
  showTips = function showTips(e, data) {
    actTip = data;
    var tips = data.tips,
        inTab = data.inTab,
        tabId = data.tabId,
        l = tips.length,
        sameModule = data.sameModule,
        $target,
        $tip,
        TABMARGINTOP = 69,
        TABMARGINLEFT = 205,
        forceRight = false,
        forceBottom = false;
    //show only one tip
    if ($('.b-tip').length) {
      return;
    }
    while (l--) {
      //check for exist this tip
      if ($('.b-tip_name_' + tips[l].name).length) {
        continue;
      }
      //check for sameModule load form menu
      if (tips[l].name === 'title_reload' && !sameModule) {
        continue;
      }
      if (tips[l].name === 'mbar_pin') {
        inTab = false;
      }
      if (tips[l].name === 'tabs_close') {
        if ($('.tab-group').length < 9) {
          continue;
        }
        inTab = false;
      }
      //show inside tab
      if (inTab) {
        $target = $('#cont-' + tabId + ' .i-tip-target_st_' + tips[l].name);
      } else {
        $target = $('.i-tip-target_st_' + tips[l].name);
      }
      //show textarea only when it focused
      if (tips[l].name === 'textarea_resize' && !data.textareaTip) {
        $('.b-textarea').bind('focus', showTipsForTextarea);
        textareaTip = [tips[l]];
        continue;
      } else if (data.textareaTip) {
        var $textarea = $('.b-textarea');
        if ($target.length) {
          var $targetTextarea = $target.prev();
          if ($targetTextarea.length) {
            var height = $targetTextarea[0].offsetHeight,
                scrollHeight = $targetTextarea[0].scrollHeight - 1;
            if (height < scrollHeight) {
              $textarea.off('focus', showTipsForTextarea);
              forceBottom = true;
            } else {
              continue;
            }
          }
        }
      }

      //force bottom position for new_btn tip
      if (tips[l].name === 'btn_new') {
        forceBottom = true;
      }
      if ($target.length) {
        //check for visibility
        if ($target[0].offsetWidth === 0 || $target[0].offsetHeight === 0) {
          continue;
        }
        $tip = renderTip(tips[l], inTab);
        setHintPosition($target, false, $tip, $tip.find('.b-tip__inner'), forceRight, forceBottom);
        //correct position inside tab
        if (inTab) {
          $tip.css('top', parseFloat($tip.css('top')) - TABMARGINTOP);
          var left;
          if ($tip.length) {
            left = $tip[0].style.left;
          }
          if (left) {
            $tip.css('left', parseFloat(left) - TABMARGINLEFT);
          }
        }
        $target.on('click', $.proxy(closeTipByCross, {
          elem: $tip.find('.b-tip__close') }));
      }
    }
  },
      textareaTip = [],
      showTipsForTextarea = function showTipsForTextarea(e) {
    var tabId = this.getAttribute('data-tabid'),
        tips = textareaTip;
    EventMgr.trigger('showTips', {
      tips: tips,
      inTab: true,
      textareaTip: true,
      tabId: tabId });
  },
      closeTipByCross = function closeTipByCross(e) {
    var self = this,
        $self = $(this);
    if (this.elem && this.elem[0]) {
      this.elem.trigger('click');
      return;
    }
    var id = self.getAttribute('data-name');
    if (!id) {
      id = $self.find('.b-tip__close').attr('data-name');
    } else {
      $self = $self.closest('.b-tip');
    }
    var param = {
      func: 'tip',
      elid: id
    };
    EventMgr.trigger('ajaxRequest', {
      param: param,
      type: 'get',
      outtype: 'json',
      trfunc: 'DoNothing',
      queue: 'noqueue' });
    //$('.i-tip-target_st_' + id).off('click');

    actTip = null;
    $self.remove();
  },
      closeTip = function closeTip(e) {
    $(this).remove();
    actTip = null;
  },
      checkTipsForDesktop = function checkTipsForDesktop(e, data) {
    if (pageInfo && pageInfo.tips) {
      //timeout for make all objects in theme
      setTimeout(function () {
        showTips.apply(window, [{}, { tips: pageInfo.tips }]);
      }, 1500);
    }
  },

  /**
   * update position for Tip
   * @param {object} e
   * @param {object} data
   */
  updateTipPosition = function updateTipPosition(e, data) {
    if (actTip) {
      $('.b-tip').remove();
      showTips.apply(window, [{}, actTip]);
    }
  };

  return {
    init: init
  };
}(window, $, EventMgr, App);
//# sourceMappingURL=App.Hint.js.map

'use strict';

/**
 * Модуль кастомного мультиселекта
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 */
App.MultiSelect = function (window, $, EventMgr, App) {
  'use strict';

  var init = function init() {
    EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__view-value', 'click', listOpenHandler);
    EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__ul-choose li', 'click', chooseElemHandler);
    EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__ul-view .b-mselect__unselect', 'click', unChooseElemHandler);
    // EventMgr.on('#main-wrapper', '.mselect-av .b-input-btn_type_plus',
    //     'click', selectAllHandler);
    // EventMgr.on('#main-wrapper', '.mselect-av .b-input-btn_type_minus',
    //     'click', unSelectAllHandler);
    EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__item_select-all', 'dblclick', unSelectAllHandler);
    EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__ul-view .b-mselect__item', 'mouseover', checkSize);
    EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__view-value', 'keydown', keydownHandler);
    EventMgr.bind('selectValues', selectValues);
    EventMgr.bind('multiSelectUnselect', unSelectAllFromOut);
    EventMgr.bind('mselectUnselectByDepend', unselectByDepend);
  },
      listWrapperIdPostfix = '-ms-list-wrapper',
      listIdPostfix = '-ms-list',
      chooseListIdPostfix = '-ms-view',
      appDom = App.Dom,
      $body = function $body() {
    return $('body');
  },

  //show select options
  listOpenHandler = function listOpenHandler(e) {
    var id = this.getAttribute('data-id'),
        list = appDom.byId(id + listWrapperIdPostfix),
        bodyHeight,
        elemHeight,
        formTop,
        elemTop,
        tabId,
        form;
    if (e.target && e.target.className.match('scrlbr')) {
      return;
    }
    if (list) {
      if (list.offsetWidth === 0) {
        //for close other list
        $('body').trigger('click');
        bodyHeight = window.document.body.offsetHeight;
        appDom.removeClass(list, 'closed');
        //calculate list options position
        elemHeight = list.offsetHeight;
        list.style.top = '';
        elemTop = $(list).offset().top;
        if (bodyHeight - elemTop < elemHeight) {
          tabId = list.getAttribute('data-tabid');
          form = $('#form-scroll-' + tabId);
          formTop = form.offset().top;
          if (formTop > elemTop - elemHeight - appDom.byId(id + '-ms-view').offsetHeight) {
            list.style.top = '-' + elemHeight / 2 + 'px';
          } else {
            list.style.top = '-' + elemHeight + 'px';
          }
        }
        $body().on('click', listCloseHandler);
        e.stopPropagation();
        EventMgr.trigger('updateScroll', { id: id + listIdPostfix });
      } else {
        appDom.addClass(list, 'closed');
        EventMgr.off('body', 'click');
        $body().off('click', listCloseHandler);
      }
    }
  },

  //close select options
  listCloseHandler = function listCloseHandler(e) {
    if (e.target) {
      if (!appDom.hasClass(e.target, 'b-mselect__item') && !appDom.hasClass(e.target, 'scrlbr')) {
        closeList();
      } else {
        return;
      }
    }
    $body().off('click', listCloseHandler);
    e.stopPropagation();
  },

  //
  closeList = function closeList(id) {
    var elems, selected;
    if (typeof id === 'string') {
      elems = $('#' + id + '-ms-list-wrapper');
    } else {
      elems = $('.b-mselect__options');
    }
    elems.addClass('closed');
    //remove selected hightlight
    if (typeof id === 'string') {
      selected = $('#' + id + '-ms-list-ul').find('.b-mselect__item_st_selected');
    } else {
      selected = $('.b-mselect__item_st_selected');
    }
    selected.removeClass('b-mselect__item_st_selected');
  },
      checkAllSelectedElem = function checkAllSelectedElem(id) {
    var $items = $('#' + id + '-ms-list-ul'),
        selectedCount = $items.find('.chosen').length,
        allCount = $items.find('.b-mselect__item').length - 1;
    return {
      selectedCount: selectedCount,
      allCount: allCount,
      allSelected: allCount === selectedCount
    };
  },
      chooseElemHandler = function chooseElemHandler(e, data) {
    var clone = this.cloneNode(true),
        id = this.parentNode.getAttribute('data-id'),
        clist = App.Dom.byId(id + chooseListIdPostfix),
        maxSelect = clist.getAttribute('data-maxselect'),
        selectedObj = checkAllSelectedElem(id),
        selectedCount = selectedObj.selectedCount,
        preventChange = data ? data.preventChange ? true : false : false;
    maxSelect = maxSelect === '' ? 9999 : parseInt(maxSelect, 10);
    if (selectedCount === maxSelect) {
      //closeList(id);
      return;
    }

    //check for selected
    if (appDom.hasClass(this, 'b-mselect__item_select-all')) {
      if (selectedObj.allSelected) {
        unSelectAllValues(id);
      } else {
        selectAllValues(id);
      }
    } else if (appDom.hasClass(this, 'chosen')) {
      appDom.removeClass(this, 'chosen');
      $('.b-mselect__item[data-s-id="' + clone.id + '"] .b-mselect__unselect').trigger('click');
    } else {
      clone.setAttribute('data-s-id', clone.id);
      clone.id = '';
      if (!clist) {
        return;
      }
      appDom.addClass(this, 'chosen');
      appDom.addClass(clone, 'chosen');
      clist.appendChild(clone);
      setValue(id, preventChange);
    }
  },
      unChooseElemHandler = function unChooseElemHandler(e) {
    var elem = this.parentNode,
        sid = elem.getAttribute('data-s-id'),
        sElem = appDom.byId(sid),
        id = sElem.parentNode.getAttribute('data-id');
    elem.parentNode.removeChild(elem);
    appDom.removeClass(sElem, 'chosen');
    setValue(id);
    // closeList(id);
    e.stopPropagation();
  },
      unSelectAllHandler = function unSelectAllHandler(e) {
    var id = this.getAttribute('data-id');
    unSelectAllValues(id);
    e.preventDefault();
  },
      unSelectAllFromOut = function unSelectAllFromOut(e, data) {
    var id = data.id;
    unSelectAllValues(id);
  },

  //unselect all values
  unSelectAllValues = function unSelectAllValues(id) {
    $('#' + id + '-ms-view .b-mselect__item.chosen').remove();
    $('#' + id + '-ms-list-ul .chosen').removeClass('chosen');
    setValue(id);
  },
      selectAllHandler = function selectAllHandler(e) {
    var id = this.getAttribute('data-id');
    selectAllValues(id);
    e.preventDefault();
  },

  //select all values
  selectAllValues = function selectAllValues(id) {
    var elems = $('#' + id + '-ms-list-ul .b-mselect__item'),
        l = elems.length,
        clone,
        clist = App.Dom.byId(id + chooseListIdPostfix),
        maxSelect = clist.getAttribute('data-maxselect'),
        selectedCount = $('#' + id + '-ms-list-ul li.chosen').length;
    maxSelect = maxSelect === '' ? 9999 : parseInt(maxSelect, 10);
    for (var i = 0; i < l; i++) {
      if (selectedCount === maxSelect) {
        break;
      }
      if (appDom.hasClass(elems[i], 'dependelem') && !appDom.hasClass(elems[i], 'b-myselect__select-li_show_yes')) {
        continue;
      }
      if (appDom.hasClass(elems[i], 'b-mselect__item_select-all')) {
        continue;
      }
      if (!appDom.hasClass(elems[i], 'chosen')) {
        clone = elems[i].cloneNode(true);
        clone.setAttribute('data-s-id', clone.id);
        clone.id = '';
        appDom.addClass(elems[i], 'chosen');
        appDom.addClass(clone, 'chosen');
        clist.appendChild(clone);
        selectedCount++;
      }
    }
    setValue(id);
  },


  //setvalue when change
  setValue = function setValue(id, preventChange) {
    var elem = appDom.byId(id + chooseListIdPostfix),
        cElems = elem.children,
        l = cElems.length,
        val,
        value = '',
        input = appDom.byId(id + '-ms-value'),
        wrapper = appDom.byId(id + '-ms'),
        scrollId = $(wrapper).find('.b-mselect__view-value').attr('id'),
        tabId = elem.getAttribute('data-tabId');
    if (l !== 1) {
      while (l--) {
        val = cElems[l].getAttribute('data-val');
        value += val;
        if (l !== 1) {
          value += ',';
        } else {
          break;
        }
      }
    } else {
      value = '';
    }

    input.value = value;
    if (value === '') {
      appDom.removeClass(wrapper, 'selected');
    } else {
      appDom.addClass(wrapper, 'selected');
    }
    if (!preventChange) {
      $(input).trigger('change');
    }
    EventMgr.trigger('updateScroll', { id: 'form-scroll-' + tabId });
    EventMgr.trigger('updateScroll', { id: scrollId });
  },

  //apply setvalues
  selectValues = function selectValues(e, data) {
    var id = data.id,
        slist = data.sElems.slist,
        values = data.sElems.value !== undefined ? data.sElems.value : data.sElems,
        l = values.length,
        elem,
        maxSelect = $('#' + id + '-ms-view').attr('data-maxselect');
    maxSelect = maxSelect === '' ? 9999 : parseInt(maxSelect, 10);
    if (slist) {
      $('#' + id + '-ms-list-ul').html(renderMultiSelectValues(slist, id));
    }
    $('#' + id + '-ms').removeClass('selected');
    $('#' + id + '-ms-list-ul li.chosen').removeClass('chosen');
    $('#' + id + '-ms-view li.chosen').remove();
    if (typeof values === 'string' && values !== '') {
      elem = $('#' + id + '-ms-list-ul li[data-val="' + values + '"]').trigger('click');
    } else {
      if (maxSelect < l) {
        l = maxSelect;
      }
      for (var i = 0; i < l; i++) {
        if (i === l - 1) {
          elem = $('#' + id + '-ms-list-ul li[data-val="' + values[i] + '"]').trigger('click', { 'preventChange': false });
        } else {
          elem = $('#' + id + '-ms-list-ul li[data-val="' + values[i] + '"]').trigger('click', { 'preventChange': true });
        }
      }
    }
  },
      unselectByDepend = function unselectByDepend(e, data) {
    var self = data.self;
    $(self).find('.b-mselect__ul-view .dependelem:not(".b-myselect__select-li_show_yes") .b-mselect__unselect').each(function () {
      $(this).trigger('click');
    });
  },

  //render options for setvalues
  renderMultiSelectValues = function renderMultiSelectValues(slist, id) {
    var html = '',
        l = slist.length;

    html += '<li class="b-mselect__item b-mselect__item_select-all">' + pageInfo.messages.msg_select_all + '</li>';
    for (var i = 0; i < l; i++) {
      html += '<li class="b-mselect__item" data-val="' + slist[i].key + '" unselectable="on" data-handler-val="' + hash(slist[i].key) + '"  data-dependkey="' + slist[i].depend + '" id="' + id + '-' + i + '">' + slist[i].value + '<span class="b-mselect__unselect"></span></li>';
    }
    return html;
  },
      UPKEY = 38,
      DOWNKEY = 40,
      LEFTKEY = 37,
      RIGHTKEY = 39,
      ENTERKEY = 13,
      TABKEY = 9,
      ESCKEY = 27,
      SPACE = 32,
      keydownHandler = function keydownHandler(e) {
    var codeKey = e.which || e.keyCode,
        ctrlKey = e.metaKey || e.ctrlKey,
        closed = appDom.hasClass(appDom.byId(this.getAttribute('data-id') + listWrapperIdPostfix), 'closed');
    //go up
    if (codeKey === UPKEY && !closed) {
      selectPrevOption.apply(this, []);
      //go down
    } else if (codeKey === DOWNKEY && !closed) {
      selectNextOption.apply(this, []);
      //close tab
    } else if (codeKey === TABKEY && !closed) {
      closeList();
      //choose selected value & close select or not?
    } else if ((codeKey === ENTERKEY || codeKey === SPACE) && !ctrlKey) {
      if (closed) {
        listOpenHandler.apply(this, [e]);
      } else {
        chooseSelected.apply(this, [e]);
      }
      //close list
    } else if (codeKey === ESCKEY && !closed) {
      e.stopPropagation();
      closeList();
    }
  },
      selectPrevOption = function selectPrevOption() {
    var id = this.getAttribute('data-id'),
        $list = $('#' + id + '-ms-list-ul'),
        selElem = $list.find('.b-mselect__item_st_selected'),
        prev = true,
        prevElem = selElem;
    if (selElem.length > 0) {
      while (prev) {
        prevElem = prevElem.prev();
        if (prevElem.length > 0) {
          prev = prevElem.hasClass('chosen');
        } else {
          prevElem = null;
          prev = false;
        }
      }
      if (prevElem) {
        selElem.removeClass('b-mselect__item_st_selected');
        prevElem.addClass('b-mselect__item_st_selected');
      }
    } else {
      selElem = $list.find('.b-mselect__item:first:not(".chosen")');
      selElem.addClass('b-mselect__item_st_selected');
    }
  },
      selectNextOption = function selectNextOption() {
    var id = this.getAttribute('data-id'),
        $list = $('#' + id + '-ms-list-ul'),
        selElem = $list.find('.b-mselect__item_st_selected'),
        nextElem = selElem,
        next = true;
    if (selElem.length > 0) {
      while (next) {
        nextElem = nextElem.next();
        if (nextElem.length > 0) {
          next = nextElem.hasClass('chosen');
        } else {
          nextElem = null;
          next = false;
        }
      }
      if (nextElem) {
        selElem.removeClass('b-mselect__item_st_selected');
        nextElem.addClass('b-mselect__item_st_selected');
      }
    } else {
      selElem = findFirst($list);
      if (selElem) {
        selElem.addClass('b-mselect__item_st_selected');
      }
    }
  },
      findFirst = function findFirst($list) {
    var finding = true,
        first = $list.find('.b-mselect__item:first');
    while (finding) {
      if (first.length > 0) {
        if (first.hasClass('chosen')) {
          first = first.next();
          finding = true;
        } else {
          return first;
        }
      } else {
        return false;
      }
    }
  },
      chooseSelected = function chooseSelected(e) {
    var id = this.getAttribute('data-id'),
        selected = $('#' + id + '-ms-list-ul').find('.b-mselect__item_st_selected');
    if (selected.length > 0) {
      selected.trigger('click');
    } else {
      closeList(id);
    }
  },
      checkSize = function checkSize() {
    if (App.Dom.hasClass(this, 'overwidth') || App.Dom.hasClass(this, 'notoverwidth')) {
      return;
    }
    if (this.scrollWidth > this.offsetWidth) {
      App.Dom.addClass(this, 'overwidth');
      $(this).trigger('mouseover');
    } else {
      App.Dom.addClass(this, 'notoverwidth');
    }
  };

  return {
    init: init
  };
}(window, $, EventMgr, App);
//# sourceMappingURL=App.MultiSelect.js.map

'use strict';

/**
 * Select Module
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 *  @return {object} api
 */
App.Select = function (window, $, EventMgr, App) {
  'use strict';

  var UPKEY = 38,
      DOWNKEY = 40,
      LEFTKEY = 37,
      RIGHTKEY = 39,
      ENTERKEY = 13,
      TABKEY = 9,
      ESCKEY = 27,
      SPACE = 32,

  //wrapper for select
  selectSelector = '.b-myselect:not(".readonly")' + ' .b-myselect__select-selected',

  //wrapper for select item
  selectItemSelector = '.b-myselect:not(".readonly")' + ' .b-myselect__select-li',
      selectKeySelector = '.b-myselect:not(".readonly")' + ' .b-myselect__select-selected,' + ' .b-myselect:not(".readonly") .sb-input',
      CACHE = {},
      CACHEOPENEDSELECT = {},
      dependSlistSelector = '.depend.b-myselect input[type="hidden"],' + ' .depend.b-select-ac input[type="hidden"],' + ' .depend.b-radio input[type="hidden"]';

  function $body() {
    return $('body');
  }

  function getActiveTabId() {
    return $('.tab-content_st_active').attr('data-tabid') || false;
  }
  //flag for active select list
  function $content() {
    return App.Common.selectorCache('.i-form-wr');
  }

  function $selectCont(id) {
    if (id) {
      return $('#' + id + '.b-myselect');
    } else {
      return $('.b-myselect');
    }
  }

  //add /remove handler for body, for close selectlist
  function addRemoveHandlerForBody(add) {
    if (add) {
      $body().on('click', bodyHandlerClick);
    } else {
      $body().off('click', bodyHandlerClick);
    }
  }

  function closeOtherSelectList(tabId, click) {
    if (!tabId) {
      tabId = getActiveTabId();
    }
    if (CACHEOPENEDSELECT[tabId] && CACHEOPENEDSELECT[tabId].removeClass) {
      CACHEOPENEDSELECT[tabId].addClass('b-myselect_st_close').removeClass('b-myselect_st_open');
      addRemoveHandlerForBody();
    }
  }

  function bodyHandlerClick(e) {
    if (e) {
      var scrElemClass = e.srcElement ? e.srcElement.className : e.target ? e.target.className : '',
          scrollFlag = scrElemClass.indexOf('scrlbr'),
          highlightFlag = scrElemClass.indexOf('highlight');
      if (scrollFlag === -1 && highlightFlag === -1) {
        closeOtherSelectList();
      }
    } else {
      //what is it?!
      e.stopPropagation();
    }
  }
  //click for select
  function selectListHandler(e) {
    e.preventDefault();
    e.stopPropagation();
    var id = this.getAttribute('data-id'),
        $selectContVar = $selectCont(id),
        ids,
        searchBox,
        tabId = getActiveTabId(),
        keySymbol,
        r;
    //check current state option list
    if (!$selectContVar.hasClass('b-myselect_st_open')) {
      $('body').trigger('click');
      closeOtherSelectList(tabId);
      $selectContVar.removeClass('b-myselect_st_close').addClass('b-myselect_st_open');
      //set optionlist position
      App.Common.setOptionListPosition('#opt', id);

      ids = $selectContVar.find('.b-myselect__select-list').attr('id');
      EventMgr.trigger('updateScroll', { id: ids });
      addRemoveHandlerForBody(true);
      //set focus on searchbox
      if (this.parentNode.className.match('sb-select')) {
        searchBox = App.Dom.byId('sb-' + ids);
        if (searchBox) {
          //try guess symbol of pressed key
          if (e && e.originalEvent) {
            if (e.originalEvent.key) {
              keySymbol = e.originalEvent.key;
              if (keySymbol.length > 1) {
                keySymbol = null;
              }
            }
          }
          searchBox.value = keySymbol || '';
          setTimeout(function () {
            findElemsInSelect.apply(searchBox, [{ codeKey: 'ololo' }]);
          }, 1);
          searchBox.focus();
          //set cursor after 1st symbol
          if (keySymbol) {
            if (searchBox.setSelectionRange) {
              searchBox.setSelectionRange(1, 1);
            } else {
              r = searchBox.createTextRange();
              r.collapse(true);
              r.select(1, 1);
            }
          }
          window.scrollToTopLeft();
        }
      }
      CACHEOPENEDSELECT[tabId] = $selectContVar;
    } else {
      $selectContVar.removeClass('b-myselect_st_open').addClass('b-myselect_st_close');
      delete CACHEOPENEDSELECT[tabId];
      addRemoveHandlerForBody(false);
      this.childNodes[1].focus();
      window.scrollToTopLeft();
    }
  }

  //select item handler
  function setSelectedValue(e, sv, close) {
    var self = $(this),
        val = this.getAttribute('data-val'),
        handlerVal = this.getAttribute('data-handler-val'),
        content = self.html(),
        id = self.parent().attr('data-id'),
        currentSelect = $('#' + id + ' .b-myselect__select-value');
    if (self.hasClass('group')) {
      return;
    }
    var $inputValue = $('input#' + id + '-val');
    var prevValue = $inputValue.val();

    //вызываем change только при изменение значения, чтобы не зациклить setvalues
    if (prevValue !== val) {
      $inputValue.val(val).attr('data-handler-val', handlerVal).trigger('change', [sv, close]);
    }
    //if it clone from search - search self made it
    if (!self.hasClass('b-myselect__select-li_clone_true')) {
      self.addClass('selected').siblings().removeClass('selected');
    } else if (!e) {
      //up/down keydown
      self.addClass('selected').siblings().removeClass('selected');
      self.trigger('customclick');
      content = self.siblings('.selected').find('.b-myselect__option-value').html();
    }
    currentSelect.html(content);
    if (close !== false) {
      $body().trigger('click');
      if (e && !e.isTrigger) {
        currentSelect.focus();
        window.scrollToTopLeft();
      }
    }
    EventMgr.trigger('selectChange', { id: id });
  }

  //идем по селекту вниз downkey
  function selectListNext(e) {
    var tabId = getActiveTabId(),
        id = this.getAttribute('data-id'),
        l,
        currentLi = $('#' + id + ' li.selected'),
        nextLi = currentLi.next(),
        next = true,
        closed = currentLi.parent()[0].offsetWidth ? false : true;
    if (!currentLi[0].offsetWidth && !closed) {
      currentLi = $('#' + id + ' li[style$="display: block;"]');
      l = currentLi.length;
      if (l > 0) {
        setSelectedValue.apply(currentLi[0], [false, false, false]);
        return;
      }
    }
    while (next) {
      if (nextLi.length === 0) {
        return;
        //detect showed elements by class 'show'
      } else if (nextLi[0].offsetWidth && !closed) {
        next = false;
      } else if (closed && nextLi[0].className.match('b-myselect__select-li_show_yes')) {
        next = false;
      } else {
        nextLi = nextLi.next();
      }
    }
    setSelectedValue.apply(nextLi[0], [false, false, false]);
    var offsetTop = nextLi[0].offsetTop,
        scrollId = 'cont-' + id;

    //if (offsetTop != 0) {
    ScrollHandler.forceMoveSelectItem(scrollId, offsetTop);
    //}
  }

  //идем по селекту вверх upkey
  function selectListPrev() {
    var tabId = getActiveTabId(),
        id = this.getAttribute('data-id'),
        l,
        currentLi = $('#' + id + ' li.selected'),
        prevLi = currentLi.prev(),
        prev = true,
        closed = currentLi.parent()[0].offsetWidth ? false : true;
    if (!currentLi[0].offsetWidth && !closed) {
      currentLi = $('#' + id + ' li[style$="display: block;"]');
      l = currentLi.length;
      if (l > 0) {
        setSelectedValue.apply(currentLi[l - 1], [false, false, false]);
        return;
      }
    }
    while (prev) {
      if (prevLi.length === 0) {
        return;
        //detect showed elements by class 'show'
      } else if (prevLi[0].offsetWidth && !closed) {
        prev = false;
      } else if (closed && prevLi[0].className.match('b-myselect__select-li_show_yes')) {
        prev = false;
      } else {
        prevLi = prevLi.prev();
      }
    }

    setSelectedValue.apply(prevLi[0], [false, false, false]);
    var offsetTop = prevLi[0].offsetTop,
        scrollId = 'cont-' + id;

    //if (offsetTop !== 0) {
    ScrollHandler.forceMoveSelectItem(scrollId, offsetTop);
    //}
  }

  //обработчик клавишных нажатий по селекту
  function selectListKeyDownHandler(e) {
    var codeKey = e.which || e.keyCode,
        tabId = this.getAttribute('data-tabid'),
        listOpened = !!CACHEOPENEDSELECT[tabId];
    //by ENTER and SPACE
    if ((codeKey === ENTERKEY || codeKey === SPACE) && !e.ctrlKey && this.type !== 'text') {
      e.preventDefault();
      selectListHandler.apply(this, [e]);
      //by ENTER and SPACE search field
    } else if (codeKey === ENTERKEY && !e.ctrlKey && this.type === 'text') {
      selectFindFirstElem(this);
      e.preventDefault();
      //by TABKEY when openlist
    } else if ((codeKey === TABKEY || codeKey === ESCKEY) && listOpened) {
      //      e.preventDefault();
      //      closeSelectList(e, true);
      e.stopPropagation();
      closeOtherSelectList(false, true);
      //UP or LEFT when list opened
    } else if ((codeKey === UPKEY || codeKey === LEFTKEY) && !listOpened && !e.ctrlKey && this.type !== 'text') {
      e.preventDefault();
      selectListPrev.apply(this, [e]);
      //DOWN or RIGHT list opened
    } else if ((codeKey === DOWNKEY || codeKey === RIGHTKEY) && !listOpened && !e.ctrlKey && this.type !== 'text') {
      e.preventDefault();
      selectListNext.apply(this, [e]);
      //DOWN when list closed
    } else if (codeKey === DOWNKEY && listOpened && !e.ctrlKey) {
      e.preventDefault();
      selectListNext.apply(this, [e]);
      //UP when list closed
    } else if (codeKey === UPKEY && listOpened && !e.ctrlKey) {
      e.preventDefault();
      selectListPrev.apply(this, [e]);
      //Open by any symbol
    } else if (this.type !== 'text' && codeKey > 32) {
      selectListHandler.apply(this, [e]);
    }
  }

  function selectFindFirstElem(self) {
    var id, sElem, selElem, currentSelect;
    id = self.getAttribute('data-id');
    sElem = $('#' + id);
    if (sElem.length === 0) {
      return;
    }
    selElem = sElem.find('li.selected:visible');
    if (selElem.length !== 0) {
      selElem.trigger('click');
    } else {
      selElem = sElem.find('li:visible:first');
      if (selElem.length !== 0) {
        selElem.trigger('click');
      } else {
        $('body').trigger('click');
      }
    }
    //set focus on select
    currentSelect = $('#' + sElem.attr('data-id') + ' .b-myselect__select-value');
    currentSelect.focus();
    window.scrollToTopLeft();
  }

  var matchesElems = {};
  //поиск по селекту
  function findElemsInSelect(e) {
    e = e || window.event;
    var codeKey = e.which || e.keyCode;
    if (codeKey === UPKEY || codeKey === DOWNKEY || TABKEY === codeKey) {
      return;
    }
    var value,
        id,
        sElem,
        sElems,
        len,
        regEx,
        words,
        wLen,
        find,
        inner,
        searchAll = true,
        optListId,
        curElem,
        selElems,
        tabId,
        matches,
        listParent;
    value = this.value.toLowerCase();

    value = App.u.escapeRegExp(value);
    id = this.getAttribute('data-id');
    sElem = App.Dom.byId(id);
    if (!sElem) {
      return;
    }
    var $sElem = $(sElem);
    optListId = String(sElem.getAttribute('data-id'));
    sElems = sElem.children;
    len = sElems.length;
    tabId = this.getAttribute('data-tabId');
    //cache html nodes
    if (!CACHE[tabId]) {
      CACHE[tabId] = {};
    }
    if (!CACHE[tabId][id]) {
      sElems = sElem.children;
      selElems = [];
      var l = sElems.length,
          t1,
          pushed,
          clone;
      while (l--) {
        clone = sElems[l].cloneNode(true);
        clone.className += ' b-myselect__select-li_clone_true';
        t1 = $(clone).find('.b-myselect__option-value');
        /* jslint loopfunc:true */
        pushed = selElems.push({
          node: sElems[l],
          clone: clone,
          innerNode: t1,
          inner: t1.html(),
          bindClick: function bindClick() {
            var $clone = $(this.clone);
            $clone.bind('click', $.proxy(function (e) {
              this.returnDefValue();
              var $node = $(this.node);
              $node.addClass('selected').siblings().removeClass('selected');
              //for unknow reasons it doesn't bubble to parent li
              //force click
              if (e) {
                var scrElemClass = e.srcElement ? e.srcElement.className : e.target ? e.target.className : '';
                if (scrElemClass.indexOf('highlight') === 0) {
                  $node.trigger('click');
                }
              }
            }, this));

            $clone.bind('customclick', $.proxy(function () {
              var $node = $(this.node);
              $node.addClass('selected');
            }, this));
          },
          returnDefValue: function returnDefValue() {
            if (this.isMatched) {
              this.innerNode.html(this.inner);
            }
            this.isMatched = false;
          }
        });
        /* jslint loopfunc:false */
        selElems[pushed - 1].bindClick();
        CACHE[tabId][id] = selElems;
      }
    } else {
      selElems = CACHE[tabId][id];
      len = selElems.length;
    }
    if (value === '') {
      //show all elems in list
      $sElem.removeClass('b-myselect__select-ul_searching_true');
      hideElement(matchesElems[id]);
      scrollToSelectedElement(sElem, id);
      EventMgr.trigger('updateScroll', { id: 'cont-' + id });
      return;
    } else {
      $sElem.addClass('b-myselect__select-ul_searching_true');
    }
    if (!searchAll) {
      regEx = new RegExp('^' + value);
    } else {
      regEx = new RegExp(value);
    }

    var wordLowerCase = '';
    matchesElems[id] = [];

    while (len--) {
      curElem = selElems[len];
      curElem.returnDefValue();
      inner = curElem.inner;
      words = inner.split(' ');
      wLen = words.length;
      find = false;
      while (wLen--) {
        wordLowerCase = words[wLen].toLocaleLowerCase();
        matches = wordLowerCase.match(regEx);
        if (matches) {
          selElems[len].isMatched = true;
          selElems[len].searchIndex = wordLowerCase.indexOf(matches[0]) + Math.pow(10, wLen);
          find = true;
          words[wLen] = addHightLight(value, words[wLen], searchAll);
          matchesElems[id].push(selElems[len]);
        }
      }
      if (!find) {
        hideElement(curElem);
      } else {
        showElement(curElem);
        curElem.innerNode.html(words.join(' '));
      }
    }
    //sort result of find

    if (matchesElems[id].length > 0) {
      var lMatchesElems = matchesElems[id];
      lMatchesElems.sort(sortMatches);
      listParent = $(sElem);
      var mLen = lMatchesElems.length;
      while (mLen--) {
        listParent.prepend(lMatchesElems[mLen].clone);
      }
    }
    EventMgr.trigger('updateScroll', { id: 'cont-' + id });
    ScrollHandler.scrollTo('cont-' + id, 0);
    App.Common.setOptionListPosition('#opt', optListId);
  }

  function sortMatches(a, b) {
    if (b.searchIndex === a.searchIndex) {
      return 0;
    }
    if (b.searchIndex < a.searchIndex) {
      return 1;
    } else {
      return -1;
    }
  }

  function scrollToSelectedElement(sElem, id) {
    var top, selectedElem;
    selectedElem = $(sElem).find('.selected:not(".b-myselect__select-li_clone_true")');
    if (selectedElem.length) {
      top = selectedElem[0].offsetTop;
      setTimeout(function () {
        ScrollHandler.scrollTo('cont-' + id, top);
      }, 1);
    }
  }

  //показываем элемент или элементы в селекте
  function showElement(elem) {
    if (!elem) {
      return;
    }
    var len = elem.length;
    if (len) {
      while (len--) {
        if (elem[len].clone.className.match('b-myselect__select-li_show_yes')) {
          elem[len].clone.style.display = 'block';
        } else {
          elem[len].clone.style.display = 'none';
        }
      }
    } else {
      if (elem.clone) {
        if (elem.clone.className.match('b-myselect__select-li_show_yes')) {
          elem.clone.style.display = 'block';
        } else {
          elem.clone.style.display = 'none';
        }
      }
    }
  }

  //скрываем элемент или элементы в селекте
  function hideElement(elem) {
    if (!elem) {
      return;
    }
    var len = elem.length;
    if (len) {
      while (len--) {
        elem[len].clone.style.display = 'none';
      }
    } else {
      if (elem.clone) {
        elem.clone.style.display = 'none';
      }
    }
  }
  //добавляем выделение
  function addHightLight(rep, value, searchAll) {
    var re, elemValue;
    if (!searchAll) {
      re = rep ? new RegExp('(^' + rep + ')', 'i') : false;
    } else {
      re = rep ? new RegExp('(' + rep + ')', 'i') : false;
    }
    elemValue = value.replace(re, '<span class="highlight">$1</span>');
    return elemValue;
  }

  /**
   * Обрабатываем зависимости при отрисовке формы
   */
  function firstDependSlistHandler(e, data) {
    var tabId = data.tabId;
    $('#cont-' + tabId + ' tr:not(".row-error") .depend.b-myselect ' + 'input[type="hidden"],' + ' #cont-' + tabId + ' .depend.b-radio input[type="hidden"],' + ' #cont-' + tabId + ' .depend.b-select-ac input[type="hidden"]').each(function () {
      dependSlistHandler.apply(this);
    });
    EventMgr.trigger('updFormHeight', { tabId: tabId });
  }

  function dependSlistHandler() {
    var value = this.value,
        name = this.getAttribute('name'),
        type = this.getAttribute('data-type'),
        tabId = this.getAttribute('data-tabid'),
        elem,
        selectElem,
        showElem,
        $dependSelect;
    //hide select options
    $dependSelect = $('#frm-' + tabId + ' div[data-depend="' + name + '"]');
    if ($dependSelect.length > 1) {
      $dependSelect.each(function () {
        var $self = $(this);
        selectElem = $self.find('li.dependelem[data-dependkey="' + value + '"].selected.b-myselect__select-li_show_yes');
        dependSlistCheckSelected(selectElem, $self);
      });
    } else {
      selectElem = $dependSelect.find('li.dependelem[data-dependkey="' + value + '"].selected.b-myselect__select-li_show_yes');
      dependSlistCheckSelected(selectElem, $dependSelect);
    }
    //set first value or prev key
    EventMgr.trigger('updateScroll', { id: 'form-scroll-' + tabId });
  }

  function dependSlistCheckSelected(selectElem, $dependSelect) {
    if (selectElem.length === 0) {
      var id = $dependSelect.attr('id'),
          prevValue = $('#' + id + '-val').val();

      $dependSelect.find('li').removeClass('selected');
      var elem = $dependSelect.find('li.b-myselect__select-li_show_yes[data-val="' + prevValue + '"]')[0] || $dependSelect.find('li.b-myselect__select-li_show_yes')[0];
      if (elem) {
        setSelectedValue.apply(elem);
      } else {
        //console.log('alarm!!! no elem');
      }
    }
  }

  /**
   * Clean cache if slist changed by setvalues
   * @param {object} e
   * @param {object} data
   */
  function cleanSlistCache(e, data) {
    var id = data.id,
        tabId = data.tabId;
    if (CACHE && CACHE[tabId] && CACHE[tabId][id]) {
      delete CACHE[tabId][id];
    }
  }

  function init() {
    //select
    EventMgr.on($content(), selectSelector, 'click', selectListHandler);
    EventMgr.on($content(), selectKeySelector, 'keydown', selectListKeyDownHandler);
    EventMgr.on($content(), selectItemSelector, 'click', setSelectedValue);
    EventMgr.on($content(), '.sb-input', 'keyup', findElemsInSelect);
    EventMgr.on($content(), dependSlistSelector, 'change', dependSlistHandler);
    EventMgr.bind('appendForm,appendReport,appendedFilter,forceDepend', firstDependSlistHandler);
    EventMgr.bind('cleanSlistCache', cleanSlistCache);
  }

  var api = {
    init: init
  };

  return api;
}(window, $, EventMgr, App);
//# sourceMappingURL=App.Select.js.map

'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

/**
 *  Модуль.
 *  ваш К.О.
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 */
App.ActionHandler = function (window, $, EventMgr, App) {
  'use strict';

  var init = function init() {
    EventMgr.onwithdata($content(), actionBtnSel, 'click', 'menuAction', actionController);
    EventMgr.on($content(), formBtnFunc, 'click', actionFormController);
    EventMgr.on($content(), cancelDefActionNonActSel, 'click', cancelDefAct);
    EventMgr.on($content(), reloadTabBtnSel, 'click', reloadTabController);
    EventMgr.on('#main-wrapper', formSubmitSel, 'click', submitForm);
    EventMgr.on($content(), ticketRate, 'click', ticketRateHandler);
    EventMgr.bind('rateResponse', rateResponseHandler);
    //    EventMgr.onwithdata('#main-wrapper', formSubmitSel, 'click', 'formSubmit',
    //        submitForm);
    EventMgr.bind('failedAjaxResponseForDashboard', failedDashboardBlockRequestHandler);
    EventMgr.bind('failMenuAjaxResponse', failMenuRequest);
    EventMgr.bind('failCommonAjaxResponse', failListRequest);
    EventMgr.bind('failFormAjaxResponse', failFormRequest);
    EventMgr.bind('tabLoading', tabLoadingHandler);
    EventMgr.bind('tabLoadingHide', tabLoadingHideHandler);
    EventMgr.on($content(), dismissMsgSelector, 'click', dismissMessage);
  },
      $content = function $content() {
    return $('#main-wrapper');
  },


  // wrapper for right menu links
  actionBtnSel = '.m-item a, .b-menu-item',


  //wrapper for reload tab btn
  reloadTabBtnSel = '.reload',

  // wrapper for toolbar's group btn

  //prevent default not active actions
  cancelDefActionNonActSel = '.notActive span',
      formSubmitSel = '.i-button_type_ok',
      formBtnFunc = '.i-button_type_func',
      dismissMsgSelector = '.i-message__dismiss-link',
      ticketRate = '.i-ticket__rate',
      cancelDefAct = function cancelDefAct(e) {
    e.preventDefault();
  },
      tabLoadingId = {},
      tabLoadingHandler = function tabLoadingHandler(e, data) {
    var tabId = data.tabId;
    clearTimeout(tabLoadingId[tabId]);
    tabLoadingId[tabId] = setTimeout(function () {
      $('#cont-' + tabId).addClass('loading');
    }, 350);
  },
      tabLoadingHideHandler = function tabLoadingHideHandler(e, data) {
    var tabId = data.tabId;
    setTimeout(function () {
      clearTimeout(tabLoadingId[tabId]);
      $('#cont-' + tabId).removeClass('loading');
    }, 0);
    //for be sure what it fucking loading hide
    setTimeout(function () {
      $('#cont-' + tabId).removeClass('loading');
    }, 100);
    //for be defintly sure what it fucking loading hide
    setTimeout(function () {
      $('#cont-' + tabId).removeClass('loading');
    }, 200);
    //for be absolutly sure  what it fucking loading hide
    setTimeout(function () {
      $('#cont-' + tabId).removeClass('loading');
    }, 350);
  },

  //handler for failed request from menu
  failMenuRequest = function failMenuRequest(e, data) {
    $('.m-item.loading').removeClass('loading');
    if (data.erType === 'json') {
      EventMgr.trigger('pullMsg', { msg: 'JSON Parse Error. Func: "' + data.param.func + '"' });
    } else if (data.erMsg) {
      EventMgr.trigger('pullMsg', { msg: data.erMsg });
    } else {
      EventMgr.trigger('pullMsg', { msg: 'Request failed. Try again. Func: "' + data.param.func + '"' });
    }
  },

  //handler for failed request from list
  failListRequest = function failListRequest(e, data) {
    var tabId = data.invar ? data.invar.tabId ? data.invar.tabId : data.invar.parent ? data.invar.parent : data.invar.targetTabId : undefined;
    EventMgr.trigger('tabLoadingHide', { tabId: tabId });
    if (data.erType === 'json') {
      EventMgr.trigger('pullMsg', { msg: 'JSON Parse Error. Func: "' + data.param.func + '"' });
    } else if (data.erMsg) {
      EventMgr.trigger('pullMsg', { msg: data.erMsg });
    } else {
      EventMgr.trigger('pullMsg', { msg: 'Request failed. Try again. Func: "' + data.param.func + '"' });
    }
  },
      disabledButton = function disabledButton(btn) {
    btn.addClass('b-button_st_disabled');
    btn.html(btn.attr('data-disabled'));
  },
      resetButtonForDefault = function resetButtonForDefault(arg) {
    //return btn state
    var btn, tabId;
    if (typeof arg === 'string') {
      tabId = arg;
      btn = $('#form-wrapper-' + tabId + ' .b-button_st_disabled');
    } else {
      btn = arg;
    }
    if (btn.length) {
      btn.html(btn[0].getAttribute('data-enabled'));
      btn.removeClass('b-button_st_disabled');
    }
  },

  //handler fot failed request from form
  failFormRequest = function failFormRequest(e, data) {
    var tabId = data.invar.tabId;

    if (data.erType === 'json') {
      EventMgr.trigger('pullMsg', { msg: 'JSON Parse Error. Func: "' + data.param.func + '"' });
    } else if (data.erMsg) {
      EventMgr.trigger('pullMsg', { msg: data.erMsg });
    } else {
      EventMgr.trigger('pullMsg', { msg: 'Request failed. Try again. Func: "' + data.param.func + '"' });
    }
    //reset button
    resetButtonForDefault(tabId);
    //for run after upload callback
    setTimeout(function () {
      //return progressbar state
      var loader = $('#' + tabId + '-progressbar .b-progressbar__loader');
      $('#' + tabId + '-progressbar').removeClass('b-progressbar_type_withbtn');
      //remove animated
      loader.addClass('b-progressbar__loader_type_animate');
      //add static color
      loader.removeClass('b-progressbar__loader_type_static');
      loader.css('width', '');
      loader.html('');
      //remove cancel btn
      $('#' + tabId + '-progressbar .b-progressbar__btn-wr').remove();
    }, 1);

    EventMgr.trigger('tabLoadingHide', { tabId: tabId });
  },
      failedDashboardBlockRequestHandler = function failedDashboardBlockRequestHandler(e, data) {
    var blockId = data.invar.blockId,
        tblock = App.Dom.byId('t' + blockId);
    if (tblock) {
      tblock.className = tblock.className.replace(/loading/g, '');
    }
    if (data.erType === 'json') {
      EventMgr.trigger('pullMsg', { msg: 'JSON Parse Error. Func: "' + data.param.func + '"' });
    } else if (data.erMsg) {
      EventMgr.trigger('pullMsg', { msg: data.erMsg });
    } else {
      EventMgr.trigger('pullMsg', { msg: 'Request failed. Try again. Func: "' + data.param.func + '"' });
    }
  },


  //reload page handler
  reloadTabController = function reloadTabController(e, data) {
    var tabId = '',
        addedParam = {};
    if (e) {
      tabId = this.getAttribute('data-tabid');
      addedParam = {
        clickstat: 'title'
      };
      e.preventDefault();
    } else {
      tabId = data.tabId;
    }
    EventMgr.trigger('reloadTab', {
      addedParam: addedParam,
      tabId: tabId,
      help: true,
      selid: true,
      filter: true });
  },
      ticketRateHandler = function ticketRateHandler(e) {
    var func = this.getAttribute('data-func'),
        type = this.getAttribute('data-type'),
        name = this.getAttribute('data-name'),
        $parent = this.parentNode,
        elid = $parent.getAttribute('data-id'),
        plid = $parent.getAttribute('data-elid'),
        param = {
      func: func,
      elid: elid,
      plid: plid
    };
    if (type === 'setrate') {
      EventMgr.trigger('ajaxRequest', {
        param: param,
        invar: {
          $parent: $parent,
          rateType: name,
          self: this
        },
        outtype: 'json',
        trfunc: 'rateResponse',
        failfunc: 'failCommonAjaxResponse'
      });
    } else if (type === 'rate') {
      EventMgr.trigger('ajaxRequest', {
        param: param,
        invar: {
          parent: $(this).closest('.tab-content_st_active').attr('data-tabid')
        },
        type: 'get',
        outtype: 'json',
        trfunc: 'ajaxResponse',
        failfunc: 'failCommonAjaxResponse',
        queue: 'noqueue' });
    }
  },
      rateResponseHandler = function rateResponseHandler(e, data) {
    if (!data.error) {
      $(data.$parent).addClass('b-ticket__rate_rated_' + data.rateType);
      $(data.self).removeClass('i-ticket__rate');
    } else if (data.erMsg) {
      EventMgr.trigger('pullMsg', { msg: data.erMsg });
    }
  },
      actionFormController = function actionFormController(e) {
    var $self = $(this),
        func = $self.attr('data-func'),
        id = $self.attr('data-id'),
        tabId = $self.attr('data-tabid'),
        param = {
      func: func
    };
    //check for button id
    if (id && id !== 'undefined') {
      id = id.split('=', 2);
      if (id[1]) {
        param[id[0]] = id[1];
      }
    }
    EventMgr.trigger('ajaxRequest', {
      param: param,
      invar: {
        parent: tabId
      },
      type: 'get',
      outtype: 'json',
      trfunc: 'ajaxResponse',
      failfunc: 'failMenuAjaxResponse',
      queue: 'menu' });
    EventMgr.trigger('tabLoading', { tabId: tabId });
  },
      checkSameTabsOpened = function checkSameTabsOpened(func, tabs) {
    var resp = {
      exist: false,
      tabId: null,
      status: 0
    };
    var curFunc, regExpWitDot;
    if (func && tabs && (typeof tabs === 'undefined' ? 'undefined' : _typeof(tabs)) === 'object') {
      /* jslint forin:true */
      for (var key in tabs) {
        if (tabs[key]) {
          curFunc = tabs[key].func;
          if (!curFunc && tabs[key].paramObjAll) {
            curFunc = tabs[key].paramObjAll.func;
          }
          //check if empty func like basket.empty
          //regExpWitDot = new RegExp('^' + func + '\\.');
          //.empty
          regExpWitDot = func + '.empty';
          //if ((String(curFunc).match(regExpWitDot) || curFunc === func) &&
          if ((regExpWitDot === curFunc || curFunc === func) && tabs[key].hType === 'parent') {
            resp.exist = true;
            resp.tabId = key;
            resp.status = tabs[key].status;
            //be sure that found active same tab
            if (resp.status === 1) {
              break;
            }
          }
        }
      }
    }
    return resp;
  },


  //handler for menu action
  actionController = function actionController(e, data) {
    var self = $(this),
        href = this.getAttribute('data-url'),
        parent = this.getAttribute('data-parent'),
        re = new RegExp('/?func=+'),
        cgi = this.getAttribute('data-cgi'),
        sameModule = false,
        queue = 'menu',
        isFromMenu = self.hasClass('i-menu-link'),
        fromFatalError = self.parent().hasClass('b-fatal-error__refresh-link'),
        newtab = false,
        url,
        param;
    if (e.ctrlKey || e.metaKey || self.hasClass('newtab')) {
      newtab = true;
      queue = 'noqueue';
    }
    if (self.hasClass('wohan')) {
      return true;
    }
    //if from fatal error close alertBox
    if (fromFatalError) {
      $('#modal_alert_ok').trigger('click');
    }

    if (href) {
      if (href.match(re)) {
        url = cgi ? pageInfo.host + cgi : pageInfo.url;
        href = href.replace('?', '');
        param = App.Common.parseParams(href);
        param.clickstat = 'yes';
        //check for same module open from menu
        if (!newtab) {
          var actFunc = $('.tab-content_st_active').attr('data-func');
          if (param.func === actFunc) {
            sameModule = true;
          }
        }
        //check for exist tabs with this function
        var checkTabs = checkSameTabsOpened(param.func, data.__tabs);
        if (checkTabs.exist && !checkTabs.status && isFromMenu) {
          $('#switch-' + checkTabs.tabId).trigger('lclick');
          EventMgr.trigger('reloadTab', { tabId: checkTabs.tabId, resetFilterOn: true });
        } else {
          EventMgr.trigger('ajaxRequest', {
            url: url,
            param: param,
            invar: {
              parent: parent, newtab: newtab, sameModule: sameModule, __src: 'menuAction', __src_func: param.func },
            type: 'get',
            outtype: 'json',
            trfunc: 'ajaxResponse',
            failfunc: 'failMenuAjaxResponse',
            queue: queue });
          //add loading class to menu
          self.parents('.m-item').addClass('loading');
        }
      } else {
        //what else?
        console.log(url);
      }
    }
    if (e) {
      e.preventDefault();
    }
  },


  //handler for submit form
  submitForm = function submitForm(e, data) {
    e.preventDefault();
    var self = $(this),
        flags = self.getFlags(),
        tabId = self.attr('data-tabid'),
        form = $('#frm-' + tabId),
        vars = form.getVars(),
        action = form.attr('action'),
        param = form.serializeObject(),
        parent = self.attr('data-parent'),
        type = self.attr('data-type'),
        hasFiles = form.hasClass('withfiles'),
        act = self.attr('data-act'),
        id = self.attr('data-id'),
        isShowcaseForm = form.hasClass('b-form_showcase_yes'),
        name = self.attr('data-name'),
        progressTypeElem = App.Dom.byId(tabId + '-progresstype'),
        progressType,
        confirmMsg,
        RequiredMsg,
        progressid,
        param1,
        text,
        passwdField,
        pwstrength,
        options;
    //prevent dbclick
    if (self.hasClass('b-button_st_disabled')) {
      return false;
    }
    disabledButton(self);
    if (progressTypeElem !== null) {
      progressType = progressTypeElem.value;
    }
    //check for valid
    if (act !== 'back') {
      //check file length
      var fileSizeRes = App.u.checkFileSize(tabId);
      if (fileSizeRes.msg) {
        EventMgr.trigger('errMsgValid', {
          self: fileSizeRes.field,
          err: fileSizeRes.msg,
          number: 0
        });
        resetButtonForDefault(self);
        return false;
      }
      //check passwd confirm fields
      confirmMsg = checkConfirm(tabId);
      if (confirmMsg.msg !== '') {
        EventMgr.trigger('showAlert', confirmMsg);
        resetButtonForDefault(self);
        return false;
      }
      //check required fields
      RequiredMsg = checkRequired(tabId);
      if (RequiredMsg.msg !== '') {
        EventMgr.trigger('errMsgValid', {
          self: RequiredMsg.himself,
          err: RequiredMsg.msg,
          number: 0
        });
        //watching while input not be empty for remove error
        $(RequiredMsg.himself).bind('keyup', function () {
          if (this.value !== '') {
            $(this).unbind('keyup');
            EventMgr.trigger('okMsgValid', {
              self: this,
              number: 0,
              notOk: true
            });
          }
        });
        resetButtonForDefault(self);
        return false;
      }
      //maybe it not needed
      // if ($('#frm-' + tabId +
      //     ' .row-error:not(".l-form__row_hidden_yes") input.test').length !== 0) {
      //   return false;
      // }
      //check password strength
      passwdField = $('#frm-' + tabId + ' input[data-check-field]');
      if (passwdField.length !== 0) {
        pwstrength = getPwdStrength(passwdField);
        var badPwd = false;
        passwdField.each(function () {
          var pname = this.getAttribute('name');
          if (pwstrength !== 0 && param[pname] !== '' && $(this).width() !== 0) {
            if (pwstrength > App.Forms.checkPassStrength(param[pname])) {
              EventMgr.trigger('showAlert', { msg: pageInfo.pwErrorMsg });
              badPwd = true;
              return false;
            }
          }
        });
        if (badPwd) {
          resetButtonForDefault(self);
          return false;
        }
      }
    }

    if (act === 'back') {
      param.sback = 'ok';
      //not needed progress when press back btn
      progressType = 'false';
    }
    //check for button id
    if (id && id !== 'undefined') {
      id = id.split('=', 2);
      if (id[1]) {
        param[id[0]] = id[1];
      }
    }

    //add name of button
    if (name) {
      /* jslint camelcase: false */
      param.clicked_button = name;
      /* jslint camelcase: true */
    }
    //add progressid
    progressid = progressType;
    param.progressid = progressid;
    param1 = { elid: progressid, func: 'progress.get', sfrom: 'ajax' };
    //check for target
    if (act === 'blank') {
      var $form,
          winId = progressid + new Date().getTime(),
          $formWrapper = $('#form-wrapper-' + tabId);
      $formWrapper.wrap(function () {
        return '<form action="' + action + '" id="form-' + winId + '" method="POST" enctype="multipart/form-data" target="' + winId + '"/>';
      });
      $form = $('#form-' + winId);
      $form.append('<input type="hidden" class="i-input-tmp-elem" value="ok" name="sok"/>');
      $form.append('<input type="hidden" class="i-input-tmp-elem" value="' + name + '" name="clicked_button"/>');
      if (id && id[1]) {
        $form.append('<input type="hidden" class="i-input-tmp-elem"' + ' value="' + id[1] + '" name="' + id[0] + '"/>');
      }
      //remove sfrom=ajax
      $form.find('input[name="sfrom"]').remove();
      window.open('', winId);
      $form.submit();
      if (!flags.keepform) {
        App.Tabs.closeTab(e, tabId);
        if (parent) {
          EventMgr.trigger('reloadTab', { tabId: parent });
        }
      } else {
        $formWrapper.unwrap();
        $('.i-input-tmp-elem').remove();
      }
      //try reload parent after close form
      resetButtonForDefault(self);
      return false;
    }
    var $mixedContols = $('#frm-' + tabId + ' .i-control-mixed');
    if ($mixedContols.length !== 0) {
      param = App.u.removeParam($mixedContols, param);
    }
    //get progressType before request
    progressType = String(progressType).split('_')[0];
    //options for form & form with files submit
    options = {
      url: pageInfo.host + action,
      param: param,
      invar: {
        tabId: tabId,
        parent: parent,
        type: type,
        progresstype: progressType,
        progressid: progressid,
        iType: 'replace',
        dataSaved: true,
        targetTabId: tabId,
        __vars: vars
      },
      type: 'post',
      outtype: 'json',
      trfunc: 'ajaxFormResponse',
      queue: 'noqueue',
      failfunc: 'failFormAjaxResponse' };
    //check for files
    //THIS IS FORM WITH FILE
    /* jshint camelcase: false */
    if (hasFiles) {
      param.sok = 'ok';
      EventMgr.trigger('setBrandSettings', {
        options: options,
        tabId: tabId,
        pid: progressid,
        name: name,
        param: param,
        addParams: {
          sok: 'ok',
          sfrom: 'ajax',
          clicked_button: name,
          pid: progressid
        },
        parent: parent });
    } else if (type === 'report') {
      //THIS IS REPORT
      param.sok = 'ok';
      options = {
        url: pageInfo.host + action,
        param: param,
        invar: { parent: parent, tabId: tabId, __src: 'report' },
        outtype: 'json',
        trfunc: 'ajaxResponse',
        queue: 'noqueue',
        failfunc: 'failCommonAjaxResponse'
      };
      EventMgr.trigger('ajaxRequest', options);
    } else {
      //THIS IS FORM
      param.sok = 'ok';
      EventMgr.trigger('ajaxRequest', options);
    }
    if (progressType !== 'false') {
      setTimeout(function () {
        EventMgr.trigger('ajaxRequest', {
          param: param1,
          invar: {
            tabId: tabId,
            param: param1,
            type: type,
            progresstype: progressType },
          outtype: 'json',
          trfunc: 'progressBarResponse',
          queue: 'noqueue' });
      }, 1000);
    }
    EventMgr.trigger('tabLoading', { tabId: tabId });
  },
      getPwdStrength = function getPwdStrength(passwdField) {
    var pws = passwdField.attr('data-check-args'),
        firstSing;
    if (!pws) {
      return pageInfo.pwstrength;
    }
    firstSing = pws.substring(0, 1);
    if (firstSing === '-' || firstSing === '+') {
      return parseFloat(pws) + parseFloat(pageInfo.pwstrength);
    } else {
      return parseFloat(pws);
    }
  },


  //check required field on form
  checkRequired = function checkRequired(tabId) {
    var field = $('#form-wrapper-' + tabId + ' input[required="required"],' + ' #form-wrapper-' + tabId + ' .b-textarea[required="required"]'),
        msg = '',
        self = null;
    if (field.length > 0) {
      field.each(function () {
        //check for empty and not hidden
        var value = String(this.value).replace(/\s/g, '');
        if (this.className.match('i-control-mixed')) {
          return true;
        }
        if (value === '' && this.offsetWidth !== 0) {
          msg = getRequiredMsg();
          self = this;
          return false;
        }
        if (this.getAttribute('data-type') === 'multiple' && value === '') {
          var id = this.getAttribute('data-id'),
              elem = App.Dom.byId(id + '-ms-view');
          if (elem && elem.offsetWidth !== 0) {
            msg = getRequiredMsg();
            self = elem.parentNode;
            return false;
          }
        }
      });
    }
    return {
      param: tabId,
      msg: msg,
      himself: self
    };
  },


  //get message for required error
  getRequiredMsg = function getRequiredMsg() {
    return pageInfo.messages.empty;
  },

  //check password confirm field
  checkConfirm = function checkConfirm(tabId) {
    var field = $('#form-wrapper-' + tabId + ' input[data-confirm="yes"]'),
        msg = '',
        self = null;
    if (field.length > 0) {
      field.each(function () {
        var confirmField = this.getAttribute('data-check-field'),
            value1 = this.value,
            confirmFieldElem = App.Dom.byId(confirmField + '-' + tabId),
            confirmFieldElemFake = App.Dom.byId(confirmField + '-' + tabId + '-fake'),
            value2;
        if (confirmFieldElem !== null) {
          value2 = confirmFieldElem.value;
        }
        if (value1 !== value2 && (confirmFieldElem.offsetWidth !== 0 || confirmFieldElemFake.offsetWidth !== 0)) {
          msg = pageInfo.confirm;
          self = this;
        }
        return;
      });
    }
    return {
      msg: msg,
      himself: self,
      callback: function callback() {
        this.focus();
      }
    };
  },


  //banner dismiss link handler
  dismissMessage = function dismissMessage(e, data) {
    if (e) {
      e.preventDefault();
    }
    var self = $(this),
        param;
    self.parents('.i-message').hide();
    param = this.getAttribute('data-href');
    EventMgr.trigger('updTableHeight');
    param = App.Common.parseParams(param);
    EventMgr.trigger('ajaxRequest', {
      url: pageInfo.url,
      param: param,
      trfunc: 'DoNothing',
      queue: 'noqueue' });
  };
  return {
    init: init
  };
}(window, $, EventMgr, App);
//# sourceMappingURL=App.ActionHandler.js.map

'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

/**
 * Модуль отвечает за вкладки и их рендер
 * @param {object} window global object
 * @param {object|function} $ jQuery
 * @param {object} EventMgr Event manager
 * @param {object} App Application
 * @param {object} templates HTML templates
 */
App.Tabs = function (window, $, EventMgr, App, templates) {
  'use strict';

  var tabs = {},
      pageInfo = window.pageInfo,
      tabIndex = 1,
      tabN = 'tab',
      rowId = 0,
      activeTab = '',
      //current active tab id

  defaultTab = '',
      //defaultTab

  mainWrapperSel = '#main-wrapper',
      init = function init() {
    EventMgr.bind('ajaxResponse', buildTabWrapper);
    EventMgr.bind('builtTab', appendTab);
    EventMgr.bind('comboCtrlShiftZKeyUp', closeAllTabs);
    EventMgr.bind('comboCtrlShiftXKeyUp', closeOthersTabs);
    EventMgr.on(mainWrapperSel, 'a.close', 'click', closeTabClickHandler);
    EventMgr.on(mainWrapperSel, 'span.back', 'click', backBtnHandler);
    EventMgr.on(mainWrapperSel, '#tabs .switch', 'click', switchTabs);
    EventMgr.on(mainWrapperSel, '#tabs .switch', 'mousedown', closeTabsByMiddleBtn);
    EventMgr.on(mainWrapperSel, '#tabs .switch', 'dblclick', upSwitchedTabs);
    EventMgr.bind('reloadTab', reloadTabData);
    EventMgr.bind('updateTab', updateTab);
    EventMgr.bind('ajaxFormResponse', formHandler);
    EventMgr.on(mainWrapperSel, '.i-button_type_cancel', 'click', cancelBtnHandler);
    EventMgr.bind('ajaxResponseForDashboard', renderDashboardTable);
    EventMgr.bind('addedChart', addChartToTab);
    EventMgr.bind('formGetTreeBranch', formGetTreeBranch);
    EventMgr.bind('getActiveHint', getActiveHint);
    EventMgr.on(mainWrapperSel, 'input, textarea', 'change', formFieldChangeHandler);
    EventMgr.on(mainWrapperSel, '.i-list-icon__stop', 'click', stopAutoUpdate);
    EventMgr.addHook('formSetValues,formSubmit', addModelToSetvalues);
    EventMgr.bind('updateModel', updateModelBySetvalues);
    EventMgr.addHook('listMultiSelect,listSelect,listLiveFound,' + 'listUnSelect,ajaxResponseEditInListSave,updateTotalList,' + 'clickedGroupItem', addListModel);
    EventMgr.bind('saveFormPageState', saveFormPageState);
    EventMgr.on(mainWrapperSel, '.i-take-favorite', 'click', favoriteToggle);
    EventMgr.on(mainWrapperSel, '.i-pin', 'click', pinToggle);
    EventMgr.bind('loadPage', removeSfromParam);
    EventMgr.addHook('menuAction,testColCheck', addTabsModel);
    EventMgr.bind('changeTabSortIndex', changeTabSortIndex);
    EventMgr.bind('updateTotalWithConvertReport', updateTotalWithConvertReport);
    EventMgr.addToTriggerStack('escKeyUp', esckeyHandler, 1);
  },

  //remove sfrom param form url after login
  removeSfromParam = function removeSfromParam() {
    var params = App.u.parseParams(window.location.search);
    if (params.sfrom) {
      if (window.history) {
        setTimeout(function () {
          window.history.pushState('default', '', pageInfo.binary);
        }, 10000);
      }
    }
  },
      checkDasboard = function checkDasboard(d) {
    if (d && d.dashboard) {
      $('#switch-tab0').trigger('click');
      return false;
    }
    return true;
  },
      checkFeatures = function checkFeatures(data) {
    //if has redirect keep new tabs
    if (data && data.__src !== 'okList' && data.__src !== 'okForm') {
      var params;
      if (data.features && pageInfo.features && !data.wizard && data.features !== pageInfo.features) {
        params = App.u.parseParams(window.location.search);
        params.ssavetabs = 1;
        if (!params.scountreload) {
          params.scountreload = 1;
        } else {
          params.scountreload -= 0;
          params.scountreload += 1;
        }
        if (params.scountreload < 5) {
          window.location.search = '?' + App.u.getQueryString(params);
          return false;
        }
      } else {
        //remove params from url
        params = App.u.parseParams(window.location.search);
        if (params.ssavetabs) {
          setTimeout(function () {
            if (window.history) {
              window.history.pushState('default', '', pageInfo.binary);
            }
          }, 10000);
        }
      }
    }
    return true;
  },
      checkReload = function checkReload(data) {
    if (data) {
      if (data.reload) {
        var newLocation = pageInfo.url;
        if (data.savetab) {
          newLocation += '?sfrom=sessionexpired';
        }
        if (data.__src && (data.__src === 'menuAction' || data.__src === 'toolbarAction' || data.__src === 'report' || data.__src === 'reloadTab')) {
          makeFakeTab(data);
        }
        if (data.__src && data.__src === 'filterset') {
          addBeforeLoadRequest(data);
        }
        window.location = newLocation;
        return false;
      }
    }
    return true;
  },
      checkNewWin = function checkNewWin(data) {
    if (data) {
      if (data.location && data.newwin) {
        window.open(data.location, '_blank');
        //remove loading className
        $('.m-item.loading').removeClass('loading');
        return false;
      } else if (data.location) {
        window.location = data.location;
        return false;
      }
    }
    return true;
  },
      checkNewForm = function checkNewForm(data) {
    if (data) {
      var param,
          options,
          newFormParams = data.formParam,
          parent = data.parent;
      if (newFormParams) {
        param = App.u.parseParams(newFormParams);
        options = {
          noesc: true,
          param: param,
          invar: {
            waitingTabId: data.targetTabId,
            parent: parent,
            dataSaved: true,
            '__src_func': data.__src_func,
            '__src': 'okForm',
            '__srcBtn': data.__srcBtn,
            newtab: data.newtab
          },
          type: 'get',
          outtype: 'json',
          trfunc: 'ajaxResponse',
          queue: 'noqueue' };
        if (data.openAsChild) {
          options.invar.parent = data.tabId;
        }
        EventMgr.trigger('ajaxRequest', options);
        return false;
      }
    }
    return true;
  },
      checkNewList = function checkNewList(data) {
    if (data) {
      var param,
          newListParams = data.listParam,
          parent = data.parent;
      if (newListParams) {
        param = App.u.parseParams(newListParams);
        EventMgr.trigger('ajaxRequest', {
          noesc: true,
          param: param,
          invar: {
            waitingTabId: data.targetTabId,
            parent: parent,
            dataSaved: true,
            '__src': 'okList',
            '__srcBtn': data.__srcBtn,
            newtab: data.newtab
          },
          type: 'get',
          outtype: 'json',
          trfunc: 'ajaxResponse',
          queue: 'noqueue' });
        if (data.openAsChild) {
          options.invar.parent = data.tabId;
        }
        EventMgr.trigger('tabLoading', { tabId: parent });
        return false;
      }
    }
    return true;
  },
      storage = App.Common.storage,

  //render breadcrumb
  getBreadcrumb = function getBreadcrumb(breadcrumb) {
    var str = '';
    /* jslint forin:true */
    for (var key in breadcrumb) {
      str += '<a href="#" data-id="' + key + '" class="breadcrumb">' + breadcrumb[key].name + '</a>';
    }
    return str;
  },
      resetToDefaultFormButton = function resetToDefaultFormButton(tabId) {
    if (tabs[tabId] && tabs[tabId].type === 'form') {
      $('#frm-' + tabId + ' .b-button_st_disabled').each(function () {
        var $self = $(this);
        $self.html($self.attr('data-enabled'));
        $self.removeClass('b-button_st_disabled');
      });
    }
  },

  //cancel btn handler
  cancelBtnHandler = function cancelBtnHandler(e) {
    var tabId = this.getAttribute('data-tabid'),
        func = this.getAttribute('data-func'),
        $self = $(this),
        form = $('#frm-' + tabId),
        isShowcaseForm = form.hasClass('b-form_showcase_yes'),
        flags = $self.getFlags(),
        parent,
        options;
    if (!tabs[tabId]) {
      return;
    }
    parent = tabs[tabId].parent;

    if (flags.refresh && parent) {
      EventMgr.trigger('reloadTab', { tabId: parent, __src: 'formCancelRefresh', filter: true });
    }
    //return list if it from sametab
    if (tabs[tabId].rParentObj) {
      var param = tabs[tabId].rParentObj,
          targetTabId = tabId;
      tabs[tabId].rParent = undefined;
      EventMgr.trigger('ajaxRequest', {
        url: pageInfo.url, param: param,
        invar: {
          parent: parent,
          targetTabId: targetTabId,
          iType: 'replace',
          dataSaved: true
        },
        type: 'get',
        outtype: 'json',
        trfunc: 'ajaxResponse',
        failfunc: 'failCommonAjaxResponse',
        queue: 'noqueue' });
      EventMgr.trigger('tabLoading', { tabId: tabId });
    } else if (func) {
      options = {
        param: {
          func: func
        },
        invar: {
          parent: parent,
          targetTabId: tabId,
          iType: 'replace',
          dataSaved: true
        },
        type: 'get',
        outtype: 'json',
        trfunc: 'ajaxResponse',
        failfunc: 'failCommonAjaxResponse',
        queue: 'noqueue'
      };
      EventMgr.trigger('ajaxRequest', options);
      EventMgr.trigger('tabLoading', { tabId: tabId });
    } else {
      closeTab(e, tabId);
    }
    e.preventDefault();
  },
      unsavedDataCheckboxHandler = function unsavedDataCheckboxHandler(val) {
    if (val === 'on') {
      var options = {
        param: {
          func: 'usrparam',
          elid: pageInfo.user,
          checkunsaved: 'off',
          sok: 'ok'
        },
        type: 'get',
        outtype: 'json',
        trfunc: 'DoNothing',
        queue: 'noqueue'
      };
      EventMgr.trigger('ajaxRequest', options);
      pageInfo.checkUnsaved = false;
    }
  },
      addBeforeLoadRequest = function addBeforeLoadRequest(data) {
    var tabId = data.tabId;
    if (tabs[tabId]) {
      tabs[tabId].beforeRequest = data.sourceParamString;
    }
    EventMgr.trigger("changedTabs", { tabs: tabs, forceActive: true });
  },
      makeFakeTab = function makeFakeTab(data) {
    var tabId, tabObj;
    tabId = tabN + tabIndex;
    tabObj = {
      status: 1,
      forceActive: true,
      title: '',
      paramObjAll: App.u.parseParams(data.sourceParamString)
    };
    //check for su func
    var func = tabObj.paramObjAll.func;
    if (String(func).match(/su$/) || func === 'chlevel') {
      return;
    }
    if (data.parent) {
      if (data.targetTabId || data.tabId) {
        tabId = data.targetTabId || data.tabId;
      }
      tabObj.hType = 'child';
      if (tabs[data.parent]) {
        tabs[data.parent].child = tabId;
      }
    } else {
      if (data.targetTabId) {
        tabId = data.targetTabId;
      }
      tabObj.hType = 'parent';
    }
    tabs[tabId] = tabObj;

    EventMgr.trigger('changedTabs', { tabs: tabs, forceActive: true });
  },

  //wrapper buildTab for check for unsaved form data
  buildTabWrapper = function buildTabWrapper(e, data) {
    var isChanged = false,
        tabId;
    //check for open in new tab & replace tab from redirect
    if (!data.newtab && !data.dataSaved && pageInfo.checkUnsaved) {
      //check for active tab is form
      if (tabs[activeTab]) {
        //find form in tab group
        tabId = findTabForm(activeTab);
        if (tabId !== activeTab) {
          //activate tab if not active
          if (tabs[tabId] && tabs[tabId].status === 0) {
            activateTab(tabId);
          }
        }
        var changedFields = checkFormChange(tabId);
        if (changedFields.isChanged) {
          isChanged = true;
          //show confirmBox
          EventMgr.trigger('confirmBoxShow', {
            callbackOk: buildTab,
            callbackCancel: function callbackCancel() {
              $('.m-item.loading').removeClass('loading');
            },
            text: String(pageInfo.unsavedData).replace('__VALUE__', changedFields.count) + '<br/><span class="b-text_style_bold">' + changedFields.labels + '</span>',
            args: [e, data],
            checkbox: {
              msg: pageInfo.unsavedDontShow,
              cb: unsavedDataCheckboxHandler
            }
          });
        }
      }
    }
    if (!isChanged) {
      buildTab(e, data);
    }
  },
      findTabForm = function findTabForm(tabId) {
    if (tabs[tabId] && tabs[tabId].type === 'form') {
      return tabId;
    } else {
      //form can be only last in tab group
      if (tabs[tabId].child) {
        return findTabForm(tabs[tabId].child);
      }
    }
    return false;
  },

  //build new tab
  buildTab = function buildTab(e, data) {
    EventMgr.trigger('hideHint');
    //check for user.su
    var parent = data.parent ? data.parent : '',
        ok = data.ok || false,
        tabId,
        obj,
        type,
        delay,
        timeId;
    //hide loader for parent tab
    if (parent) {
      EventMgr.trigger('tabLoadingHide', { tabId: parent });
      //reset btn on form if opened as a child
      resetToDefaultFormButton(parent);
    }
    //hide loader for targetTab (for case if has error)
    if (data.targetTabId) {
      EventMgr.trigger('tabLoadingHide', { tabId: data.targetTabId });
    }
    //hide loader for srcTab (when redirect) (for case if has error)
    if (data.srcTabId) {
      EventMgr.trigger('tabLoadingHide', { tabId: data.srcTabId });
    }

    if (!checkReload(data) || !checkNewWin(data) || !checkNewList(data) || !checkNewForm(data)) {
      return false;
    }

    if (ok) {
      if (parent !== undefined) {
        EventMgr.trigger('reloadTab', { tabId: parent, filter: true, __src: 'buildTabOk' });
        return;
      }
    }

    EventMgr.trigger('startbuildTab', 'new empty tab');

    tabId = tabN + tabIndex;
    obj = data;
    type = obj.type || obj.id;

    if (obj.exType === 'dashboard') {
      tabId = 'tab0';
    } else if (obj.targetTabId) {
      tabId = obj.targetTabId;
    } else if (obj.showcase) {
      tabId = 'tab0';
    } else {
      tabIndex++;
    }

    //Гвозди
    //check for error on big Cicle
    if (obj.error && !obj.ignErr && obj.type !== 'form' && obj.type !== 'inspectorForm' && obj.type !== 'showcaseForm' && obj.type !== 'report' || obj.userexpMsg === undefined && obj.error && obj.type === 'form') {
      EventMgr.trigger('hideLoader');
      type = 'fatalerror';
    } else if (obj.error && obj.ignErr) {
      return;
    }
    if (type === '' && !tabs.tab0 || obj.exType === 'dashboard') {
      type = 'dashboard';
    }
    if (obj.msg) {
      $.extend(App.Common.msg, obj.msg);
    }

    switch (type) {
      case 'list':
        buildList(tabId, obj);
        break;
      case 'form':
        buildForm(tabId, obj);
        break;
      case 'dashboard':
        buildDashboard(tabId, obj);
        break;
      case 'report':
        buildReport(tabId, obj);
        EventMgr.trigger('reportLoad');
        break;
      case 'map':
      case 'rack':
        buildMap(tabId, obj);
        break;
      case 'fatalerror':
        buildFatalError(tabId, obj);
        break;
      case 'empty':
        buildEmpty(tabId, obj);
        break;
      case 'inspectorForm':
        buildInspectorForm(tabId, obj);
        break;
      case 'showcaseForm':
        buildShowcaseForm(tabId, obj);
        break;
      default:
        EventMgr.trigger('pullMsg', { msg: 'Do not support type = "' + type + '" of metadata' });
    }
    //handler for autoupdate
    //@TODO this shit must to rewrite
    delay = obj.autoupdate;

    if (!tabs[tabId]) {
      return;
    }

    if (tabs[tabId].timeId) {
      clearTimeout(tabs[tabId].timeId);
    }
    if (obj.autoupdate !== undefined) {
      timeId = setTimeout(function (tabId, delay) {
        return function () {
          EventMgr.trigger('updateTab', { tabId: tabId, delay: delay });
        };
      }(tabId, delay), obj.autoupdate * 1000);
      tabs[tabId].autoupdate = true;
      tabs[tabId].timeId = timeId;
    } else {
      tabs[tabId].autoupdate = false;
      tabs[tabId].timeId = undefined;
    }
    //show tips
    if (obj.tips) {
      setTimeout(function () {
        EventMgr.trigger('showTips', {
          tips: obj.tips,
          inTab: true,
          tabId: tabId,
          sameModule: obj.sameModule });
      }, 1);
    }
  },

  //build tab with list/table
  buildList = function buildList(tabId, obj) {
    var plid = '',
        elid = '',
        pagerParam = '',
        breadcrumb,
        body = prepareTab(obj, tabId);
    if (obj.plid) {
      //what the hell?
      plid = '&plid=' + encodeURIComponent(obj.plid);
    }
    if (obj.elid) {
      elid = '&elid=' + encodeURIComponent(obj.elid);
    }

    if (obj.sortOrder) {
      pagerParam += '&p_order=' + obj.sortOrder;
    }
    if (obj.sortCol) {
      pagerParam += '&p_sort=' + obj.sortCol;
    }
    if (obj.pager.pager === 'true') {
      pagerParam += '&p_num=' + obj.pager.pageNum + '&p_cnt=' + obj.pager.pageCnt;
    }

    //flag for render bottom bar
    obj.sbar = true;
    if (App.Global.warning) {
      obj.warning = App.Global.warning;
    }
    if (obj.selid) {
      App.Global.selid = obj.selid;
    }
    if (obj.scrollTop) {
      App.Global.scrollTop = obj.scrollTop;
    }
    obj.tabId = tabId;

    //check for extra confirm
    if (obj.warning) {
      var warning = $.extend({}, obj.warning);
      EventMgr.trigger('checkWarningForConfirm', { d: obj, w: warning });
    }
    var table = renderTable(obj);
    //render pager
    var pager = '';
    if (obj.pager.pager === 'true') {
      pager = buildPager(obj.pager, tabId);
    }
    var filter = '';
    if (obj.filter === 'true') {
      if (obj.activeFilter.status) {
        filter = 'filter filter-hide filter-set';
      } else {
        filter = 'filter filter-hide';
      }
    }

    breadcrumb = getBreadcrumb(obj.breadcrumb);
    delete obj.breadcrumb.name;
    storage.breadcrumb[tabId] = obj.breadcrumb;

    body.autoupdate = obj.autoupdate !== undefined;
    body.tsettings = App.u.escapeQuote(obj.hintTsettings) || '';
    body.hAutoupdate = App.u.escapeQuote(obj.hintAutoupdate) || '';
    body.hExport = App.u.escapeQuote(obj.hintExport) || '';
    body.hSelectAll = App.u.escapeQuote(obj.hintSelectAll) || '';
    body.fHelp = App.u.escapeQuote(obj.hintFilter) || '';
    body.pNum = obj.pager.pageNum;
    body.porder = obj.sortOrder;
    body.sortCol = obj.sortCol;
    body.pcnt = obj.pager.pageCnt;
    body.breadcrumb = breadcrumb;
    body.plidAttr = obj.plid ? 'data-plid= "' + filterXSS.safeAttrValue('div', 'data-plid', obj.plid) + '"' : '';
    body.convertAttr = obj.convert ? 'data-convert=' + obj.convert : '';
    body.oplid = obj.plid || '';
    body.tsplid = obj.tsplid || '';
    body.tsettingsParam = filterXSS.safeAttrValue('a', 'data-url', '?func=tsetting&elid=' + obj.func + '&plid=' + obj.tsplid);
    body.table = table;
    body.progressid = obj.progressid;
    //for toolbar btn
    body.tabIdAttr = 'data-parent=' + tabId;
    body.pager = pager;
    body.filter = filter;
    body.afilter = obj.activeFilter;
    body.param = pagerParam;
    body.livefilter = obj.liveFilter || '';

    tabs[tabId].body = body;
    //save model
    tabs[tabId].__content = obj.content;
    tabs[tabId].__headers = obj.headers;

    App.Global.bannerHtml = null;
    App.Global.targetId = '';
    //APP.Global.warning = null;

    if (obj.filter === 'true') {
      tabs[tabId].filter = true;
      tabs[tabId].filterFunc = obj.filterFunc;
    } else {
      tabs[tabId].filter = false;
    }

    EventMgr.trigger('builtTab', {
      tab: tabs[tabId],
      newtab: obj.newtab,
      targetTabId: obj.targetTabId,
      iType: obj.iType,
      srcData: obj });

    activateNewTab(tabId, obj.newtab, obj.iType);

    if (obj.children) {
      EventMgr.trigger('loadChildren', {
        parent: tabId,
        children: obj.children });
    }
    //if tab have progressbar - run it
    if (obj.progressid) {
      var param = { elid: obj.progressid, func: 'progress.get' };
      EventMgr.trigger('ajaxRequest', {
        url: pageInfo.url,
        param: param,
        invar: { tabId: tabId, param: param, progresstype: undefined },
        type: 'get',
        outtype: 'json',
        trfunc: 'progressBarResponse',
        queue: 'noqueue' });
    }
    //if tab have diagram - insert it
    if (obj.diagram && obj.diagram[0]) {
      EventMgr.trigger('appendListWithDiagram', {
        diagram: obj.diagram[0],
        content: obj.content,
        tabId: tabId,
        gid: 'diagram-' + tabId });
    }
    //check for saved live filter
    if (obj.liveFilter) {
      $('#' + tabId + '-search').trigger('keyup');
    }
  },

  //build tab with form
  buildForm = function buildForm(tabId, obj) {
    var body = prepareTab(obj, tabId);

    if (!obj.form) {
      return;
    }

    obj.form.id = tabId;
    obj.form.formflags = obj.formflags || {};
    obj.form.parent = obj.parent || '';
    obj.form.func = obj.func;

    body = prepareFormTab(obj, tabId, body);

    tabs[tabId].formModel = body.model;
    tabs[tabId].formSource = body.formSource;

    tabs[tabId].body = body;

    EventMgr.trigger('builtTab', {
      tab: tabs[tabId],
      newtab: obj.newtab,
      targetTabId: obj.targetTabId,
      iType: obj.iType,
      srcData: obj });

    activateNewTab(tabId, obj.newtab, obj.iType);
    if (obj.error) {
      EventMgr.trigger('focusOnErrorField', { tabId: tabId });
    }
  },

  //build tab with dashboard
  buildDashboard = function buildDashboard(tabId, obj) {
    var msg;
    tabs[tabId] = new TabObj(tabId, 1, 'dashboard');

    if (!obj.error && obj.blocks) {
      tabs[tabId].body = renderDashboard(obj.blocks);
    } else if (obj.lateLoad) {
      msg = pageInfo.loading;
      /*jslint sub: true*/
      tabs[tabId].body = { id: tabId, top: msg, left: '', right: '' };
      /*jslint sub: false*/
    } else if (!obj.shithappend) {
      msg = templates.fatalError({ message: obj.ermsg, ref: false });
      tabs[tabId].body = { 'id': tabId, top: msg, left: '', right: '' };
    } else {
      msg = pageInfo.loading;
      tabs[tabId].body = { id: tabId, top: msg, left: '', right: '' };
      //shit happend trying again
      setTimeout(function () {
        var url = pageInfo.url,
            param = { func: 'dashboard' };
        EventMgr.trigger('ajaxRequest', {
          url: url,
          param: param,
          invar: { exType: 'dashboard' },
          type: 'get',
          outtype: 'json',
          trfunc: 'ajaxResponse',
          queue: 'dashboard' });
      }, 500);
    }
    //if was error
    $('#cont-tab0').remove();

    tabs[tabId].func = obj.func;

    EventMgr.trigger('builtTab', { tab: tabs[tabId] });

    defaultTab = tabId;
    //if dashboard loaded after list/form
    /*jslint sub: true*/
    if (!tabs['tab1'] || !tabs['tab1'].active) {
      activateNewTab(tabId);
    } else {
      tabs['tab0'].deactive();
    }
    /*jslint sub: false*/
  },
      buildFatalError = function buildFatalError(tabId, obj) {
    var ref,
        refreshLink,
        sTabId = obj.targetTabId || tabId,
        cb;
    $('.m-item.loading').removeClass('loading');
    if (obj.__src === 'groupAction' || obj.__src === 'report' || obj.__src === 'toolbarAction-refresh') {
      EventMgr.trigger('tabLoadingHide', { tabId: obj.tabId });
      if (obj.__src === 'groupAction') {
        EventMgr.trigger('reloadTab', { tabId: obj.tabId, filter: true });
      }
    } else if (obj.__src === 'wizardLink') {
      EventMgr.trigger('tabLoadingHide', { tabId: obj.tabId });
      sTabId = false;
    } else if (obj.targetTabId) {
      EventMgr.trigger('tabLoadingHide', { tabId: obj.targetTabId || obj.waitingTabId });
    } else if (obj.waitingTabId) {
      //reset to default form state
      EventMgr.trigger('tabLoadingHide', { tabId: obj.waitingTabId });
      resetToDefaultFormButton(obj.waitingTabId);
    }
    if (obj.ref) {
      ref = pageInfo.url + obj.ref;
    }
    if (obj.ertype === 'unavailable') {
      refreshLink = obj.sourceParamString;
    }
    //check for exist tab, and close it
    if (sTabId) {
      if (tabs[sTabId]) {
        closeTab({ preventDefault: function preventDefault() {} }, sTabId);
      }
    }
    //reload parent, becase it can be unexist elem
    if (obj.parent) {
      cb = function cb() {
        EventMgr.trigger('reloadTab', { tabId: obj.parent, __src: 'fatalError' });
      };
    }
    var html = templates.fatalAlert({
      msg: obj.ermsg,
      ref: ref,
      refreshLink: refreshLink,
      refreshLinkMsg: pageInfo.tryreload,
      moreMsg: pageInfo.moreinfo
    });
    EventMgr.trigger('showAlert', {
      msg: html,
      callback: cb });
  },
      buildReport = function buildReport(tabId, obj) {
    //@todo вынести
    var bands,
        body = prepareTab(obj, tabId);

    obj.form.id = tabId;
    obj.form.func = obj.func;
    obj.reports.func = obj.func;

    bands = renderBands(obj.reports, tabId);
    body = prepareFormTab(obj, tabId, body);

    body.helpType = 'default';
    body.helpurl = '';
    body.type = 'report';
    body.bands = bands;
    body.reportInfo = obj.reportInfo;

    tabs[tabId].body = body;

    EventMgr.trigger('builtTab', {
      tab: tabs[tabId],
      newtab: obj.newtab,
      bands: obj.reports,
      targetTabId: obj.targetTabId });

    activateNewTab(tabId, obj.newtab, obj.iType);
  },
      buildMap = function buildMap(tabId, obj) {
    var body = prepareTab(obj, tabId),
        ermsg,
        type = obj.type;

    if (obj.ermsg && !obj.erobj) {
      ermsg = templates.banner({ message: {
          status: 'error',
          classes: '',
          id: tabId,
          text: App.Common.wordWrap(obj.ermsg, 100),
          ref: false,
          refText: pageInfo.moreinfo,
          dismiss: obj.msg.dismiss
        } });
    }

    body.helpType = 'default';
    body.helpurl = '';
    body.type = type;
    body.plid = obj.plid ? String(obj.plid).replace(/"/g, '&quot;') : '';
    body.elid = obj.elid ? String(obj.elid).replace(/"/g, '&quot;') : '';
    body.parent = obj.parent ? obj.parent : '';
    body.ermsg = ermsg;
    body.btng = obj.btng ? obj.btng : [];
    body.btnview = obj.btnview ? 'o-' + obj.btnview : '';
    body.plidAttr = obj.plid ? 'data-plid= "' + filterXSS.safeAttrValue('div', 'data-plid', obj.plid) + '"' : '';
    body.convertAttr = obj.convert ? 'data-convert=' + obj.convert : '';

    tabs[tabId].body = body;

    EventMgr.trigger('builtTab', {
      tab: tabs[tabId],
      map: obj[type],
      newtab: obj.newtab,
      targetTabId: obj.targetTabId });

    activateNewTab(tabId, obj.newtab, obj.iType);
  },
      buildEmpty = function buildEmpty(tabId, obj) {
    var body = pageInfo.loading,
        curTab;
    prepareTab(obj, tabId);
    curTab = tabs[tabId];
    curTab.body = { id: tabId, text: '', comment: body };
    curTab.status = 0;
    curTab.notLoaded = true;
    curTab.pin = obj.pin;

    if (obj.children) {
      EventMgr.trigger('loadChildren', {
        parent: tabId,
        children: obj.children });
    }

    EventMgr.trigger('builtTab', {
      tab: curTab,
      newtab: obj.newtab,
      targetTabId: obj.targetTabId });
    EventMgr.trigger('changedTabs', { tabs: tabs });
  },
      buildInspectorForm = function buildInspectorForm(tabId, obj) {
    //if fatal error without form
    if (obj.error && obj.userexpMsg === undefined) {
      EventMgr.trigger('pullMsg', { msg: obj.ermsg });
      return;
    }
    var body = prepareTab(obj, tabId);
    //rename id
    delete tabs[tabId];
    tabId = 'modal1';
    body.id = tabId;

    if (!obj.form) {
      return;
    }

    obj.form.id = tabId;

    body = prepareFormTab(obj, tabId, body);

    body.parent = obj.sourceTab;

    var html = templates.tabContForm(body);
    EventMgr.trigger('readyInspectorFormHtml', html);
  },

  //build external form
  buildShowcaseForm = function buildShowcaseForm(tabId, obj) {
    tabId = 'tab0';
    var body = prepareTab(obj, tabId);
    obj.form.id = tabId;

    obj.form.formflags = obj.formflags || {};

    obj.form.parent = obj.parent || '';

    body = prepareFormTab(obj, tabId, body);

    tabs[tabId].formModel = body.model;
    tabs[tabId].formSource = body.formSource;

    body.showcase = true;
    body.nostep = !pageInfo.wizard_step;
    body.notitle = !pageInfo.title;

    //        body.parent = obj.sourceTab;

    var html = templates.tabContForm(body);
    EventMgr.trigger('readyShowcaseFormHtml', html);
  },

  //fill body object for form
  prepareFormTab = function prepareFormTab(obj, tabId, body) {
    if (!body || !obj) {
      return;
    }
    var ermsg = '',
        userexpMsg = String(obj.userexpMsg).replace('__value__', obj.userexpHideFields),
        renderObject;
    //banner
    if (obj.ermsg && !obj.erobj) {
      ermsg = templates.banner({ message: {
          status: 'error',
          classes: 'i-message__outer-link',
          id: tabId,
          text: App.Common.wordWrap(obj.ermsg, 100),
          ref: obj.ref ? obj.ref : false,
          refText: pageInfo.moreinfo,
          dismiss: obj.msg.dismiss || pageInfo.dismiss
        } });
    }

    body.form = obj.form;
    body.tabClass = obj.testMode ? ' tab-content_st_testmode' : '';
    body.formstatus = obj.formstatus;
    body.files = obj.withfiles ? 'withfiles' : 'withoutfiles';
    body.bands = '';
    body.progress = obj.progress ? obj.progress + '_' + body.itemId : false;
    body.helpType = obj.helpType;
    body.helpurl = obj.helpurl;
    obj.form.testMode = obj.testMode;
    renderObject = renderFormItems(obj.form, tabId);
    body.pages = renderObject.html;
    body.model = renderObject.model;
    body.formSource = renderObject.source;
    body.action = pageInfo.binary;
    body.step = pageInfo.step;
    body.formflags = obj.formflags ? obj.formflags : {};
    body.buttons = obj.buttons;
    body.parent = obj.parent ? obj.parent : '';
    body.plid = obj.plid ? String(obj.plid).replace(/"/g, '&quot;') : '';
    body.elid = obj.elid ? String(obj.elid).replace(/"/g, '&quot;') : '';
    body.plidAttr = obj.plid ? 'data-plid= "' + filterXSS.safeAttrValue('div', 'data-plid', obj.plid) + '"' : '';
    body.type = 'form';
    //body.isUserexp = obj.isUserexp;
    body.userexp = obj.userexp;
    body.userexpMsg = userexpMsg;
    body.reportInfo = undefined;
    body.arePages = obj.form.length > 1 ? 'a-lot-of-pages' : '';
    body.ermsg = ermsg;
    body.__innervars = obj.__innervars ? objectToString(obj.__innervars) : '';

    //add buttons to formModel
    if (obj.buttons) {
      body.model.__buttons = obj.buttons;
    }

    return body;
  },
      objectToString = function objectToString(object) {
    var stringVars = '',
        index = 0;
    for (var key in object) {
      if (index !== 0) {
        stringVars += '|';
      }
      index++;
      stringVars += key + ':' + object[key];
    }

    return stringVars;
  },
      isAlreadyPinTab = function isAlreadyPinTab(obj, tabId) {
    var func = obj.func || (obj.urlObj ? obj.urlObj.func : ''),
        already = false,
        tab;
    for (var key in tabs) {
      tab = tabs[key];
      if (key === tabId) {
        return true;
      }
      if (tab && tab.paramObjAll && tab.paramObjAll.func === func) {
        return true;
      } else if (tab && tab.urlObj && tab.urlObj.func === func) {
        return true;
      }
    }
    return already;
  },

  //fill body object for all types
  prepareTab = function prepareTab(obj, tabId) {
    var body = {},
        title,
        titleLen = 0,
        shortTitle,
        hint,
        tImg,
        tStyle,
        imgId,
        selfUrl = obj.selfUrl ? obj.selfUrl.replace(/sfrom=ajax/g, '') : '',
        curTab;

    //dont show pin when isPin && from menu
    obj.pin = obj.pin && obj.__src !== 'menuAction';
    //check already same pin tab
    if (obj.pin && !isAlreadyPinTab(obj, tabId)) {
      obj.pin = true;
    }
    /* jshint camelcase: false*/
    body.commonDir = pageInfo.commonDir;
    body.itemId = obj.type + new Date().getTime();
    body.id = tabId;
    body.func = obj.func;
    body.theme = obj.theme;
    body.hReload = App.u.escapeQuote(obj.hintReload) || '';
    body.comment = App.u.escapeQuote(obj.msg_loading) || '';
    body.hFavorite = App.u.escapeQuote(obj.hintFavorite) || '';
    body.hUnfavorite = App.u.escapeQuote(obj.hintUnFavorite) || '';
    body.hPrint = App.u.escapeQuote(obj.hintPrint) || '';
    body.hCopy = App.u.escapeQuote(obj.hintCopy) || '';
    body.hPdf = App.u.escapeQuote(obj.hintPdf) || '';
    body.hHelp = App.u.escapeQuote(obj.hHelp) || '';
    body.hintUnpin = App.u.escapeQuote(obj.hintPin) || '';
    body.hintPin = App.u.escapeQuote(obj.hintUnpin) || '';
    body.hDevel = 'out=devel';
    body.breadcrumb = '';
    body.message = '';
    body.selfurl = pageInfo.url + '?' + getQueryString(obj.urlObj);
    body.devMode = devMode;
    body.testMode = obj.testMode;
    body.pdfOn = pdfOn;
    body.btng = obj.btng ? obj.btng : [];
    body.btnview = obj.btnview ? 'o-' + obj.btnview : '';
    body.favorite = obj.favorite || false;
    body.pin = obj.pin || false;
    body.inmenu = !!App.Dom.byId('l-' + String(obj.func).replace(/\./g, '_'));
    //for btn in form
    body.parentAttr = obj.parent ? 'data-parent=' + obj.parent : '';
    //for toolbar btn
    body.tabIdAttr = 'data-parent=' + tabId;
    //make permalink
    var permaLinkObj = $.extend({}, obj.urlObj);
    delete permaLinkObj.sfrom;
    delete permaLinkObj.operafake;
    delete permaLinkObj.clickstat;
    permaLinkObj.startform = permaLinkObj.func;
    delete permaLinkObj.elname;
    delete permaLinkObj.func;
    body.permaLink = pageInfo.url + '?' + getQueryString(permaLinkObj);
    //remove error if not tagret tab
    if (App.Global.targetId && App.Global.targetId !== tabId && App.Global.bannerHtml && App.Global.bannerHtml.length > 0) {
      var msgLen = App.Global.bannerHtml.length;
      while (msgLen--) {
        if (App.Global.bannerHtml[msgLen].status === 'error') {
          App.Global.bannerHtml.splice(msgLen, 1);
        }
      }
    }
    if (obj.message) {
      if (App.Global.bannerHtml) {
        body.message = obj.message.concat(App.Global.bannerHtml);
      } else {
        body.message = obj.message;
      }
    } else {
      if (App.Global.bannerHtml) {
        body.message = App.Global.bannerHtml;
      }
    }
    if (body.message) {
      //check for message exists
      var l = body.message.length;
      while (l--) {
        if (body.message[l].refText === '') {
          body.message[l].refText = obj.msg.moreinfo;
        }
        if (body.message[l].dismiss === '') {
          body.message[l].dismiss = obj.msg.dismiss || pageInfo.dismiss;
        }
      }
    }

    if (!obj.targetTabId) {
      tabs[tabId] = new TabObj(tabId, 1, obj.type, selfUrl);
    } else {
      tabs[tabId].type = obj.type;
      tabs[tabId].selfUrl = selfUrl;
    }
    //set menu func name
    if (obj.__src_func) {
      tabs[tabId].menuFunc = obj.__src_func;
    }

    curTab = tabs[tabId];

    if (obj.iType !== 'hardUpdate' && obj.iType !== 'replace') {
      if (!obj.parent) {
        curTab.hType = 'parent';
      } else {
        if (tabs[obj.parent] === undefined) {
          return;
        }
        curTab.hType = 'child';
        curTab.parent = obj.parent;
        curTab.gParent = tabs[obj.parent].gParent ? tabs[obj.parent].gParent : obj.parent;
        if (obj.type === 'empty') {
          tabs[obj.parent].child = tabId;
        }
      }
    } else {
      obj.parent = curTab.parent;
    }

    //get title
    if (obj.title && obj.title !== '') {
      titleLen = obj.title.length;
      if (titleLen < 25) {
        title = obj.title;
      } else {
        title = obj.title.substr(0, 25) + '...';
      }
      if (titleLen < 10) {
        shortTitle = obj.title;
      } else {
        shortTitle = obj.title.substr(0, 10) + '...';
      }
      hint = App.u.escapeQuote(obj.title);
    } else {
      title = '...';
    }
    curTab.title = obj.title;
    body.tabTitle = obj.title;

    //get icon for title
    if (obj.parent) {
      imgId = tabs[tabs[tabId].gParent].func;
    } else {
      imgId = obj.id;
    }
    tImg = getMainImg(imgId, obj.selfIcon, pageInfo.commonDir);
    tStyle = getMainImg(imgId, obj.selfIcon, pageInfo.commonDir, true);

    body.tImg = tImg;
    body.tStyle = tStyle;
    //remember parent params for return parent by cancel
    if (obj.rParent) {
      curTab.rParentObj = tabs[tabId].paramObjAll;
    } else {
      curTab.rParentObj = undefined;
    }

    //set tabs props
    curTab.paramObjAll = obj.urlObj;

    if (obj.type !== 'empty') {
      curTab.notLoaded = false;
    }

    curTab.iType = obj.iType;
    curTab.pinIcon = obj.pinIcon ? obj.pinIcon : getGroupIcon(imgId);
    curTab.pin = obj.pin || false;

    curTab.header = {
      tabId: tabId,
      title: title,
      hint: hint,
      isPin: obj.pin,
      pinIcon: curTab.pinIcon,
      shortTitle: shortTitle,
      theme: pageInfo.theme };

    curTab.func = obj.func;

    curTab.favorite = obj.favorite;

    curTab.features = obj.features;
    curTab.wizard = obj.wizard;
    //make help param
    if (obj.help) {
      curTab.help = obj.help;
    } else if (obj.__src === 'toolbarAction' || obj.__src === 'okForm' || obj.__src === 'tSetting') {
      if (obj.parent && tabs[obj.parent]) {
        curTab.help = tabs[obj.parent].help + '.' + obj.__srcBtn;
      } else {
        curTab.help = obj.func;
      }
    } else {
      //obj.__src === 'menuAction' ||
      //  obj.newtab ||
      //  obj.__src === 'dashboardBtn'
      curTab.help = obj.func;
    }
    body.help = curTab.help;

    return body;
  },
      getQueryString = function getQueryString(queryObj) {
    var paramString = '',
        j = 0,
        curValue;
    for (var key in queryObj) {
      if (key !== '') {
        if (j !== 0) {
          paramString += '&';
        }
        //encode params
        paramString += key + '=' + encodeURIComponent(queryObj[key]);
        j++;
      }
    }
    return paramString;
  },


  /**
   * activate tab when switching
   * @param {String} tabId
   */
  activateTab = function activateTab(tabId) {
    var gParent = '',
        prevTabId = activeTab,
        pTabId = '',
        selid = [],
        func;
    //checking, probably deleted it early
    if (tabs[activeTab]) {
      tabs[activeTab].deactive();
      //remove actChild from gParent if child
      if (tabs[activeTab].gParent) {
        gParent = tabs[activeTab].gParent;
        tabs[gParent].actChild = null;
      }
    }
    //write actChild to gParent if child
    if (tabs[tabId].gParent) {
      gParent = tabs[tabId].gParent;
      tabs[gParent].actChild = tabId;
    }
    tabs[tabId].activate();
    if (!gParent) {
      pTabId = tabId;
    } else {
      pTabId = gParent;
    }

    EventMgr.trigger('activateTab', { tabId: tabId });
    EventMgr.trigger('changedTab', { tabId: tabId, prevTabId: prevTabId });
    EventMgr.trigger('changeTabStatus', {
      func: getMenuFunction(pTabId),
      type: 'activate' });
    EventMgr.trigger('changedTabs', { tabs: tabs });
    //EventMgr.trigger('switchTab', {tabId : tabId});
    activeTab = tabId;
    //updateTab or load if notloaded
    if (tabs[tabId].aupdate || tabs[tabId].notLoaded) {
      selid = true;
      EventMgr.trigger('reloadTab', {
        tabId: tabId,
        selid: selid,
        help: true,
        filter: true });
    }
  },
      isPinTab = function isPinTab(tabId) {
    var isPin = false;
    if (tabs[tabId] && tabs[tabId].pin) {
      isPin = true;
    } else if (tabs[tabId] && tabs[tabId].gParent) {
      if (tabs[tabs[tabId].gParent] && tabs[tabs[tabId].gParent].pin) {
        isPin = true;
      }
    }
    return isPin;
  },
      getMenuFunction = function getMenuFunction(pTabId) {
    var func = '';
    //get func name
    if (tabs[pTabId]) {
      if (tabs[pTabId].menuFunc) {
        func = tabs[pTabId].menuFunc;
      } else if (tabs[pTabId].func) {
        func = tabs[pTabId].func;
      } else if (tabs[pTabId].paramObjAll) {
        func = tabs[pTabId].paramObjAll.func;
      }
    }
    return func;
  },

  /**
   * activate new opened tab
   * @param {String} tabId Activated tabId
   * @param {Boolean} empty Empty Tabrea
   * @param {String} iType
   */
  activateNewTab = function activateNewTab(tabId, empty, iType) {
    var isPin = isPinTab(activeTab);
    if (activeTab === tabId) {
      tabs[tabId].activate();
      return;
    }
    var hType = tabs[tabId].hType,
        parent = tabs[tabId].parent || null,
        gParent = tabs[tabId].gParent || null,
        pTabId,
        child,
        update = iType === 'hardUpdate' || iType === 'softUpdate',
        replace = iType === 'replace';
    //delete active tab if not default and not child
    if (activeTab && activeTab !== defaultTab && !empty && hType !== 'child' && tabId !== 'tab0' && !update && !replace && !isPin) {
      //close tabs group (parents & children)
      closeTabGroup(activeTab);
    }
    //delete sibling child
    if (parent && tabs[parent].child && !update && !replace) {
      child = tabs[parent].child;
      closeChildTab(child);
    }

    if (hType === 'child') {
      //write child to parent
      tabs[parent].child = tabId;
      //write actChild to greatParent
      tabs[gParent].actChild = tabId;
    }
    if (tabs[activeTab]) {
      tabs[activeTab].deactive();
    }
    tabs[tabId].activate();

    if (!gParent) {
      pTabId = tabId;
    } else {
      pTabId = gParent;
    }
    activeTab = tabId;
    //remove loading className
    $('.m-item.loading').removeClass('loading');
    EventMgr.trigger('activateTab', { tabId: tabId });
    EventMgr.trigger('changeTabStatus', {
      func: getMenuFunction(pTabId),
      type: 'activate' });
    EventMgr.trigger('changedTabs', { tabs: tabs });
  },

  /**
   * finding out new active tab
   * @param {String} tabId closed TabId
   */
  newActiveTab = function newActiveTab(tabId, src) {
    var newActTab, gParent, pTabId;
    //check actChild
    if (!tabs[tabId]) {
      return;
    }
    if (tabs[tabId].gParent) {
      gParent = tabs[tabId].gParent;
      if (!tabs[gParent].actChild) {
        return;
      }
    } else if (tabs[tabId].actChild) {} else if (tabId !== activeTab) {
      return;
    }
    //set active to dashboard
    if (tabs[tabId].hType === 'parent') {
      if (src === 'backBtn') {
        newActTab = 'tab0';
      } else {
        newActTab = getNextTab(tabId);
      }
    } else {
      //set active to parent
      newActTab = tabs[tabId].parent;
      if (tabs[tabId].gParent) {
        gParent = tabs[tabId].gParent;
        tabs[gParent].actChild = newActTab;
      }
    }
    //set actChild for
    if (tabs[newActTab].gParent) {
      tabs[tabs[newActTab].gParent].actChild = newActTab;
    }

    tabs[newActTab].activate();

    if (!gParent) {
      pTabId = newActTab;
    } else {
      pTabId = gParent;
    }
    activeTab = newActTab;
    EventMgr.trigger('activateTab', { tabId: newActTab });
    EventMgr.trigger('changeTabStatus', {
      func: getMenuFunction(pTabId),
      type: 'activate' });
    EventMgr.trigger('changedTab', { tabId: newActTab });
    EventMgr.trigger('changedTabs', { tabs: tabs });

    if (tabs[newActTab].aupdate || tabs[newActTab].notLoaded) {
      EventMgr.trigger('reloadTab', {
        tabId: newActTab,
        __src: 'activateTab',
        selid: true,
        filter: true });
    }
  },

  //get right or left tab
  getNextTab = function getNextTab(tabId) {
    var tabsArr = [],
        ind = 0,
        selfIndex,
        next,
        prev;
    for (var key in tabs) {
      if (tabs[key].hType === 'parent') {
        tabsArr.push(key);
        if (key === tabId) {
          selfIndex = ind;
        }
        ind++;
      }
    }
    next = selfIndex + 1;
    prev = selfIndex - 1;
    if (tabsArr[next]) {
      return getChild(tabsArr[next]);
    } else if (tabsArr[prev]) {
      return getChild(tabsArr[prev]);
    } else {
      return defaultTab;
    }
  },

  //get last child tab
  getChild = function getChild(tabId) {
    var childTabId = tabId;
    if (tabs[tabId].child) {
      childTabId = getChild(tabs[tabId].child);
    }
    return childTabId;
  },

  //switch tabs
  switchTabs = function switchTabs(e) {
    e.preventDefault();
    var tabId = this.getAttribute('data-tabid');

    if (activeTab === tabId) {
      return;
    }
    activateTab(tabId);
    if (tabs[tabId].type === 'form' || tabs[tabId].type === 'report') {
      EventMgr.trigger('switchTabForm', { tabId: tabId });
      EventMgr.trigger('updFormHeight', { tabId: tabId });
    } else {
      EventMgr.trigger('updTableHeight');
    }
    EventMgr.trigger('switchTab', { tabId: tabId });
  },
      closeTabsByMiddleBtn = function closeTabsByMiddleBtn(e) {
    if (e.which === 2 || e.button === 1) {
      var tabId = this.getAttribute('data-tabid');
      e.preventDefault();
      if (tabId !== 'tab0') {
        closeTabClickHandler.apply(this, [e]);
      }
    }
  },

  //update tab by dbclick
  upSwitchedTabs = function upSwitchedTabs(e) {
    e.preventDefault();
    var tabId = this.getAttribute('data-tabid');
    EventMgr.trigger('reloadTab', { tabId: tabId, __src: 'dblclickTab', filter: true });
  },

  //append new tab
  appendTab = function appendTab(e, data) {
    var tabObj = data.tab,
        newtab = data.newtab || false,
        bands = data.bands || '',
        map = data.map || '',
        tabId,
        isPin = isPinTab(activeTab);
    if (activeTab !== defaultTab && !newtab && !isPin) {
      if (tabs[activeTab].gParent) {
        tabId = tabs[activeTab].gParent;
      } else {
        tabId = activeTab;
      }
    }
    if (!tabObj.iType) {
      tabObj.render().append(tabId).clean();
    } else if (tabObj.iType === 'hardUpdate') {
      tabObj.render().update().clean();
    } else if (tabObj.iType === 'softUpdate') {
      tabObj.softUpdate().clean();
    } else if (tabObj.iType === 'replace') {
      tabObj.render().replace().clean();
    }

    EventMgr.trigger('appended', { tabId: tabObj.id });
    //trigger events
    if (tabObj.type === 'form') {
      EventMgr.trigger('appendForm', {
        tabId: tabObj.id,
        tabObj: tabObj,
        srcData: data.srcData });
    } else if (tabObj.type === 'list') {
      EventMgr.trigger('appendList', { tabId: tabObj.id, srcData: data.srcData });
    } else if (tabObj.type === 'dashboard') {
      EventMgr.trigger('appendDashboard', {});
    } else if (tabObj.type === 'report') {
      EventMgr.trigger('appendReport', { tabId: tabObj.id, bands: bands });
    } else if (tabObj.type === 'map' || tabObj.type === 'rack') {
      EventMgr.trigger('appendMap', { tabId: tabObj.id, map: map });
    }
    //get filter
    if (tabObj.filter === true) {
      EventMgr.trigger('appendFilter', {
        tabId: tabObj.id,
        listParam: tabObj.paramObjAll,
        func: tabObj.filterFunc });
    }
    data = null;
    checkFeatures(tabObj);
  },
      closeTabClickHandler = function closeTabClickHandler(e) {
    e.stopPropagation();
    var tabId = this.getAttribute('rel') || this.getAttribute('data-tabid'),
        isChanged = false,
        isPin = tabs[tabId].pin;
    if (isPin) {
      return;
    }
    if (tabs[tabId] && tabs[tabId].type === 'form' && pageInfo.checkUnsaved) {
      var changedFields = checkFormChange(tabId);
      if (changedFields.isChanged) {
        isChanged = true;
        EventMgr.trigger('confirmBoxShow', {
          callbackOk: closeTab,
          callbackCancel: '',
          self: this,
          text: String(pageInfo.unsavedData).replace('__VALUE__', changedFields.count) + '<br/><span class="b-text_style_bold">' + changedFields.labels + '</span>',
          args: [e, tabId],
          checkbox: {
            msg: pageInfo.unsavedDontShow,
            cb: unsavedDataCheckboxHandler
          }
        });
      }
    }
    if (!isChanged) {
      closeTab(e, tabId);
    }
  },


  //close tab
  closeTab = function closeTab(e, data, src) {
    EventMgr.trigger('closeTab', {});
    var tabId, parent;
    if (data) {
      tabId = data;
    } else {
      tabId = this.getAttribute('rel');
    }
    if (!tabs[tabId]) {
      return;
    }
    //check for tab is pin
    if (tabs[tabId] && tabs[tabId].pin) {
      //reload tab if it form
      if (tabs[tabId].type === 'form') {
        EventMgr.trigger('reloadTab', { tabId: tabId, __src: 'pinForm' });
      }
      return;
    }
    EventMgr.trigger('closeTabEvent', { tabId: tabId });

    newActiveTab(tabId, src); //set new active tab
    //killing children
    if (tabs[tabId] && tabs[tabId].child) {
      closeChildTab(tabs[tabId].child);
    }
    //clear child from parent
    if (tabs[tabId] && tabs[tabId].hType === 'child') {
      parent = tabs[tabId].parent;
      tabs[parent].child = null;
    }
    tabs[tabId].close();
    delete tabs[tabId];
    if (e) {
      e.preventDefault();
    }

    EventMgr.trigger('updTableHeight');
    EventMgr.trigger('changedTabs', { tabs: tabs });
  },

  /**
   * close tab's group
   * @param {Stirng} tabId closing tab
   */
  closeTabGroup = function closeTabGroup(tabId) {
    EventMgr.trigger('closeTab', { tabId: tabId });
    if (tabs[tabId].child) {
      closeChildTab(tabs[tabId].child);
    }
    if (tabs[tabId].parent) {
      closeParentTab(tabs[tabId].parent);
    }
    if (tabId !== 'tab0') {
      tabs[tabId].close();
      delete tabs[tabId];
      EventMgr.trigger('closeTabEvent', { tabId: tabId });
    }
  },

  /**
   * close tab's parent
   * @param {String} tabId closing tab parent (will remove)
   */
  closeParentTab = function closeParentTab(tabId) {
    EventMgr.trigger('closeTabEvent', { tabId: tabId });
    if (tabs[tabId].parent) {
      closeParentTab(tabs[tabId].parent);
    }
    tabs[tabId].close();
    delete tabs[tabId];
  },

  /**
   * close tab's child
   * @param {Stirng} tabId closing tab child (will remove)
   */
  closeChildTab = function closeChildTab(tabId) {
    EventMgr.trigger('closeTabEvent', { tabId: tabId });
    if (tabs[tabId].child) {
      closeChildTab(tabs[tabId].child);
    }
    tabs[tabId].close();
    delete tabs[tabId];
  },

  //close all tabs
  closeAllTabs = function closeAllTabs(e) {
    if (tabs) {
      for (var key in tabs) {
        if (tabs.hasOwnProperty(key)) {
          if (key !== 'tab0') {
            closeTab(e, key);
          }
        }
      }
    }
  },

  //close all tabs expect active
  closeOthersTabs = function closeOthersTabs(e) {
    if (tabs) {
      var actTabId = $('.tab-content_st_active').attr('data-tabid'),
          actParentTabId = tabs[actTabId].gParent ? tabs[actTabId].gParent : actTabId;
      for (var key in tabs) {
        if (tabs.hasOwnProperty(key)) {
          if (key !== 'tab0' && tabs[key].hType === 'parent' && key !== actParentTabId) {
            closeTab(e, key);
          }
        }
      }
    }
  },

  //back btn handler
  backBtnHandler = function backBtnHandler(e, data) {
    e.preventDefault();
    var tabId,
        parentId,
        selid = [],
        self = $(this),
        plid = filterXSS.friendlyAttrValue(self.parents('.toolbar').attr('data-plid') || ''),
        isReport = self.closest('.tab-content').attr('data-report') === 'report';
    if (data) {
      tabId = data;
    } else {
      tabId = this.getAttribute('rel');
    }
    selid.push(plid);
    parentId = tabs[tabId].parent;
    if (App.Dom.hasClass(this, 'updatetab')) {
      var pos = plid.lastIndexOf('/'),
          url = pageInfo.url,
          parent = null,
          targetId = tabId,
          funcName = this.getAttribute('data-url').replace('func=', ''),
          param = {};
      param.func = funcName;
      if (pos !== -1) {
        plid = plid.substring(0, pos);
        pos = plid.lastIndexOf('/');
        if (pos === -1) {
          param.elid = plid;
        } else {
          param.plid = plid.substring(0, pos);
          param.elid = plid.substr(pos + 1);
        }
      }
      EventMgr.trigger('ajaxRequest', {
        url: url,
        param: param,
        invar: { parent: parent, targetTabId: targetId, iType: 'replace', __src: 'toolbarAction' },
        type: 'get',
        outtype: 'json',
        trfunc: 'ajaxResponse',
        failfunc: 'failCommonAjaxResponse',
        queue: 'noqueue' });
      EventMgr.trigger('tabLoading', { tabId: tabId });
    } else {
      closeTab.apply(this, [e, tabId, 'backBtn']);
      if (parentId && !isReport) {
        EventMgr.trigger('reloadTab', {
          tabId: parentId,
          __src: 'backBtn',
          selid: selid,
          filter: true });
        EventMgr.trigger('tabLoading', { tabId: parentId });
      }
    }
  },

  //update tab by autoupdate
  updateTab = function updateTab(e, data) {
    var tabId = data.tabId,
        delay = data.delay,
        selid;
    if (activeTab !== tabId) {
      if (tabs[tabId] !== undefined && tabs[tabId].autoupdate) {
        setTimeout(function (tabId, delay) {
          return function () {
            EventMgr.trigger('updateTab', { tabId: tabId, delay: delay });
          };
        }(tabId, delay), delay * 1000);
        tabs[tabId].autoupdate = true;
      }
    } else {
      selid = true;
      EventMgr.trigger('reloadTab', {
        tabId: tabId,
        __src: 'autoUpdate',
        selid: selid,
        filter: true });
    }
  },

  //stop autoupdate by click button
  stopAutoUpdate = function stopAutoUpdate(e) {
    e.preventDefault();
    var tabId = this.getAttribute('data-tabid');
    if (tabs[tabId]) {
      tabs[tabId].autoupdate = false;
      clearTimeout(tabs[tabId].timeId);
      App.Dom.removeClass(this, 'i-list-icon__stop');
      App.Dom.addClass(this, 'b-elem_style_gracescale');
    }
  },

  //get elid selected elements
  getSelectedElems = function getSelectedElems(tabId) {
    var selid = [],
        elid;
    $('#cont-' + tabId + ' .list_table tr.selected:not(".filtred")').each(function () {
      elid = this.getAttribute('data-elid');
      selid.push(elid);
    });
    return selid;
  },
      getScrollTop = function getScrollTop(tabId) {
    var elem = App.Dom.byId('ltwr-' + tabId + '-scrollbar-handler'),
        top = 0;
    if (elem) {
      top = parseFloat(elem.style.top, 10);
    }
    return top;
  },

  //render table
  //return with unopenned <div>,
  // for external usage need to add unclosed <div>
  renderTable = function renderTable(args) {
    var keyVar,
        headers = args.headers,
        headersName = {},
        tableHead,
        tableBody,
        output;
    /* jslint forin: true */
    for (keyVar in headers) {
      headersName[headers[keyVar].name] = {
        type: headers[keyVar].type,
        hidden: headers[keyVar].hidden ? true : false
      };
    }
    args.headersName = headersName;
    tableHead = renderTableHeader(args);
    tableBody = renderTableBody(args);
    output = tableHead.output;
    output += tableBody;
    if (args.sbar) {
      output += '<div class="bottom-bar">';
      output += tableHead.sBar;
    }
    return output;
  },
      renderTableHeader = function renderTableHeader(args) {
    var output = '',
        dHeader = '',
        sBar = '',
        tabId = args.tabId,
        headers = args.headers,
        props = args.props,
        elKeyName = args.elKeyName || args.elKey,
        elKey = args.elKey,
        colLen = headers.length,
        keyVar,
        header,
        className,
        triangle,
        thAttr,
        divAttr,
        rowHandler,
        dataSorttype,
        text,
        total,
        first;

    output += '<table class="list_table init b-list__table_type_body" id="lt-' + tabId + '">' + '<thead><tr>';
    dHeader += '<table id="sort_table-' + tabId + '" class="sort_table b-list__table_type_head">' + '<thead class="1"><tr>';
    sBar += '<table id="statusbar-' + tabId + '" class="statusbar b-list__table_type_footer">' + '<tbody class="1"><tr>';
    /* jslint forin: true */
    for (keyVar in headers) {
      header = headers[keyVar];
      //check for only data diagram col
      if (header && header.hidden) {
        continue;
      }
      className = header.hint ? ' hint ' : '';
      className += header.align ? ' align-' + header.align : '';
      if (header.minimize) {
        className += ' i-minimize-col ';
      }
      triangle = '';
      first = keyVar - 0 === 0;
      thAttr = ' data-colname="' + header.name + '" ';
      divAttr = ' data-colname="' + header.name + '" ';
      divAttr += ' data-coln="' + keyVar + '" ';
      thAttr += header.total ? ' data-type="' + header.type + '" ' : '';
      thAttr += header.nestedreport ? ' data-nestedreport="' + header.nestedreport + '" ' : '';
      thAttr += header.nestedlist ? ' data-nestedlist="' + header.nestedlist + '" ' : '';
      thAttr += header.nestedlistBlank ? ' data-nestedlist-blank="true" ' : '';
      thAttr += header.editform ? ' data-editform="' + header.editform + '" ' : '';
      header.hint = header.hint ? App.u.escapeQuote(header.hint) : undefined;
      thAttr += header.hint ? ' data-hint="' + header.hint + '" ' : '';
      thAttr += header.width ? ' width="' + header.width + '"' : '';
      //resize col handler
      rowHandler = keyVar - 0 !== 0 ? '<div class="rowHandler"><div class="rowLine1"></div>' + '<div class="rowLine2"></div></div>' : '';
      thAttr += header.edit ? ' data-edit-func="' + header.edit + '" ' : '';
      if (elKey === header.name) {
        className += ' keyfield ';
      }
      if (elKeyName === header.name) {
        className += ' keynamefield ';
      }
      if (first) {
        className += 'first ';
        text = pageInfo.selected + ' - 1';
      } else {
        text = '';
      }
      if (colLen - 1 === keyVar) {
        className += 'last';
      }
      //sorting cols
      if (header.sort && !args.band) {
        className += ' td_sort i-tip-target_st_sort i-tip-target_st_msort';
        dataSorttype = header.sort;
      } else if (header.sort && args.band) {
        className += ' td_client_sort i-tip-target_st_sort i-tip-target_st_msort';
        dataSorttype = header.sort;
      }
      divAttr += dataSorttype ? ' data-sorttype="' + dataSorttype + '" ' : '';
      //sorted col
      if (header.sorted) {
        if (String(header.sorted).match(/\+/)) {
          //asc
          triangle = '<div class="triangl-bot triangle"></div>';
        } else {
          //desc
          triangle = '<div class="triangl-top triangle"></div>';
        }
        if (args.sortedCount > 1) {
          triangle += '<div class="b-sort-table__sort-order">' + String(header.sorted).charAt(1) + '</div>';
        }
        divAttr += 'sorting="' + header.sorted + '"';
      } else {
        triangle = '<div class="triangle"></div>';
      }

      triangle += '<div class="filter-icon hint"  data-hint=""></div>';
      //check for development flag
      if (devMode) {
        triangle += '<a href="#" class="devel-link-settings devel-link-settings--col" data-elid="' + header.name + '" data-tabid="' + tabId + '"></a>';
        triangle += '<a href="#" class="devel-link-delete devel-link-delete--col" data-elid="' + header.name + '" data-name="' + header.pName + '" data-tabid="' + tabId + '"></a>';
        if (first) {
          triangle += '<a href="#" class="devel-link-add devel-link-add--col"  data-tabid="' + tabId + '"></a>';
        }
      }

      if (header.type === 'button') {
        for (keyVar in header.confirm) {
          if (header.confirm[keyVar] !== '') {
            divAttr += ' data-confirm-' + keyVar + '="' + header.confirm[keyVar] + '" ';
          }
        }
      }
      //@todo warning!!! diff html
      output += '<th  class="' + className + '" ' + thAttr + '>' + '<div class="ovf" ' + divAttr + '><span class="data-wrapper" data-mn="' + header.name + '" data-fn="' + args.func + '">' + header.pName + '</span>' + triangle + '</div> ' + rowHandler + '</th>';
      dHeader += '<td  class="' + className + '" ' + thAttr + '>' + '<div class="ovf"  ' + divAttr + '><span class="data-wrapper" data-mn="' + header.name + '" data-fn="' + args.func + '">' + header.pName + '</span>' + triangle + '</div> ' + rowHandler + '</td>';
      //row selected
      if (keyVar - 0 === 0) {
        sBar += '<td ' + thAttr + '>' + '<div class="ovf"><span class="sb-result sb-result_index_0 sb-result_st_active" data-mn="msg_total" data-fn="desktop">' + pageInfo.total + ': ' + args.pager.pageElems + '</span><span class="sb-selected sb-selected_index_0" data-mn="msg_selected" data-fn="desktop">' + pageInfo.selected + ': 1</span></div></td>';
      } else {
        //count total row
        if (header.total !== '') {
          //check for type props or not
          if (_typeof(header.total) === 'object') {
            total = renderPropsStat(header.total, props);
            className += ' data';
          } else {
            total = header.total;
            className += ' data';
          }
        } else {
          total = '';
          className += ' empty';
        }

        sBar += '<td ' + thAttr + '>' + '<div class="ovf">' + '<span class="sb-result sb-result_st_active sb-result_index_' + keyVar + '">' + total + ' </span>' + '<span class="sb-selected sb-selected_index_' + keyVar + '">' + text + '</span></div></td>';
      }
    }

    output += '</tr></thead>';
    dHeader += '</tr></thead></table>';
    output = dHeader + output;
    sBar += '</tr></thead></table>';

    return {
      output: output,
      sBar: sBar };
  },
      renderTableBody = function renderTableBody(args) {
    var output = '<tbody>',
        plid = args.plid ? ' data-plid="' + filterXSS.safeAttrValue('div', 'data-plid', args.plid) + '" ' : '',
        keyVar,
        contentItem,
        elid,
        className,
        curElKeyName,
        curElKey,
        id,
        hint,
        attr,
        len,
        headers = args.headers,
        elKeyName = args.elKeyName || args.elKey,
        elKey = args.elKey,
        ii = 0,
        content = args.content;
    args.defProp = args.props ? findDefProp(args.props) : null;
    if (args.backBtn) {
      len = args.headers.length;
      output += '<tr class="back-btn"><td colspan="' + len + '">' + '<div class="back-btn-row hint" data-tabid="' + args.tabId + '" >' + '<div class="hint back-btn-row-hint" data-hint="' + App.u.escapeQuote(App.Common.msg.hintBack) + '"></div></td></tr>';
      ii++;
    }
    //render tbody
    /* jslint forin:true */
    for (keyVar in content) {
      contentItem = content[keyVar];
      elid = '';
      className = '';
      curElKeyName = '';
      curElKey = '';
      ii++;
      rowId++;
      id = '';
      hint = '';
      attr = plid;
      attr += ' id="i-' + rowId + '" ';
      //data-index for detect row in model
      attr += ' data-index="' + keyVar + '"';
      if (elKey !== undefined && contentItem[elKey] !== undefined) {
        curElKey = contentItem[elKey].v.replace(/"/g, '&quot;');
        attr += ' data-elid="' + curElKey + '" ';
        elid = contentItem[elKey].v;
      }
      if (elKeyName !== undefined && contentItem[elKeyName] !== undefined) {
        curElKeyName = contentItem[elKeyName].v.replace(/"/g, '&quot;');
        attr += ' data-elkeyname ="' + curElKeyName + '" ';
      }
      if (ii % 2 === 0) {
        className = ' even ';
      } else {
        className = '';
      }
      if (contentItem._ovcol) {
        className += ' ' + contentItem._ovcol + ' ';
      }
      if (contentItem._ovhide) {
        attr += ' data-hide="' + contentItem._ovhide + '" ';
        className += ' toolbtn-hide ';
      }
      if (contentItem._ovremove) {
        attr += ' data-remove="' + contentItem._ovremove + '" ';
        className += ' toolbtn-remove ';
      }
      if (contentItem._ovshow) {
        attr += ' data-show="' + contentItem._ovshow + '" ';
        className += ' toolbtn-show ';
      }
      if (args.warning) {
        if (args.warning[elid] !== undefined) {
          if (args.warning[elid].msg !== undefined) {
            className += ' warning';
            hint = App.u.escapeQuote(args.warning[elid].msg);
            delete args.warning[elid];
          }
        }
      }

      className += ' b-list__table-row';
      output += '<tr class="' + className + '"' + attr + ' >';
      output += buildRow(contentItem, args, hint);
      output += '</tr>';
    }
    if (args.warning) {
      EventMgr.trigger('nextEventBind', {
        event: 'appendList',
        tData: args.warning,
        cb: function cb(e, data) {
          if (e.data) {
            var tabId = data.tabId,
                bannerText = $('#cont-' + tabId + ' .b-message__text_warning').get(0),
                warning = e.data,
                extraText = '';

            if (bannerText) {
              for (var key in warning) {
                if (warning[key]) {
                  extraText += warning[key].msg + '<br/>';
                }
              }
              if (extraText) {
                bannerText.innerHTML = extraText;
              }
              EventMgr.trigger('updateScroll', { id: 'cont-' + tabId });
            }
          }
        }
      });
    }
    output += '</tbody>';
    output += buildLastRow(args);
    output += '</table>';
    output += '</div>'; //close table div from template
    return output;
  },


  //render Row
  buildRow = function buildRow(row, args, hint) {
    var headers = args.headersName,
        output = '',
        elKey = args.elKey,
        i = 0,
        ind = 0,
        warning,
        color,
        keyVar,
        usage,
        type,
        currentRow,
        editableClass,
        contentClassName,
        colNameClass,
        contentAttrs,
        attr,
        className,
        value,
        id,
        per,
        buttons,
        j,
        button,
        func,
        form,
        name,
        btnMsg,
        onlyForm;
    /* jslint forin:true */
    for (keyVar in headers) {
      //check for only diagram col
      if (headers[keyVar] && headers[keyVar].hidden) {
        continue;
      }
      i++;
      warning = '';
      className = '';
      editableClass = '';
      colNameClass = 'b-list__table-col_name_' + keyVar;
      color = '';
      value = '';
      attr = '';
      usage = '';
      per = '';
      contentAttrs = '';
      buttons = '';
      onlyForm = false;
      if (elKey === keyVar) {
        className += ' key-field ';
      }
      if (i === 1 && hint !== '' && hint !== undefined) {
        warning = '<div class="warning-img hint" data-hint="' + hint + '"></div>';
      }
      currentRow = row[keyVar];
      if (args.headers[ind].edit) {
        editableClass += ' editable ';
      }
      if (args.testMode) {
        editableClass += ' i-testmode-field ';
      }
      if (args.headers[ind].fastFilter && !args.blockId) {
        editableClass += ' i-filter-field ';
      }
      contentClassName = args.headers[ind].nestedlist !== undefined && !currentRow.nestedlist ? ' i-nestedlist b-list__table-col-content_type_link' : '';
      contentClassName += args.headers[ind].editform !== undefined && !currentRow.nolink ? ' i-editform b-list__table-col-content_type_link ' + 'b-list__table-col-content_style_underline' : '';
      if (currentRow !== undefined) {
        type = headers[keyVar].type;
        //data/prop/money
        if (type === 'data' || type === 'prop' || type === 'money') {
          if (currentRow.color !== undefined) {
            className += ' status-' + currentRow.color;
          }
          if (args.headers[ind].acthint) {
            className += ' acthint ';
          }
          value = args.headers[ind].noescaping ? window.filterXSS(window.htmlDecode(currentRow.v)) : currentRow.v;
          id = currentRow.id ? window.filterXSS(window.htmlDecode(currentRow.id)) : null;
          contentClassName += args.headers[ind].wrap ? ' b-list__table-col-content_is_wrap ' : '';
          className += args.headers[ind].nestedreport !== undefined ? ' nestedreport ' : '';
          className += args.headers[ind].align ? ' align-' + args.headers[ind].align : '';
          attr += currentRow.link ? ' data-child-id="' + args.oTabId + '-' + currentRow.childid + '" ' : '';
          attr += currentRow.elid ? ' data-elid="' + currentRow.elid + '" ' : '';
          contentAttrs += id ? ' data-v-id="' + id + '"' : '';
          contentAttrs += currentRow.orig ? 'data-orig="' + currentRow.orig + '"' : '';
          if (currentRow.props) {
            attr += currentRow.psp ? ' data-stat="' + currentRow.psp + '" ' : '';
            output += '\n                  <td>\n                    <div class="ovf i-text-content ' + editableClass + '">\n                      ' + warning + '\n                      <span class="data-wrapper " ' + attr + '>\n                        ' + makeProps(currentRow, args, row) + '\n                      </span>\n                      <span class="data middle ' + className + '">\n                        <span class="b-list__table-col-content ' + contentClassName + '" ' + contentAttrs + '>' + currentRow.v + '</span>\n                      </span>\n                    </div>\n                  </td>';
          } else {
            output += '\n                  <td class="first ' + colNameClass + '">\n                    ' + warning + '\n                    <span class="i-text-content data-wrapper data ' + className + ' ' + editableClass + '" ' + attr + '>\n                      <span class="b-list__table-col-content ' + contentClassName + '" ' + contentAttrs + '>' + value + '</span>\n                    </span>\n                  </td>';
          }
          //indicator
        } else if (type === 'indicator') {
          if (currentRow.u && currentRow.l) {
            if (currentRow.color !== undefined) {
              className = ' status-' + currentRow.color;
            }
            if (parseInt(currentRow.l, 10) !== 0) {
              if (parseInt(currentRow.u, 10) === 0) {
                per = 0;
              } else {
                per = Math.round(currentRow.u / currentRow.l * 100);
                if (per === 0 || !per) {
                  per = 0;
                }
                per = per > 100 ? 100 : per;
              }
              usage = '<div class="used-wr">' + '<div class="used" style="width:' + per + '%"></div></div>';
            }
          }
          output += '<td class="first">' + '<span class="i-text-content data-wrapper data ' + className + editableClass + '">' + warning + '<span class="b-list__table-col-content ' + contentClassName + '">' + window.htmlDecode(currentRow.v) + '</span>' + '</span>' + usage + '</td>';
          //indicator brackets
        } else if (type === 'indicatorbrackets') {
          if (currentRow.color !== undefined) {
            className = ' status-' + currentRow.color;
          }
          value = currentRow.l || '';
          if (currentRow.u !== '') {
            value += ' (<span class="' + className + '">' + currentRow.u + '</span>)';
          }
          output += '<td class="first">' + '<span class="i-text-content data-wrapper data">' + warning + '<span class="b-list__table-col-content ' + contentClassName + '">' + value + '</span>' + '</span></td>';
          //buttons
        } else if (type === 'button') {
          for (j = 0; j < currentRow.buttons.length; j++) {
            button = currentRow.buttons[j];
            if (button !== '') {
              name = button;
              //for billing dashboard show msg for btn from col & open only form
              onlyForm = args.btn[name].msgsrc && row[args.btn[name].msgsrc];
              attr = '';
              if (!onlyForm) {
                attr += ' data-func="func=' + args.func + '" ';
              }
              attr += ' data-type="' + args.btn[button].type + '" ';
              attr += ' data-name="' + button + '" ';
              type = args.btn[button].type;
              if (onlyForm) {
                btnMsg = row[args.btn[name].msgsrc].v;
              } else {
                btnMsg = args.btn[name].name;
              }
              if (type === 'edit' || type === 'group' || type === 'editlist') {
                attr += ' data-form="func=' + args.btn[button].func + '&elid=' + row[args.elKey].v + '" ';
              }

              buttons += '<a href="#" ' + attr + ' class="dashboard-button">' + btnMsg + '</a> ';

              //buttons += args.btn[currentRow.buttons[i]].name + ' ';
            }
          }
          output += '<td><span class="data-wrapper">' + buttons + '</span></td>';
        }
      } else {
        output += '<td><span class="data-wrapper ' + className + '"></span></td>';
      }
      ind++;
    }
    return output;
  },


  /**
   * Рендерем props и xprop для статусбара
   * @param total
   */
  renderPropsStat = function renderPropsStat(total, props) {
    var stat = '',
        i = 0,
        keyVar,
        cumma = '',
        propName,
        prop,
        sprite = false,
        extension,
        className = '';
    /* jslint forin:true */
    for (keyVar in total) {
      if (i !== 0) {
        cumma = ',</span> ';
      } else {
        cumma = '';
      }
      if (total[keyVar] - 0 === 0) {
        className = 'no';
      } else {
        className = 'default';
      }
      prop = props[keyVar];
      sprite = prop.style === '';
      if (!sprite) {
        extension = prop.animated ? '.gif' : '.png';
        stat += cumma + '<span class="' + className + '"><img class="props" src="' + pageInfo.commonDir + 'img/' + prop.onImg + extension + '"/>' + total[keyVar];
      } else {
        stat += cumma + '<span class="' + className + '"><div class="props s-icon s16x16 ' + prop.onImg + ' i-total-prop-' + keyVar + '"></div>' + total[keyVar];
      }
      i++;
    }
    stat += '</span>';
    return stat;
  },

  //render props
  makeProps = function makeProps(row, args, rows) {
    var output = '',
        propName,
        func,
        type,
        className,
        hide,
        hint,
        attr,
        props = row.props,
        len = props.length,
        i;
    for (i = 1; i < len; i++) {
      if (props[i].n) {
        propName = props[i].n;
        hint = App.u.escapeQuote(args.props[propName].hint);
        func = args.props[propName].func;
        type = args.props[propName].type;
        hide = args.props[propName].hide;
        attr = '';
        className = '';
        if (func && checkFunc(hide, rows)) {
          attr += ' data-func="' + func + '" ';
          attr += ' data-type="' + type + '" ';
          attr += ' data-value="' + props[i].v.replace(/"/g, '&quot;') + '" ';
          className += 'controlprop';
          if (type === 'group') {
            attr += ' data-confirm="' + args.props[propName].confirm + '" ';
          }
          if (args.props[propName].cgi) {
            attr += ' data-cgi="' + args.props[propName].cgi + '" ';
          }
        }
        attr += 'data-name="' + args.props[propName].name + '"';
        // I don't why this rules
        //if (args.props[propName].name !== propName) {
        //check for don't rewrite func attr
        if (!func) {
          attr += ' data-value="' + props[i].v.replace(/"/g, '&quot;') + '" ';
        }

        if (args.props[propName].acthint) {
          className += ' acthint';
        } else {
          className += ' hint';
        }
        if (hint !== '' && hint) {
          hint = App.u.escapeQuote(hint.replace('__value__', props[i].v));
          attr += ' data-hint="' + hint + '" ';
        } else if (props[i].v !== '' && props[i].v) {
          attr += ' data-hint="' + App.u.escapeQuote(props[i].v) + '" ';
        }
        if (args.props[propName].style) {
          attr += args.props[propName].style;
        }
        if (args.props[propName].animated) {
          output += '<img class="props ' + className + ' " ' + attr + ' src="' + pageInfo.commonDir + 'img/' + args.props[propName].onImg + '.gif"/>';
        } else {
          output += '<div class="s-icon s16x16 props ' + className + ' ' + args.props[propName].onImg + '" ' + attr + '></div>';
        }
      }
    }
    return output;
  },

  //check for hide rule for function
  checkFunc = function checkFunc(hide, rows) {
    if (!hide) {
      return true;
    }
    var l = hide.length,
        name,
        value;
    while (l--) {
      name = hide[l].n;
      value = hide[l].v;
      if (rows[name] && rows[name].v === value) {
        return false;
      }
    }
    return true;
  },

  //find default prop
  findDefProp = function findDefProp(props) {
    var keyVar;
    for (keyVar in props) {
      if (props[keyVar].defImg) {
        return keyVar;
      }
    }
    return null;
  },

  //update total report for convert col
  updateTotalWithConvertReport = function updateTotalWithConvertReport(e, data) {
    var id = data.id;
    $('#' + id).html(data.convertValue);
  },
      buildLastRow = function buildLastRow(args) {
    var headers = args.headers,
        colCount = headers.length,
        tFoot = '<tfoot><tr>',
        content = args.content,
        total,
        hint = '',
        msg = App.Common.msg,
        align = '',
        name,
        id;

    for (var i = 0; i < colCount; i++) {
      if (headers && headers[i] && headers[i].hidden) {
        continue;
      }
      total = '';
      id = '';
      align = 'align-' + (headers[i].align || '');
      if (headers[i].total === 'sum') {
        name = headers[i].name;
        total = sumRows(name, content);
        hint = msg.totalSum || '';
      } else if (headers[i].total === 'sumsuffix') {
        hint = msg.totalSum || '';
        total = sumRowsSuffix(name, content, headers[i].convert);
        name = headers[i].name;
      } else if (headers[i].total === 'count') {
        total = content.length;
        hint = msg.totalCount || '';
      } else if (headers[i].total === 'avg') {
        name = headers[i].name;
        total = avgRows(name, content);
        hint = msg.totalAvg || '';
      }

      if (headers[i].convert && total !== '') {
        id = args.tabId + '-' + name;
        EventMgr.trigger('ajaxRequest', {
          param: {
            func: 'convert',
            name: headers[i].convert,
            value: total
          },
          invar: {
            id: id
          },
          type: 'get',
          outtype: 'json',
          trfunc: 'updateTotalWithConvertReport',
          failfunc: 'failMenuAjaxResponse',
          queue: 'multiload'
        });
      }
      tFoot += '<td id="' + id + '" class="hint ' + align + '" data-hint="' + App.u.escapeQuote(hint) + '">' + total + '</td>';
    }
    tFoot += '</tfoot>';
    return tFoot;
  },
      sumRows = function sumRows(name, rows) {
    var len = rows.length,
        sum = 0,
        v,
        maxDec = 0,
        curDec;
    while (len--) {
      if (rows[len][name].orig) {
        v = rows[len][name].orig - 0;
      } else if (rows[len][name].v === '') {
        v = 0;
      } else {
        v = parseFloat(rows[len][name].v.replace(/\s/g, ''));
      }
      curDec = decimalPlaces(v);
      maxDec = curDec > maxDec ? curDec : maxDec;
      sum += v;
    }
    if (maxDec > 0) {
      sum = sum.toFixed(maxDec);
    }
    return sum;
  },
      sumRowsSuffix = function sumRowsSuffix(name, rows, convert) {
    var len = rows.length,
        resultC,
        resultSum = '';
    while (len--) {
      resultC = App.List.dataCalc(resultC, rows[len][name]);
    }
    /* jslint forin: true */
    for (var key in resultC) {
      if (resultSum !== '') {
        resultSum += '; ';
      }
      if (convert === 'money') {
        resultSum += App.Tabs.moneyFormat(resultC[key]) + ' ' + key;
      } else {
        resultSum += resultC[key] + ' ' + key;
      }
    }
    return resultSum;
  },
      avgRows = function avgRows(name, rows) {
    var len = rows.length,
        lenForLoop = len,
        sum = 0,
        avg,
        v;
    while (lenForLoop--) {
      v = rows[lenForLoop][name].v === '' ? 0 : parseFloat(rows[lenForLoop][name].orig || rows[lenForLoop][name].v);
      sum += v;
    }
    avg = sum / len;
    if (avg.toFixed) {
      avg = avg.toFixed(2);
    }
    return avg;
  },
      moneyFormat = function moneyFormat(num) {
    var strNum = '' + parseFloat(num).toFixed(2),
        parts = strNum.split('.'),
        head = parts[0] || '',
        tail = parts[1] || '',
        s = [];
    if (head) {
      var l = head.length,
          p = Math.floor(l / 3);
      for (var i = 0; i < p; i++) {
        s.push(head.substr(l - i * 3 - 3, 3));
      }
      s.push(head.substr(0, l % 3));
      s.reverse();
    }
    if (s.length > 0) {
      return s.join(' ') + '.' + tail;
    } else {
      return num;
    }
  },
      decimalPlaces = function decimalPlaces(num) {
    var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
    if (!match) {
      return 0;
    }
    return Math.max(0,
    // Number of digits right of decimal point.
    match[1] ? match[1].length : 0,
    // Adjust for scientific notation.
    -(match[2] ? +match[2] : 0));
  },

  /**
   * get Image for group
   * check for selficon, else get icon from menu group
   * @param {String} id
   * @param {String} name
   * @param {String} theme
   * @param {Boolean} style
   */
  getMainImg = function getMainImg(id, name, theme, style) {
    var elem, output, pElem, extImg;
    elem = App.Dom.byId('l-' + id);
    pElem = $(elem).parent();
    extImg = pElem.attr('data-img');
    if (!name) {
      //use this way because id can have dot.
      name = pElem.attr('data-group');
    }
    if (name && name.indexOf(".") != -1) {
      output = '';
    } else {
      output = 'mb-' + name;
    }

    if (style && extImg) {
      if (name && name.indexOf(".") != -1) {
        output = 'style="background: url(' + name + ') left top no-repeat"';
      } else {
        var prefix = 'img/mb-',
            suffix = '.png';
        output = 'style="background: url(' + theme + prefix + name + suffix + ') left top no-repeat"';
      }
    }
    if (!extImg && style) {
      output = '';
    }

    //output = theme + prefix + name + suffix;
    return output;
  },
      getGroupIcon = function getGroupIcon(id) {
    var elem, pElem, output, extImg;
    id = String(id).replace(/\./g, '_');
    elem = App.Dom.byId('l-' + id);
    pElem = $(elem).parent();
    name = pElem.attr('data-group');
    extImg = pElem.attr('data-img');

    if (extImg) {
      output = 'class="subtab__text_for_pin s16x16 s-icon" style="background: url(/manimg/common/img/m-' + name + '.png) left top no-repeat"';
    } else {
      output = 'class="subtab__text_for_pin s16x16 s-icon m-' + name + '"';
    }
    return output;
  },
      devMode = pageInfo.devmode,
      pdfOn = pageInfo.pdfOn,
      dateTimeId,
      renderFormItem = function renderFormItem(item, tabId, classes) {
    var itemHTML = '';
    classes = classes || '';
    //render input text ||hidden || password
    if (item.type === 'text' || item.type === 'hidden' || item.type === 'color' || item.type === 'password') {
      item.setvalue = item.setvalue || '';
      if (item.value) {
        item.value = App.u.escapeQuote(item.value);
      }
      if (item.test && !item.zoom) {
        classes += ' test';
      } else if (item.test && item.zoom) {
        classes += ' testzoom';
      }
      //render help buttons
      if (item.passwd) {
        itemHTML += '<div class="b-input-btn b-input-btn_type_passwd hint"' + ' data-hint="' + App.u.escapeQuote(item.hintGenBtn) + '"' + ' data-control-field="' + item.name + '"></div>';
      }
      if (item.showpwd) {
        itemHTML += '<div class="' + (item.passwd ? 'b-input-btn_is_left' : '') + ' b-input-btn b-input-btn_type_showpwd hint"' + ' data-hint="' + App.u.escapeQuote(item.hintShowPwdBtn) + '"' + ' data-control-field="' + item.name + '"' + ' data-tabid="' + tabId + '"></div>';
      }
      if (item.date) {
        itemHTML += '<div class="b-input-btn b-input-btn_type_calendar hint"' + ' data-hint="' + App.u.escapeQuote(item.hintBtn) + '"' + ' data-control-field="' + item.name + '"' + ' data-type="' + item.date + '"></div>';
      }
      if (item.unlimit) {
        itemHTML += '<div class="b-input-btn b-input-btn_type_unlimit hint"' + ' data-hint="' + App.u.escapeQuote(item.hintBtn) + '"' + ' data-control-field="' + item.name + '"></div>';
      }
      if (item.change) {
        itemHTML += '<div class="b-input-btn b-input-btn_type_change hint"' + ' data-hint="' + App.u.escapeQuote(item.hintBtn) + '"></div>';
      }
      if (item.zoom) {
        itemHTML += '<div class="b-input-btn b-input-btn_type_zoom hint"' + ' data-hint="' + App.u.escapeQuote(item.hintBtn) + '" ' + 'data-control-field="' + item.name + '"></div>';
        item.inputAttr = item.attr;
        item.inputClasses = classes;
        item.inputName = item.name;
        item.textareaClasses = ' b-textarea_for_zoom';
        itemHTML += templates.formItemInputWithZoom(item);
      } else if (item.type === 'password') {
        item.classes += classes;
        if (item.confirm) {
          item.confirmField = item.confirmField + '-' + tabId;
          item.classes += ' b-form-confirm-field';
        } else if (item.passwd) {
          item.classes += ' b-form-passwd-field';
        }
        itemHTML += templates.formItemPassword(item);
        if (item.passwd) {
          item.pwcheck.id = tabId;
          item.pwcheck.name = item.name;
          itemHTML += templates.passwdCheck(item.pwcheck);
        } else if (item.confirm) {
          itemHTML += templates.confirmCheck(item);
        }
      } else {
        item.classes += classes;
        itemHTML += templates.formItemInput(item);
      }
      //render input@type=file
    } else if (item.type === 'file') {
      item.classes += classes;
      item.setvalue = '';
      item.value = '';
      itemHTML += templates.formItemFile(item);
    } else if (item.type === 'textarea') {
      //render textarea
      item.classes += item.editor;
      item.value = window.htmlEscape(item.value);
      itemHTML += templates.formItemTextarea(item);
      //data for plugin
      if (item.variables) {
        EventMgr.trigger('saveVarsTinyMCE', {
          name: item.name,
          tabId: tabId,
          vars: item.variables
        });
      }
    } else if (item.type === 'desc') {
      //render description
      itemHTML += templates.formItemDesk(item);
    } else if (item.type === 'htmldata') {
      //render htmldata
      itemHTML += templates.formItemHtmldata(item);
    } else if (item.type === 'select') {
      //render select
      //separate image & value for filtred value
      item.msg = window.filterXSS(item.msg);
      item.msg = item.img + item.msg;
      itemHTML += templates.formItemSelect(item);
    } else if (item.type === 'mselect') {
      //render multi select
      itemHTML += templates.formItemMSelect(item);
      if (item.msg_select_all && pageInfo && pageInfo.messages) {
        pageInfo.messages.msg_select_all = item.msg_select_all;
      }
    } else if (item.type === 'aselect') {
      //render select autocomplete
      itemHTML += templates.formItemSelectAutocomplete(item);
    } else if (item.type === 'radio') {
      if (item.hint === '') {
        item.readonly += ' nohint';
      }
      //render radio
      itemHTML += templates.formItemRadio(item);
    } else if (item.type === 'radioimg') {
      //render radio-img
      itemHTML += templates.formItemRadioImg(item);
    } else if (item.type === 'checkbox') {
      if (item.hint === '') {
        item.dependFields += ' nohint';
      }
      if (item.desc === '') {
        item.dependFields += ' nodesc';
      }
      itemHTML += templates.formItemCheckbox(item);
      //render slider
    } else if (item.type === 'slider') {
      //@TODO change with value
      itemHTML += templates.formItemSlider(item);
      //render mgrview
    } else if (item.type === 'mgrview') {
      itemHTML += templates.formItemMgrview({
        tabId: tabId, theme: pageInfo.theme });
      //render textdata
    } else if (item.type === 'textdata') {
      item.value = window.htmlDecode(item.value);
      itemHTML += templates.formItemTextData(item);
      //render tree
    } else if (item.type === 'tree') {
      itemHTML += renderTree(item, tabId);
    } else if (item.type === 'ticket') {
      itemHTML += templates.formItemTicket(item);
    } else if (item.type === 'link') {
      itemHTML += templates.formItemLink(item);
    } else if (item.type === 'frame') {
      itemHTML += templates.formItemFrame(item);
    } else if (item.type === 'datetime') {
      var d = App.u.parseDate(item.value);
      item.difftime = new Date().getTime() - d.getTime();
      item.value = App.u.formatDateTime(d.getTime());
      itemHTML += templates.formItemDateTime(item);
      dateTimeId = setInterval(function (tabId, name) {
        return function () {
          var elem = App.Dom.byId(tabId + '-' + name);
          if (!tabs[tabId] || !elem) {
            clearInterval(dateTimeId);
            return;
          }
          var dt = elem.getAttribute('data-difftime') - 0;
          elem.innerHTML = App.u.formatDateTime(new Date().getTime() - dt);
        };
      }(tabId, item.name), 500);
    } else if (item.type === 'listfilter') {
      itemHTML += templates.formListFilterWrapper({ name: item.name, id: item.id, content: templates.formListFilter(item) });
    } else if (item.type === 'captcha') {
      itemHTML += templates.formItemCaptcha(item);
      EventMgr.trigger('appendCaptcha', { id: tabId + '-' + item.name });
    }
    return itemHTML;
  },

  //render form items
  renderFormItems = function renderFormItems(form, tabId) {
    var length = form.length,
        i,
        pages = '',
        formHtml,
        formItemsLen,
        j,
        formItems,
        formItemLen,
        k,
        formItem,
        formRow,
        classes,
        valuesForm = {},
        sourceForm = {};
    for (i = 0; i < length; i++) {
      formHtml = {
        name: form[i].name,
        title: '',
        content: '',
        classes: '',
        withList: form[i].withList,
        display: form[i].collapsed ? 'none' : 'block',
        collapsed: form[i].collapsed,
        hide: form[i].hide ? form[i].hide : {},
        show: form[i].show ? form[i].show : {},
        tabId: tabId
      };
      if (form[i].title !== '') {
        //render title Page
        formHtml.title = templates.formPageTitle({
          title: form[i].title,
          name: form[i].name,
          id: form[i].name,
          type: 'page',
          collapsed: form[i].collapsed,
          hintCollapse: pageInfo.pageCollapse,
          hintExpand: pageInfo.pageExpand,
          blockType: '',
          theme: pageInfo.theme,
          reload: false });
      }
      if (!form[i].formItems) {
        continue;
      }
      formItemsLen = form[i].formItems.length;

      formItems = form[i].formItems;
      //foreach for fields
      for (j = 0; j < formItemsLen; j++) {
        formItemLen = formItems[j].length;
        formItem = formItems[j];
        //foreach for elems
        for (k = 0; k < formItemLen; k++) {
          if (formItem[k].skip) {
            continue;
          }
          sourceForm[formItem[k].name] = formItem[k];
          //make form model for watching
          valuesForm[formItem[k].name] = {
            'defValue': formItem[k].value,
            'isChanged': false,
            'value': formItem[k].value,
            'label': formItem[k].label || formItem[k].desc || false
          };
          if (formItem[k].type === 'textarea') {
            if (formItem[k].value === '\n') {
              formItem[k].value = '';
              valuesForm[formItem[k].name].value = '';
              valuesForm[formItem[k].name].defValue = '';
            }
          }
          formRow = {};
          formRow.first = '';
          formRow.second = '';
          formRow.third = '';
          formRow.hint = '';
          formRow.classes = '';
          formRow.hide = formItem[k].hide || {};
          formRow.show = formItem[k].show || {};
          formRow.id = formItem[k].name + '-' + form.id;
          formRow.desc = '';
          formRow.error = formItem[k].error ? formItem[k].error : '';
          formRow.colspan = formItem[k].error ? 'colspan="2"' : '';
          formRow.fname = formItem[k].name;
          formRow.label = formItem[k].label;
          formRow.tabId = form.id;
          formRow.devMode = devMode;
          formRow.testMode = form.testMode;
          formItem[k].id = form.id;
          //render label
          if (formItem[k].label) {
            formRow.first += templates.formItemLabel({
              label: formItem[k].label,
              img: formItem[k].l_img || '',
              required: formItem[k].required,
              tabId: form.id,
              func: form.func,
              id: formItem[k].name,
              devMode: devMode });
          } else if (formItem[k].type !== 'textdata') {
            formRow.first += '<div></div>';
          }
          //render hint
          if (formItem[k].hint !== '' && formItem[k].hint) {
            formRow.third += App.u.escapeQuote(formItem[k].hint);
            if (formItem[k].shadowHint) {
              formRow.third += " <span class='hint-shadow'>" + App.u.escapeQuote(formItem[k].shadowHint) + '</span>';
              formRow.hint += ' shadow ';
            }
            formRow.hint += 'field-help_available_yes';
          }
          if (formItem[k].setvalue) {
            var timeout = parseInt(formItem[k].setvalue, 10),
                timeId;
            if (!isNaN(timeout)) {
              /* jslint loopfunc:true*/
              timeId = setInterval(function (tabId, name) {
                return function () {
                  if (!tabs[tabId]) {
                    clearInterval(timeId);
                  }
                  EventMgr.trigger('forceSetValues', {
                    tabId: tabId, name: name
                  });
                };
              }(tabId, formItem[k].name), timeout * 1000);
            }
          } else if (formItem[k].type === 'textarea') {
            if (formItem[k].quote) {
              formRow.classes += ' b-form-row_with_quote ';
            }
            formItem[k].third = formRow.third;
            formItem[k].error = formRow.error;
          }
          //@todo move to template
          if (formItem[k].desc && formItem[k].desc !== '') {
            formRow.desc = formItem[k].desc || '';
            //check for checkbox desc
            if (formItem[k].type === 'checkbox') {
              if (formItem[k].desc !== '') {
                formRow.desc = '';
              }
            }
            formRow.descName = formItem[k].descName || '';
          }
          if (formItem[k].type === 'checkbox' && !formItem[k].desc) {
            formRow.classes += ' row-with-no-desc ';
          }
          formRow.classes += ' l-form__row_type_' + formItem[k].type;
          if (formItem[k].fixed) {
            formRow.classes += ' i-form__row_fixed_yes b-form__row_fixed_yes';
          }
          if (formItem[k].error) {
            formRow.classes += ' row-error';
          }
          //check for hide/show rules
          if (formItem[k].show !== undefined) {
            if (formItem[k].shadow) {
              formRow.classes += ' depended-shadow-s';
            } else {
              formRow.classes += ' depended-hidden-s';
            }
          }
          //render form item
          formRow.second = renderFormItem(formItem[k], tabId, '');
          //render extra field
          if (formItem[k].hasAddition) {
            var nextFormItem = formItem[k + 1];
            if (nextFormItem) {
              if (nextFormItem.type === 'checkbox') {
                if (nextFormItem.desc !== '') {
                  formRow.desc = '';
                }
              } else if (nextFormItem.type === 'text') {
                formRow.id = nextFormItem.name + '-' + form.id;
              }
              nextFormItem.id = form.id;
              formRow.second += renderFormItem(nextFormItem, tabId, '');
              formRow.classes += ' l-form__row_has_addition';
              if (formItem[k].propWidth) {
                formRow.classes += ' l-form__row_propwidth';
              }
              //check for error
              if (nextFormItem.error) {
                formRow.error = nextFormItem.error;
                formRow.classes += ' row-error';
                formRow.colspan = 'colspan="2"';
              }
            }
          }
          //render form row
          //render input@type=hidden row
          if (formItem[k].type === 'hidden') {
            formHtml.content += templates.formItemRowHidden(formRow);
            //render fullwidth row
          } else if (formItem[k].fullwidth) {
            formRow.classes += ' fullwidth-row';
            formHtml.content += templates.formItemFullWidthRow(formRow);
            //render desc row
          } else if (formItem[k].formwidth) {
            formRow.classes += ' formwidth-row';
            formHtml.content += templates.formItemFormWidthRow(formRow);
            //render desc row
          } else if (formItem[k].type === 'desc') {
            formRow.third = '';
            formRow.hint = '';
            formHtml.content += templates.formItemRowDesc(formRow);
            //render row without label
          } else if (formItem[k].type === 'list') {
            formItem[k].id = form.id;
            formItem[k].formflags = form.formflags;
            formItem[k].parent = form.parent;
            formItem[k].testMode = form.testMode;
            //for btn template change type
            formItem[k].type = 'form';
            if (!(formItem[k].rows && formItem[k].rows.length === 1 && formItem[k].view === 'table')) {
              formHtml.content += templates.formListItemRow(formItem[k]);
            }
          } else if (formRow.first === '') {
            formHtml.content += templates.formItemRowWithoutLabel(formRow);
            //render normal row
          } else {
            formHtml.content += templates.formItemRow(formRow);
          }
          if (formItem[k].plainhint) {
            var hLen = formItem[k].plainhint.length;
            //start from 1 because 1st elem empty
            for (var h = 1; h < hLen; h++) {
              formItem[k].plainhint[h].name = formItem[k].name;
              formHtml.content += templates.formPlainHintRow(formItem[k].plainhint[h]);
            }
          }
        }
      }
      formHtml.view = 'form';
      pages += templates.formPageWrapper(formHtml);
    }
    return {
      html: pages,
      model: valuesForm,
      source: sourceForm
    };
  },
      formGetTreeBranch = function formGetTreeBranch(e, data) {
    var setvalues = data.setvalues,
        elem = data.elem,
        name = data.name,
        items = setvalues[name].tlist,
        html = renderTlist(items),
        id = data.id;
    elem.after(html);
    data.img.attr('src', data.src);
    elem.parent().addClass('loaded t-opened').removeClass('collapsed loading');
    EventMgr.trigger('updateScroll', { id: id });
  },

  //render tree
  renderTree = function renderTree(items, tabId) {
    var elems = items.tlist,
        html,
        rows = items.rows * 18,
        id = items.name + '-' + tabId;
    html = renderTlist(elems, items.value);
    return '<div class="tree-wrapper ' + items.setvalue + ' ' + items.multiple + '" id="cont-' + id + '"  style="height:' + rows + 'px;">' + '<div id="' + id + '" class="tree-inner" data-tabid="' + tabId + '">' + html + '<input data-type="tree" type="hidden" name="' + items.name + '" value="' + items.value + '" class="' + items.classes + '"id="' + items.name + '-' + tabId + '-value" data-tabid="' + tabId + '"/></div></div>' + '<div class="b-resizer" data-move-trigger="updateScroll" data-id="cont-' + id + '" data-tabid="' + tabId + '"></div>';
  },

  //render tree list
  renderTlist = function renderTlist(items, value) {
    var len = items.length,
        i,
        html = '',
        child,
        className = '',
        selected;
    html = '<ul>';
    for (i = 0; i < len; i++) {
      child = items[i].child.length > 0;
      className = child ? 't-opened loaded' : items[i].collapsed ? 'collapsed' : '';
      className += len - 1 === i ? ' last ' : '';
      selected = items[i].key === value ? ' selected ' : '';
      html += ' <li class="' + className + ' folder"> <div class="tree-hitarea bline"></div> <div class="tree-handler ' + selected + '"  data-val="' + items[i].key + '" ><div class="bline icon"><img src="' + pageInfo.commonDir + 'img/' + items[i].img + '.png" /></div><div class="tree-label bline">' + items[i].value + '</div></div>';
      if (child) {
        html += renderTlist(items[i].child, value);
      }
      html += '</li>';
    }
    html += '</ul>';
    return html;
  },
      renderInfoList = function renderInfoList(obj) {
    return templates.infoList({ rows: obj.rows, testMode: obj.testMode });
  },


  //render dashboard blocks
  renderDashboard = function renderDashboard(blocks) {
    var bLength = blocks.length,
        top = '',
        left = '',
        right = '',
        dashboard = '',
        contentBlock,
        title,
        param,
        classes,
        display,
        blockId,
        id,
        titleObject,
        contentObject,
        obj;
    storage.dashboard = {};
    for (var i = 0; i < bLength; i++) {
      blocks[i].name = String(blocks[i].name).replace(/\./g, '_');
      id = blocks[i].name;
      blockId = blocks[i].name;

      titleObject = {
        name: blocks[i].name,
        id: id,
        title: blocks[i].title,
        type: 'dashboard-block',
        blockType: blocks[i].type,
        theme: pageInfo.theme,
        collapsed: blocks[i].display === 'min',
        hintCollapse: pageInfo.pageCollapse,
        hintExpand: pageInfo.pageExpand,
        hintReload: blocks[i].hintReload,
        reload: false };
      if (blocks[i].type === 'toolbar') {
        contentBlock = templates.dashTaskbar({
          toolbar: blocks[i].toolbar });
      } else if (blocks[i].type === 'list') {
        /* jslint camelcase:false */
        param = {
          func: blocks[i].func,
          p_num: 1,
          dashboard: blocks[i].name };
        if (blocks[i].rows) {
          param.p_cnt = blocks[i].rows;
        }
        /* jslint camelcase:true */
        $.extend(param, blocks[i].params);
        storage.dashboard[blocks[i].name] = param;
        if (blocks[i].autoupdate) {
          setTimeout(function (block) {
            return function () {
              EventMgr.trigger('refreshDashBlock', { block: block });
            };
          }(blocks[i]), blocks[i].autoupdate * 1000);
        }
        EventMgr.trigger('ajaxRequest', {
          url: pageInfo.url,
          param: param,
          invar: { blockId: 'block-' + blocks[i].name },
          type: 'get',
          outtype: 'json',
          trfunc: 'ajaxResponseForDashboard',
          failfunc: 'failedAjaxResponseForDashboard',
          queue: 'noqueue' });
        contentBlock = '<div id="block-' + blockId + '" class="block-table" data-block-name="' + blocks[i].name + '" data-block-cnt="' + blocks[i].rows + '" data-block-pnum="1' + '" data-block-func="' + blocks[i].func + '">' + '<div class="dashboard-nodata">' + pageInfo.loading + '</div></div>';
        titleObject.reload = true;
      } else if (blocks[i].type === 'report') {
        param = { func: blocks[i].func, dashboard: blocks[i].name };
        $.extend(param, blocks[i].params);
        storage.dashboard[blocks[i].name] = param;
        EventMgr.trigger('ajaxRequest', {
          url: pageInfo.url,
          param: param,
          invar: { blockId: 'block-' + blocks[i].name },
          type: 'get',
          outtype: 'json',
          trfunc: 'ajaxResponseForDashboard',
          failfunc: 'failedAjaxResponseForDashboard',
          queue: 'noqueue' });
        contentBlock = '<div id="block-' + blockId + '" class="block-table" data-block-name="' + blocks[i].name + '" data-block-func="' + blocks[i].func + '" data-block-param="' + App.Common.serializeForAttr(blocks[i].params) + '"><div class="dashboard-nodata">' + pageInfo.loading + '</div></div>';
        titleObject.reload = true;
      } else if (blocks[i].type === 'url') {
        var ifId = 'f-' + blocks[i].name;
        contentBlock = '<div><iframe id="' + ifId + '" width="100%" src="' + blocks[i].url + '"></iframe></div>';
      } else if (blocks[i].type === 'infolist') {
        param = { func: blocks[i].func, dashboard: blocks[i].name };
        storage.dashboard[blocks[i].name] = param;
        if (blocks[i].autoupdate) {
          setTimeout(function (block) {
            return function () {
              EventMgr.trigger('refreshDashBlock', { block: block });
            };
          }(blocks[i]), blocks[i].autoupdate * 1000);
        }
        EventMgr.trigger('ajaxRequest', {
          url: pageInfo.url,
          param: param,
          invar: { blockId: 'block-' + blocks[i].name },
          type: 'get',
          outtype: 'json',
          trfunc: 'ajaxResponseForDashboard',
          failfunc: 'failedAjaxResponseForDashboard',
          queue: 'noqueue' });
        titleObject.reload = true;
        contentBlock = '<div class="" id="block-' + blockId + '" data-block-name="' + blocks[i].name + '"></div>';
      } else if (blocks[i].type === 'isplicense' || blocks[i].type === 'ispupdate') {
        param = { func: blocks[i].func, dashboard: blocks[i].name };
        storage.dashboard[blocks[i].name] = param;
        EventMgr.trigger('ajaxRequest', {
          url: pageInfo.url,
          param: param,
          invar: { blockId: 'block-' + blocks[i].name },
          type: 'get',
          outtype: 'json',
          trfunc: 'ajaxResponseForDashboard',
          failfunc: 'failedAjaxResponseForDashboard',
          queue: 'noqueue' });
        titleObject.reload = true;
        contentBlock = '<div class="" id="block-' + blockId + '" data-block-name="' + blocks[i].name + '"><div class="dashboard-nodata">' + pageInfo.loading + '</div></div>';
      } else {
        EventMgr.trigger('pullMsg', { msg: 'Dashboard type "' + blocks[i].type + '" do not support.' });
        return;
      }
      //check for update
      if (blocks[i].update) {
        EventMgr.trigger('addBlockToUpdate', blocks[i]);
      }
      title = templates.formPageTitle(titleObject);

      classes = blocks[i].display === 'min' ? ' b-form-page_st_collapsed ' : '';
      display = blocks[i].display === 'min' ? 'none' : 'block';

      contentObject = {
        view: 'dblock',
        title: title,
        content: contentBlock,
        classes: classes,
        display: display,
        tabId: blocks[i].name,
        hide: [],
        show: [] };

      if (blocks[i].position === 'top' || blocks[i].position === 'undefined') {
        top += templates.formPageWrapper(contentObject);
      } else if (blocks[i].position === 'left') {
        left += templates.formPageWrapper(contentObject);
      } else if (blocks[i].position === 'right') {
        right += templates.formPageWrapper(contentObject);
      }
      contentBlock = '';
      title = '';
      classes = '';
      display = '';
    }

    obj = {
      top: top,
      left: left,
      right: right,
      id: 'tab0'
    };
    return obj;
  },
      renderDashboardTable = function renderDashboardTable(e, data) {
    var resp = data,
        startTime = resp.startTime || 0,
        extraTime,
        blockId = resp.blockId.replace(/\./g, '_'),
        block,
        bandHTML,
        table,
        pagerList,
        blockHTML,
        bName,
        bCnt,
        bFunc,
        bPnum,
        tblock;
    resp.tabId = blockId;
    block = App.Dom.byId(blockId);
    //remove loading class
    tblock = App.Dom.byId('t' + blockId);
    //calc time end of animation
    extraTime = 1000 - (new Date().getTime() - startTime) % 1000;
    setTimeout(function () {
      if (tblock) {
        tblock.className = tblock.className.replace(/loading/g, '');
      }
    }, extraTime);
    if (block === null) {
      return;
    }
    if (resp.type === 'report') {
      bandHTML = renderBandDash(resp.bands, blockId);
      block.innerHTML = bandHTML;
      setTimeout(function () {
        EventMgr.trigger('loadGCharts', { bands: resp, tabId: blockId });
      }, 10);
    } else if (resp.type === 'infolist') {
      blockHTML = renderInfoList({ rows: resp.rows, testMode: resp.testMode });
      block.innerHTML = blockHTML;
    } else if (resp.type === 'isplicense') {
      blockHTML = renderLicenseBlock(resp.isplicense_data);
      block.innerHTML = blockHTML;
    } else if (resp.type === 'ispupdate') {
      blockHTML = renderUpdateBlock(resp.ispupdate_data);
      block.innerHTML = blockHTML;
    } else {
      table = '';
      pagerList = '';
      if (resp.error) {
        table = resp.ermsg;
      } else {
        table = renderTable(resp);
        if (resp.pager.pager === 'true') {
          pagerList = buildPagerList(resp.pager.pageCount, resp.pager.pageNum);
        }
      }

      blockHTML = '<div id="' + blockId + '-scrollwrapper">' + table + '</div><div class="pager_list pager-list_type_dashboard">' + pagerList + '</div>';
      bName = block.getAttribute('data-block-name');
      bCnt = block.getAttribute('data-block-cnt');
      bFunc = block.getAttribute('data-block-func');
      bPnum = block.getAttribute('data-block-pnum');

      block = App.Common.replaceHtml(block, blockHTML);
      block.setAttribute('data-block-pnum', resp.pager ? resp.pager.pageNum : 1);
      block.setAttribute('data-block-name', bName);
      block.setAttribute('data-block-cnt', bCnt);
      block.setAttribute('data-block-func', bFunc);
      block.setAttribute('data-block-pnum', bPnum);
      if (!resp.error) {
        EventMgr.trigger('appendDashList', { tabId: blockId });
      }
    }
    setTimeout(function () {
      EventMgr.trigger('updateScroll', { id: 'cont-tab0' });
    }, 300);
    setTimeout(function () {
      EventMgr.trigger('updateScroll', { id: 'cont-tab0' });
    }, 7000);
    block = null;
  },

  //render bands for
  renderBandDash = function renderBandDash(bands, id) {
    var bandLen = bands.length - 1,
        output = '',
        i,
        gid,
        title,
        titleClass,
        fullwidth;
    if (bandLen > 0) {
      for (i = 0; i < bandLen; i++) {
        gid = id + '-' + i + bands[i].id + '0';
        title = '';
        titleClass = '';
        fullwidth = bands[i].fullwidth ? 'fullwidth-band' : '';
        if (bands[i].bigTitle !== '') {
          title = bands[i].bigTitle || '';
          titleClass = 'big-title';
        } else if (bands[i].smallTitle !== '') {
          title = bands[i].smallTitle || '';
          titleClass = 'small-title';
        }
        output += templates.reportBandDash({
          empty: bands[i].empty,
          emptymsg: pageInfo.emptyreport,
          title: title,
          titleClass: titleClass,
          id: id,
          gid: gid,
          fullwidth: fullwidth });
      }
    } else {
      output = '<div class="dashboard-nodata">' + pageInfo.nodata + '</div>';
    }
    return output;
  },

  // render license block on dashboard
  renderLicenseBlock = function renderLicenseBlock(data) {
    return templates.licenseDashBlock(data);
  },

  // render update to isp6 block on dashboard
  renderUpdateBlock = function renderUpdateBlock(data) {
    return templates.updateToIsp6(data);
  },

  //render tables in reports
  renderBands = function renderBands(reports, tabId) {
    //if no data return fake chart
    if (reports.emptyBand) {
      if (reports.hasDiagram) {
        return templates.emptyBandOverlay({
          emptymsg: pageInfo.emptyreport, tabId: tabId });
      } else {
        return '<div class="report-nodata">' + pageInfo.nodata + '</div>';
      }
    }
    var bandsContent = '',
        bands = reports.bands,
        len = bands.length - 1,
        id = null,
        fullwidth,
        i;
    //go for bands
    for (i = 0; i < len; i++) {
      id = tabId + '-' + i;
      if (bands[i].content.length === 0) {
        if (bands[i - 1] && bands[i - 1].title) {
          bandsContent += '<div class="b-report-nodata">' + pageInfo.nodata + '</div>';
        }
        continue;
      }

      //check for band like title
      if (bands[i].title !== undefined) {
        fullwidth = bands[i].fullwidth ? 'fullwidth-band' : '';
        bandsContent += '<div class="band-content b-title ' + fullwidth + '"><div class="band-title big-title">' + bands[i].title + '</div></div>';
      } else {
        $.extend(bands[i], {
          elKey: bands[i].headers[0].name,
          pager: { pageElems: 0 },
          tabId: id, oTabId: tabId });
        bands[i].func = reports.func;
        var table = '<div>' + renderTable(bands[i]),
            gid = id + bands[i].id,
            aid = tabId + '-' + bands[i].id,
            title = '',
            titleClass = '',
            hidden = bands[i].hidden ? 'data-table-hidden' : '',
            showMsg = bands[i].showMsg,
            hideMsg = bands[i].hideMsg,
            hiddenClass = bands[i].hidden ? 'hidden' : '',
            diagrmCount = bands[i].diagram.length;
        fullwidth = bands[i].fullwidth ? 'fullwidth-band' : '';
        if (diagrmCount === 0) {
          fullwidth += ' nodiagram';
        }
        if (bands[i].smallTitle !== '') {
          title = bands[i].smallTitle;
          titleClass = 'small-title';
        }
        bandsContent += templates.reportBand({
          title: title || '',
          titleClass: titleClass,
          table: table,
          id: id,
          aid: aid,
          gid: gid,
          fullwidth: fullwidth,
          hidden: hidden,
          showMsg: showMsg,
          hideMsg: hideMsg,
          hiddenClass: hiddenClass,
          dc: diagrmCount });
        bandsContent += createTableRow(bands[i].headers, id);
      } // EventMgr.trigger('loadChart', {diagram :
      // bands[i].diagram, gid : gid});
    }
    return bandsContent;
  },

  //render table with one row for sum in table reports
  createTableRow = function createTableRow(headers, id) {
    var table = '<table id="table_sum-' + id + '"><tr>';
    for (var i = 0; i < headers; i++) {
      table += '<td>' + '<span class="data-sum" id="' + headers[i].name + '"></span>' + '</td>';
    }
    table += '</tr></table>';
    return table;
  },

  //data for reload page
  reloadTabData = function reloadTabData(e, data) {
    var tabId = data.tabId,
        resetFilterOn = data.resetFilterOn,
        url = pageInfo.url,
        iType = data.softUpdate ? 'softUpdate' : 'hardUpdate',
        filter = data.filter || false,
        param,
        scrollTop = 0,

    //stay help chain
    help = data.help,
        selid = data.selid || true;
    if (data.reload) {
      if (!checkReload(data)) {
        return;
      }
    }
    if (tabs[tabId] === undefined) {
      return;
    }
    var defParams = tabs[tabId].paramObjAll,
        parent = tabs[tabId].parent,
        newUrl = data.newurl ? true : false;
    if (data.param) {
      param = data.param;
      //check for pager
      /* jslint camelcase:false */
      if (param.p_num !== defParams.p_num) {
        selid = false;
      }
      /* jslint camelcase:true */
      /* jslint camelcase:false */
      if (param.p_num) {
        delete defParams.p_num;
      }
      /* jslint camelcase:true */
    } else {
      param = data.addedParam || {};
      if (tabs[tabId].param.match('p_num')) {
        param = App.Common.parseParams(tabs[tabId].param);
      }
    }
    defParams = $.extend(defParams, param);

    if (newUrl) {
      url = pageInfo.url;
    }
    //if has selected elems remember it
    if (selid) {
      scrollTop = getScrollTop(tabId);
      if (selid === true) {
        selid = getSelectedElems(tabId);
      }
    }
    //save filter value
    if (filter) {
      var filterBox = App.Dom.byId(tabId + '-search');
      if (filterBox) {
        filter = filterBox.value;
      } else {
        filter = false;
      }
    }

    //reset filter on when update from menu
    if (resetFilterOn) {
      delete defParams.filter;
    }

    //if request from filter drop, remove filter=on param from list
    if (data.__src === 'filterset' || data.__src === 'buildTabOk') {
      delete defParams.filter;
    }
    EventMgr.trigger('ajaxRequest', {
      url: url,
      param: defParams,
      invar: {
        dataSaved: true,
        parent: parent,
        targetTabId: tabId,
        selid: selid,
        scrollTop: scrollTop,
        iType: iType,
        __src: 'reloadTab',
        help: help ? tabs[tabId].help : false,
        liveFilter: filter },
      type: 'get',
      outtype: 'json',
      trfunc: 'ajaxResponse',
      queue: 'reloadTab' + tabId,
      failfunc: 'failCommonAjaxResponse' });
    if (iType !== 'softUpdate') {
      EventMgr.trigger('tabLoading', { tabId: tabId });
    }
  },


  //handler for submit form
  formHandler = function formHandler(e, data) {
    var tabId = data.tabId,
        selid = data.elid ? [data.elid] : true,
        parent = '',
        granny = '';
    //check for modal
    if (!tabs[tabId] && tabId === 'modal1') {
      EventMgr.trigger('formInspectorResponse', data);
    }
    //progressok for wizard form
    if (data.ok || data.progressok) {
      //check for notifyUp
      if (data.notifyUp) {
        EventMgr.trigger('forceCheckNotify');
      }
      //check for late update
      if (data.progresstype === 'wait') {
        EventMgr.trigger('progressBarSaveState', data);
        return false;
      }
      //check for banners
      if (data.message && data.message.length) {
        App.Global.bannerHtml = data.message;
        App.Global.warning = data.warning;
        App.Global.targetId = '';
      }
      if (tabs[tabId] && tabs[tabId].parent) {
        parent = tabs[tabId].parent;
      }

      if (!checkReload(data) || !checkNewWin(data) || !checkFeatures(data) || !checkDasboard(data)) {
        closeTab(e, tabId);
        return false;
      }

      if (!checkNewForm(data) || !checkNewList(data)) {
        //            closeTab(e, tabId);
        return false;
      }
      App.Common.checkRefreshMenu(data);

      if (data.bootTime) {
        EventMgr.trigger('startCheckRestart', { bootTime: data.bootTime });
      }
      //if has parent close self and reload parent
      if (tabs[tabId] && tabs[tabId].parent) {
        parent = tabs[tabId].parent;
        granny = tabs[tabs[tabId].parent].parent;
        closeTab(e, tabId);
        EventMgr.trigger('reloadTab', { tabId: parent, selid: selid, filter: true });
        EventMgr.trigger('tabLoading', { parent: granny });
      } else {
        closeTab(e, tabId);
      }
    } else if (data.error && !data.form) {
      showErrorOnForm(data);
    } else {
      EventMgr.trigger('ajaxResponse', data);
    }
  },
      showErrorOnForm = function showErrorOnForm(data) {
    if (data.error && data.targetTabId) {
      var ermsg = templates.banner({ message: {
          status: 'error',
          classes: '',
          id: data.targetTabId,
          text: App.Common.wordWrap(data.ermsg, 100),
          ref: false,
          refText: pageInfo.moreinfo,
          dismiss: data.msg.dismiss
        } });
      $('#cont-' + data.targetTabId).find('.error-message').html(ermsg);
      EventMgr.trigger('tabLoadingHide', { tabId: data.targetTabId });
      resetToDefaultFormButton(data.targetTabId);
      EventMgr.trigger('updateScroll', { id: 'form-scroll-' + data.targetTabId });
    }
  },


  //BuildPager
  buildPager = function buildPager(pager, tabId) {
    var slist = templates.formItemSelect({
      name: 'pager-slist',
      slist: pager.pageSlist,
      value: pager.pageNum,
      msg: pager.pageSlist[pager.pageNum - 1].value,
      depend: pager.depend,
      dependMaster: pager.dependMaster,
      dependFields: '',
      hide: '',
      show: '',
      readonly: '',
      setvalue: '',
      id: tabId,
      attrInput: '' }),
        pagerList = buildPagerList(pager.pageCount, pager.pageNum),
        pageCnt = pager.pageCnt,
        msgBegan = pager.msgPagershow,
        msgEnd = pager.msgPagerline,
        pagerHTML = templates.listPager({
      slist: slist,
      cnt: pageCnt,
      pagerList: pagerList,
      msgBegan: msgBegan,
      msgEnd: msgEnd });
    return pagerHTML;
  },

  //build list pager
  buildPagerList = function buildPagerList(pages, current) {
    var html = '',
        maxLen = 9,
        active = '',

    // length environment
    rl = Math.round((maxLen - 5) / 2);
    if (!current) {
      current = 1;
    }
    current = parseInt(current, 10);

    var standartPager = function standartPager(pages, current) {
      var html = '';
      for (var i = 1; i <= pages; i++) {
        if (i === current - 0) {
          active = 'pager-list__item_active';
        } else {
          active = 'pager-list__item_act';
        }
        html += '<span class="page pager-list__item ' + active + '" data-n="' + i + '">' + i + '</span>';
      }
      return html;
    },
        firstPageActive = function firstPageActive(maxLen, pages, current) {
      var html = '',
          prevLast = maxLen - 1;
      for (var i = 1; i <= maxLen; i++) {
        if (i === current - 0) {
          active = 'pager-list__item_active';
        } else {
          active = 'pager-list__item_act';
        }
        if (i === prevLast) {
          html += '<span class="page ellipsis">...</span>';
        } else if (i === maxLen) {
          html += '<span class="page pager-list__item ' + active + '" data-n="' + pages + '">' + pages + '</span>';
        } else {
          html += '<span class="page pager-list__item ' + active + '" data-n="' + i + '">' + i + '</span>';
        }
      }
      return html;
    },
        lastPageActive = function lastPageActive(maxLen, pages, current) {
      var html = '',
          first = pages - maxLen;
      for (var i = 1; i <= maxLen; i++) {
        if (i + first === current - 0) {
          active = 'pager-list__item_active';
        } else {
          active = 'pager-list__item_act';
        }
        if (i === 2) {
          html += '<span class="page ellipsis"> ... </span>';
        } else if (i === 1) {
          html += '<span class="page pager-list__item ' + active + '" data-n="1">1</span>';
        } else {
          html += '<span class="page pager-list__item ' + active + '" data-n="' + (i + first) + '">' + (i + first) + '</span>';
        }
      }
      return html;
    },
        middlePageActive = function middlePageActive(maxLen, pages, current, rl) {
      var html = '',
          first = current - rl - 3,
          prevLast = maxLen - 1;
      for (var i = 1; i <= maxLen; i++) {
        if (i + first === current) {
          active = 'pager-list__item_active';
        } else {
          active = '';
        }
        if (i === 1) {
          html += '<span class="page pager-list__item pager-list__item_act' + active + '" data-n="1">1</span>';
        } else if (i === 2 || i === prevLast) {
          html += '<span class="page ellipsis">...</span>';
        } else if (i === maxLen) {
          html += '<span class="page pager-list__item pager-list__item_act ' + active + '"  data-n="' + pages + '">' + pages + '</span>';
        } else {
          html += '<span class="page pager-list__item pager-list__item_act ' + active + '" data-n="' + (i + first) + '">' + (i + first) + '</span>';
        }
      }
      return html;
    };

    if (pages <= maxLen) {
      // console.log("case: standart");
      html = standartPager(pages, current);
    } else if (pages >= maxLen && current - rl <= 1) {
      // console.log("case: first");
      html = firstPageActive(maxLen, pages, current);
    } else if (pages >= maxLen && current + rl >= pages) {
      // console.log("case: last");
      html = lastPageActive(maxLen, pages, current);
    } else if (pages >= maxLen && (current - rl >= 1 || current + rl <= pages)) {
      // console.log("case: middle");
      html = middlePageActive(maxLen, pages, current, rl);
    }

    return html;
  },
      addChartToTab = function addChartToTab(e, data) {
    var tabId = data.tabId,
        chart = data.chart;
    if (tabs[tabId] !== undefined) {
      tabs[tabId].chart = tabs[tabId].chart || [];
      tabs[tabId].chart.push(chart);
    }
  },
      getActiveHint = function getActiveHint(e, data) {
    var tabId = data.tabId,
        elid = data.elid,
        pName = data.pName,
        value = data.value,
        url = pageInfo.url,
        self = data.self,
        params;
    if (tabs[tabId] === undefined) {
      return;
    }
    params = App.Common.clone(tabs[tabId].paramObjAll);
    /* jslint camelcase:false */
    params.hint_field = pName;
    /* jslint camelcase:true */
    params.plid = params.elid;
    params.elid = elid;
    if (value) {
      params.value = value;
    }

    EventMgr.trigger('ajaxRequest', {
      url: url,
      param: params,
      invar: {
        hintTabId: tabId,
        hintElid: elid,
        hintValue: value,
        hintPName: pName,
        self: self },
      type: 'get',
      outtype: 'json',
      trfunc: 'ajaxResponseHint',
      queue: 'actHint' + tabId,
      failfunc: 'failCommonAjaxResponse' });
  },

  //hook for change field callbacks
  formFieldChangeHandler = function formFieldChangeHandler(e) {
    var tabId = this.getAttribute('data-tabid');
    //check for input contains in tab
    if (tabs[tabId]) {
      EventMgr.trigger('formFieldChanged', {
        tabObj: tabs[tabId],
        tabId: tabId,
        field: this });
    }
  },


  //  add formModel to data for setvalues
  addModelToSetvalues = function addModelToSetvalues(data) {
    var tabId = data.tabId;
    if (tabs[tabId]) {
      data.__formModel = tabs[tabId].formModel;
    }
  },
      addListModel = function addListModel(data) {
    if (data.tabId) {
      var tabId = data.tabId.replace('cont-', '');
      if (tabs[tabId] && tabs[tabId].__content && tabs[tabId].__headers) {
        data.__content = tabs[tabId].__content;
        data.__headers = tabs[tabId].__headers;
      }
    }
  },
      updateModelBySetvalues = function updateModelBySetvalues(e, data) {
    var tabId = data.tabId;
    if (tabs[tabId]) {
      tabs[tabId].formModel[data.name] = data.value;
    }
  },
      addTabsModel = function addTabsModel(data) {
    if (data) {
      data.__tabs = tabs;
    }
  },

  //check form changed
  checkFormChange = function checkFormChange(tabId) {
    if (tabs[tabId] && tabs[tabId].formModel) {
      var formModel = tabs[tabId].formModel,
          count = 0,
          labels = '',
          isChanged = false;
      for (var keyVar in formModel) {
        if (formModel[keyVar].isChanged && formModel[keyVar].label) {
          count++;
          labels += formModel[keyVar].label + '<br/>';
          isChanged = true;
        }
      }
      return {
        isChanged: isChanged,
        count: count,
        labels: labels
      };
    } else {
      return {
        isChanged: false,
        count: 0
      };
    }
  },

  //save form page collapsed state to server
  saveFormPageState = function saveFormPageState(e, data) {
    var tabId = data.tabId;
    if (tabs[tabId]) {
      var param = {
        page: data.name,
        action: tabs[tabId].func,
        func: 'collapse',
        collapse: data.collapsed ? 'off' : 'on'
      };
      EventMgr.trigger('ajaxRequest', {
        param: param,
        trfunc: 'DoNothing',
        queue: 'noqueue'
      });
    }
  },
      favoriteToggle = function favoriteToggle(e) {
    e.preventDefault();
    var $self = $(this),
        tabId = $self.closest('.tab-content').attr('data-tabid'),
        favorite,
        options = {
      param: {},
      trfunc: 'favoriteMenuUpdateDone',
      outtype: 'json'
    };
    if (tabs[tabId]) {
      favorite = tabs[tabId].favorite;
      if (favorite) {
        options.param.func = 'usermenu.suspend';
        $self.addClass('b-elem_style_gracescale');
        $self.attr('data-state', 'unfavorite');
      } else {
        options.param.func = 'usermenu.resume';
        $self.removeClass('b-elem_style_gracescale');
        $self.attr('data-state', 'favorite');
      }
      options.param.elid = tabs[tabId].func;
      EventMgr.trigger('ajaxRequest', options);
      tabs[tabId].favorite = !favorite;
    }
  },
      pinToggle = function pinToggle(e) {
    e.preventDefault();
    var $self = $(this),
        tabId = $self.closest('.tab-content').attr('data-tabid'),
        pin,
        $tabLi = $('#switch-' + tabId),
        options = {
      param: {},
      trfunc: 'pinTabDone',
      outtype: 'json'
    };
    if (tabs[tabId]) {
      pin = tabs[tabId].pin;
      if (pin) {
        options.param.func = 'usermenu.unpin';
        //options.param.func = 'usermenu.unpin';
        $self.addClass('b-elem_style_gracescale');
        $self.attr('data-state', 'unpin');
        $tabLi.removeClass('subtab_is_pin');
      } else {
        options.param.func = 'usermenu.pin';
        //options.param.func = 'usermenu.pin';
        $self.removeClass('b-elem_style_gracescale');
        $self.attr('data-state', 'pin');
        $tabLi.addClass('subtab_is_pin');
      }
      options.param.elid = tabs[tabId].func;
      EventMgr.trigger('ajaxRequest', options);
      tabs[tabId].pin = !pin;
      //update localstorage tabs
      EventMgr.trigger('changedTabs', { tabs: tabs });
    }
  },
      changeTabSortIndex = function changeTabSortIndex(e, data) {
    if (data.s && data.t && tabs[data.s] && tabs[data.t]) {
      var sIndex = tabs[data.s].sIndex;
      tabs[data.s].sIndex = tabs[data.t].sIndex;
      tabs[data.t].sIndex = sIndex;
      EventMgr.trigger('changedTabs', { tabs: tabs });
    }
  },

  /**
   * close form & child list/report by ESC key
   * e {object} event object
   * data {object|undefined} event object data
   */
  esckeyHandler = function esckeyHandler(e, data) {
    var $actTab = $('.tab-content_st_active'),
        type = $actTab.attr('data-tab-type'),
        tabId = $actTab.attr('data-tabid');
    if (type === 'list' || type === 'report') {
      $actTab.find('.toolbar-button__item-img.back').trigger('click');
    } else if (type === 'form') {
      $('#switch-' + tabId).find('.i-tab-close').trigger('click');
    }
  };

  return {
    init: init,
    //for dev
    tabs: tabs,
    closeTab: closeTab,
    moneyFormat: moneyFormat
  };
}(window, $, EventMgr, App, templates);
//# sourceMappingURL=App.Tabs.js.map

'use strict';

/**
 *  Showcaseform
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 *  @return {object} api
 */
/*global App:true*/
App.Showcase = function (window, $, EventMgr, App) {
  'use strict';

  var wizardStepSel = '.i-wizard__step-link',
      mainWrapperSel = '#main-wrapper';

  function $formContent() {
    return window.document.getElementById('wr-content');
  }
  //insert form in tab-content box
  function insertShowCaseForm(e, data) {
    var html = data;
    $formContent().innerHTML = html;
    EventMgr.trigger('appendForm', { tabId: 'tab0' });
  }
  //caught event & set type of content
  function preRespActions(e, data) {
    var obj = data;
    //caught fatal error
    if (obj.form) {
      obj.type = 'showcaseForm';
    }
    obj.showcase = true;
    EventMgr.trigger('ajaxResponse', obj);
  }
  //handler for wizard step link
  function defaultActionHandler(e) {
    if (e) {
      e.preventDefault();
    }
    var href = this.getAttribute('href'),
        iType = 'replace',
        param = App.Common.parseParams(href),
        tabId = $(this).parents('.tab-content').attr('data-tabid'),
        formParam = $('#frm-' + tabId).serializeObject();
    if (formParam) {
      delete formParam.func;
      delete formParam.snext;
      delete formParam.sfrom;
      delete formParam.sok;
      $.extend(param, formParam);
    }
    EventMgr.trigger('ajaxRequest', {
      param: param,
      trfunc: 'showcaseFormResp',
      invar: { iType: iType },
      queue: 'noqueue',
      outtype: 'json',
      failfunc: 'failCommonAjaxResponse' });
    EventMgr.trigger('tabLoading', { tabId: tabId });
  }

  function preRequest(e, data) {
    var options = data;
    options.trfunc = 'showcaseFormResp';
    options.invar.showcase = true;
    delete options.invar.targetTabId;
    delete options.param.showcase;
    EventMgr.trigger('ajaxRequest', options);
  }

  function init() {
    EventMgr.bind('readyShowcaseFormHtml', insertShowCaseForm);
    EventMgr.bind('showcaseFormResp', preRespActions);
    EventMgr.on(mainWrapperSel, wizardStepSel, 'click', defaultActionHandler);
    EventMgr.bind('preRequestShowcase', preRequest);
  }

  var api = {
    init: init
  };

  return api;
}(window, $, EventMgr, App);
//# sourceMappingURL=App.Showcase.js.map

'use strict';

/**
 *  ExtFormHelper
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 *  @return {object} api API functions
 */
/*global App:true*/
App.ExtFormHelper = function (window, $, EventMgr, App) {
  'use strict';

  var self = '';
  // отправка формы по клику по кнопке
  var clickedButton = false;

  //convert rules for if/else in default format
  function convertIfRules(value, template) {
    var attrName = String(template).replace('__VALUE__', window.hash(value));
    //    self.removeAttribute('data-init-func');
    self.setAttribute(attrName, 'yes');
  }
  //convert data-handler
  function convertDataHandler(value) {
    //    self.removeAttribute('data-init-func');
    self.setAttribute('data-handler-val', window.hash(String(value)));
  }
  //run init function from attribute
  function initFunc() {
    var elems = $('*[data-init-func]'),
        l = elems.length,
        funcArr;
    while (l--) {
      self = elems[l];
      funcArr = String(self.getAttribute('data-init-func')).split('||');
      var funcLen = funcArr.length;
      for (var i = 0; i < funcLen; i++) {
        var func = funcArr[i].replace(/\s/g, '');
        try {
          /*jslint evil: true */
          eval('App.ExtFormHelper.' + func);
        } catch (e) {
          console.log('undefined function:', func);
        }
      }
      //remove attribute
      self.removeAttribute('data-init-func');
    }

    EventMgr.trigger('appendForm', { tabId: 'tab0' });

    setTimeout(function () {
      setRequiredField();
    }, 0);
  }

  function checkRequired() {
    var ok = true;
    $('#frm-tab0').find('input[required], textarea[required]').each(function () {
      var empty = this.value === '',
          hide = this.offsetWidth === 0;
      if (empty && !hide) {
        ok = false;
        return false;
      }
    });
    return ok;
  }

  function checkConfirm() {
    var field = $('#frm-tab0 input[data-confirm="yes"]'),
        confirmed = true;
    if (field.length > 0) {
      field.each(function () {
        var confirmField = this.getAttribute('data-check-field'),
            value1 = this.value,
            confirmFieldElem = App.Dom.byId(confirmField + '-tab0'),
            confirmFieldElemFake = App.Dom.byId(confirmField + '-' + 'tab0-fake'),
            value2;
        if (confirmFieldElem !== null) {
          value2 = confirmFieldElem.value;
        }
        if (value1 !== value2 && (confirmFieldElem.offsetWidth !== 0 || confirmFieldElemFake.offsetWidth !== 0)) {
          this.focus();
          confirmed = false;
        }
      });
    }
    return confirmed;
  }

  /**
   * Обработчик отправки формы по кнопке
   * @param { object } e объект события
   * @return { boolean } флаг отправки формы
   * @this button
   */
  function submitFormAction(e) {
    var name = this.getAttribute('name'),
        func = this.getAttribute('data-func'),
        isRequiredOk = checkRequired(),
        isPasswdConfirmed = checkConfirm();

    if (func) {
      e.preventDefault();
      window.location = pageInfo.host + pageInfo.binary + '?func=' + func;
    } else if (isRequiredOk && isPasswdConfirmed) {
      $('#i-clicked-button-input').val(name);
      this.value = this.getAttribute('data-disabled');
      this.className += ' b-button_st_disabled';
      clickedButton = true;
      $('#frm-tab0').submit();
      return false;
    } else if (!isPasswdConfirmed) {
      return false;
    }
  }

  /**
   * Обработчик отправки формы по ENTER
   */
  function formSubmitHandler() {
    var name = $('#i-default-button').attr('data-name');
    if (name && !clickedButton) {
      $('#i-clicked-button-input').val(name);
    }
  }

  /**
   *  Убирать у скрытых полей атрибут required, у видимых добавлять
   */
  function setRequiredField() {
    $('#frm-tab0').find('input[data-required], textarea[data-required]').each(function () {
      var hide = this.offsetWidth === 0;
      if (hide) {
        this.removeAttribute('required');
      } else if (!this.hasAttribute('required')) {
        this.setAttribute('required', 'required');
      }
    });
  }

  /**
   * Обработчик изменений полей, которые управляют скрытием других полей
   */
  function changeControlFieldHandler() {
    setTimeout(function () {
      setRequiredField();
    }, 0);
  }

  function init() {
    EventMgr.bind('pageLoad', initFunc);
    EventMgr.obind('.i-button-extform', 'click', submitFormAction);
    EventMgr.obind('#frm-tab0', 'submit', formSubmitHandler);
    EventMgr.obind('.control-field input[type="hidden"], .control-field .b-input, .control-field .b-input_type_file, .control-field .b-textarea', 'change', changeControlFieldHandler);
  }

  var api = {
    init: init,
    convertIfRules: convertIfRules,
    convertDataHandler: convertDataHandler
  };

  return api;
}(window, $, EventMgr, App);
//# sourceMappingURL=App.ExtFormHelper.js.map

'use strict';

/**
 * Progressbar module
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 *  @param {object} templates Templates of App
 */
App.ProgressBar = function (window, $, EventMgr, App, templates) {
  'use strict';

  var CACHE = {};
  // закончившиеся wait прогрессбары, на случай когда прогрессбар пришел раньше респонса формы
  var ENDED_WAIT_PROGRESSBAR = {};
  /**
   * Remove ProgressBar
   * @param {string} tabId
   */
  function removeProgressBar(tabId) {
    var tabCont = App.Dom.byId('cont-' + tabId);
    App.Dom.removeClass(tabCont, 'tab-content__progressbar_show');
    var progressbar = App.Dom.byId('cont-' + tabId + '-progressbar');
    if (progressbar === null) {
      return;
    }
    progressbar.style.display = 'none';
    progressbar.innerHTML = '';
    //show default loader
    var defProgress = App.Dom.byId('cont-' + tabId + '-progressbar-default');
    if (defProgress === null) {
      return false;
    }
    if (defProgress.style.display === 'none') {
      defProgress.style.display = null;
    }
    progressbar = null;
  }

  /**
   * Wait progressbar response after panel restart
   * @param {object} e
   * @param {object} data
   */
  function waitProgressBar(e, data) {
    if (data.progresstype === 'wait' || data.invar && data.invar.progresstype === 'wait') {
      setTimeout(function () {
        EventMgr.trigger('ajaxRequest', {
          param: data.param,
          invar: data.invar,
          type: 'get',
          outtype: 'json',
          trfunc: 'progressBarResponse',
          failfunc: 'progressBarResponseFail',
          queue: 'noqueue' });
      }, 1500);
    }
  }

  /**
   * Render Progressbar HTML
   * @param {object} e
   * @param {object} data
   */
  function renderProgressBar(e, data) {
    var start = data.start,
        progressType = data.progresstype,
        tabId = '',
        tabExist = false,
        progressId = data.param.elid;
    if (start !== '' && start !== undefined) {
      var done = data.done,
          now = data.now,
          steps = data.steps,
          comment = data.comment,
          param = data.param,
          colorClass = '';
      tabId = data.tabId;
      var per = 0,
          left = '';
      if (done !== '' && steps !== '') {
        per = Math.round(done / steps * 100);
      }
      if (done !== '' && steps !== '' && progressType !== 'notime') {
        var elapsedTime = now - start,
            elapsedSteps = steps - done;
        if (elapsedSteps !== 0 && done !== 0) {
          left = Math.round(elapsedTime / done * elapsedSteps) + 'sec';
        }
      }
      var width = per * 0.98;
      if (per < 6) {
        per = '.';
        colorClass = 'blue-color';
      } else {
        if (per > 100) {
          per = 100;
          width = per * 0.98;
        }
        per += '%';
      }
      var html = templates.progressBar({
        tabId: tabId,
        per: per,
        width: width,
        left: '',
        comment: comment,
        colorClass: colorClass });
      tabExist = appendProgressBar(tabId, progressId, html);
      //if exist tab
      if (tabExist) {
        setTimeout(function () {
          EventMgr.trigger('ajaxRequest', {
            param: param,
            invar: { tabId: tabId, param: param, progresstype: progressType },
            type: 'get',
            outtype: 'json',
            trfunc: 'progressBarResponse',
            failfunc: 'progressBarResponseFail',
            queue: 'noqueue' });
          param = null;tabId = null;progressType = null;
        }, 1000);
      }
    } else {
      tabId = data.tabId;
      removeProgressBar(tabId);
      //@todo remove cache
    }
    if (data.ok && progressType === 'wait') {
      if (data.param && data.param.elid) {
        ENDED_WAIT_PROGRESSBAR[data.param.elid] = true;
        if (CACHE[data.param.elid]) {
          CACHE[data.param.elid].progresstype = null;
          if (CACHE[data.param.elid].progressok) {
            CACHE[data.param.elid].__dataSource.rp = ['progressok'];
            CACHE[data.param.elid].__dataSource.rp = ['progressok'];
            EventMgr.trigger('tabLoading', { tabId: data.tabId });
            EventMgr.trigger('ajaxRequest', CACHE[data.param.elid].__dataSource);
          } else {
            EventMgr.trigger('ajaxFormResponse', CACHE[data.param.elid]);
          }
          delete CACHE[data.param.elid];
        }
      }
    }
  }

  /**
   * Append Progressbar to form
   * @param {string} tabId
   * @param {string} html
   * @return {boolean}
   */
  function appendProgressBar(tabId, progressId, html) {
    var progressChecker = App.Dom.byId(progressId),
        tabCont = App.Dom.byId('cont-' + tabId);
    if (!progressChecker) {
      return false;
    }
    App.Dom.addClass(tabCont, 'tab-content__progressbar_show');
    var progressbar = App.Dom.byId('cont-' + tabId + '-progressbar');
    if (progressbar === null) {
      return false;
    }
    progressbar.style.display = 'block';
    progressbar.innerHTML = html;
    progressbar = null;
    var defProgress = App.Dom.byId('cont-' + tabId + '-progressbar-default');
    if (defProgress === null) {
      return false;
    }
    defProgress.style.display = 'none';
    return true;
  }

  function progressBarSaveState(e, data) {
    // если wait прогресс уже пришел с ok
    if (ENDED_WAIT_PROGRESSBAR[data.progressid]) {
      data.progresstype = null;
      EventMgr.trigger('ajaxFormResponse', data);
    } else if (data && data.progressid) {
      CACHE[data.progressid] = data;
    }
  }

  function init() {
    EventMgr.bind('progressBarSaveState', progressBarSaveState);
    EventMgr.bind('progressBarResponse', renderProgressBar);
    EventMgr.bind('progressBarResponseFail', waitProgressBar);
  }

  return {
    init: init
  };
}(window, $, EventMgr, App, templates);
//# sourceMappingURL=App.ProgressBar.js.map

'use strict';

/**
 * Update elements size
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 */
App.UpSize = function (window, $, EventMgr, App) {
  'use strict';

  var init = function init() {
    EventMgr.obind($window, 'resize', getSizes);
    EventMgr.obind($window, 'resize', updateMenuHeight);
    EventMgr.obind($window, 'resize', updateHeightTabContent);
    EventMgr.obind($window, 'resize', updateTableHeight);
    EventMgr.obind($window, 'resize', updFormContent);
    EventMgr.bind('loadPage', getSizes);
    EventMgr.bind('loadPage', updateMenuHeight);
    EventMgr.bind('appended', setStyleTabContent);
    EventMgr.bind('appendList', updateTableHeight);
    EventMgr.bind('appendList', setRowsWidth);
    EventMgr.bind('setRowsWidth', setRowsWidth);
    EventMgr.bind('changedTab', updateDashTable);
    EventMgr.bind('menuPositionChanged', updateDashTable);
    EventMgr.bind('menuPositionChanged', updateTableHeightFunc);
    EventMgr.bind('updTableHeight', updateTableHeight);
    EventMgr.bind('updFormHeight', updFormContent);
    EventMgr.bind('appendForm', updFormContent);
    EventMgr.bind('appendForm, setValuesDone', updateHeightFormListBlocks);
    EventMgr.bind('verticalScroll', updateButtonBar);
  },

  // offset topBar
  top = 0,

  // height work window
  tabHeight = 0,

  //window height
  windowHeight = 0,


  //windowWidth = 0,

  getWindowHeight = function getWindowHeight() {
    windowHeight = $window.height();
    //windowWidth = $window.width();
  },
      calcHeight = function calcHeight() {
    tabHeight = windowHeight - getTopF();
  },

  //offset topBar
  getTopF = function getTopF() {
    if (top === 0 && $menu().length > 0) {
      top = $menu().offset().top;
    }
    return top;
  },
      $menu = function $menu() {
    return App.u.selectorCache('#menu-items-wr');
  },
      $window = function () {
    return $(window);
  }(),

  //calculate height
  getSizes = function getSizes() {
    getWindowHeight();
    calcHeight();
  },
      updateMenuHeight = function updateMenuHeight() {
    $menu().height(tabHeight);
  },

  //@todo add update
  setStyleTabContent = function setStyleTabContent(e, data) {
    var tabId = data.tabId,
        tabCont = App.Dom.byId('cont-' + tabId);
    if (tabCont !== null) {
      tabCont.style.height = tabHeight + 'px';
      if (tabId === 'tab0') {
        tabCont.style.marginTop = '-' + tabHeight + 'px';
      }
    }
    tabCont = null;
  },
      updFormContent = function updFormContent(e, data) {
    setTimeout(function () {
      var formHeight = windowHeight - getTopF(),
          tabId,
          formWrapper,
          topForm,
          availableHeight;
      if (data) {
        tabId = data.tabId;
      } else {
        var tabAct = $('.tab-content_st_active');
        if (tabAct.attr('data-tab-type') === 'form') {
          tabId = tabAct.attr('data-tabid');
        } else {
          return;
        }
      }
      formWrapper = $('#incont-' + tabId + ' .topWrapper');
      if (formWrapper.length > 0) {
        //set height for formwrapper
        $('.tab-content').height(formHeight);
        var formScrollCont = $('#form-scroll-' + tabId);
        topForm = formWrapper[0].offsetHeight;
        availableHeight = tabHeight - topForm;
        var allFormHeight = formScrollCont[0].scrollHeight;
        if (tabId === 'modal1') {
          formScrollCont.height('auto');
          var innerFormHeigth = formScrollCont.height();
          formScrollCont.height(innerFormHeigth + 'px');
          if (allFormHeight < availableHeight) {
            $('#cont-modal1').height('auto');
          }
        } else {
          //set height for form inner
          formScrollCont.height(availableHeight);
          EventMgr.trigger('updateScroll', { id: 'form-scroll-' + tabId });
          //fixed or not buttons
          if (allFormHeight > availableHeight) {
            $('#incont-' + tabId + ' .i-buttons_form-type_form').addClass('l-buttons_pos_fixed');
            $('#form-scroll-in-' + tabId).addClass('l-form__inner_fly_buttons');
          } else {
            $('#incont-' + tabId + ' .i-buttons_form-type_form').removeClass('l-buttons_pos_fixed');
            $('#form-scroll-in-' + tabId).removeClass('l-form__inner_fly_buttons');
          }
        }
      }
    }, 0);
  },
      updateHeightTabContent = function updateHeightTabContent() {
    $('#cont-tab0').css('marginTop', '-' + tabHeight + 'px').height(tabHeight);
    $('.tab-content').height(tabHeight);
  },
      updateTableHeight = function updateTableHeight() {
    // setTimeout('APP.upSize.updth()', '100');
    setTimeout(function () {
      updateTableHeightFunc();
    }, '100');
  },
      updateTableHeightFunc = function updateTableHeightFunc() {
    var self, tabId, statusBarHeight, topTable, availableHeight;
    $('.tab-content_st_active .content').each(function () {
      tabId = this.getAttribute('data-tabid');
      self = $(this);
      //height table
      statusBarHeight = '27';
      // offset top table
      topTable = this.offsetTop;
      // availible height for table
      availableHeight = tabHeight - topTable - statusBarHeight;
      // new table height
      self.height(availableHeight);
      updateWidthTableHead(tabId);
      EventMgr.trigger('updateScroll', { id: 'ltwr-' + tabId });
    });
    EventMgr.trigger('updatedTableHeight', { tabId: tabId });
  },

  //set row width for sorting table
  setRowsWidth = function setRowsWidth(e, data) {
    var id = data.tabId,
        table = App.Dom.byId('sort_table-' + id),
        tabElem = $('#cont-' + id),
        sBarCells;
    if (!table) {
      return;
    }

    var tableWidth = table.offsetWidth,
        cellsSort = table.rows['0'].cells,
        statusBar = App.Dom.byId('statusbar-' + id);
    if (statusBar !== null) {
      sBarCells = statusBar.rows['0'].cells;
    }
    if (tableWidth === 0) {
      return null;
    }
    var parentTable = App.Dom.byId('lt-' + id);
    if (parentTable === null) {
      return;
    }
    var cellsParent = parentTable.rows['0'].cells,
        len = cellsSort.length,
        lenTmp = len,
        width,
        per,
        autoSize = false,
        colWithoutWidth = 0,
        widthPer,
        widths = [],
        widthsPer = [],
        sumWidthPer = 0,
        sumWidth = 0,
        halfSumWidth,
        otherWidths = 0;

    tabElem.addClass('table-manip');
    //get all width
    while (lenTmp--) {
      widths[lenTmp] = cellsParent[lenTmp].clientWidth;
      widthPer = parseInt(cellsSort[lenTmp].getAttribute('width'), 10);
      if (isNaN(widthPer)) {
        colWithoutWidth++;
      } else {
        widthsPer[lenTmp] = widthPer;
      }
      sumWidth += widths[lenTmp];
      sumWidthPer += widthsPer[lenTmp];
    }
    if (colWithoutWidth || sumWidthPer < 90 && sumWidthPer > 110) {
      autoSize = true;
    }
    //check for more 50% width
    halfSumWidth = sumWidth / 2;
    lenTmp = len;
    while (lenTmp--) {
      if (widths[lenTmp] > halfSumWidth) {
        for (var i = 0; i < len; i++) {
          if (i !== lenTmp) {
            otherWidths += widths[i];
          }
        }
        widths[lenTmp] = otherWidths;
        sumWidth = otherWidths * 2;
        break;
      }
    }
    //set width in percent
    while (len--) {
      width = widths[len];
      if (autoSize) {
        per = Math.round(width / sumWidth * 100) + '%';
      } else {
        per = widthsPer[len] + '%';
      }
      cellsSort[len].style.width = per;
      cellsParent[len].style.width = per;
      try {
        sBarCells[len].style.width = per;
      } catch (ex) {}
    }
    parentTable.style.tableLayout = 'fixed';
    table.style.tableLayout = 'fixed';
    setTimeout(function () {
      tabElem.removeClass('table-manip');
      tabElem.removeClass('init');
    }, 100);
  },
      updateWidthTableHead = function updateWidthTableHead(tabId) {
    var parentTable = App.Dom.byId('lt-' + tabId),
        sortTable = App.Dom.byId('sort_table-' + tabId),
        statusTable = App.Dom.byId('statusbar-' + tabId),
        width;
    if (parentTable !== null) {
      width = parentTable.offsetWidth + 'px';
      if (sortTable !== null) {
        sortTable.style.width = width;
      }
      if (statusTable !== null) {
        statusTable.style.width = width;
      }
    }
    parentTable = null;
    sortTable = null;
    statusTable = null;
  },
      updateDashTable = function updateDashTable(e, data) {
    var tabId = data.tabId;
    if (tabId === 'tab0') {
      EventMgr.trigger('updateScroll', {});
    }
  },

  /**
   * Set height for all blocks in form list block
   * @param {object} e
   * @param {object} data
   */
  updateHeightFormListBlocks = function updateHeightFormListBlocks(e, data) {
    var tabId = data.tabId,
        selector = '.' + tabId + '-list .b-form-blocks__block',
        maxHeight = 0,
        curHeight,
        $elems = $(selector);
    if ($elems.length > 0) {
      $elems.each(function () {
        curHeight = this.offsetHeight;
        if (curHeight > maxHeight) {
          maxHeight = curHeight;
        }
      });
      $elems.each(function () {
        this.style.height = maxHeight + 'px';
        App.Dom.addClass(this, 'b-form-block__block_set_height');
      });
    }
  },

  /**
   * update class for buttons wrapper
   * @param {object} e
   */
  updateButtonBar = function updateButtonBar(e) {
    var data, $btnWrapper;
    if (e.originalEvent && e.originalEvent.detail) {
      data = e.originalEvent.detail;
      //check for is it form scroll
      if (data.id && data.id.match('form-scroll')) {
        $btnWrapper = $('#' + data.id + ' .l-buttons_pos_fixed');
        if ($btnWrapper.length > 0) {
          //check for scroll state top/middle/bottom
          if (data.bottom) {
            if (!$btnWrapper.hasClass('l-buttons_pos_bottom')) {
              $btnWrapper.addClass('l-buttons_pos_bottom');
            }
          } else {
            if ($btnWrapper.hasClass('l-buttons_pos_bottom')) {
              $btnWrapper.removeClass('l-buttons_pos_bottom');
            }
          }
        }
      }
    }
  };
  return {
    init: init,
    updth: updateTableHeightFunc
  };
}(window, $, EventMgr, App);
//# sourceMappingURL=App.UpSize.js.map

'use strict';

/**
 * App.InputMask wrapper for http://jasny.github.io/bootstrap/javascript/#inputmask
 *
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 */
App.InputMask = function (window, $, EventMgr, App) {
  'use strict';

  function bindInputMask(e, data) {
    var tabId = data.tabId;
    $('#frm-' + tabId).find('.i-input-mask').each(function () {
      var mask = this.getAttribute('data-mask');
      if (mask) {
        $(this).inputmask({
          mask: mask,
          showMaskOnHover: false
        });
      }
    });
  }

  function changeMask(e, data) {
    var value;
    if (data.elem && data.mask !== undefined) {
      if (data.mask === '') {
        //save value
        value = data.elem.value;
        $(data.elem).inputmask('remove');
        data.elem.value = value;
      } else {
        value = data.value;
        data.elem.setAttribute('data-mask', data.mask);
        $(data.elem).inputmask({
          mask: data.mask,
          showMaskOnHover: false
        });
        data.elem.value = value;
      }
    }
  }

  function init() {
    EventMgr.bind('appendForm', bindInputMask);
    EventMgr.bind('inputMaskChangeBySetvalues', changeMask);
  }
  return {
    init: init
  };
}(window, $, EventMgr, App, doT);
//# sourceMappingURL=App.InputMask.js.map

'use strict';

/**
 * Calendar module
 *
 * show calendar
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} em EventMgr library
 */
App.Calendar = function (window, $, em) {
  'use strict';

  function init() {
    loadMessages();
  }

  function addListeners() {
    em.on($calCont(), toolsSelector, 'click', toolMouseupRep);
    em.on($calCont(), calMonthSel, 'click', chooseMonthHandler);
    em.on($calCont(), daysSelector, 'click', daysMousedownRep);
    em.on($calCont(), calMonthSelector, 'mousedown', toolMousedownRep);
    em.on($calCont(), calYearSelector, 'mousedown', toolMousedownRep);
    em.on($calMonthCombo(), calComboboxSelector, 'mouseup', comboMouseupRep);
    em.on($calYearCombo(), calComboboxSelector, 'mouseup', comboMouseupRep);
    em.on($calYearCombo(), calComboboxSelector, 'mouseover', comboMouseover);
    em.on($calYearCombo(), calComboboxSelector, 'mouseout', comboMouseout);
    em.on($calMonthCombo(), calComboboxSelector, 'mouseover', comboMouseover);
    em.on($calMonthCombo(), calComboboxSelector, 'mouseout', comboMouseout);
    addedListener = true;
  }

  var addedListener = false,
      isIe = /msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent),
      clActive = false,
      clCalendar = null,
      clCalendarCell = null,
      clField = null,
      clDate = null,
      clTimeout = null,
      clTtool = null,
      clElYears = null,
      clElMonths = null,
      clElHead = null,
      clElDays = null,
      clElDaysTbody = null,
      clSyncField = null,
      clMsgMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
      clMsgSmonths = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
      clMsgWdays = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
      calMonthSelector = '#calmonth',
      calYearSelector = '#calyear',
      toolsSelector = '.cl-tool-td',
      daysSelector = 'td.cl-days',
      calComboboxSelector = ' div',
      calMonthSel = '.b-cal__month',
      pageInfo = window.pageInfo;

  function loadMessages() {
    var i;
    for (i = 0; i < 12; i++) {
      clMsgMonths[i] = pageInfo.calendar['m' + i];
      clMsgSmonths[i] = pageInfo.calendar['ms' + i];
    }
    for (i = 0; i < 7; i++) {
      clMsgWdays[i] = pageInfo.calendar['w' + i];
    }
  }

  function $calCont() {
    return $('#calendar');
  }

  function $calMonthCombo() {
    return $('#calendar-m');
  }

  function $calYearCombo() {
    return $('#calendar-y');
  }

  function getHtmlNodes() {
    if (!clCalendar) {
      clCalendar = document.getElementById('calendar');
      if (!clCalendar) {
        clCalendar = document.createElement('div');
        clCalendar.setAttribute('class', 'cl');
        clCalendar.setAttribute('id', 'calendar');
        clCalendarCell = document.createElement('div');
        clCalendarCell.setAttribute('class', 'cl-cell');
        clCalendarCell.setAttribute('id', 'calendar-cell');
        clCalendar.appendChild(clCalendarCell);
        document.body.appendChild(clCalendar);
      }
    }
    if (!clCalendarCell) {
      clCalendarCell = document.getElementById('calendar-cell');
    }
    if (!clElYears) {
      clElYears = document.getElementById('calendar-y');
      if (!clElYears) {
        clElYears = document.createElement('div');
        clElYears.setAttribute('id', 'calendar-y');
        clElYears.setAttribute('class', 'cl-ym-y');
        document.body.appendChild(clElYears);
      }
    }
    if (!clElMonths) {
      clElMonths = document.getElementById('calendar-m');
      if (!clElMonths) {
        clElMonths = document.createElement('div');
        clElMonths.setAttribute('id', 'calendar-m');
        clElMonths.setAttribute('class', 'cl-ym-m');
        document.body.appendChild(clElMonths);
      }
    }
    if (!addedListener) {
      addListeners();
    }
  }

  function setPosition(e) {
    // Set position
    // Get object which fire even
    var obj = e.target ? e.target : e.srcElement,
        ipos = $(obj).offset(),
        windowWidth = window.innerWidth,
        windowHeight = window.innerHeight,
        cWidth = clCalendar.offsetWidth,
        cHeight = clCalendar.offsetHeight,
        x = ipos.left - cWidth + obj.offsetWidth,
        y = ipos.top + obj.offsetHeight - 1,
        diffY = windowHeight - (y + cHeight),
        diffX = windowWidth - (x + cWidth);
    if (diffX < 0) {
      x = windowWidth - cWidth;
    }
    if (diffY < 0) {
      y = ipos.top - cHeight;
    }
    if (isIe) {
      x += 1;
    }
    clCalendar.style.left = x + 'px';
    clCalendar.style.top = y + 'px';
    clCalendar.style.visibility = 'visible';
    clActive = true;
  }

  var calTempl = '<div class="b-cal">' + '<div class="b-cal__head cl-head">' + '<div class="cl-tool-td" id="prevY"><div class="t-inner"></div></div>' + '<div class="cl-tool-td" id="calyear">{{=it.cYear}}</div>' + '<div class="cl-tool-td" id="nextY"><div class="t-inner"></div></div>' + '<div class="cl-tool-td b-cal__today" id="curMonth"></div>' + '</div>' + '<div class="cl-days-wrapper b-cal__month-wrapper">' + '{{~it.months :value :index}}' + '<div class="b-cal__month ' + '{{?index === it.month}}b-cal__month_selected{{?}}"' + ' data-value="{{=index}}">' + '{{=value}}' + '</div>' + '{{~}}' + '</div>' + '</div>',
      calTemplFunc = window.doT.template(calTempl);

  /**
   * show Month calendar
   * @param {object} field current field HTML node
   * @param {object} syncField HTML node
   * @param {object} e event object
   */
  function showMonthCal(field, syncField, e) {

    getHtmlNodes();

    buildComboBox();

    document.onmousedown = checkOutclick;

    clField = field;
    clSyncField = syncField;
    clDate = parseDate(field.value, true);

    var html = calTemplFunc({
      cYear: clDate.getFullYear(),
      months: clMsgMonths,
      month: clDate.getMonth()
    });

    clCalendar.setAttribute('data-type', 'month');

    clCalendarCell.innerHTML = html;

    setPosition(e);
  }

  function chooseMonthHandler(e) {
    e.preventDefault();
    if (!this) {
      return;
    }
    var month = this.getAttribute('data-value'),
        year = clDate.getFullYear();
    month -= 0;
    setMonth(year, month + 1);
    hide();
  }

  function showRep(field, syncField, e) {
    e = e || window.event;

    getHtmlNodes();

    // Register events
    document.onmousedown = checkOutclick;

    // Parse field date
    clField = field;
    clSyncField = syncField;
    clDate = parseDate(clField.value);

    // Draw calendar
    drawCalendarRep();
    drawDateRep(clDate);

    setPosition(e);
  }

  function hideRep() {
    if (!clCalendar) {
      clCalendar = document.getElementById('calendar');
    }
    document.onmouseup = null;
    document.onmousedown = null;
    clCalendar.style.visibility = 'hidden';
    clActive = false;
  }

  function buildComboBox() {
    // COMBO BOXES
    if (clElYears.innerHTML !== '') {
      return;
    }
    var i;
    for (i = 0; i < 12; i++) {
      var elDiv = document.createElement('div');
      elDiv.id = 'ycombo' + i;
      elDiv.className = i % 2 === 0 ? 'cl-ym-div' : 'cl-ym-diveven';
      elDiv.innerHTML = 'y ' + i;

      clElYears.appendChild(elDiv);

      elDiv = document.createElement('div');
      elDiv.id = 'mcombo' + i;
      elDiv.className = i % 2 === 0 ? 'cl-ym-div' : 'cl-ym-diveven';
      elDiv.innerHTML = 'm ' + i;

      clElMonths.appendChild(elDiv);
    }
    // COMBO BOXES
  }

  function drawCalendarRep() {
    if (clElHead && clCalendar.getAttribute('data-type') === 'default') {
      return;
    }
    var i;
    clCalendarCell.innerHTML = '';
    // HEAD
    clElHead = document.createElement('div');
    clElHead.className = 'cl-head';

    clCalendarCell.appendChild(clElHead);
    clCalendar.setAttribute('data-type', 'default');
    clElHead.innerHTML = '';
    //HEAD

    buildComboBox();
    // TOOLBAR and DAYS
    var elWrDays = document.createElement('div');
    elWrDays.className = 'cl-days-wrapper';
    clCalendarCell.appendChild(elWrDays);
    clElDays = document.createElement('table');
    clElDays.className = 'cl-days';
    elWrDays.appendChild(clElDays);

    clElDaysTbody = document.createElement('tbody');
    clElDays.appendChild(clElDaysTbody);

    var toolcontent = {
      prevM: '.',
      calmonth: '',
      nextM: '.',
      prevY: '.',
      calyear: '',
      nextY: '.',
      today: ''
    };
    /* jslint forin:true */
    for (var keyVar in toolcontent) {
      var elToolTd = document.createElement('div');
      elToolTd.className = 'cl-tool-td';
      elToolTd.id = keyVar;
      elToolTd.setAttribute('unselectable', true);
      if (toolcontent[keyVar] === '.') {
        elToolTd.innerHTML = '<div class="t-inner"></div>';
      } else {
        elToolTd.innerHTML = toolcontent[keyVar];
      }

      clElHead.appendChild(elToolTd);
    }
    var emptyRow = document.createElement('tr');
    clElDaysTbody.appendChild(emptyRow);

    for (i = 0; i < 7; i++) {
      var elDaysTr = document.createElement('tr');
      if (i === 0) {
        elDaysTr.className = 'cl-dayst-tr';
      }
      clElDaysTbody.appendChild(elDaysTr);

      for (var j = 0; j < 7; j++) {
        var elDaysTd = document.createElement('td');
        if (j === 6) {
          elDaysTd.style.borderRightWidth = 0;
        }
        elDaysTd.innerHTML = i === 0 ? clMsgWdays[j] : '&nbsp;';
        if (j === 0) {
          addClass(elDaysTd, 'cl-first');
        } else if (j === 6) {
          addClass(elDaysTd, 'cl-last');
        }

        elDaysTr.appendChild(elDaysTd);
      }
    }
    // TOOLBAR and DAYS
  }
  /**
   * Draw calendar dates
   * @param {Date} cdate current Date object
   */
  function drawDateRep(cdate) {
    var cyear = cdate.getFullYear();
    var cmon = cdate.getMonth();
    var cday = cdate.getDate();
    var cyearb, cmonb;
    if (cmon === 0) {
      cyearb = cyear - 1;
      cmonb = 11;
    } else {
      cyearb = cyear;
      cmonb = cmon - 1;
    }
    var elMonth = document.getElementById('calmonth');
    var elYear = document.getElementById('calyear');

    elYear.innerHTML = cyear;

    if (!elMonth) {
      return;
    }
    elMonth.innerHTML = clMsgMonths[cmon];

    // 1th week day
    var firstdayDate = new Date(cdate.getFullYear(), cdate.getMonth(), cdate.getDate());
    firstdayDate.setDate(1);
    var startWday = firstdayDate.getDay();
    if (startWday === 0) {
      startWday = 7;
    }

    // last day in month
    var lastDay = getLastday(cyear, cmon);
    var lastDayBehind = getLastday(cyearb, cmonb);
    var cb = lastDayBehind - (startWday - 2);
    var showRows = [1, 1, 1, 1, 1, 1, 1, 1];
    var c = 1;
    var nextm = 1;
    var innerTd;
    for (var i = 2; i < 8; i++) {

      for (var j = 0; j < 7; j++) {
        clElDays.rows[i].className = '';
        if (i % 2 === 0) {
          clElDays.rows[i].cells[j].className = 'cl-days';
        } else {
          clElDays.rows[i].cells[j].className = 'cl-even cl-days';
        }
        if (j >= 5) {
          addClass(clElDays.rows[i].cells[j], 'cl-weekend');
        }
        clElDays.rows[i].cells[j].id = '';
        //prev month
        if (i === 2 && j + 1 < startWday) {
          // ******
          //even day
          if (i % 2 === 0) {
            clElDays.rows[i].cells[j].className = 'cl-behind cl-days';
          } else {
            clElDays.rows[i].cells[j].className = 'cl-even cl-behind cl-days';
          }
          //weekend
          if (j >= 5) {
            addClass(clElDays.rows[i].cells[j], 'cl-weekend');
          }
          innerTd = '<div class="inner-td">' + cb + '</div>';
          clElDays.rows[i].cells[j].innerHTML = innerTd;
          clElDays.rows[i].cells[j].id = cb;
          //add event behind day

          cb++;
          //next month
        } else if (c > lastDay) {
          // ******
          //even day
          if (i % 2 === 0) {
            clElDays.rows[i].cells[j].className = 'cl-days cl-future';
          } else {
            clElDays.rows[i].cells[j].className = 'cl-even cl-future cl-days';
          }
          //weekend
          if (j >= 5) {
            addClass(clElDays.rows[i].cells[j], 'cl-weekend');
          }
          innerTd = '<div class="inner-td">' + nextm + '</div>';
          clElDays.rows[i].cells[j].innerHTML = innerTd;
          clElDays.rows[i].cells[j].id = nextm;
          nextm++;
          if (j === 0) {
            showRows[i] = 0;
          }
          //current month
        } else {
          innerTd = '<div class="inner-td">' + c + '</div>';
          clElDays.rows[i].cells[j].innerHTML = innerTd;
          if (c === cday) {
            addClass(clElDays.rows[i].cells[j], 'cl-selected');
          }
          c++;
        }
        if (j === 0) {
          addClass(clElDays.rows[i].cells[j], 'cl-first');
        } else if (j === 6) {
          addClass(clElDays.rows[i].cells[j], 'cl-last');
        }
        if (i === 2) {
          clElDays.rows[i].className = 'first-row';
        } else if (i === 7) {
          if (showRows[i] !== 0) {
            clElDays.rows[i].className = 'last-row';
          } else {
            clElDays.rows[i - 1].className = 'last-row';
          }
        }
      }
    }

    for (var ii = 5; ii < showRows.length; ii++) {
      if (showRows[ii] === 1) {
        clElDays.rows[ii].style.display = 'table-row';
      } else {
        clElDays.rows[ii].style.display = 'none';
      }
    }
  }

  /////// Select clicked day
  function daysMousedownRep(e) {
    e = e || window.event;
    // Get object which fire event
    var obj = e.target ? e.target : e.srcElement,
        inner = obj.innerHTML;
    if (!String(inner).match(/\d+/)) {
      return;
    }
    /* jslint validthis: true */
    inner = inner.replace(/\D[^\.]/g, '');
    var self = $(this),
        cday = parseInt(inner, 10);
    /* jslint validthis: false */
    if (self.hasClass('cl-behind')) {
      clDate.setMonth(clDate.getMonth() - 1, cday);
    } else if (self.hasClass('cl-future')) {
      clDate.setMonth(clDate.getMonth() + 1, cday);
    } else {
      if (isNaN(cday)) {
        return;
      }
    }

    setDate(clDate.getFullYear(), clDate.getMonth() + 1, cday);
    hideRep();
    stopEvent(e);
  }

  /**
   * set month & year in input
   * @param {Number} y year XXXX
   * @param {Number|String} m month XX
   */
  function setMonth(y, m) {
    if (m < 10) {
      m = '0' + String(m);
    }
    if (clField.getAttribute('readonly') === null) {
      var value = y + '-' + m;
      clField.value = value;
      $(clField).trigger('change');
      if (clSyncField && clSyncField.value === '') {
        clSyncField.value = value;
        $(clSyncField).trigger('change');
      }
    }
  }

  /**
   * set full date in input
   * @param {Number|String} y year XXXX
   * @param {Number|String} m month XX
   * @param {Number|String} d day XX
   */
  function setDate(y, m, d) {
    if (m < 10) {
      m = '0' + String(m);
    }
    if (d < 10) {
      d = '0' + String(d);
    }
    if (clField.getAttribute('readonly') === null) {
      var value = y + '-' + m + '-' + d;
      clField.value = value;
      $(clField).trigger('change');
      if (clSyncField && clSyncField.value === '') {
        clSyncField.value = value;
        $(clSyncField).trigger('change');
      }
    }
  }

  function getLastday(y, m) {
    var months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    if (m === 1 && y % 4 === 0 && (y % 100 !== 0 || y % 400 === 0)) {
      return 29;
    } else {
      return months[m];
    }
  }

  function applyCurMonth() {
    $('.b-cal__month_selected').removeClass('b-cal__month_selected');
    $('.b-cal__month[data-value="' + clDate.getMonth() + '"]').addClass('b-cal__month_selected');
    $('#calyear').html(clDate.getFullYear());
  }

  function toolMouseupRep(e) {
    e = e || window.event;
    // Get object which fire event
    /* jslint validthis: true */
    var obj = this;
    /* jslint validthis: false */
    var cday = clDate.getDate();
    var cmonth = clDate.getMonth();
    var cyear = clDate.getFullYear();
    var lastDay, todayDate;
    clDate.setDate(1);
    if (obj.id === 'prevY') {
      clDate.setFullYear(clDate.getFullYear() - 1);
      lastDay = getLastday(clDate.getFullYear(), clDate.getMonth());
      if (lastDay < cday) {
        clDate.setDate(lastDay);
      } else {
        clDate.setDate(cday);
      }
      drawDateRep(clDate);
    } else if (obj.id === 'prevM') {
      clDate.setMonth(clDate.getMonth() - 1);
      lastDay = getLastday(clDate.getFullYear(), clDate.getMonth());
      if (lastDay < cday) {
        clDate.setDate(lastDay);
      } else {
        clDate.setDate(cday);
      }
      drawDateRep(clDate);
    } else if (obj.id === 'today') {
      todayDate = new Date();
      if (todayDate.getFullYear() === cyear && todayDate.getMonth() === cmonth && todayDate.getDate() === cday) {
        setDate(cyear, cmonth + 1, cday);
        hide();
      } else {
        clDate = todayDate;
        drawDateRep(clDate);
      }
    } else if (obj.id === 'curMonth') {
      todayDate = new Date();
      if (todayDate.getFullYear() === cyear && todayDate.getMonth() === cmonth) {
        setMonth(cyear, cmonth + 1);
        hide();
      } else {
        clDate = todayDate;
        applyCurMonth();
      }
    } else if (obj.id === 'nextM') {
      clDate.setMonth(clDate.getMonth() + 1);
      lastDay = getLastday(clDate.getFullYear(), clDate.getMonth());
      if (lastDay < cday) {
        clDate.setDate(lastDay);
      } else {
        clDate.setDate(cday);
      }
      drawDateRep(clDate);
    } else if (obj.id === 'nextY') {
      clDate.setFullYear(clDate.getFullYear() + 1);
      lastDay = getLastday(clDate.getFullYear(), clDate.getMonth());
      if (lastDay < cday) {
        clDate.setDate(lastDay);
      } else {
        clDate.setDate(cday);
      }
      drawDateRep(clDate);
    }
    stopEvent(e);
  }

  /**
   * Year & month click handler
   * @param {object} e event object
   */
  function toolMousedownRep(e) {
    e = e || window.event;
    // Get object which fire event
    var obj = e.target ? e.target : e.srcElement;
    clTtool = obj;

    if (obj.id === 'calyear') {
      if (clTimeout) {
        clearTimeout(clTimeout);
      }
      clTimeout = setTimeout(function () {
        showYear();
      }, 250);
      document.onmouseup = hideMyRep;
    } else if (obj.id === 'calmonth') {
      if (clTimeout) {
        clearTimeout(clTimeout);
      }
      clTimeout = setTimeout(function () {
        showMonths();
      }, 250);
      document.onmouseup = hideMyRep;
    }
    stopEvent(e);
  }

  function hideMyRep() {
    if (clTimeout) {
      clearTimeout(clTimeout);
    }
    document.onmouseup = null;
    clElYears.style.visibility = 'hidden';
    clElMonths.style.visibility = 'hidden';
    if (clTtool) {
      removeClass(clTtool, 'cl-tool-selected');
    }
  }

  function showMonths() {
    var cmonth = clDate.getMonth();
    for (var i = 0; i < 12; i++) {
      clElMonths.childNodes[i].innerHTML = clMsgSmonths[i];
      if (cmonth === i) {
        addClass(clElMonths.childNodes[i], 'cl-ym-selected');
      } else {
        removeClass(clElMonths.childNodes[i], 'cl-ym-selected');
      }
    }

    var pos = $(clTtool).offset();

    var x = clTtool.id === 'calmonth' ? pos.left : pos.left + clTtool.offsetWidth - clElMonths.offsetWidth;
    if (isIe) {
      x += 1;
    }
    clElMonths.style.left = x + 'px';
    clElMonths.style.top = pos.top + clTtool.offsetHeight - 1 + 'px';
    clElMonths.style.visibility = 'visible';
    addClass(clTtool, 'cl-tool-selected');
  }
  /**
   * Show years combo box
   */
  function showYear() {
    var cyear = clDate.getFullYear();
    cyear += 12;
    for (var i = 0; i < 12; i++) {
      clElYears.childNodes[i].innerHTML = cyear - 1 - i * 2;
    }
    var pos = $(clTtool).offset();
    //var pos = mn_get_obj_pos(clTtool);
    var x = clTtool.id === 'calyear' ? pos.left - 1 : pos.left + clTtool.offsetWidth - clElYears.offsetWidth + 1;
    if (isIe) {
      x += 1;
    }
    clElYears.style.left = x + 'px';
    clElYears.style.top = pos.top + clTtool.offsetHeight - 1 + 'px';
    clElYears.style.visibility = 'visible';
    addClass(clTtool, 'cl-tool-selected');
  }
  /**
   * close calendar
   */
  function hide() {
    if (!clCalendar) {
      clCalendar = document.getElementById('calendar');
    }
    document.onmousedown = null;
    clCalendar.style.visibility = 'hidden';
    clActive = false;
  }
  /**
   * Out caledar click handler
   * close calendar
   * @param {object} e event object
   */
  function checkOutclick(e) {
    e = e || window.event;
    // Get object which fire event
    var obj = e.target ? e.target : e.srcElement;
    while (obj.parentNode) {
      if (obj.id === 'calendar') {
        return;
      }
      obj = obj.parentNode;
    }
    hide();
  }

  /**
   * Combo month & year click handler
   * show chosen year or month
   * @param {object} e event object
   */
  function comboMouseupRep(e) {
    e = e || window.event;
    // Get object which fire event
    var obj = e.target ? e.target : e.srcElement;

    var cday = clDate.getDate();
    var lastDay;
    clDate.setDate(1);
    if (String(obj.id).match(/ycombo/)) {
      clDate.setFullYear(parseInt(obj.innerHTML, 10));
      lastDay = getLastday(clDate.getFullYear(), clDate.getMonth());
      if (lastDay < cday) {
        clDate.setDate(lastDay);
      } else {
        clDate.setDate(cday);
      }
      drawDateRep(clDate);
    } else if (String(obj.id).match(/mcombo(\d+)/)) {
      clDate.setMonth(parseInt(RegExp.$1, 10));
      lastDay = getLastday(clDate.getFullYear(), clDate.getMonth());
      if (lastDay < cday) {
        clDate.setDate(lastDay);
      } else {
        clDate.setDate(cday);
      }
      drawDateRep(clDate);
    }
  }

  function parseDate(str, month) {
    var isfieldok = false,
        fy = null,
        fm = null,
        fd = null;
    if (month) {
      if (String(str).match(/^(\d\d\d\d)-(\d+)/)) {
        fy = parseInt(RegExp.$1, 10);
        fm = parseInt(RegExp.$2, 10);
        fd = 1;
        if (!isNaN(fy) && !isNaN(fm)) {
          fm -= 1;
          isfieldok = true;
        }
      }
    } else {
      if (String(str).match(/^(\d\d\d\d)-(\d+)-(\d+)/)) {
        fy = parseInt(RegExp.$1, 10);
        fm = parseInt(RegExp.$2, 10);
        fd = parseInt(RegExp.$3, 10);
        if (!isNaN(fy) && !isNaN(fm) && !isNaN(fd)) {
          fm -= 1;
          isfieldok = true;
        }
      }
    }
    var rdate = null;
    if (isfieldok) {
      rdate = new Date(fy, fm, fd);
    } else {
      rdate = new Date();
    }

    return rdate;
  }

  function comboMouseover(e) {
    e = e || window.event;
    // Get object which fire event
    var obj = e.target ? e.target : e.srcElement;
    addClass(obj, 'cl-ym-hover');
  }

  function comboMouseout(e) {
    e = e || window.event;
    // Get object which fire event
    var obj = e.target ? e.target : e.srcElement;
    removeClass(obj, 'cl-ym-hover');
  }

  // Remove class from element
  function removeClass(el, name) {
    if (!(el && el.className)) {
      return;
    }
    var cls = el.className.split(' ');
    var ar = [];
    for (var i = cls.length; i > 0;) {
      if (cls[--i] !== name) {
        ar[ar.length] = cls[i];
      }
    }
    el.className = ar.join(' ');
  }

  // Add class to element
  function addClass(el, name) {
    removeClass(el, name);
    el.className += ' ' + name;
  }

  function stopEvent(e) {
    e = e || window.event;
    if (isIe) {
      e.cancelBubble = true;e.returnValue = false;
    } else {
      e.preventDefault();e.stopPropagation();
    }
    return false;
  }

  return {
    init: init,
    show: showRep,
    showMonth: showMonthCal
  };
}(window, $, EventMgr);

/*
 try {
  if ( pageInfo.calendar['today'] ) clMsgToday = pageInfo.calendar['today'];
 } catch (ex) {}
 for ( var i=0; i<12; i++ ) {
 clMsgMonths[i] = pageInfo.calendar['m' + i];
  clMsgSmonths[i] = pageInfo.calendar['ms' + i]; }
 for ( var i=0; i<7; i++ ) { clMsgWdays[i] = pageInfo.calendar['w' + i];; }
 */
//# sourceMappingURL=App.Calendar.js.map

'use strict';

/**
 * Select Module
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 *  @return {object} api
 */
App.PrefixSelect = function (window, $, EventMgr, App) {
  'use strict';

  var CACHE = {},
      selectPrefixSelector = '.i-myselect_is_prefix',
      inputPrefixSelector = 'input.i-input_has_prefix',
      timeOutId;

  function $content() {
    return App.Common.selectorCache('.i-form-wr');
  }

  function inputPrefixHandlerWrapper(e) {
    var self = this;
    clearTimeout(timeOutId);
    timeOutId = setTimeout(function () {
      inputPrefixHandler(self);
    }, 300);
  }
  /**
   * Input prefix handler
   *
   **/
  function inputPrefixHandler(elem, isInit) {
    var value = elem.value,
        tabId = elem.getAttribute('data-tabid'),
        prefixSelectName = elem.getAttribute('data-prefix-name'),
        selectIndex = getSelectIndex(tabId, prefixSelectName),
        prevPrefix = elem.getAttribute('data-prefix'),
        findObject = findInSelect(value, selectIndex),
        selectElem;
    if (isInit) {
      selectElem = $('#' + tabId + '-' + prefixSelectName + ' li.selected').trigger('click', [null, { isIgnore: true }]);
      var prefix = selectElem.attr('data-code');
      var mask = selectElem.attr('data-mask');
      //set data-prefix
      elem.setAttribute('data-prefix', prefix);
      //set data-mask
      if (mask) {
        elem.setAttribute('data-mask', mask);
        EventMgr.trigger('inputMaskChangeBySetvalues', { elem: elem, mask: mask, value: value });
      }
      return;
    }
    //set find prefix value
    if (findObject.isFind && prevPrefix !== findObject.prefix) {
      $($('#' + tabId + '-' + prefixSelectName + ' li[data-code="' + findObject.prefix + '"]:not(".selected")')[0]).trigger('click', [null, { isIgnore: true }]);
      //set data-prefix
      elem.setAttribute('data-prefix', findObject.prefix);
      if (findObject.mask) {
        elem.setAttribute('data-mask', findObject.mask);
        EventMgr.trigger('inputMaskChangeBySetvalues', { elem: elem, mask: findObject.mask, value: value });
      }
    }
  }
  //get cached index
  function getSelectIndex(tabId, name) {
    if (!CACHE[tabId]) {
      CACHE[tabId] = {};
    } else if (CACHE[tabId][name]) {
      return CACHE[tabId][name];
    }

    CACHE[tabId][name] = makeIndex(tabId, name);
    return CACHE[tabId][name];
  }
  //make select values index
  function makeIndex(tabId, name) {
    var items = $('#' + tabId + '-' + name + ' li'),
        l = items.length,
        index = {};
    while (l--) {
      index[items[l].getAttribute('data-code')] = { mask: items[l].getAttribute('data-mask') };
    }
    return index;
  }
  //find in select index
  function findInSelect(value, selectIndex) {
    var searchPrefix = String(value).replace(/\)/g, '').replace(/\(/g, '').replace(/\s/g, '');
    for (var i = 0, l = String(value).length; i < l; i++) {
      if (selectIndex[searchPrefix]) {
        return { isFind: true, prefix: searchPrefix, mask: selectIndex[searchPrefix].mask };
      }
      searchPrefix = searchPrefix.substring(0, searchPrefix.length - 1);
    }
    return { isFind: false };
  }
  //remove value ignore white spaces
  function removeIgnoreWhiteSpace(replacement, value) {
    var valueArr = String(value).split(''),
        replacementArr = String(replacement).split(''),
        replacementLength = replacementArr.length,
        ii = 0;
    for (var i = 0, l = valueArr.length; i < l; i++) {
      if (valueArr[i] !== ' ' && valueArr[i] !== '(' && valueArr[i] !== ')' && valueArr[i] !== '_' && valueArr[i] !== '-') {

        if (valueArr[i] === replacementArr[ii]) {
          ii++;
          valueArr[i] = '';
          if (replacementLength === ii) {
            break;
          }
        }
      } else {
        valueArr[i] = '';
      }
    }
    return valueArr.join('');
  }
  /**
   * Select prefix handler 
   *
   **/
  function prefixHandler(e, data, d) {
    if (d && d.isIgnore) {
      return;
    }
    var targetName = this.getAttribute('data-targetinput'),
        tabId = this.getAttribute('data-tabid'),
        $target = $('#' + targetName + '-' + tabId),
        targetPrefix = $target.attr('data-prefix'),
        key = this.value,
        value = $target.val(),
        $selectElem = $('#' + tabId + '-' + this.getAttribute('name') + ' li[data-val="' + key + '"]'),
        newPrefix = $selectElem.attr('data-code'),
        mask = $selectElem.attr('data-mask');
    //remove prev prefix
    value = removeIgnoreWhiteSpace(targetPrefix, value);
    //just insert to 1st position
    value = newPrefix + value;
    $target.val(value);
    if (mask) {
      EventMgr.trigger('inputMaskChangeBySetvalues', { elem: $target[0], mask: mask, value: value });
    }
    //set new prefix
    $target.attr('data-prefix', newPrefix);
  }

  function checkInitValue(e, data) {
    var tabId = data.tabId;
    $('#cont-' + tabId + ' .i-input_has_prefix').each(function () {
      inputPrefixHandler(this, true);
    });
  }

  function init() {
    EventMgr.on($content(), selectPrefixSelector, 'change', prefixHandler);
    EventMgr.on($content(), inputPrefixSelector, 'change', inputPrefixHandlerWrapper);
    EventMgr.on($content(), inputPrefixSelector, 'keyup', inputPrefixHandlerWrapper);
    EventMgr.bind('appendForm', checkInitValue);
  }

  var api = {
    init: init
  };

  return api;
}(window, $, EventMgr, App);
//# sourceMappingURL=App.PrefixSelect.js.map

'use strict';

/**
 * Form validators module
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 */
App.Validators = function (window, $, EventMgr, App) {
  'use strict';

  var init = function init() {
    EventMgr.on('#main-wrapper', 'input[type="text"].test', 'change', validate);
    EventMgr.on('#main-wrapper', 'input[type="text"].testzoom', 'change', multiValidate);
    EventMgr.bind('errMsgValid', setErrorMessage);
    EventMgr.bind('okMsgValid', setOkMessage);
  },
      pageInfo = window.pageInfo,
      $activeTab = function $activeTab() {
    return $('.tab-content_st_active');
  },

  //Callback for changed input value
  validate = function validate(e, data) {
    var nameValid = this.getAttribute('data-check'),
        paramValid = this.getAttribute('data-check-args'),
        errMsg = this.getAttribute('data-error-msg'),
        fieldName = this.getAttribute('data-fieldname'),
        funcName = this.getAttribute('data-funcname'),
        prefix = $(this).siblings('.b-input__prefix').html(),
        convert = this.getAttribute('data-convert');
    if (this.value === '') {
      EventMgr.trigger('okMsgValid', { self: this, number: 0, value: '' });
      return;
    }
    //trigger checkvalue
    EventMgr.trigger('checkValue', {
      name: nameValid,
      prefix: prefix,
      param: paramValid,
      err: errMsg,
      fieldname: fieldName,
      number: 0,
      funcname: funcName,
      convert: convert,
      self: this,
      value: this.value });
  },

  //function for checking duplicate
  checkDuplicate = function checkDuplicate(values) {
    var i, j, n;
    n = values.length;
    // to ensure the fewest possible comparisons
    // outer loop uses each item i at 0 through n
    for (i = 0; i < n; i++) {
      // inner loop only compares items j at i+1 to n
      for (j = i + 1; j < n; j++) {
        if (values[i] === values[j]) {
          return true;
        }
      }
    }
    return false;
  },
      multiValidate = function multiValidate(e, data) {
    if (this.value === '') {
      EventMgr.trigger('okMsgValid', { self: this, number: 0, value: '' });
      return;
    }
    var number = 0,
        value = this.value,
        values = this.value.split(/\s+/),
        len = values.length;
    if (data) {
      number = data.number;
      var nextNumber = number + 1;
      if (len === nextNumber) {
        number = 0;
      } else {
        number = nextNumber;
      }
      value = values[nextNumber - 1];
    } else {
      if (len === 1) {
        number = 0;
      } else {
        if (this.getAttribute('duplicate') !== 'yes') {
          if (checkDuplicate(values)) {
            EventMgr.trigger('errMsgValid', {
              type: 'duplicate',
              self: this,
              err: pageInfo.duplicate,
              number: 0 });
            return;
          }
        }
        number = 1;
      }
      value = this.value.split(/\s+/)[0];
    }
    var nameValid = this.getAttribute('data-check'),
        paramValid = this.getAttribute('data-check-args'),
        errMsg = this.getAttribute('data-error-msg'),
        fieldName = this.getAttribute('data-fieldname'),
        funcName = this.getAttribute('data-funcname'),
        convert = this.getAttribute('data-convert');
    EventMgr.trigger('checkValue', {
      name: nameValid,
      param: paramValid,
      err: errMsg,
      multi: true,
      fieldname: fieldName,
      funcname: funcName,
      self: this,
      number: number,
      value: value,
      convert: convert });
  },
      replaceValidValue = function replaceValidValue(where, what, than) {
    var arr = String(where).split(/\s+|\n/),
        l = arr.length,
        obj = {
      v: '',
      changed: false
    };
    while (l--) {
      if (String(arr[l]) === String(what)) {
        if (String(what) !== String(than)) {
          obj.changed = true;
        }
        arr[l] = than;
        break;
      }
    }
    obj.v = arr.join(' ');
    return obj;
  },
      setOkMessage = function setOkMessage(e, data) {
    var self = data.self,
        number = data.number,
        value = data.value,
        ovalue = data.ovalue,
        vvalue = data.vvalue,
        multi = data.multi,
        notOk = data.notOk,
        tabId,
        secondTdElem,
        sData = data,
        o;
    data = {};
    data.number = number;
    //for multi value
    if (number - 0 !== 0) {
      o = replaceValidValue(self.value, vvalue, value);
      self.value = o.v;
      if (o.changed) {
        setWarningError(e, sData);
      }
      multiValidate.apply(self, [null, data]);
    } else {
      secondTdElem = $(self).parents('.l-form__col_cont_control');
      if (secondTdElem.attr('colspan') - 0 === 2 && !secondTdElem.hasClass('formwidth')) {
        secondTdElem.attr('colspan', '');
      }
      if (value === '' && self.getAttribute('required') || notOk) {
        secondTdElem.parents('.l-form__row').removeClass('row-error').removeClass('row-ok');
      } else {
        secondTdElem.parents('.l-form__row').removeClass('row-error').addClass('row-ok');
      }
      //replace value if this changed
      if (value !== undefined && ovalue !== undefined && vvalue !== undefined) {
        o = {};
        if (multi) {
          o = replaceValidValue(self.value, vvalue, value);
          self.value = o.v;
          if (o.changed) {
            setWarningError(e, sData);
          }
        } else if (value !== '') {
          if (self.value !== value || o.changed) {
            setWarningError(e, sData);
          }
          self.value = value;
        }
      }
    }
    tabId = $(self).closest('.tab-content').attr('data-tabid');
    EventMgr.trigger('syncInputToZoom', { tabId: tabId, self: self });
    EventMgr.trigger('updFormHeight', { tabId: tabId });
  },
      setWarningError = function setWarningError(e, data) {
    data.warning = true;
    data.err = pageInfo.messages.validChangeVal;
    setErrorMessage.apply(window, [e, data]);
  },


  // Write error
  setErrorMessage = function setErrorMessage(e, data) {
    var msg = data.err,
        self = data.self,
        name = self.getAttribute('name'),
        id = self.getAttribute('id'),
        number = data.number,
        arrValues = self.value ? self.value.split(' ') : [],
        tmp = '',
        warning = data.warning,
        i,
        index,
        tabId,
        r,
        secondTdElem;
    //show error box if created
    if (number - 0 === 0) {
      number = arrValues.length;
    }
    for (i = 0; i < number - 1; i++) {
      tmp += arrValues[i] + ' ';
    }
    index = tmp.length;

    var errHTML = '<div class="b-error-box"><div class="b-error-box__top-triangle"></div>' + '<div class="b-error-box__inner">' + msg + '</div></div>';
    $('.b-error-box__wrapper[data-id="' + id + '"]').html(errHTML);
    secondTdElem = $(self).parents('.l-form__col_cont_control');
    if (!secondTdElem.attr('colspan') && !warning) {
      secondTdElem.attr('colspan', '2');
    }
    if (!warning) {
      secondTdElem.parents('.l-form__row').addClass('row-error').removeClass('row-ok');
    } else {
      secondTdElem.parents('.l-form__row').addClass('row-warning');
      setTimeout(function () {
        secondTdElem.parents('.l-form__row').removeClass('row-warning');
      }, 2000);
    }
    tabId = $(self).closest('.tab-content').attr('data-tabid');
    EventMgr.trigger('updFormHeight', { tabId: tabId });
    EventMgr.trigger('updateFixedField', { tabId: tabId });
    if (!warning) {
      //scroll to field
      var $self = $(self),
          offsetTop = $self.closest('.l-form__row')[0] ? $self.closest('.l-form__row')[0].offsetTop : 0,
          $page = $self.closest('.b-form-page'),
          $formSW = $('#form-scroll-' + tabId),
          MAGICNUMBER = 62 + 12 + 2 + 2; //button block height + padding + margin
      if ($page.hasClass('b-form-page_st_collapsed')) {
        $page.find('.i-form-page__title').trigger('click');
      }
      //it can be extform
      if ($formSW.length) {
        var height = parseFloat($formSW[0].style.height),
            scrollTop = $formSW[0].scrollTop;
        if ($page[0]) {
          offsetTop += $page[0].offsetTop;
        }
        //offsetTop -= MAGICNUMBER;
        offsetTop += MAGICNUMBER;
        //scrolltop when not in viewport
        if (offsetTop < scrollTop || height + scrollTop < offsetTop) {
          EventMgr.trigger('scrollTo', {
            id: 'form-scroll-' + tabId,
            offsetTop: offsetTop,
            animate: false,
            raw: false
          });
        }
      }
      //setfocus and cursor
      //check for type=file
      if (String(self.getAttribute('type')).toLowerCase() !== 'file') {
        if (self.offsetWidth !== 0) {
          self.focus();
          window.scrollTo(0, 0);
          if (self.setSelectionRange) {
            self.setSelectionRange(index, index);
          } else if (self.createTextRange) {
            r = self.createTextRange();
            r.collapse(true);
            r.select(index, index);
          }
        } else if (self.nextSibling) {
          //for passwd I think
          self.nextSibling.focus();
          window.scrollTo(0, 0);
          if (self.setSelectionRange) {
            self.nextSibling.setSelectionRange(index, index);
          } else {
            r = self.nextSibling.createTextRange();
            r.collapse(true);
            r.select(index, index);
          }
        }
      }
    }
  };
  return {
    init: init
  };
}(window, $, EventMgr, App);
//# sourceMappingURL=App.Validators.js.map

//module loaders
App.mgr = function () {
	'use strict';
	var modules = [

			App.Common.init
			,App.Dom.init
			,App.FormUtils.init
			,App.FormDependFields.init
			,App.Forms.init
			,App.Wizards.init
			,App.ScrollController.init
			,App.AjaxHelper.init
			,App.ValidChecker.init
			,App.Slider.init
			,App.SelectAutoComplete.init
			,App.Help.init
			,App.Hint.init
			,App.MultiSelect.init
			,App.Select.init
			,App.ActionHandler.init
			,App.Tabs.init
			,App.Showcase.init
			,App.ExtFormHelper.init
			,App.ProgressBar.init
			,App.UpSize.init
			,App.InputMask.init
			,App.Calendar.init
			,App.PrefixSelect.init
			,App.Validators.init

	],
	len = modules.length,
		i, data = 'data';

	for (i = 0; i < len; i++) {
    if (typeof modules[i] === 'function') {
      modules[i]();
    } else {
      console.log('undefined init function of module number: ', i);
    }
	}
	EventMgr.trigger('loadPage', data);
};

/**
 *  ErrorReport module
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 *  @return {object} api
 */
/*global App:true*/
/*global EventMgr:true*/
/*global $:true*/
App.ErrorReport = function(window, $, EventMgr, App) {
  'use strict';

  function errorReport(errorMsg, url, lineNumber, colNumber, error) {
    var param = {};
    param.error_url = url + '______' + window.location.href;
    param.error_message = errorMsg;
    param.stack_trace = lineNumber;
    param.error = error;
    param.col_number = colNumber;
    param.user_level = pageInfo.userLevel;
    param.product = pageInfo._product;
    param.is_branding = pageInfo.isBranding;
    param.theme = 'orion';
    param.module = $('.tab-content_st_active').attr('data-func');
    param.version = pageInfo.version;
    EventMgr.trigger('ajaxRequest', {
      url: 'https://themereport.ispsystem.net:3001/api/errorreport/',
      param: param,
      type: 'jsonp'
    });
  }

  window.onerror = errorReport;

} (window, $, EventMgr, App);

//Constructor for tabs
(function(window, $, templates) {
  'use strict';
  function TabObj(id, status, type, selfUrl) {
    this.id = id;
    this.cid = 'cont-' + this.id;
    //this.title = title;
    this.status = status || 0;
    this.type = type;
    this.selfUrl = selfUrl;
    this.body = '';
    this.header = '';
    this.param = '';
    this.sIndex = String(id).replace('tab', '') - 0;
  }

  TabObj.fn = TabObj.prototype;

  TabObj.fn.deactive = function() {
    $('#' + this.id).removeClass('active');
    $('#switch-' + this.id).removeClass('active');
    //$('#s-' + this.id).removeClass('active');
    if (this.hType === 'child') {
      $('#' + this.gParent).removeClass('active');
      $('#switch-' + this.gParent).removeClass('active');
    }
    $('#' + this.cid).removeClass('tab-content_st_active').addClass('hidden');
    this.status = 0;
  };

  TabObj.fn.activate = function() {
    $('#' + this.id).addClass('active');
    $('#switch-' + this.id).addClass('active');
    //$('#s-' + this.id).addClass('active');
    if (this.hType === 'child') {
      $('#' + this.gParent).addClass('active');
    }
    $('#' + this.cid).addClass('tab-content_st_active').removeClass('hidden');
    this.status = 1;
  };
  //render HTML for tabHead and tabBody
  TabObj.fn.render = function() {
    switch (this.type) {
      case 'empty':
        this.htmlBody = templates.tabContEmpty(this.body);
        if (this.hType === 'parent') {
          this.htmlHeader = templates.tabLi(this.header);
        } else {
          this.htmlHeader = templates.tabChld(this.header);
        }
        break;
      case 'list':
        this.htmlBody = templates.tabCont(this.body);
        if (this.hType === 'parent') {
          this.htmlHeader = templates.tabLi(this.header);
        } else {
          this.htmlHeader = templates.tabChld(this.header);
        }
        break;
      case 'form':
        this.htmlBody = templates.tabContForm(this.body); //going replace
        if (this.hType === 'parent') {
          this.htmlHeader = templates.tabLi(this.header);
        } else {
          this.htmlHeader = templates.tabChld(this.header);
        }
        break;
      case 'report':
        this.htmlBody = templates.tabContForm(this.body); //going replace
        if (this.hType === 'parent') {
          this.htmlHeader = templates.tabLi(this.header);
        } else {
          this.htmlHeader = templates.tabChld(this.header);
        }
        break;
      case 'dashboard':
        this.htmlBody = templates.tabContDashBoard(this.body);
        break;
      case 'map':
      case 'rack':
        this.htmlBody = templates.tabContMap(this.body); //going replace
        if (this.hType === 'parent') {
          this.htmlHeader = templates.tabLi(this.header);
        } else {
          this.htmlHeader = templates.tabChld(this.header);
        }
        break;

    }
    return this;
  };
  //append tabBody and tabHead
  TabObj.fn.append = function(tabId) {
    if (this.htmlHeader && this.htmlBody) {
      if (this.hType === 'parent') {
        tabId = tabId || 'add-tab';
        $('#nav-tabs #' + tabId).before(this.htmlHeader);
      } else {
        $('#' + this.gParent).append(this.htmlHeader);
      }
      $('#wr-content').append(this.htmlBody);
    } else if (this.htmlBody) {
      $('#wr-content').append(this.htmlBody);
    }

    return this;
  };
  //replace tabBody
  TabObj.fn.update = function() {
    var body = document.getElementById(this.cid);
    if (body !== null) {
      body.parentNode.removeChild(body);
    }
    $('#wr-content').append(this.htmlBody);
    return this;
  };
  //replace only table
  TabObj.fn.softUpdate = function() {
    var table = document.getElementById('ltwr-' + this.id),
        newTable = '';
    if (table !== null) {
      newTable = '<div class="content" id="ltwr-' + this.id +
          '" data-tabid=' + this.id + '>' + this.body.table + '</div>';
      $(table).replaceWith(newTable);
    }
    return this;
  };
  //replace tabBody and tabHeader
  TabObj.fn.replace = function() {
    var tabHeader = document.getElementById(this.id),
        tabBody = document.getElementById(this.cid);
    if (tabBody !== null) {
      tabBody.parentNode.removeChild(tabBody);
    }
    $('#wr-content').append(this.htmlBody);
    if (tabHeader !== null) {
      $(tabHeader).replaceWith(this.htmlHeader);
    }
    return this;
  };
  //remove temprorary properties
  TabObj.fn.clean = function() {
    this.htmlBody = null;
    this.htmlHeader = null;
    this.header = null;
    this.body = null;
  };
  //close tab
  TabObj.fn.close = function() {
    if (this.chart !== undefined) {
      var myArray = this.chart,
          i = this.chart.length;
      while (i--) {
        if (typeof myArray[i].clearChart === 'function') {
          myArray[i].clearChart();
          myArray[i] = null;
        }
      }
    }
    var header = document.getElementById(this.id),
        body = document.getElementById(this.cid);
    if (header !== null) {
      header.parentNode.removeChild(header);
    }
    if (body !== null) {
      body.parentNode.removeChild(body);
    }
    header = null;
    body = null;
  };

  window.TabObj = TabObj;
  //Constructor for menuGroup
  function MenuGroup(level, id, status, self) {
    this.level = level;
    this.id = id;
    this.status = (status !== null) ? status : '0';
    this.self = self;
  }
  MenuGroup.fn = MenuGroup.prototype;
  //methods
  MenuGroup.fn.statusUp = function(status) {
    this.status = status;
  };

  MenuGroup.fn.activate = function() {
    this.status = '1';
    this.self.removeClass('collapsed');
  };

  MenuGroup.fn.disactivate = function() {
    this.status = '0';
    this.self.addClass('collapsed');
  };

  MenuGroup.fn.toggle = function() {
    if (this.status === '1') {
      this.status = '0';
    } else {
      this.status = '1';
    }
    this.self.toggleClass('collapsed');
  };

  window.MenuGroup = MenuGroup;
  //utilits
  //setCookie
  function setCookie(cName, value, exdays) {
    var exdate = new Date();
    exdate.setDate(exdate.getDate() + exdays);
    var cValue = encodeURIComponent(value) + ((exdays === null) ? '' :
        '; expires=' + exdate.toUTCString());
    document.cookie = cName + '=' + cValue;
  }
  window.setCookie = setCookie;
  //getCookie
  function getCookie(cName) {
    var i, x, y, ARRcookies = document.cookie.split(';');
    for (i = 0; i < ARRcookies.length; i++) {
      x = ARRcookies[i].substr(0, ARRcookies[i].indexOf('='));
      y = ARRcookies[i].substr(ARRcookies[i].indexOf('=') + 1);
      x = x.replace(/^\s+|\s+$/g, '');
      if (x === cName) {
        return decodeURIComponent(y);
      }
    }
    return '';
  }
  window.getCookie = getCookie;
  //jquery !plugins
  $.fn.switchClass = function(added, removed) {
    return this.removeClass(removed).addClass(added);
  };

  $.fn.serializeObject = function() {
    var formArray = this.serializeArray(),
        formObject = {},
        length = formArray.length,
        i;
    for (i = 0; i < length; i++) {
      formObject[formArray[i].name] = formArray[i].value;
    }
    return formObject;
  };
  //get flags from attr data-flag="default|reload"
  $.fn.getFlags = function() {
    var flags = {},
        flagString = this.attr('data-flags'),
        flagStringArr;
    if (flagString) {
      flagStringArr = flagString.split('|');
      for (var i = 0, l = flagStringArr.length; i < l; i++) {
        flags[$.trim(flagStringArr[i])] = true;
      }
    }
    return flags;
  };

  //get vars from attribute data-vars="t:1|r:25"
  $.fn.getVars = function() {
    var vars = {},
        varsString = this.attr('data-vars'),
        varsStringAttr,
        varsStringValue;
    if (varsString) {
      varsStringAttr = String(varsString).split('|');
      for (var i = 0, l = varsStringAttr.length; i < l; i++) {
        varsStringValue = varsStringAttr[i].split(':');
        if (varsStringValue && varsStringValue[0] && varsStringValue[1]) {
          vars[varsStringValue[0]] = varsStringValue[1];
        }
      }
    }
    return vars;
  };

  //@todo remove from all

  function blockEvent(e) {
    e = e || window.event;
    if (e.stopPropagation) {
      e.stopPropagation();
    }
    else {
      e.cancelBubble = true;
    }
    if (e.preventDefault) {
      e.preventDefault();
    }
    else {
      e.returnValue = false;
    }
  }
  window.blockEvent = blockEvent;

  //from here https://github.com/janl/mustache.js/blob/master/mustache.js#L47
  var entityMap = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;',
    '/': '&#x2F;',
    '&amp;': '&',
    '&lt;': '<',
    '&gt;': '>' ,
    '&quot;': '"',
    '&#39;': "'" ,
    '&#x2F;': '/'
  };

  function scrollToTopLeft() {
    if (!window.pageInfo.mobile && !window.pageInfo.store && !window.pageInfo.extform) {
      window.scrollTo(0, 0);
    }
  }

  window.scrollToTopLeft = scrollToTopLeft;

  function htmlEscape(string) {
    return String(string).replace(/[&<>"'\/]/g, function(s) {
      return entityMap[s];
    });
  }

  window.htmlEscape = htmlEscape;
  function htmlDecode(value) {
    return $('<div/>').html(value).text();
  }
  window.htmlDecode = htmlDecode;

  function htmlEncode(s) {
    s = String(s).replace(/&lt;/g, '<').replace(/&gt;/g, '>');
    return s;
  }
  window.htmlEncode = htmlEncode;
  function blockSelection() {
    if (window.getSelection) { window.getSelection().removeAllRanges(); }
    //else if (document.selection && document.selection.clear) {
    // document.selection.clear();
    // }
    else if (document.selection && document.selection.empty) {
      document.selection.empty();
    }
  }
  window.blockSelection = blockSelection;
  function hash(input) {
    var hashI = 0, charI, i;
    if (input.length === 0) {
      return hashI;
    }
    for (i = 0; i < input.length; i++) {
      charI = input.charCodeAt(i);
      hashI = ((hashI << 5) - hashI) + charI;
      hashI = hashI & hashI; // Convert to 32bit integer
    }
    return 'id' + hashI;
  }
  window.hash = hash;


  var split;

  // Avoid running twice; that would break the `nativeSplit` reference
  split = window.split || function(undef) {

    var nativeSplit = String.prototype.split,
        // NPCG: nonparticipating capturing group
        compliantExecNpcg = /()??/.exec('')[1] === undef,
        self;

    self = function(str, separator, limit) {
      // If `separator` is not a regex, use `nativeSplit`
      if (Object.prototype.toString.call(separator) !== '[object RegExp]') {
        return nativeSplit.call(str, separator, limit);
      }
      var output = [],
          flags = (separator.ignoreCase ? 'i' : '') +
          (separator.multiline ? 'm' : '') +
          (separator.extended ? 'x' : '') + // Proposed for ES6
          (separator.sticky ? 'y' : ''), // Firefox 3+
          lastLastIndex = 0,
          // Make `global` and avoid `lastIndex` issues by working with a copy
          separator2, match, lastIndex, lastLength;
      separator = new RegExp(separator.source, flags + 'g');
      str += ''; // Type-convert
      if (!compliantExecNpcg) {
        // Doesn't need flags gy, but they don't hurt
        separator2 = new RegExp('^' + separator.source + '$(?!\\s)', flags);
      }

      limit = limit === undef ?
          -1 >>> 0 : // Math.pow(2, 32) - 1
          limit >>> 0; // ToUint32(limit)
      /* jslint boss:true*/
      while (match = separator.exec(str)) {
        // `separator.lastIndex` is not reliable cross-browser
        lastIndex = match.index + match[0].length;
        if (lastIndex > lastLastIndex) {
          output.push(str.slice(lastLastIndex, match.index));
          // Fix browsers whose `exec` methods don't consistently
          // return `undefined` for
          // nonparticipating capturing groups
          /* jslint loopfunc:true*/
          if (!compliantExecNpcg && match.length > 1) {
            match[0].replace(separator2, function() {
              for (var i = 1; i < arguments.length - 2; i++) {
                if (arguments[i] === undef) {
                  match[i] = undef;
                }
              }
            });
          }
          if (match.length > 1 && match.index < str.length) {
            Array.prototype.push.apply(output, match.slice(1));
          }
          lastLength = match[0].length;
          lastLastIndex = lastIndex;
          if (output.length >= limit) {
            break;
          }
        }
        if (separator.lastIndex === match.index) {
          separator.lastIndex++; // Avoid an infinite loop
        }
      }
      if (lastLastIndex === str.length) {
        if (lastLength || !separator.test('')) {
          output.push('');
        }
      } else {
        output.push(str.slice(lastLastIndex));
      }
      return output.length > limit ? output.slice(0, limit) : output;
    };

    // For convenience
    String.prototype.split = function(separator, limit) {
      return self(this, separator, limit);
    };

    return self;

  }();

}(window, $, templates));