/* Minification failed. Returning unminified contents.
(11,3): run-time error CSS1019: Unexpected token, found '('
(11,13): run-time error CSS1031: Expected selector, found '('
(11,13): run-time error CSS1025: Expected comma or open brace, found '('
(93,2): run-time error CSS1019: Unexpected token, found ')'
(93,3): run-time error CSS1019: Unexpected token, found '('
(93,10): run-time error CSS1031: Expected selector, found ')'
(93,10): run-time error CSS1025: Expected comma or open brace, found ')'
(95,10): run-time error CSS1031: Expected selector, found 'loadLeftMenu('
(95,10): run-time error CSS1025: Expected comma or open brace, found 'loadLeftMenu('
(126,10): run-time error CSS1031: Expected selector, found 'hideMenuChildren('
(126,10): run-time error CSS1025: Expected comma or open brace, found 'hideMenuChildren('
(130,1): run-time error CSS1019: Unexpected token, found '$'
(130,2): run-time error CSS1019: Unexpected token, found '('
(130,11): run-time error CSS1031: Expected selector, found ')'
(130,11): run-time error CSS1025: Expected comma or open brace, found ')'
(136,2): run-time error CSS1019: Unexpected token, found ')'
(153,138): run-time error CSS1031: Expected selector, found '='
(153,138): run-time error CSS1025: Expected comma or open brace, found '='
(157,1): run-time error CSS1019: Unexpected token, found '$'
(157,2): run-time error CSS1019: Unexpected token, found '('
(157,11): run-time error CSS1031: Expected selector, found ')'
(157,11): run-time error CSS1025: Expected comma or open brace, found ')'
(161,2): run-time error CSS1019: Unexpected token, found ')'
(163,10): run-time error CSS1031: Expected selector, found '_uPInitDontShowModalTree('
(163,10): run-time error CSS1025: Expected comma or open brace, found '_uPInitDontShowModalTree('
(183,10): run-time error CSS1031: Expected selector, found 'searchUnitProgram('
(183,10): run-time error CSS1025: Expected comma or open brace, found 'searchUnitProgram('
(248,10): run-time error CSS1031: Expected selector, found '_uPsetUpParametes('
(248,10): run-time error CSS1025: Expected comma or open brace, found '_uPsetUpParametes('
(271,10): run-time error CSS1031: Expected selector, found 'uPBindTree('
(271,10): run-time error CSS1025: Expected comma or open brace, found 'uPBindTree('
(421,10): run-time error CSS1031: Expected selector, found 'uPModalShow('
(421,10): run-time error CSS1025: Expected comma or open brace, found 'uPModalShow('
(581,10): run-time error CSS1031: Expected selector, found 'openAllThisTreeSelection('
(581,10): run-time error CSS1025: Expected comma or open brace, found 'openAllThisTreeSelection('
(590,10): run-time error CSS1031: Expected selector, found 'closeAllThisTreeSelection('
(590,10): run-time error CSS1025: Expected comma or open brace, found 'closeAllThisTreeSelection('
(599,10): run-time error CSS1031: Expected selector, found 'hasProgram('
(599,10): run-time error CSS1025: Expected comma or open brace, found 'hasProgram('
(614,10): run-time error CSS1031: Expected selector, found 'closeThisModal('
(614,10): run-time error CSS1025: Expected comma or open brace, found 'closeThisModal('
(620,10): run-time error CSS1031: Expected selector, found 'clearThisTreeSelection('
(620,10): run-time error CSS1025: Expected comma or open brace, found 'clearThisTreeSelection('
(635,10): run-time error CSS1031: Expected selector, found 'getSelectedItem('
(635,10): run-time error CSS1025: Expected comma or open brace, found 'getSelectedItem('
(670,23): run-time error CSS1031: Expected selector, found '='
(670,23): run-time error CSS1025: Expected comma or open brace, found '='
(674,11): run-time error CSS1030: Expected identifier, found 'extend('
(674,11): run-time error CSS1031: Expected selector, found 'extend('
(674,11): run-time error CSS1025: Expected comma or open brace, found 'extend('
(735,2): run-time error CSS1019: Unexpected token, found ')'
(738,10): run-time error CSS1031: Expected selector, found 'setThisItemDatas('
(738,10): run-time error CSS1025: Expected comma or open brace, found 'setThisItemDatas('
(793,10): run-time error CSS1031: Expected selector, found 'cleanUnitTreeData('
(793,10): run-time error CSS1025: Expected comma or open brace, found 'cleanUnitTreeData('
(798,10): run-time error CSS1031: Expected selector, found 'unitTreeSearch('
(798,10): run-time error CSS1025: Expected comma or open brace, found 'unitTreeSearch('
(820,1): run-time error CSS1019: Unexpected token, found '('
(820,11): run-time error CSS1031: Expected selector, found '('
(820,11): run-time error CSS1025: Expected comma or open brace, found '('
(831,2): run-time error CSS1019: Unexpected token, found '('
(831,12): run-time error CSS1031: Expected selector, found '('
(831,12): run-time error CSS1025: Expected comma or open brace, found '('
(910,54): Scanner error CSS1002: Unterminated string: '+~#";.,=\- \/${}%?`]/g
 */
/**
 * gnmenu.js v1.0.0
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright 2013, Codrops
 * http://www.codrops.com
 */
; (function (window) {
  'use strict';

  // http://stackoverflow.com/a/11381730/989439
  function mobilecheck() {
    var check = false;
    (function (a) { if (/(android|ipad|playbook|silk|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true })(navigator.userAgent || navigator.vendor || window.opera);
    return check;
  }

  function gnMenu(el, options) {
    this.el = el;
    this._init();
  }

  gnMenu.prototype = {
    _init: function () {
      this.trigger = this.el.querySelector('a.trig');
      this.menu = this.el;
      this.isMenuOpen = false;
      this.eventtype = mobilecheck() ? 'touchstart' : 'click';
      this._initEvents();

      var self = this;
      this.bodyClickFn = function () {
        self._closeMenu();
        this.removeEventListener(self.eventtype, self.bodyClickFn);
      };
    },
    _initEvents: function () {
      var self = this;

      //if (mobilecheck()) {
      //  $(".trig").html("<i class='fa fa-bars fa-fw'></i>MENU");
      //}
      this.trigger.addEventListener('mouseover', function (ev) { self._openIconMenu(); });
      this.trigger.addEventListener('mouseout', function (ev) { self._closeIconMenu(); });

      this.menu.addEventListener('mouseover', function (ev) {
        self._openMenu();
        document.addEventListener(self.eventtype, self.bodyClickFn);
      });

      this.menu.addEventListener('mouseout', function (ev) {
        self._closeMenu();
        document.removeEventListener(self.eventtype, self.bodyClickFn);
      });

      this.trigger.addEventListener(this.eventtype, function (ev) {
        ev.stopPropagation();
        ev.preventDefault();
        if (self.isMenuOpen) {
          self._closeMenu();
          document.removeEventListener(self.eventtype, self.bodyClickFn);
        }
        else {
          self._openMenu();
          document.addEventListener(self.eventtype, self.bodyClickFn);
        }
      });
      this.menu.addEventListener(this.eventtype, function (ev) { ev.stopPropagation(); });
    },
    _openIconMenu: function () {

      classie.add(this.menu, 'left-menu-open-part');
    },
    _closeIconMenu: function () {
    },
    _openMenu: function () {
      if (this.isMenuOpen) return;
      this.isMenuOpen = true;
      classie.add(this.menu, 'left-menu-open-all');
    },
    _closeMenu: function () {
      if (!this.isMenuOpen) return;
      this.isMenuOpen = false;
      classie.remove(this.menu, 'left-menu-open-all');
    }
  }

  // add to global namespace
  window.gnMenu = gnMenu;
})(window);

function loadLeftMenu() {
  var _elem = document.getElementById('left-menu-wrapper');
  if (_elem) {
    new gnMenu(_elem);

    var currentAction = $('#currentAction').val();
    $('#left-menu-ul a').each(function () {
      var $current = $(this);
      if ($current.first().attr("href").indexOf(currentAction) > -1) {
        if (!$current.hasClass("none-active")) {
          $current.first().addClass("left-menuactive-a");
        }
        $current.parent().first().addClass("left-menu-active-li");
      }
    });

    //tree toggler

    $('.tree-toggle').click(function () {
      $(this).parent().children('ul.tree').toggle(200);
    });

    $("#left-menu-ul li ul").hide();

    $("#left-menu-ul").on("mouseleave", hideMenuChildren);

    // $("#left-menu-ul").on("mouseleave", hideMenuChildren); // dokunmatik ekransa çalışmayacak ??

  }
}

function hideMenuChildren(e) {
  $("#left-menu-ul li ul").hide("slow");
}

$(document).ready(function () {
  loadLeftMenu();

  $(".loader").on("click", function () {
    showIndicator();
  });
});

//Left Menu Örnek HTML Kodu Kullanım için layout a ekleyin
//<nav id="left-menu-wrapper" class="left-menu-open-part">
//<div id="left-menu-scroller">
//    <!--LeftMenu Container Silme-->
//    <ul id="left-menu-ul" class="list-unstyled">
//        <div class="menuname"><a href="#" class="trig"></a></div>
//        <li><a href="#" class="trig"></a></li>
//        <li>
//            <a href='@Url.Action("Index","Home")' class="tree-toggler loader none-active"><i class="icomoon-book"></i>Ana Sayfa</a>
//            </li>
//        </ul>
//    </div>
//    <span class="pagetitle rotate ellipsis" title="@ViewBag.Title" data-placement="right" rel="tooltip">@ViewBag.Title</span>
//</nav>
var _uPData, _uPId, _uPSelectedEvent, _uPMultiSelect, _uPShowProgram, _uPEed, _uPGEtFullTree, _uPbtn,
  _uPClearEvent, _uPUnitAndProgramMultiselect, _uPSelectHierarchical, _uPDontShowModal, _uPDataSelectedItems, _uPGetOnlyActiveForBologna = null,
  _uPDontUsePrivilage, _uPDataSource,
  _uPAllowedTypes, _uPParentIds, _uFilteredUnitIds, _programTypes, _uPGetPassivePrograms, _uPShowOnlyUnitSingleProgram;

$(document).ready(function () {
  cleanUnitTreeData();

  _uPInitDontShowModalTree();
});

function _uPInitDontShowModalTree() {
  $("[data-dont-show-modal]").each(function () {
    if ($(this).data("dont-show-modal") == "True") {
      _uPId = $(this).data("id");

      $("#up-tree-div-" + _uPId).html("");
      $("#up-tree-div-" + _uPId).data("id", _uPId);
      var _html = "";
      _html += "<div class='row form-group'>";
      _html += "  <div id='up-tree-div-" + _uPId + "' class='col-md-12' style='font-size: 0.95em;' >";
      _html += "  </div>";
      _html += "</div>";
      $(_html).insertAfter("#container-" + _uPId);

      searchUnitProgram(_uPId);
    }
  });
}

//birimleri arar
function searchUnitProgram(_id) {
  _uPId = _id;

  //parametreler setleniyor.
  _uPsetUpParametes();

  var criter = {};

  if (_uPDontUsePrivilage) {
    criter.DontUsePrivilage = _uPDontUsePrivilage;
  }

  if (_uPAllowedTypes) {
    criter.AllowedTypes = _uPAllowedTypes;
  }
  if (_uPGetOnlyActiveForBologna) {
    criter.GetOnlyActiveForBologna = _uPGetOnlyActiveForBologna;
  }
  if (_uPParentIds) {
    criter.ParentIds = _uPParentIds;
  }
  if (_uFilteredUnitIds) {
    criter.FilteredUnitIds = _uFilteredUnitIds
  }

  if (_programTypes) {
    criter.ProgramTypes = _programTypes;
  }

  if (_uPShowOnlyUnitSingleProgram)
    criter.ShowOnlyUnitSingleProgram = true;

  //data varmı bakılıyor
  if (_uPData == null || !criter.AllowedTypes) {
    $.ajax({
      url: location.origin + "/AIS/Common/Helper/GetUnitProgramDataSource",
      data: JSON.stringify({ criter: criter }),
      type: "POST",
      contentType: 'application/json; charset=utf-8',
      beforeSend: showIndicator,
      success: function (data) {
        if (!data || data.length == 0) {
          alert("Yetkiniz dahilinde birim bulunamadı.");
          return;
        }
        _uPData = data;
        if (_uPDontShowModal) {
          uPBindTree();
        } else {
          uPModalShow();
        }
      },
      error: onFailure,
      complete: hideIndicator
    });
  } else {
    if (_uPDontShowModal) {
      uPBindTree();
    } else {
      uPModalShow();
    }
  }
}

//açılan modal için parametreleri setler
function _uPsetUpParametes() {
  _uPbtn = $("#btn-" + _uPId);
  _uPSelectedEvent = _uPbtn.data("selected-event");
  _uPClearEvent = _uPbtn.data("clear-event");
  _uPUnitAndProgramMultiselect = _uPbtn.data("unit-and-program-multiselect") == "True" ? true : false;
  _uPMultiSelect = _uPbtn.data("multiselect") == "True" ? true : false;
  _uPShowProgram = _uPbtn.data("show-program") == "True" ? true : false;
  _uPEed = _uPbtn.data("eed");
  _uPGEtFullTree = _uPbtn.data("get-full-tree") == "True" ? true : false;
  _uPSelectHierarchical = _uPbtn.data("select-hierarchical") == "True" ? true : false;
  _uPDontUsePrivilage = _uPbtn.data("dont-use-privilage") == "True" ? true : false;
  _uPAllowedTypes = _uPbtn.data("allowed-types");
  _uPDontShowModal = _uPbtn.data("dont-show-modal") == "True" ? true : false;
  _uPDataSelectedItems = _uPbtn.data("items");
  _uPGetOnlyActiveForBologna = _uPbtn.data("get-only-active-for-bologna") == "True" ? true : false;
  _uPParentIds = _uPbtn.data("parent-ids");
  _uFilteredUnitIds = _uPbtn.data("filtered-unit-ids");
  _programTypes = _uPbtn.data("program-types");
  _uPGetPassivePrograms = _uPbtn.data("get-passive-programs") == "True" ? true : false;
  _uPShowOnlyUnitSingleProgram = _uPbtn.data("show-only-unit-single-program") == "True" ? true : false;
}

//tree çiziliyor
function uPBindTree() {
  //datalar ayarlanıyor
  var _tempData = [];
  var filteredData = jQuery.extend(true, [], _uPData);
  var allUnits = $.Enumerable.From(filteredData).Where(function (x) { return x.IsAcademicProgram == false }).ToArray();
  var allPrograms = $.Enumerable.From(filteredData).Where(function (x) { return x.IsAcademicProgram == true }).ToArray();
  if (_uPEed != null && _uPEed.length > 0) { allPrograms = $.Enumerable.From(allPrograms).Where(function (x) { return x.EducationQualificatinDegree != null && $.inArray(x.EducationQualificatinDegree, _uPEed) > -1 }).ToArray(); }
  if (_programTypes != null && _programTypes.length > 0) { allPrograms = $.Enumerable.From(allPrograms).Where(function (x) { return x.ProgramType != null && $.inArray(x.ProgramType, _programTypes) > -1 }).ToArray(); }
  if (!_uPGetPassivePrograms) { allPrograms = $.Enumerable.From(allPrograms).Where(function (x) { return 1 == 1 || x.Status == 10201; }).ToArray(); }
  if (!_uPGEtFullTree) {
    var tempUnits = [];
    $.Enumerable.From(allUnits).ForEach(function (item) {
      if (hasProgram(allUnits, allPrograms, item.Id) == true) {
        if (_uPShowOnlyUnitSingleProgram && $.Enumerable.From(allPrograms).Count(function (x) { return x.ParentId == item.Id }) == 1) {
          item.AcademicProgramId = $.Enumerable.From(allPrograms).Where(function (x) { return x.ParentId == item.Id }).FirstOrDefault().Id;
          item.CurriculumId = $.Enumerable.From(allPrograms).Where(function (x) { return x.ParentId == item.Id }).FirstOrDefault().CurriculumId;
        }
        tempUnits.push(item);
      }
    }); allUnits = tempUnits;
  }
  filteredData = allUnits;
  if (_uPShowProgram) { filteredData = filteredData.concat(allPrograms); }
  _uPDataSource = filteredData;
  //tree için data oluşturuluyor.
  $.Enumerable.From(filteredData).ForEach(function (item) {
    //var _isSingle = _uPShowOnlyUnitSingleProgram && item.IsAcademicProgram && $.Enumerable.From(allPrograms).Count(function (x) { return x.ParentId == item.ParentId }) == 1 && !hasProgram([], allUnits, item.ParentId);
    //if (!_isSingle) {
      var _isselected = (_uPDataSelectedItems && $.Enumerable.From(_uPDataSelectedItems).Any(function (x) { return x.Id == item.Id }) ? true : false);
      _tempData.push({
        aisId: item.Id,
        id: item.tId, // required
        parent: item.tParentId,
        text: item.Name, // node text            
        state: {
          opened: item.ParentId == "" || item.ParentId == null ? true : false,  // is the node open
          disabled: !item.IsAcademicProgram ? true : _uPUnitAndProgramMultiselect ? false : (_uPShowProgram ? !item.IsAcademicProgram : false),  // is the node disabled
          selected: _isselected   // is the node selected
        },
        li_attr: {},  // attributes for the generated LI node            
      });
    //}
  });
  var _option = {};
  _option.plugins = [];
  _option.core = {
    "multiple": _uPMultiSelect,
    "animation": 0,
    "themes": {
      "stripes": false,
      "theme": "ubys-theme",
      "icons": false,
      "dots": false,
      "url": true,
      "dir": location.origin + "/FPM/Application/Content/jstree/themes/ubys-theme"
    },
    "data": _tempData,
    "open": ["u1001"],
  };
  _option.search = {
    "show_only_matches": true,
    "show_only_matches_children": true,
    "close_opened_onclear": true
  };

  if (_uPMultiSelect) {
    _option.checkbox = {
      three_state: _uPSelectHierarchical,// false,// _uPMultiSelect, //hiyerarşik toplu seçime izin verme
      cascade: 'undetermined'
    }
    _option.plugins.push("checkbox");
  }

  _option.plugins.push("dnd");
  _option.plugins.push("sort");
  _option.plugins.push("state");
  _option.plugins.push("types");
  _option.plugins.push("unique");
  _option.plugins.push("wholerow");
  _option.plugins.push("search");
  _option.plugins.push("themes");



  //initjstree
  $("#up-tree-div-" + _uPId).jstree(_option);

  $("#up-tree-div-" + _uPId).bind("loaded.jstree", function (e, data) {
    _uPId = e.currentTarget.id.substring(12);
    _uPsetUpParametes();

    //var olan datalar setlensin
    //setli idler alınıyor.
    var _tempSelecteditems = $(_uPbtn).data("items");

    if (_tempSelecteditems != null && _tempSelecteditems.length > 0) {
      _tempIds = [];
      $.Enumerable.From(_tempSelecteditems).ForEach(function (item) {
        _tempIds.push(item.tId.toString());
      });

      $("#" + e.currentTarget.id).jstree(true).select_node(_tempIds);
    }
  });

  //click eventi atanıyor.
  $("#up-tree-div-" + _uPId).on('select_node.jstree', function (e, data) {
    _uPId = e.currentTarget.id.substring(12);
    _uPsetUpParametes();

    var _ids = [];
    var _tempTreeIds = [];
    var _realDatas = [];

    _tempTreeIds = $("#" + e.currentTarget.id).data("jstree").get_selected();

    if (_tempTreeIds != null && _tempTreeIds.length > 0) {
      _realDatas = $.Enumerable.From(_uPData).Where(function (x) { return $.inArray(x.tId, _tempTreeIds) > -1 }).ToArray();
    }

    if (_realDatas != null && _realDatas.length > 0) {
      for (var i = 0; i < _realDatas.length; i++) {
        _ids.push(parseInt(_realDatas[i].Id));
      }
    }

    _uPbtn.data("ids", _ids);
    _uPbtn.data("items", _realDatas);

    //eğer tanımlı bir event varsa
    if (_uPSelectedEvent) {
      var fn = window[_uPSelectedEvent];
      fn(_ids, _uPbtn);
    }
  });

  var to = false;
  $('#search-tree-' + _uPId).keyup(function () {
    _uPId = $(this).attr("id").substring(12);
    if (to) { clearTimeout(to); }
    to = setTimeout(function () {
      var v = $('#search-tree-' + _uPId).val();
      $('#up-tree-div-' + _uPId).jstree(true).search(v);
    }, 250);
  });

  initTooltipFix();
}

//modeli açar
function uPModalShow() {
  showIndicator();

  //datalar ayarlanıyor
  var _tempData = [];
  var filteredData = jQuery.extend(true, [], _uPData);
  var allUnits = $.Enumerable.From(filteredData).Where(function (x) { return x.IsAcademicProgram == false }).ToArray();
  var allPrograms = $.Enumerable.From(filteredData).Where(function (x) { return x.IsAcademicProgram == true }).ToArray();
  if (_uPEed != null && _uPEed.length > 0) { allPrograms = $.Enumerable.From(allPrograms).Where(function (x) { return x.EducationQualificatinDegree != null && $.inArray(x.EducationQualificatinDegree, _uPEed) > -1 }).ToArray(); }
  if (_programTypes != null && _programTypes.length > 0) { allPrograms = $.Enumerable.From(allPrograms).Where(function (x) { return x.ProgramType != null && $.inArray(x.ProgramType, _programTypes) > -1 }).ToArray(); }
  if (!_uPGetPassivePrograms) { allPrograms = $.Enumerable.From(allPrograms).Where(function (x) { return 1 == 1 || x.Status == 10201; }).ToArray(); }
  if (!_uPGEtFullTree) {
    var tempUnits = [];
    $.Enumerable.From(allUnits).ForEach(function (item) {
      if (hasProgram(allUnits, allPrograms, item.Id) == true) {
        if (_uPShowOnlyUnitSingleProgram && $.Enumerable.From(allPrograms).Count(function (x) { return x.ParentId == item.Id }) == 1) {
          item.AcademicProgramId = $.Enumerable.From(allPrograms).Where(function (x) { return x.ParentId == item.Id }).FirstOrDefault().Id;
          item.CurriculumId = $.Enumerable.From(allPrograms).Where(function (x) { return x.ParentId == item.Id }).FirstOrDefault().CurriculumId;
        }
        tempUnits.push(item);
      }
    }); allUnits = tempUnits;
  }
  filteredData = allUnits;
  if (_uPShowProgram) { filteredData = filteredData.concat(allPrograms); }
  _uPDataSource = filteredData;
  //tree için data oluşturuluyor.
  $.Enumerable.From(filteredData).ForEach(function (item) {
    var _isSingle = _uPShowOnlyUnitSingleProgram && item.IsAcademicProgram && $.Enumerable.From(allPrograms).Count(function (x) { return x.ParentId == item.ParentId }) == 1;
    if (!_isSingle) {
      _tempData.push({
        aisId: item.Id,
        id: item.tId, // required
        parent: item.tParentId,
        text: item.Name, // node text            
        state: {
          opened: item.ParentId == "" || item.ParentId == null ? true : false,  // is the node open
          disabled: _uPUnitAndProgramMultiselect ? false : (_uPShowProgram ? !item.IsAcademicProgram : false),  // is the node disabled
          selected: false  // is the node selected
        },
        li_attr: {},  // attributes for the generated LI node
        a_attr: item.IsAcademicProgram ? { "style": "color:#003DFF" } : {}  // attributes for the generated A node
      });
    }
  });
  sessionStorage.removeItem("jstree");

  var _html = "";
  _html += "<section id='mm-" + _uPId + "' class='modal--show' tabindex='-1' role='dialog' aria-labelledby='label-show' aria-hidden='true'>";
  _html += "<div class='modal--inner'>";

  //modal başlığı
  _html += "<header>";
  _html += "<h4 id='label-show'>" + (_uPShowProgram ? "Program Ağacı" : "Birim Program Ağacı") + "</h4>";
  _html += "<div class='row'><div class='col-md-10'><input type='search' data-id='" + _uPId + "' data-unit-search='ul-" + _uPId + "' data-target='li' class='form-control input-sm mb10' id='search-" + _uPId + "' placeholder='Birim veya program arayabilirsiniz...' />";
  _html += "</div>";
  _html += "<div class='col-md-2'>";
  _html += "<div class='btn-group btn-group-sm btn-group-justified'>";
  _html += "<a onclick='openAllThisTreeSelection()' rel='tooltip' title='Tümünü Aç'  class='btn btn-default '><i class='fa fa-expand fa-fw'></i></a>";
  _html += "<a onclick='closeAllThisTreeSelection()' rel='tooltip' title='Tümünü Kapat'   class='btn btn-default'><i class='fa fa-compress fa-fw'></i></a>";
  _html += "</div>";
  _html += "</div>";
  _html += "</header>";

  //modal içeriği
  _html += "<div class='modal--content' id='ul-" + _uPId + "' style='  font-size: 0.95em;' ></div>";

  //modal butonları
  _html += "<footer class='text-right'>";
  _html += "<a onclick='clearThisTreeSelection()'   class='btn btn-default btn-xs mr5'><i class='fa fa-refresh fa-fw'></i>Temizle</a>";
  _html += "<a onclick='getSelectedItem()'  class='btn btn-success btn-xs'><i class='fa fa-magic fa-fw'></i>Seç</a>";
  _html += "</footer>";

  _html += "</div>";
  _html += "<a onclick='closeThisModal()' class='modal-close' title='Close this modal' data-dismiss='modal' data-close='Close'>×</a>";
  _html += "</section>";
  var __modal = _uPbtn.closest(".modal");
  if (__modal.length > 0) {
    if (__modal.find("section").length > 0) {
      __modal.find("section").prepend(_html);
    } else {
      __modal.prepend(_html);
    }
  } else {
    $("body").append(_html);
  }

  //initjstree
  $("#ul-" + _uPId).jstree(
    {
      "core": {
        "multiple": _uPMultiSelect,
        "animation": 0,
        "themes": {
          "stripes": true,
          "theme": "default-dark",
          "icons": false
        },
        "data": _tempData,
        "open": ["u1001"]
      },

      search: {
        show_only_matches: false,
        show_only_matches_children: false,
        close_opened_onclear: true,
        //search_leaves_only:true//en altta aramaya yarıyor
      },


      "checkbox": {
        three_state: _uPSelectHierarchical,// false,// _uPMultiSelect, //hiyerarşik toplu seçime izin verme
        cascade: 'undetermined'
      },
      "plugins": ["checkbox", "dnd", "sort", "state", "types", "unique", "wholerow", "search"] //, "search"
    }).bind("loaded.jstree", function (event, data) {
      //esc tuşuna basınca kapansın
      document.addEventListener("keydown", function (e) {
        if (e.keyCode == 27) {
          closeThisModal();
        }
      }, false);

      //önceden kalmış data var ise sıfırlanıyor.
      $("#ul-" + _uPId).jstree(true).deselect_all();

      //var olan datalar setlensin
      //setli idler alınıyor.
      var _tempSelecteditems = $(_uPbtn).data("items");

      if (_tempSelecteditems != null && _tempSelecteditems.length > 0) {
        _tempIds = [];
        $.Enumerable.From(_tempSelecteditems).ForEach(function (item) {
          _tempIds.push(item.tId.toString());
        });

        $("#ul-" + _uPId).jstree(true).select_node(_tempIds);
      }
      unitTreeSearch();

      var to = false;
      $('#search-' + _uPId).keyup(function () {
        _uPId = $(this).attr("id").substring(7);
        if (to) { clearTimeout(to); }
        to = setTimeout(function () {
          var v = $('#search-' + _uPId).val();
          $("#ul-" + _uPId).jstree(true).search(v);
        }, 250);
      });


      $("#mm-" + _uPId).addClass("is-active").attr("aria-hidden", false);
    });

  initTooltipFix();

  hideIndicator();
}

//tree collapse
function openAllThisTreeSelection(_id) {
  if (_id) {
    $("#up-tree-div-" + _uPId).jstree("open_all");
  } else {
    $("#ul-" + _uPId).jstree("open_all");
  }
}

//tree expand
function closeAllThisTreeSelection(_id) {
  if (_id) {
    $("#up-tree-div-" + _uPId).jstree("close_all");
  } else {
    $("#ul-" + _uPId).jstree("close_all");
  }
}

//program kontrolü
function hasProgram(_allUnits, _allPrograms, Id) {
  var result = $.Enumerable.From(_allPrograms).Any(function (x) { return x.ParentId == Id });
  if (!result) {
    var br = false;
    $.Enumerable.From(_allUnits).Where(function (x) { return x.ParentId == Id }).ForEach(function (item) {
      if (!br & hasProgram(_allUnits, _allPrograms, item.Id)) {
        result = true;
        br = true;
      }
    });
  }
  return result;
}

//modalı kapatmak için
function closeThisModal() {
  $("#mm-" + _uPId).removeClass("is-active").attr("aria-hidden", true);
  getSelectedItem();
}

//seçimleri temizlemek için.
function clearThisTreeSelection(_id) {
  if (_id != null && _id != undefined) {
    setThisItemDatas(_id, []);
  } else if (_uPId != null && _uPId != undefined) {
    $("#ul-" + _uPId).jstree(true).deselect_all();
    setThisItemDatas(_uPId, []);
  }

  if (_uPClearEvent != null && _uPClearEvent != "") {
    var _clearFn = window[_uPClearEvent];
    _clearFn(_uPbtn);
  }
}

//seçilenleri almak için
function getSelectedItem() {
  var _ids = [];
  var _tempTreeIds = [];
  var _realDatas = [];
  var _textValues = "";

  _tempTreeIds = $("#ul-" + _uPId).data("jstree").get_selected();

  if (_tempTreeIds != null && _tempTreeIds.length > 0) {
    _realDatas = $.Enumerable.From(_uPData).Where(function (x) { return $.inArray(x.tId, _tempTreeIds) > -1 }).ToArray();
  }

  if (_realDatas != null && _realDatas.length > 0) {
    for (var i = 0; i < _realDatas.length; i++) {
      _ids.push(parseInt(_realDatas[i].Id));
    }
    _textValues = $.Enumerable.From(_realDatas).Select(function (x) { return x.FullAcademicProgramName }).ToArray().join(",");
  }

  $("#" + _uPId).val(_ids);
  $("#result-" + _uPId).val(_textValues);
  $("#btn-" + _uPId).data("ids", _ids);
  $("#btn-" + _uPId).data("items", _realDatas);

  $("#mm-" + _uPId).removeClass("is-active").attr("aria-hidden", true);

  //eğer tanımlı bir event varsa
  if (_uPSelectedEvent) {
    var fn = window[_uPSelectedEvent];
    fn(_ids, _uPbtn);
  }
  $("#mm-" + _uPId).remove();
}

//ekran yenilenince jstree sıfırlanıyor.
window.onbeforeunload = function (event) {
  cleanUnitTreeData();
};

jQuery.fn.extend({
  getSelectedItems: function () {
    var _id = this.selector.substring(1);
    return $("#btn-" + _id).data("items");
  },
  getSelectedIds: function () {
    var _id = this.selector.substring(1);
    return $("#btn-" + _id).data("ids");
  },
  getSelectedId: function () {
    var _id = this.selector.substring(1);
    var _ids = $("#btn-" + _id).data("ids");
    return _ids != null && _ids.length > 0 ? _ids[0] : null;
  },
  setSelectedIds: function (_ids, _isAp) {
    if (_ids != undefined) {
      _uPId = this.selector.substring(1);
      _uPsetUpParametes();
      if (_uPData == null) {
        $.ajax({
          url: location.origin + "/AIS/Common/Helper/GetUnitProgramDataSource",
          data: JSON.stringify({ DontUsePrivilage: _uPDontUsePrivilage }),
          type: "POST",
          contentType: 'application/json; charset=utf-8',
          beforeSend: showIndicator,
          success: function (data) {
            if (!data || data.length == 0) { return; }
            _uPData = data;
            setThisItemDatas(_uPId, _ids, _isAp);
          },
          error: onFailure,
          complete: hideIndicator
        });
      } else {
        setThisItemDatas(_uPId, _ids, _isAp);
      }
    } else {
      return showError("Bir hata ile karşılaşıldı. Birim ağacını kontrol edin...")
    }
  },
  clearSelected: function () {
    clearThisTreeSelection(this.selector.substring(1));
  },
  getSelectedItem: function () {
    var _id = this.selector.substring(1);
    var _items = $("#btn-" + _id).data("items");
    return _items != null && _items.length > 0 ? _items[0] : null;
  },
  getSelectedAcademicPrograms: function () {
    var _id = this.selector.substring(1);
    var dataAP = $("#btn-" + _id).data("items");
    return dataAP != null && $.Enumerable.From(dataAP).Any(function (x) { return x.IsAcademicProgram }) ? $.Enumerable.From(dataAP).Where(function (x) { return x.IsAcademicProgram }).ToArray() : null;
  },
  getSelectedAcademicProgramIds: function () {
    var _id = this.selector.substring(1);
    var dataAP = $("#btn-" + _id).data("items");
    return dataAP != null && $.Enumerable.From(dataAP).Any(function (x) { return x.IsAcademicProgram }) ? $.Enumerable.From(dataAP).Where(function (x) { return x.IsAcademicProgram }).Select(function (x) { return x.Id }).ToArray() : null;
  },
  getAllData: function () {
    return _uPDataSource;
  }
});

//datalar setleniyor.
function setThisItemDatas(_btnid, _selectedIds, _isAp) {
  _uPId = _btnid;

  //parametreler setleniyor.
  _uPsetUpParametes();
  //if (_btnid != _uPId) {
  //  return;
  //}
  var _items = [];
  var _textValues = "";
  var _tempIds = [];

  $(_selectedIds).each(function (i, _selectedId) {
    _selectedId = parseInt(_selectedId);
  });

  if (_uPUnitAndProgramMultiselect) {
    if (_isAp != null && _isAp != undefined && _isAp)
      _items = $.Enumerable.From(_uPData).Where(function (x) { return $.inArray(x.Id, _selectedIds) > -1 && x.IsAcademicProgram }).ToArray();
    else
      _items = $.Enumerable.From(_uPData).Where(function (x) { return $.inArray(x.Id, _selectedIds) > -1 && !x.IsAcademicProgram }).ToArray();

    if (_items != null && _items.length > 0) {
      _textValues = $.Enumerable.From(_items).Select(function (x) { return (x.IsAcademicProgram ? x.FullAcademicProgramName : x.Name) }).ToArray().join(",");
      _tempIds = $.Enumerable.From(_items).Select(function (x) { return parseInt(x.Id) }).ToArray();
    }
  } else if (_uPShowProgram) {
    _items = $.Enumerable.From(_uPData).Where(function (x) { return $.inArray(x.Id, _selectedIds) > -1 && x.IsAcademicProgram }).ToArray();
    if (_items != null && _items.length > 0) {
      _textValues = $.Enumerable.From(_items).Select(function (x) { return x.FullAcademicProgramName }).ToArray().join(",");
      _tempIds = $.Enumerable.From(_items).Select(function (x) { return parseInt(x.Id) }).ToArray();
    }
  } else {
    _items = $.Enumerable.From(_uPData).Where(function (x) { return $.inArray(x.Id, _selectedIds) > -1 && !x.IsAcademicProgram }).ToArray();
    if (_items != null && _items.length > 0) {
      _textValues = $.Enumerable.From(_items).Select(function (x) { return x.Name }).ToArray().join(",");
      _tempIds = $.Enumerable.From(_items).Select(function (x) { return parseInt(x.Id) }).ToArray();
    }
  }

  $("#" + _btnid).val(_tempIds);
  $("#result-" + _btnid).val(_textValues);
  $("#btn-" + _btnid).data("ids", _tempIds);
  $("#btn-" + _btnid).data("items", _items);

  if (_uPDontShowModal) {
    openAllThisTreeSelection(_uPId);
    $("#p" + _selectedIds[0] + "_anchor").click();
    $("#up-tree-div-" + _uPId).jstree(true).select_node(_selectedIds);
    closeAllThisTreeSelection(_uPId);
  }

}

//ağaç temp temizleniyor.
function cleanUnitTreeData() {
  sessionStorage.removeItem("jstree");
}

//aağç üzerinde arama yapmak için
function unitTreeSearch() {
  var _elem, _id, _sid, _se, _sep, _filter;

  //$('[data-unit-search]').on('focus', function () {
  //    openAllThisTreeSelection(_id);
  //    _elem = $(this);
  //    _id = _elem.data("id");
  //    _sid = _elem.prop("id")
  //    _se = _elem.data("unit-search");
  //    _sep = _elem.data("target");

  //    $("#" + _sid).unbind("keyup");
  //    $("#" + _sid).bind("keyup", function () {
  //        _filter = $.trim($(this).val()).replace(/ +/g, ' ').toLCase();
  //        $("#" + _se + " " + _sep).show().filter(function () {
  //            var itemText = $(this).text().replace(/\s+/g, ' ').toLCase();
  //            return !~itemText.indexOf(_filter);
  //        }).hide().child().show();
  //    });
  //});
}
/*globals jQuery, define, exports, require, window, document, postMessage */
(function (factory) {
	"use strict";
	if (typeof define === 'function' && define.amd) {
		define(['jquery'], factory);
	}
	else if(typeof exports === 'object') {
		factory(require('jquery'));
	}
	else {
		factory(jQuery);
	}
}(function ($, undefined) {
	"use strict";
/*!
 * jsTree 3.1.1
 * http://jstree.com/
 *
 * Copyright (c) 2014 Ivan Bozhanov (http://vakata.com)
 *
 * Licensed same as jquery - under the terms of the MIT License
 *   http://www.opensource.org/licenses/mit-license.php
 */
/*!
 * if using jslint please allow for the jQuery global and use following options:
 * jslint: browser: true, ass: true, bitwise: true, continue: true, nomen: true, plusplus: true, regexp: true, unparam: true, todo: true, white: true
 */

	// prevent another load? maybe there is a better way?
	if($.jstree) {
		return;
	}

	/**
	 * ### jsTree core functionality
	 */

	// internal variables
	var instance_counter = 0,
		ccp_node = false,
		ccp_mode = false,
		ccp_inst = false,
		themes_loaded = [],
		src = $('script:last').attr('src'),
		document = window.document, // local variable is always faster to access then a global
		_node = document.createElement('LI'), _temp1, _temp2;

	_node.setAttribute('role', 'treeitem');
	_temp1 = document.createElement('I');
	_temp1.className = 'jstree-icon jstree-ocl';
	_temp1.setAttribute('role', 'presentation');
	_node.appendChild(_temp1);
	_temp1 = document.createElement('A');
	_temp1.className = 'jstree-anchor';
	_temp1.setAttribute('href','#');
	_temp1.setAttribute('tabindex','-1');
	_temp2 = document.createElement('I');
	_temp2.className = 'jstree-icon jstree-themeicon';
	_temp2.setAttribute('role', 'presentation');
	_temp1.appendChild(_temp2);
	_node.appendChild(_temp1);
	_temp1 = _temp2 = null;


	/**
	 * holds all jstree related functions and variables, including the actual class and methods to create, access and manipulate instances.
	 * @name $.jstree
	 */
	$.jstree = {
		/**
		 * specifies the jstree version in use
		 * @name $.jstree.version
		 */
		version : '3.1.1',
		/**
		 * holds all the default options used when creating new instances
		 * @name $.jstree.defaults
		 */
		defaults : {
			/**
			 * configure which plugins will be active on an instance. Should be an array of strings, where each element is a plugin name. The default is `[]`
			 * @name $.jstree.defaults.plugins
			 */
			plugins : []
		},
		/**
		 * stores all loaded jstree plugins (used internally)
		 * @name $.jstree.plugins
		 */
		plugins : {},
		path : src && src.indexOf('/') !== -1 ? src.replace(/\/[^\/]+$/,'') : '',
		idregex : /[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g
	};
	/**
	 * creates a jstree instance
	 * @name $.jstree.create(el [, options])
	 * @param {DOMElement|jQuery|String} el the element to create the instance on, can be jQuery extended or a selector
	 * @param {Object} options options for this instance (extends `$.jstree.defaults`)
	 * @return {jsTree} the new instance
	 */
	$.jstree.create = function (el, options) {
		var tmp = new $.jstree.core(++instance_counter),
			opt = options;
		options = $.extend(true, {}, $.jstree.defaults, options);
		if(opt && opt.plugins) {
			options.plugins = opt.plugins;
		}
		$.each(options.plugins, function (i, k) {
			if(i !== 'core') {
				tmp = tmp.plugin(k, options[k]);
			}
		});
		$(el).data('jstree', tmp);
		tmp.init(el, options);
		return tmp;
	};
	/**
	 * remove all traces of jstree from the DOM and destroy all instances
	 * @name $.jstree.destroy()
	 */
	$.jstree.destroy = function () {
		$('.jstree:jstree').jstree('destroy');
		$(document).off('.jstree');
	};
	/**
	 * the jstree class constructor, used only internally
	 * @private
	 * @name $.jstree.core(id)
	 * @param {Number} id this instance's index
	 */
	$.jstree.core = function (id) {
		this._id = id;
		this._cnt = 0;
		this._wrk = null;
		this._data = {
			core : {
				themes : {
					name : false,
					dots : false,
					icons : false
				},
				selected : [],
				last_error : {},
				working : false,
				worker_queue : [],
				focused : null
			}
		};
	};
	/**
	 * get a reference to an existing instance
	 *
	 * __Examples__
	 *
	 *	// provided a container with an ID of "tree", and a nested node with an ID of "branch"
	 *	// all of there will return the same instance
	 *	$.jstree.reference('tree');
	 *	$.jstree.reference('#tree');
	 *	$.jstree.reference($('#tree'));
	 *	$.jstree.reference(document.getElementByID('tree'));
	 *	$.jstree.reference('branch');
	 *	$.jstree.reference('#branch');
	 *	$.jstree.reference($('#branch'));
	 *	$.jstree.reference(document.getElementByID('branch'));
	 *
	 * @name $.jstree.reference(needle)
	 * @param {DOMElement|jQuery|String} needle
	 * @return {jsTree|null} the instance or `null` if not found
	 */
	$.jstree.reference = function (needle) {
		var tmp = null,
			obj = null;
		if(needle && needle.id && (!needle.tagName || !needle.nodeType)) { needle = needle.id; }

		if(!obj || !obj.length) {
			try { obj = $(needle); } catch (ignore) { }
		}
		if(!obj || !obj.length) {
			try { obj = $('#' + needle.replace($.jstree.idregex,'\\$&')); } catch (ignore) { }
		}
		if(obj && obj.length && (obj = obj.closest('.jstree')).length && (obj = obj.data('jstree'))) {
			tmp = obj;
		}
		else {
			$('.jstree').each(function () {
				var inst = $(this).data('jstree');
				if(inst && inst._model.data[needle]) {
					tmp = inst;
					return false;
				}
			});
		}
		return tmp;
	};
	/**
	 * Create an instance, get an instance or invoke a command on a instance.
	 *
	 * If there is no instance associated with the current node a new one is created and `arg` is used to extend `$.jstree.defaults` for this new instance. There would be no return value (chaining is not broken).
	 *
	 * If there is an existing instance and `arg` is a string the command specified by `arg` is executed on the instance, with any additional arguments passed to the function. If the function returns a value it will be returned (chaining could break depending on function).
	 *
	 * If there is an existing instance and `arg` is not a string the instance itself is returned (similar to `$.jstree.reference`).
	 *
	 * In any other case - nothing is returned and chaining is not broken.
	 *
	 * __Examples__
	 *
	 *	$('#tree1').jstree(); // creates an instance
	 *	$('#tree2').jstree({ plugins : [] }); // create an instance with some options
	 *	$('#tree1').jstree('open_node', '#branch_1'); // call a method on an existing instance, passing additional arguments
	 *	$('#tree2').jstree(); // get an existing instance (or create an instance)
	 *	$('#tree2').jstree(true); // get an existing instance (will not create new instance)
	 *	$('#branch_1').jstree().select_node('#branch_1'); // get an instance (using a nested element and call a method)
	 *
	 * @name $().jstree([arg])
	 * @param {String|Object} arg
	 * @return {Mixed}
	 */
	$.fn.jstree = function (arg) {
		// check for string argument
		var is_method	= (typeof arg === 'string'),
			args		= Array.prototype.slice.call(arguments, 1),
			result		= null;
		if(arg === true && !this.length) { return false; }
		this.each(function () {
			// get the instance (if there is one) and method (if it exists)
			var instance = $.jstree.reference(this),
				method = is_method && instance ? instance[arg] : null;
			// if calling a method, and method is available - execute on the instance
			result = is_method && method ?
				method.apply(instance, args) :
				null;
			// if there is no instance and no method is being called - create one
			if(!instance && !is_method && (arg === undefined || $.isPlainObject(arg))) {
				$.jstree.create(this, arg);
			}
			// if there is an instance and no method is called - return the instance
			if( (instance && !is_method) || arg === true ) {
				result = instance || false;
			}
			// if there was a method call which returned a result - break and return the value
			if(result !== null && result !== undefined) {
				return false;
			}
		});
		// if there was a method call with a valid return value - return that, otherwise continue the chain
		return result !== null && result !== undefined ?
			result : this;
	};
	/**
	 * used to find elements containing an instance
	 *
	 * __Examples__
	 *
	 *	$('div:jstree').each(function () {
	 *		$(this).jstree('destroy');
	 *	});
	 *
	 * @name $(':jstree')
	 * @return {jQuery}
	 */
	$.expr[':'].jstree = $.expr.createPseudo(function(search) {
		return function(a) {
			return $(a).hasClass('jstree') &&
				$(a).data('jstree') !== undefined;
		};
	});

	/**
	 * stores all defaults for the core
	 * @name $.jstree.defaults.core
	 */
	$.jstree.defaults.core = {
		/**
		 * data configuration
		 *
		 * If left as `false` the HTML inside the jstree container element is used to populate the tree (that should be an unordered list with list items).
		 *
		 * You can also pass in a HTML string or a JSON array here.
		 *
		 * It is possible to pass in a standard jQuery-like AJAX config and jstree will automatically determine if the response is JSON or HTML and use that to populate the tree.
		 * In addition to the standard jQuery ajax options here you can suppy functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node is being loaded, the return value of those functions will be used.
		 *
		 * The last option is to specify a function, that function will receive the node being loaded as argument and a second param which is a function which should be called with the result.
		 *
		 * __Examples__
		 *
		 *	// AJAX
		 *	$('#tree').jstree({
		 *		'core' : {
		 *			'data' : {
		 *				'url' : '/get/children/',
		 *				'data' : function (node) {
		 *					return { 'id' : node.id };
		 *				}
		 *			}
		 *		});
		 *
		 *	// direct data
		 *	$('#tree').jstree({
		 *		'core' : {
		 *			'data' : [
		 *				'Simple root node',
		 *				{
		 *					'id' : 'node_2',
		 *					'text' : 'Root node with options',
		 *					'state' : { 'opened' : true, 'selected' : true },
		 *					'children' : [ { 'text' : 'Child 1' }, 'Child 2']
		 *				}
		 *			]
		 *		});
		 *
		 *	// function
		 *	$('#tree').jstree({
		 *		'core' : {
		 *			'data' : function (obj, callback) {
		 *				callback.call(this, ['Root 1', 'Root 2']);
		 *			}
		 *		});
		 *
		 * @name $.jstree.defaults.core.data
		 */
		data			: false,
		/**
		 * configure the various strings used throughout the tree
		 *
		 * You can use an object where the key is the string you need to replace and the value is your replacement.
		 * Another option is to specify a function which will be called with an argument of the needed string and should return the replacement.
		 * If left as `false` no replacement is made.
		 *
		 * __Examples__
		 *
		 *	$('#tree').jstree({
		 *		'core' : {
		 *			'strings' : {
		 *				'Loading ...' : 'Please wait ...'
		 *			}
		 *		}
		 *	});
		 *
		 * @name $.jstree.defaults.core.strings
		 */
		strings			: false,
		/**
		 * determines what happens when a user tries to modify the structure of the tree
		 * If left as `false` all operations like create, rename, delete, move or copy are prevented.
		 * You can set this to `true` to allow all interactions or use a function to have better control.
		 *
		 * __Examples__
		 *
		 *	$('#tree').jstree({
		 *		'core' : {
		 *			'check_callback' : function (operation, node, node_parent, node_position, more) {
		 *				// operation can be 'create_node', 'rename_node', 'delete_node', 'move_node' or 'copy_node'
		 *				// in case of 'rename_node' node_position is filled with the new node name
		 *				return operation === 'rename_node' ? true : false;
		 *			}
		 *		}
		 *	});
		 *
		 * @name $.jstree.defaults.core.check_callback
		 */
		check_callback	: false,
		/**
		 * a callback called with a single object parameter in the instance's scope when something goes wrong (operation prevented, ajax failed, etc)
		 * @name $.jstree.defaults.core.error
		 */
		error			: $.noop,
		/**
		 * the open / close animation duration in milliseconds - set this to `false` to disable the animation (default is `200`)
		 * @name $.jstree.defaults.core.animation
		 */
		animation		: 200,
		/**
		 * a boolean indicating if multiple nodes can be selected
		 * @name $.jstree.defaults.core.multiple
		 */
		multiple		: true,
		/**
		 * theme configuration object
		 * @name $.jstree.defaults.core.themes
		 */
		themes			: {
			/**
			 * the name of the theme to use (if left as `false` the default theme is used)
			 * @name $.jstree.defaults.core.themes.name
			 */
			name			: false,
			/**
			 * the URL of the theme's CSS file, leave this as `false` if you have manually included the theme CSS (recommended). You can set this to `true` too which will try to autoload the theme.
			 * @name $.jstree.defaults.core.themes.url
			 */
			url				: false,
			/**
			 * the location of all jstree themes - only used if `url` is set to `true`
			 * @name $.jstree.defaults.core.themes.dir
			 */
			dir				: false,
			/**
			 * a boolean indicating if connecting dots are shown
			 * @name $.jstree.defaults.core.themes.dots
			 */
			dots			: true,
			/**
			 * a boolean indicating if node icons are shown
			 * @name $.jstree.defaults.core.themes.icons
			 */
			icons			: true,
			/**
			 * a boolean indicating if the tree background is striped
			 * @name $.jstree.defaults.core.themes.stripes
			 */
			stripes			: false,
			/**
			 * a string (or boolean `false`) specifying the theme variant to use (if the theme supports variants)
			 * @name $.jstree.defaults.core.themes.variant
			 */
			variant			: false,
			/**
			 * a boolean specifying if a reponsive version of the theme should kick in on smaller screens (if the theme supports it). Defaults to `false`.
			 * @name $.jstree.defaults.core.themes.responsive
			 */
			responsive		: false
		},
		/**
		 * if left as `true` all parents of all selected nodes will be opened once the tree loads (so that all selected nodes are visible to the user)
		 * @name $.jstree.defaults.core.expand_selected_onload
		 */
		expand_selected_onload : true,
		/**
		 * if left as `true` web workers will be used to parse incoming JSON data where possible, so that the UI will not be blocked by large requests. Workers are however about 30% slower. Defaults to `true`
		 * @name $.jstree.defaults.core.worker
		 */
		worker : true,
		/**
		 * Force node text to plain text (and escape HTML). Defaults to `false`
		 * @name $.jstree.defaults.core.force_text
		 */
		force_text : false,
		/**
		 * Should the node should be toggled if the text is double clicked . Defaults to `true`
		 * @name $.jstree.defaults.core.dblclick_toggle
		 */
		dblclick_toggle : true
	};
	$.jstree.core.prototype = {
		/**
		 * used to decorate an instance with a plugin. Used internally.
		 * @private
		 * @name plugin(deco [, opts])
		 * @param  {String} deco the plugin to decorate with
		 * @param  {Object} opts options for the plugin
		 * @return {jsTree}
		 */
		plugin : function (deco, opts) {
			var Child = $.jstree.plugins[deco];
			if(Child) {
				this._data[deco] = {};
				Child.prototype = this;
				return new Child(opts, this);
			}
			return this;
		},
		/**
		 * initialize the instance. Used internally.
		 * @private
		 * @name init(el, optons)
		 * @param {DOMElement|jQuery|String} el the element we are transforming
		 * @param {Object} options options for this instance
		 * @trigger init.jstree, loading.jstree, loaded.jstree, ready.jstree, changed.jstree
		 */
		init : function (el, options) {
			this._model = {
				data : {
					'#' : {
						id : '#',
						parent : null,
						parents : [],
						children : [],
						children_d : [],
						state : { loaded : false }
					}
				},
				changed : [],
				force_full_redraw : false,
				redraw_timeout : false,
				default_state : {
					loaded : true,
					opened : false,
					selected : false,
					disabled : false
				}
			};

			this.element = $(el).addClass('jstree jstree-' + this._id);
			this.settings = options;

			this._data.core.ready = false;
			this._data.core.loaded = false;
			this._data.core.rtl = (this.element.css("direction") === "rtl");
			this.element[this._data.core.rtl ? 'addClass' : 'removeClass']("jstree-rtl");
			this.element.attr('role','tree');
			if(this.settings.core.multiple) {
				this.element.attr('aria-multiselectable', true);
			}
			if(!this.element.attr('tabindex')) {
				this.element.attr('tabindex','0');
			}

			this.bind();
			/**
			 * triggered after all events are bound
			 * @event
			 * @name init.jstree
			 */
			this.trigger("init");

			this._data.core.original_container_html = this.element.find(" > ul > li").clone(true);
			this._data.core.original_container_html
				.find("li").addBack()
				.contents().filter(function() {
					return this.nodeType === 3 && (!this.nodeValue || /^\s+$/.test(this.nodeValue));
				})
				.remove();
			this.element.html("<"+"ul class='jstree-container-ul jstree-children' role='group'><"+"li id='j"+this._id+"_loading' class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='tree-item'><i class='jstree-icon jstree-ocl'></i><"+"a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>" + this.get_string("Loading ...") + "</a></li></ul>");
			this.element.attr('aria-activedescendant','j' + this._id + '_loading');
			this._data.core.li_height = this.get_container_ul().children("li").first().height() || 24;
			/**
			 * triggered after the loading text is shown and before loading starts
			 * @event
			 * @name loading.jstree
			 */
			this.trigger("loading");
			this.load_node('#');
		},
		/**
		 * destroy an instance
		 * @name destroy()
		 * @param  {Boolean} keep_html if not set to `true` the container will be emptied, otherwise the current DOM elements will be kept intact
		 */
		destroy : function (keep_html) {
			if(this._wrk) {
				try {
					window.URL.revokeObjectURL(this._wrk);
					this._wrk = null;
				}
				catch (ignore) { }
			}
			if(!keep_html) { this.element.empty(); }
			this.teardown();
		},
		/**
		 * part of the destroying of an instance. Used internally.
		 * @private
		 * @name teardown()
		 */
		teardown : function () {
			this.unbind();
			this.element
				.removeClass('jstree')
				.removeData('jstree')
				.find("[class^='jstree']")
					.addBack()
					.attr("class", function () { return this.className.replace(/jstree[^ ]*|$/ig,''); });
			this.element = null;
		},
		/**
		 * bind all events. Used internally.
		 * @private
		 * @name bind()
		 */
		bind : function () {
			var word = '',
				tout = null,
				was_click = 0;
			this.element
				.on("dblclick.jstree", function () {
						if(document.selection && document.selection.empty) {
							document.selection.empty();
						}
						else {
							if(window.getSelection) {
								var sel = window.getSelection();
								try {
									sel.removeAllRanges();
									sel.collapse();
								} catch (ignore) { }
							}
						}
					})
				.on("mousedown.jstree", $.proxy(function (e) {
						if(e.target === this.element[0]) {
							e.preventDefault(); // prevent losing focus when clicking scroll arrows (FF, Chrome)
							was_click = +(new Date()); // ie does not allow to prevent losing focus
						}
					}, this))
				.on("mousedown.jstree", ".jstree-ocl", function (e) {
						e.preventDefault(); // prevent any node inside from losing focus when clicking the open/close icon
					})
				.on("click.jstree", ".jstree-ocl", $.proxy(function (e) {
						this.toggle_node(e.target);
					}, this))
				.on("dblclick.jstree", ".jstree-anchor", $.proxy(function (e) {
						if(this.settings.core.dblclick_toggle) {
							this.toggle_node(e.target);
						}
					}, this))
				.on("click.jstree", ".jstree-anchor", $.proxy(function (e) {
						e.preventDefault();
						if(e.currentTarget !== document.activeElement) { $(e.currentTarget).focus(); }
						this.activate_node(e.currentTarget, e);
					}, this))
				.on('keydown.jstree', '.jstree-anchor', $.proxy(function (e) {
						if(e.target.tagName === "INPUT") { return true; }
						if(e.which !== 32 && e.which !== 13 && (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey)) { return true; }
						var o = null;
						if(this._data.core.rtl) {
							if(e.which === 37) { e.which = 39; }
							else if(e.which === 39) { e.which = 37; }
						}
						switch(e.which) {
							case 32: // aria defines space only with Ctrl
								if(e.ctrlKey) {
									e.type = "click";
									$(e.currentTarget).trigger(e);
								}
								break;
							case 13: // enter
								e.type = "click";
								$(e.currentTarget).trigger(e);
								break;
							case 37: // right
								e.preventDefault();
								if(this.is_open(e.currentTarget)) {
									this.close_node(e.currentTarget);
								}
								else {
									o = this.get_parent(e.currentTarget);
									if(o && o.id !== '#') { this.get_node(o, true).children('.jstree-anchor').focus(); }
								}
								break;
							case 38: // up
								e.preventDefault();
								o = this.get_prev_dom(e.currentTarget);
								if(o && o.length) { o.children('.jstree-anchor').focus(); }
								break;
							case 39: // left
								e.preventDefault();
								if(this.is_closed(e.currentTarget)) {
									this.open_node(e.currentTarget, function (o) { this.get_node(o, true).children('.jstree-anchor').focus(); });
								}
								else if (this.is_open(e.currentTarget)) {
									o = this.get_node(e.currentTarget, true).children('.jstree-children')[0];
									if(o) { $(this._firstChild(o)).children('.jstree-anchor').focus(); }
								}
								break;
							case 40: // down
								e.preventDefault();
								o = this.get_next_dom(e.currentTarget);
								if(o && o.length) { o.children('.jstree-anchor').focus(); }
								break;
							case 106: // aria defines * on numpad as open_all - not very common
								this.open_all();
								break;
							case 36: // home
								e.preventDefault();
								o = this._firstChild(this.get_container_ul()[0]);
								if(o) { $(o).children('.jstree-anchor').filter(':visible').focus(); }
								break;
							case 35: // end
								e.preventDefault();
								this.element.find('.jstree-anchor').filter(':visible').last().focus();
								break;
							/*
							// delete
							case 46:
								e.preventDefault();
								o = this.get_node(e.currentTarget);
								if(o && o.id && o.id !== '#') {
									o = this.is_selected(o) ? this.get_selected() : o;
									this.delete_node(o);
								}
								break;
							// f2
							case 113:
								e.preventDefault();
								o = this.get_node(e.currentTarget);
								if(o && o.id && o.id !== '#') {
									// this.edit(o);
								}
								break;
							default:
								// console.log(e.which);
								break;
							*/
						}
					}, this))
				.on("load_node.jstree", $.proxy(function (e, data) {
						if(data.status) {
							if(data.node.id === '#' && !this._data.core.loaded) {
								this._data.core.loaded = true;
								if(this._firstChild(this.get_container_ul()[0])) {
									this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id);
								}
								/**
								 * triggered after the root node is loaded for the first time
								 * @event
								 * @name loaded.jstree
								 */
								this.trigger("loaded");
							}
							if(!this._data.core.ready) {
								setTimeout($.proxy(function() {
									if(this.element && !this.get_container_ul().find('.jstree-loading').length) {
										this._data.core.ready = true;
										if(this._data.core.selected.length) {
											if(this.settings.core.expand_selected_onload) {
												var tmp = [], i, j;
												for(i = 0, j = this._data.core.selected.length; i < j; i++) {
													tmp = tmp.concat(this._model.data[this._data.core.selected[i]].parents);
												}
												tmp = $.vakata.array_unique(tmp);
												for(i = 0, j = tmp.length; i < j; i++) {
													this.open_node(tmp[i], false, 0);
												}
											}
											this.trigger('changed', { 'action' : 'ready', 'selected' : this._data.core.selected });
										}
										/**
										 * triggered after all nodes are finished loading
										 * @event
										 * @name ready.jstree
										 */
										this.trigger("ready");
									}
								}, this), 0);
							}
						}
					}, this))
				// quick searching when the tree is focused
				.on('keypress.jstree', $.proxy(function (e) {
						if(e.target.tagName === "INPUT") { return true; }
						if(tout) { clearTimeout(tout); }
						tout = setTimeout(function () {
							word = '';
						}, 500);

						var chr = String.fromCharCode(e.which).toLowerCase(),
							col = this.element.find('.jstree-anchor').filter(':visible'),
							ind = col.index(document.activeElement) || 0,
							end = false;
						word += chr;

						// match for whole word from current node down (including the current node)
						if(word.length > 1) {
							col.slice(ind).each($.proxy(function (i, v) {
								if($(v).text().toLowerCase().indexOf(word) === 0) {
									$(v).focus();
									end = true;
									return false;
								}
							}, this));
							if(end) { return; }

							// match for whole word from the beginning of the tree
							col.slice(0, ind).each($.proxy(function (i, v) {
								if($(v).text().toLowerCase().indexOf(word) === 0) {
									$(v).focus();
									end = true;
									return false;
								}
							}, this));
							if(end) { return; }
						}
						// list nodes that start with that letter (only if word consists of a single char)
						if(new RegExp('^' + chr + '+$').test(word)) {
							// search for the next node starting with that letter
							col.slice(ind + 1).each($.proxy(function (i, v) {
								if($(v).text().toLowerCase().charAt(0) === chr) {
									$(v).focus();
									end = true;
									return false;
								}
							}, this));
							if(end) { return; }

							// search from the beginning
							col.slice(0, ind + 1).each($.proxy(function (i, v) {
								if($(v).text().toLowerCase().charAt(0) === chr) {
									$(v).focus();
									end = true;
									return false;
								}
							}, this));
							if(end) { return; }
						}
					}, this))
				// THEME RELATED
				.on("init.jstree", $.proxy(function () {
						var s = this.settings.core.themes;
						this._data.core.themes.dots			= s.dots;
						this._data.core.themes.stripes		= s.stripes;
						this._data.core.themes.icons		= s.icons;
						this.set_theme(s.name || "default", s.url);
						this.set_theme_variant(s.variant);
					}, this))
				.on("loading.jstree", $.proxy(function () {
						this[ this._data.core.themes.dots ? "show_dots" : "hide_dots" ]();
						this[ this._data.core.themes.icons ? "show_icons" : "hide_icons" ]();
						this[ this._data.core.themes.stripes ? "show_stripes" : "hide_stripes" ]();
					}, this))
				.on('blur.jstree', '.jstree-anchor', $.proxy(function (e) {
						this._data.core.focused = null;
						$(e.currentTarget).filter('.jstree-hovered').mouseleave();
						this.element.attr('tabindex', '0');
					}, this))
				.on('focus.jstree', '.jstree-anchor', $.proxy(function (e) {
						var tmp = this.get_node(e.currentTarget);
						if(tmp && tmp.id) {
							this._data.core.focused = tmp.id;
						}
						this.element.find('.jstree-hovered').not(e.currentTarget).mouseleave();
						$(e.currentTarget).mouseenter();
						this.element.attr('tabindex', '-1');
					}, this))
				.on('focus.jstree', $.proxy(function () {
						if(+(new Date()) - was_click > 500 && !this._data.core.focused) {
							was_click = 0;
							var act = this.get_node(this.element.attr('aria-activedescendant'), true);
							if(act) {
								act.find('> .jstree-anchor').focus();
							}
						}
					}, this))
				.on('mouseenter.jstree', '.jstree-anchor', $.proxy(function (e) {
						this.hover_node(e.currentTarget);
					}, this))
				.on('mouseleave.jstree', '.jstree-anchor', $.proxy(function (e) {
						this.dehover_node(e.currentTarget);
					}, this));
		},
		/**
		 * part of the destroying of an instance. Used internally.
		 * @private
		 * @name unbind()
		 */
		unbind : function () {
			this.element.off('.jstree');
			$(document).off('.jstree-' + this._id);
		},
		/**
		 * trigger an event. Used internally.
		 * @private
		 * @name trigger(ev [, data])
		 * @param  {String} ev the name of the event to trigger
		 * @param  {Object} data additional data to pass with the event
		 */
		trigger : function (ev, data) {
			if(!data) {
				data = {};
			}
			data.instance = this;
			this.element.triggerHandler(ev.replace('.jstree','') + '.jstree', data);
		},
		/**
		 * returns the jQuery extended instance container
		 * @name get_container()
		 * @return {jQuery}
		 */
		get_container : function () {
			return this.element;
		},
		/**
		 * returns the jQuery extended main UL node inside the instance container. Used internally.
		 * @private
		 * @name get_container_ul()
		 * @return {jQuery}
		 */
		get_container_ul : function () {
			return this.element.children(".jstree-children").first();
		},
		/**
		 * gets string replacements (localization). Used internally.
		 * @private
		 * @name get_string(key)
		 * @param  {String} key
		 * @return {String}
		 */
		get_string : function (key) {
			var a = this.settings.core.strings;
			if($.isFunction(a)) { return a.call(this, key); }
			if(a && a[key]) { return a[key]; }
			return key;
		},
		/**
		 * gets the first child of a DOM node. Used internally.
		 * @private
		 * @name _firstChild(dom)
		 * @param  {DOMElement} dom
		 * @return {DOMElement}
		 */
		_firstChild : function (dom) {
			dom = dom ? dom.firstChild : null;
			while(dom !== null && dom.nodeType !== 1) {
				dom = dom.nextSibling;
			}
			return dom;
		},
		/**
		 * gets the next sibling of a DOM node. Used internally.
		 * @private
		 * @name _nextSibling(dom)
		 * @param  {DOMElement} dom
		 * @return {DOMElement}
		 */
		_nextSibling : function (dom) {
			dom = dom ? dom.nextSibling : null;
			while(dom !== null && dom.nodeType !== 1) {
				dom = dom.nextSibling;
			}
			return dom;
		},
		/**
		 * gets the previous sibling of a DOM node. Used internally.
		 * @private
		 * @name _previousSibling(dom)
		 * @param  {DOMElement} dom
		 * @return {DOMElement}
		 */
		_previousSibling : function (dom) {
			dom = dom ? dom.previousSibling : null;
			while(dom !== null && dom.nodeType !== 1) {
				dom = dom.previousSibling;
			}
			return dom;
		},
		/**
		 * get the JSON representation of a node (or the actual jQuery extended DOM node) by using any input (child DOM element, ID string, selector, etc)
		 * @name get_node(obj [, as_dom])
		 * @param  {mixed} obj
		 * @param  {Boolean} as_dom
		 * @return {Object|jQuery}
		 */
		get_node : function (obj, as_dom) {
			if(obj && obj.id) {
				obj = obj.id;
			}
			var dom;
			try {
				if(this._model.data[obj]) {
					obj = this._model.data[obj];
				}
				else if(typeof obj === "string" && this._model.data[obj.replace(/^#/, '')]) {
					obj = this._model.data[obj.replace(/^#/, '')];
				}
				else if(typeof obj === "string" && (dom = $('#' + obj.replace($.jstree.idregex,'\\$&'), this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) {
					obj = this._model.data[dom.closest('.jstree-node').attr('id')];
				}
				else if((dom = $(obj, this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) {
					obj = this._model.data[dom.closest('.jstree-node').attr('id')];
				}
				else if((dom = $(obj, this.element)).length && dom.hasClass('jstree')) {
					obj = this._model.data['#'];
				}
				else {
					return false;
				}

				if(as_dom) {
					obj = obj.id === '#' ? this.element : $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element);
				}
				return obj;
			} catch (ex) { return false; }
		},
		/**
		 * get the path to a node, either consisting of node texts, or of node IDs, optionally glued together (otherwise an array)
		 * @name get_path(obj [, glue, ids])
		 * @param  {mixed} obj the node
		 * @param  {String} glue if you want the path as a string - pass the glue here (for example '/'), if a falsy value is supplied here, an array is returned
		 * @param  {Boolean} ids if set to true build the path using ID, otherwise node text is used
		 * @return {mixed}
		 */
		get_path : function (obj, glue, ids) {
			obj = obj.parents ? obj : this.get_node(obj);
			if(!obj || obj.id === '#' || !obj.parents) {
				return false;
			}
			var i, j, p = [];
			p.push(ids ? obj.id : obj.text);
			for(i = 0, j = obj.parents.length; i < j; i++) {
				p.push(ids ? obj.parents[i] : this.get_text(obj.parents[i]));
			}
			p = p.reverse().slice(1);
			return glue ? p.join(glue) : p;
		},
		/**
		 * get the next visible node that is below the `obj` node. If `strict` is set to `true` only sibling nodes are returned.
		 * @name get_next_dom(obj [, strict])
		 * @param  {mixed} obj
		 * @param  {Boolean} strict
		 * @return {jQuery}
		 */
		get_next_dom : function (obj, strict) {
			var tmp;
			obj = this.get_node(obj, true);
			if(obj[0] === this.element[0]) {
				tmp = this._firstChild(this.get_container_ul()[0]);
				while (tmp && tmp.offsetHeight === 0) {
					tmp = this._nextSibling(tmp);
				}
				return tmp ? $(tmp) : false;
			}
			if(!obj || !obj.length) {
				return false;
			}
			if(strict) {
				tmp = obj[0];
				do {
					tmp = this._nextSibling(tmp);
				} while (tmp && tmp.offsetHeight === 0);
				return tmp ? $(tmp) : false;
			}
			if(obj.hasClass("jstree-open")) {
				tmp = this._firstChild(obj.children('.jstree-children')[0]);
				while (tmp && tmp.offsetHeight === 0) {
					tmp = this._nextSibling(tmp);
				}
				if(tmp !== null) {
					return $(tmp);
				}
			}
			tmp = obj[0];
			do {
				tmp = this._nextSibling(tmp);
			} while (tmp && tmp.offsetHeight === 0);
			if(tmp !== null) {
				return $(tmp);
			}
			return obj.parentsUntil(".jstree",".jstree-node").nextAll(".jstree-node:visible").first();
		},
		/**
		 * get the previous visible node that is above the `obj` node. If `strict` is set to `true` only sibling nodes are returned.
		 * @name get_prev_dom(obj [, strict])
		 * @param  {mixed} obj
		 * @param  {Boolean} strict
		 * @return {jQuery}
		 */
		get_prev_dom : function (obj, strict) {
			var tmp;
			obj = this.get_node(obj, true);
			if(obj[0] === this.element[0]) {
				tmp = this.get_container_ul()[0].lastChild;
				while (tmp && tmp.offsetHeight === 0) {
					tmp = this._previousSibling(tmp);
				}
				return tmp ? $(tmp) : false;
			}
			if(!obj || !obj.length) {
				return false;
			}
			if(strict) {
				tmp = obj[0];
				do {
					tmp = this._previousSibling(tmp);
				} while (tmp && tmp.offsetHeight === 0);
				return tmp ? $(tmp) : false;
			}
			tmp = obj[0];
			do {
				tmp = this._previousSibling(tmp);
			} while (tmp && tmp.offsetHeight === 0);
			if(tmp !== null) {
				obj = $(tmp);
				while(obj.hasClass("jstree-open")) {
					obj = obj.children(".jstree-children").first().children(".jstree-node:visible:last");
				}
				return obj;
			}
			tmp = obj[0].parentNode.parentNode;
			return tmp && tmp.className && tmp.className.indexOf('jstree-node') !== -1 ? $(tmp) : false;
		},
		/**
		 * get the parent ID of a node
		 * @name get_parent(obj)
		 * @param  {mixed} obj
		 * @return {String}
		 */
		get_parent : function (obj) {
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') {
				return false;
			}
			return obj.parent;
		},
		/**
		 * get a jQuery collection of all the children of a node (node must be rendered)
		 * @name get_children_dom(obj)
		 * @param  {mixed} obj
		 * @return {jQuery}
		 */
		get_children_dom : function (obj) {
			obj = this.get_node(obj, true);
			if(obj[0] === this.element[0]) {
				return this.get_container_ul().children(".jstree-node");
			}
			if(!obj || !obj.length) {
				return false;
			}
			return obj.children(".jstree-children").children(".jstree-node");
		},
		/**
		 * checks if a node has children
		 * @name is_parent(obj)
		 * @param  {mixed} obj
		 * @return {Boolean}
		 */
		is_parent : function (obj) {
			obj = this.get_node(obj);
			return obj && (obj.state.loaded === false || obj.children.length > 0);
		},
		/**
		 * checks if a node is loaded (its children are available)
		 * @name is_loaded(obj)
		 * @param  {mixed} obj
		 * @return {Boolean}
		 */
		is_loaded : function (obj) {
			obj = this.get_node(obj);
			return obj && obj.state.loaded;
		},
		/**
		 * check if a node is currently loading (fetching children)
		 * @name is_loading(obj)
		 * @param  {mixed} obj
		 * @return {Boolean}
		 */
		is_loading : function (obj) {
			obj = this.get_node(obj);
			return obj && obj.state && obj.state.loading;
		},
		/**
		 * check if a node is opened
		 * @name is_open(obj)
		 * @param  {mixed} obj
		 * @return {Boolean}
		 */
		is_open : function (obj) {
			obj = this.get_node(obj);
			return obj && obj.state.opened;
		},
		/**
		 * check if a node is in a closed state
		 * @name is_closed(obj)
		 * @param  {mixed} obj
		 * @return {Boolean}
		 */
		is_closed : function (obj) {
			obj = this.get_node(obj);
			return obj && this.is_parent(obj) && !obj.state.opened;
		},
		/**
		 * check if a node has no children
		 * @name is_leaf(obj)
		 * @param  {mixed} obj
		 * @return {Boolean}
		 */
		is_leaf : function (obj) {
			return !this.is_parent(obj);
		},
		/**
		 * loads a node (fetches its children using the `core.data` setting). Multiple nodes can be passed to by using an array.
		 * @name load_node(obj [, callback])
		 * @param  {mixed} obj
		 * @param  {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives two arguments - the node and a boolean status
		 * @return {Boolean}
		 * @trigger load_node.jstree
		 */
		load_node : function (obj, callback) {
			var k, l, i, j, c;
			if($.isArray(obj)) {
				this._load_nodes(obj.slice(), callback);
				return true;
			}
			obj = this.get_node(obj);
			if(!obj) {
				if(callback) { callback.call(this, obj, false); }
				return false;
			}
			// if(obj.state.loading) { } // the node is already loading - just wait for it to load and invoke callback? but if called implicitly it should be loaded again?
			if(obj.state.loaded) {
				obj.state.loaded = false;
				for(k = 0, l = obj.children_d.length; k < l; k++) {
					for(i = 0, j = obj.parents.length; i < j; i++) {
						this._model.data[obj.parents[i]].children_d = $.vakata.array_remove_item(this._model.data[obj.parents[i]].children_d, obj.children_d[k]);
					}
					if(this._model.data[obj.children_d[k]].state.selected) {
						c = true;
						this._data.core.selected = $.vakata.array_remove_item(this._data.core.selected, obj.children_d[k]);
					}
					delete this._model.data[obj.children_d[k]];
				}
				obj.children = [];
				obj.children_d = [];
				if(c) {
					this.trigger('changed', { 'action' : 'load_node', 'node' : obj, 'selected' : this._data.core.selected });
				}
			}
			obj.state.failed = false;
			obj.state.loading = true;
			this.get_node(obj, true).addClass("jstree-loading").attr('aria-busy',true);
			this._load_node(obj, $.proxy(function (status) {
				obj = this._model.data[obj.id];
				obj.state.loading = false;
				obj.state.loaded = status;
				obj.state.failed = !obj.state.loaded;
				var dom = this.get_node(obj, true);
				if(obj.state.loaded && !obj.children.length && dom && dom.length && !dom.hasClass('jstree-leaf')) {
					dom.removeClass('jstree-closed jstree-open').addClass('jstree-leaf');
				}
				dom.removeClass("jstree-loading").attr('aria-busy',false);
				/**
				 * triggered after a node is loaded
				 * @event
				 * @name load_node.jstree
				 * @param {Object} node the node that was loading
				 * @param {Boolean} status was the node loaded successfully
				 */
				this.trigger('load_node', { "node" : obj, "status" : status });
				if(callback) {
					callback.call(this, obj, status);
				}
			}, this));
			return true;
		},
		/**
		 * load an array of nodes (will also load unavailable nodes as soon as the appear in the structure). Used internally.
		 * @private
		 * @name _load_nodes(nodes [, callback])
		 * @param  {array} nodes
		 * @param  {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - the array passed to _load_nodes
		 */
		_load_nodes : function (nodes, callback, is_callback) {
			var r = true,
				c = function () { this._load_nodes(nodes, callback, true); },
				m = this._model.data, i, j, tmp = [];
			for(i = 0, j = nodes.length; i < j; i++) {
				if(m[nodes[i]] && ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || !is_callback)) {
					if(!this.is_loading(nodes[i])) {
						this.load_node(nodes[i], c);
					}
					r = false;
				}
			}
			if(r) {
				for(i = 0, j = nodes.length; i < j; i++) {
					if(m[nodes[i]] && m[nodes[i]].state.loaded) {
						tmp.push(nodes[i]);
					}
				}
				if(callback && !callback.done) {
					callback.call(this, tmp);
					callback.done = true;
				}
			}
		},
		/**
		 * loads all unloaded nodes
		 * @name load_all([obj, callback])
		 * @param {mixed} obj the node to load recursively, omit to load all nodes in the tree
		 * @param {function} callback a function to be executed once loading all the nodes is complete,
		 * @trigger load_all.jstree
		 */
		load_all : function (obj, callback) {
			if(!obj) { obj = '#'; }
			obj = this.get_node(obj);
			if(!obj) { return false; }
			var to_load = [],
				m = this._model.data,
				c = m[obj.id].children_d,
				i, j;
			if(obj.state && !obj.state.loaded) {
				to_load.push(obj.id);
			}
			for(i = 0, j = c.length; i < j; i++) {
				if(m[c[i]] && m[c[i]].state && !m[c[i]].state.loaded) {
					to_load.push(c[i]);
				}
			}
			if(to_load.length) {
				this._load_nodes(to_load, function () {
					this.load_all(obj, callback);
				});
			}
			else {
				/**
				 * triggered after a load_all call completes
				 * @event
				 * @name load_all.jstree
				 * @param {Object} node the recursively loaded node
				 */
				if(callback) { callback.call(this, obj); }
				this.trigger('load_all', { "node" : obj });
			}
		},
		/**
		 * handles the actual loading of a node. Used only internally.
		 * @private
		 * @name _load_node(obj [, callback])
		 * @param  {mixed} obj
		 * @param  {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - a boolean status
		 * @return {Boolean}
		 */
		_load_node : function (obj, callback) {
			var s = this.settings.core.data, t;
			// use original HTML
			if(!s) {
				if(obj.id === '#') {
					return this._append_html_data(obj, this._data.core.original_container_html.clone(true), function (status) {
						callback.call(this, status);
					});
				}
				else {
					return callback.call(this, false);
				}
				// return callback.call(this, obj.id === '#' ? this._append_html_data(obj, this._data.core.original_container_html.clone(true)) : false);
			}
			if($.isFunction(s)) {
				return s.call(this, obj, $.proxy(function (d) {
					if(d === false) {
						callback.call(this, false);
					}
					this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $($.parseHTML(d)).filter(function () { return this.nodeType !== 3; }) : d, function (status) {
						callback.call(this, status);
					});
					// return d === false ? callback.call(this, false) : callback.call(this, this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $(d) : d));
				}, this));
			}
			if(typeof s === 'object') {
				if(s.url) {
					s = $.extend(true, {}, s);
					if($.isFunction(s.url)) {
						s.url = s.url.call(this, obj);
					}
					if($.isFunction(s.data)) {
						s.data = s.data.call(this, obj);
					}
					return $.ajax(s)
						.done($.proxy(function (d,t,x) {
								var type = x.getResponseHeader('Content-Type');
								if((type && type.indexOf('json') !== -1) || typeof d === "object") {
									return this._append_json_data(obj, d, function (status) { callback.call(this, status); });
									//return callback.call(this, this._append_json_data(obj, d));
								}
								if((type && type.indexOf('html') !== -1) || typeof d === "string") {
									return this._append_html_data(obj, $($.parseHTML(d)).filter(function () { return this.nodeType !== 3; }), function (status) { callback.call(this, status); });
									// return callback.call(this, this._append_html_data(obj, $(d)));
								}
								this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : x }) };
								this.settings.core.error.call(this, this._data.core.last_error);
								return callback.call(this, false);
							}, this))
						.fail($.proxy(function (f) {
								callback.call(this, false);
								this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : f }) };
								this.settings.core.error.call(this, this._data.core.last_error);
							}, this));
				}
				t = ($.isArray(s) || $.isPlainObject(s)) ? JSON.parse(JSON.stringify(s)) : s;
				if(obj.id === '#') {
					return this._append_json_data(obj, t, function (status) {
						callback.call(this, status);
					});
				}
				else {
					this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_05', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) };
					this.settings.core.error.call(this, this._data.core.last_error);
					return callback.call(this, false);
				}
				//return callback.call(this, (obj.id === "#" ? this._append_json_data(obj, t) : false) );
			}
			if(typeof s === 'string') {
				if(obj.id === '#') {
					return this._append_html_data(obj, $($.parseHTML(s)).filter(function () { return this.nodeType !== 3; }), function (status) {
						callback.call(this, status);
					});
				}
				else {
					this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_06', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) };
					this.settings.core.error.call(this, this._data.core.last_error);
					return callback.call(this, false);
				}
				//return callback.call(this, (obj.id === "#" ? this._append_html_data(obj, $(s)) : false) );
			}
			return callback.call(this, false);
		},
		/**
		 * adds a node to the list of nodes to redraw. Used only internally.
		 * @private
		 * @name _node_changed(obj [, callback])
		 * @param  {mixed} obj
		 */
		_node_changed : function (obj) {
			obj = this.get_node(obj);
			if(obj) {
				this._model.changed.push(obj.id);
			}
		},
		/**
		 * appends HTML content to the tree. Used internally.
		 * @private
		 * @name _append_html_data(obj, data)
		 * @param  {mixed} obj the node to append to
		 * @param  {String} data the HTML string to parse and append
		 * @trigger model.jstree, changed.jstree
		 */
		_append_html_data : function (dom, data, cb) {
			dom = this.get_node(dom);
			dom.children = [];
			dom.children_d = [];
			var dat = data.is('ul') ? data.children() : data,
				par = dom.id,
				chd = [],
				dpc = [],
				m = this._model.data,
				p = m[par],
				s = this._data.core.selected.length,
				tmp, i, j;
			dat.each($.proxy(function (i, v) {
				tmp = this._parse_model_from_html($(v), par, p.parents.concat());
				if(tmp) {
					chd.push(tmp);
					dpc.push(tmp);
					if(m[tmp].children_d.length) {
						dpc = dpc.concat(m[tmp].children_d);
					}
				}
			}, this));
			p.children = chd;
			p.children_d = dpc;
			for(i = 0, j = p.parents.length; i < j; i++) {
				m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc);
			}
			/**
			 * triggered when new data is inserted to the tree model
			 * @event
			 * @name model.jstree
			 * @param {Array} nodes an array of node IDs
			 * @param {String} parent the parent ID of the nodes
			 */
			this.trigger('model', { "nodes" : dpc, 'parent' : par });
			if(par !== '#') {
				this._node_changed(par);
				this.redraw();
			}
			else {
				this.get_container_ul().children('.jstree-initial-node').remove();
				this.redraw(true);
			}
			if(this._data.core.selected.length !== s) {
				this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected });
			}
			cb.call(this, true);
		},
		/**
		 * appends JSON content to the tree. Used internally.
		 * @private
		 * @name _append_json_data(obj, data)
		 * @param  {mixed} obj the node to append to
		 * @param  {String} data the JSON object to parse and append
		 * @param  {Boolean} force_processing internal param - do not set
		 * @trigger model.jstree, changed.jstree
		 */
		_append_json_data : function (dom, data, cb, force_processing) {
			if(this.element === null) { return; }
			dom = this.get_node(dom);
			dom.children = [];
			dom.children_d = [];
			// *%$@!!!
			if(data.d) {
				data = data.d;
				if(typeof data === "string") {
					data = JSON.parse(data);
				}
			}
			if(!$.isArray(data)) { data = [data]; }
			var w = null,
				args = {
					'df'	: this._model.default_state,
					'dat'	: data,
					'par'	: dom.id,
					'm'		: this._model.data,
					't_id'	: this._id,
					't_cnt'	: this._cnt,
					'sel'	: this._data.core.selected
				},
				func = function (data, undefined) {
					if(data.data) { data = data.data; }
					var dat = data.dat,
						par = data.par,
						chd = [],
						dpc = [],
						add = [],
						df = data.df,
						t_id = data.t_id,
						t_cnt = data.t_cnt,
						m = data.m,
						p = m[par],
						sel = data.sel,
						tmp, i, j, rslt,
						parse_flat = function (d, p, ps) {
							if(!ps) { ps = []; }
							else { ps = ps.concat(); }
							if(p) { ps.unshift(p); }
							var tid = d.id.toString(),
								i, j, c, e,
								tmp = {
									id			: tid,
									text		: d.text || '',
									icon		: d.icon !== undefined ? d.icon : true,
									parent		: p,
									parents		: ps,
									children	: d.children || [],
									children_d	: d.children_d || [],
									data		: d.data,
									state		: { },
									li_attr		: { id : false },
									a_attr		: { href : '#' },
									original	: false
								};
							for(i in df) {
								if(df.hasOwnProperty(i)) {
									tmp.state[i] = df[i];
								}
							}
							if(d && d.data && d.data.jstree && d.data.jstree.icon) {
								tmp.icon = d.data.jstree.icon;
							}
							if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") {
								tmp.icon = true;
							}
							if(d && d.data) {
								tmp.data = d.data;
								if(d.data.jstree) {
									for(i in d.data.jstree) {
										if(d.data.jstree.hasOwnProperty(i)) {
											tmp.state[i] = d.data.jstree[i];
										}
									}
								}
							}
							if(d && typeof d.state === 'object') {
								for (i in d.state) {
									if(d.state.hasOwnProperty(i)) {
										tmp.state[i] = d.state[i];
									}
								}
							}
							if(d && typeof d.li_attr === 'object') {
								for (i in d.li_attr) {
									if(d.li_attr.hasOwnProperty(i)) {
										tmp.li_attr[i] = d.li_attr[i];
									}
								}
							}
							if(!tmp.li_attr.id) {
								tmp.li_attr.id = tid;
							}
							if(d && typeof d.a_attr === 'object') {
								for (i in d.a_attr) {
									if(d.a_attr.hasOwnProperty(i)) {
										tmp.a_attr[i] = d.a_attr[i];
									}
								}
							}
							if(d && d.children && d.children === true) {
								tmp.state.loaded = false;
								tmp.children = [];
								tmp.children_d = [];
							}
							m[tmp.id] = tmp;
							for(i = 0, j = tmp.children.length; i < j; i++) {
								c = parse_flat(m[tmp.children[i]], tmp.id, ps);
								e = m[c];
								tmp.children_d.push(c);
								if(e.children_d.length) {
									tmp.children_d = tmp.children_d.concat(e.children_d);
								}
							}
							delete d.data;
							delete d.children;
							m[tmp.id].original = d;
							if(tmp.state.selected) {
								add.push(tmp.id);
							}
							return tmp.id;
						},
						parse_nest = function (d, p, ps) {
							if(!ps) { ps = []; }
							else { ps = ps.concat(); }
							if(p) { ps.unshift(p); }
							var tid = false, i, j, c, e, tmp;
							do {
								tid = 'j' + t_id + '_' + (++t_cnt);
							} while(m[tid]);

							tmp = {
								id			: false,
								text		: typeof d === 'string' ? d : '',
								icon		: typeof d === 'object' && d.icon !== undefined ? d.icon : true,
								parent		: p,
								parents		: ps,
								children	: [],
								children_d	: [],
								data		: null,
								state		: { },
								li_attr		: { id : false },
								a_attr		: { href : '#' },
								original	: false
							};
							for(i in df) {
								if(df.hasOwnProperty(i)) {
									tmp.state[i] = df[i];
								}
							}
							if(d && d.id) { tmp.id = d.id.toString(); }
							if(d && d.text) { tmp.text = d.text; }
							if(d && d.data && d.data.jstree && d.data.jstree.icon) {
								tmp.icon = d.data.jstree.icon;
							}
							if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") {
								tmp.icon = true;
							}
							if(d && d.data) {
								tmp.data = d.data;
								if(d.data.jstree) {
									for(i in d.data.jstree) {
										if(d.data.jstree.hasOwnProperty(i)) {
											tmp.state[i] = d.data.jstree[i];
										}
									}
								}
							}
							if(d && typeof d.state === 'object') {
								for (i in d.state) {
									if(d.state.hasOwnProperty(i)) {
										tmp.state[i] = d.state[i];
									}
								}
							}
							if(d && typeof d.li_attr === 'object') {
								for (i in d.li_attr) {
									if(d.li_attr.hasOwnProperty(i)) {
										tmp.li_attr[i] = d.li_attr[i];
									}
								}
							}
							if(tmp.li_attr.id && !tmp.id) {
								tmp.id = tmp.li_attr.id.toString();
							}
							if(!tmp.id) {
								tmp.id = tid;
							}
							if(!tmp.li_attr.id) {
								tmp.li_attr.id = tmp.id;
							}
							if(d && typeof d.a_attr === 'object') {
								for (i in d.a_attr) {
									if(d.a_attr.hasOwnProperty(i)) {
										tmp.a_attr[i] = d.a_attr[i];
									}
								}
							}
							if(d && d.children && d.children.length) {
								for(i = 0, j = d.children.length; i < j; i++) {
									c = parse_nest(d.children[i], tmp.id, ps);
									e = m[c];
									tmp.children.push(c);
									if(e.children_d.length) {
										tmp.children_d = tmp.children_d.concat(e.children_d);
									}
								}
								tmp.children_d = tmp.children_d.concat(tmp.children);
							}
							if(d && d.children && d.children === true) {
								tmp.state.loaded = false;
								tmp.children = [];
								tmp.children_d = [];
							}
							delete d.data;
							delete d.children;
							tmp.original = d;
							m[tmp.id] = tmp;
							if(tmp.state.selected) {
								add.push(tmp.id);
							}
							return tmp.id;
						};

					if(dat.length && dat[0].id !== undefined && dat[0].parent !== undefined) {
						// Flat JSON support (for easy import from DB):
						// 1) convert to object (foreach)
						for(i = 0, j = dat.length; i < j; i++) {
							if(dat[i]!=undefined && !dat[i].children) {
								dat[i].children = [];
							}
							m[dat[i].id.toString()] = dat[i];
						}
						// 2) populate children (foreach)
						for(i = 0, j = dat.length; i < j; i++) {
						  if (m[dat[i].parent.toString()] != undefined) {
						    m[dat[i].parent.toString()].children.push(dat[i].id.toString());
						    // populate parent.children_d
						    p.children_d.push(dat[i].id.toString());
						  }
						}
						// 3) normalize && populate parents and children_d with recursion
						for(i = 0, j = p.children.length; i < j; i++) {
							tmp = parse_flat(m[p.children[i]], par, p.parents.concat());
							dpc.push(tmp);
							if(m[tmp].children_d.length) {
								dpc = dpc.concat(m[tmp].children_d);
							}
						}
						for(i = 0, j = p.parents.length; i < j; i++) {
							m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc);
						}
						// ?) three_state selection - p.state.selected && t - (if three_state foreach(dat => ch) -> foreach(parents) if(parent.selected) child.selected = true;
						rslt = {
							'cnt' : t_cnt,
							'mod' : m,
							'sel' : sel,
							'par' : par,
							'dpc' : dpc,
							'add' : add
						};
					}
					else {
						for(i = 0, j = dat.length; i < j; i++) {
						  if (dat[i] != undefined) {
						    tmp = parse_nest(dat[i], par, p.parents.concat());
						    if (tmp) {
						      chd.push(tmp);
						      dpc.push(tmp);
						      if (m[tmp]!=undefined && m[tmp].children_d.length) {
						        dpc = dpc.concat(m[tmp].children_d);
						      }
						    }
						  }
						}
						p.children = chd;
						p.children_d = dpc;
						for(i = 0, j = p.parents.length; i < j; i++) {
							m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc);
						}
						rslt = {
							'cnt' : t_cnt,
							'mod' : m,
							'sel' : sel,
							'par' : par,
							'dpc' : dpc,
							'add' : add
						};
					}
					if(typeof window === 'undefined' || typeof window.document === 'undefined') {
						postMessage(rslt);
					}
					else {
						return rslt;
					}
				},
				rslt = function (rslt, worker) {
					if(this.element === null) { return; }
					this._cnt = rslt.cnt;
					this._model.data = rslt.mod; // breaks the reference in load_node - careful

					if(worker) {
						var i, j, a = rslt.add, r = rslt.sel, s = this._data.core.selected.slice(), m = this._model.data;
						// if selection was changed while calculating in worker
						if(r.length !== s.length || $.vakata.array_unique(r.concat(s)).length !== r.length) {
							// deselect nodes that are no longer selected
							for(i = 0, j = r.length; i < j; i++) {
								if($.inArray(r[i], a) === -1 && $.inArray(r[i], s) === -1) {
									m[r[i]].state.selected = false;
								}
							}
							// select nodes that were selected in the mean time
							for(i = 0, j = s.length; i < j; i++) {
								if($.inArray(s[i], r) === -1) {
									m[s[i]].state.selected = true;
								}
							}
						}
					}
					if(rslt.add.length) {
						this._data.core.selected = this._data.core.selected.concat(rslt.add);
					}

					this.trigger('model', { "nodes" : rslt.dpc, 'parent' : rslt.par });

					if(rslt.par !== '#') {
						this._node_changed(rslt.par);
						this.redraw();
					}
					else {
						// this.get_container_ul().children('.jstree-initial-node').remove();
						this.redraw(true);
					}
					if(rslt.add.length) {
						this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected });
					}
					cb.call(this, true);
				};
			if(this.settings.core.worker && window.Blob && window.URL && window.Worker) {
				try {
					if(this._wrk === null) {
						this._wrk = window.URL.createObjectURL(
							new window.Blob(
								['self.onmessage = ' + func.toString()],
								{type:"text/javascript"}
							)
						);
					}
					if(!this._data.core.working || force_processing) {
						this._data.core.working = true;
						w = new window.Worker(this._wrk);
						w.onmessage = $.proxy(function (e) {
							rslt.call(this, e.data, true);
							try { w.terminate(); w = null; } catch(ignore) { }
							if(this._data.core.worker_queue.length) {
								this._append_json_data.apply(this, this._data.core.worker_queue.shift());
							}
							else {
								this._data.core.working = false;
							}
						}, this);
						if(!args.par) {
							if(this._data.core.worker_queue.length) {
								this._append_json_data.apply(this, this._data.core.worker_queue.shift());
							}
							else {
								this._data.core.working = false;
							}
						}
						else {
							w.postMessage(args);
						}
					}
					else {
						this._data.core.worker_queue.push([dom, data, cb, true]);
					}
				}
				catch(e) {
					rslt.call(this, func(args), false);
					if(this._data.core.worker_queue.length) {
						this._append_json_data.apply(this, this._data.core.worker_queue.shift());
					}
					else {
						this._data.core.working = false;
					}
				}
			}
			else {
				rslt.call(this, func(args), false);
			}
		},
		/**
		 * parses a node from a jQuery object and appends them to the in memory tree model. Used internally.
		 * @private
		 * @name _parse_model_from_html(d [, p, ps])
		 * @param  {jQuery} d the jQuery object to parse
		 * @param  {String} p the parent ID
		 * @param  {Array} ps list of all parents
		 * @return {String} the ID of the object added to the model
		 */
		_parse_model_from_html : function (d, p, ps) {
			if(!ps) { ps = []; }
			else { ps = [].concat(ps); }
			if(p) { ps.unshift(p); }
			var c, e, m = this._model.data,
				data = {
					id			: false,
					text		: false,
					icon		: true,
					parent		: p,
					parents		: ps,
					children	: [],
					children_d	: [],
					data		: null,
					state		: { },
					li_attr		: { id : false },
					a_attr		: { href : '#' },
					original	: false
				}, i, tmp, tid;
			for(i in this._model.default_state) {
				if(this._model.default_state.hasOwnProperty(i)) {
					data.state[i] = this._model.default_state[i];
				}
			}
			tmp = $.vakata.attributes(d, true);
			$.each(tmp, function (i, v) {
				v = $.trim(v);
				if(!v.length) { return true; }
				data.li_attr[i] = v;
				if(i === 'id') {
					data.id = v.toString();
				}
			});
			tmp = d.children('a').first();
			if(tmp.length) {
				tmp = $.vakata.attributes(tmp, true);
				$.each(tmp, function (i, v) {
					v = $.trim(v);
					if(v.length) {
						data.a_attr[i] = v;
					}
				});
			}
			tmp = d.children("a").first().length ? d.children("a").first().clone() : d.clone();
			tmp.children("ins, i, ul").remove();
			tmp = tmp.html();
			tmp = $('<div />').html(tmp);
			data.text = this.settings.core.force_text ? tmp.text() : tmp.html();
			tmp = d.data();
			data.data = tmp ? $.extend(true, {}, tmp) : null;
			data.state.opened = d.hasClass('jstree-open');
			data.state.selected = d.children('a').hasClass('jstree-clicked');
			data.state.disabled = d.children('a').hasClass('jstree-disabled');
			if(data.data && data.data.jstree) {
				for(i in data.data.jstree) {
					if(data.data.jstree.hasOwnProperty(i)) {
						data.state[i] = data.data.jstree[i];
					}
				}
			}
			tmp = d.children("a").children(".jstree-themeicon");
			if(tmp.length) {
				data.icon = tmp.hasClass('jstree-themeicon-hidden') ? false : tmp.attr('rel');
			}
			if(data.state.icon !== undefined) {
				data.icon = data.state.icon;
			}
			if(data.icon === undefined || data.icon === null || data.icon === "") {
				data.icon = true;
			}
			tmp = d.children("ul").children("li");
			do {
				tid = 'j' + this._id + '_' + (++this._cnt);
			} while(m[tid]);
			data.id = data.li_attr.id ? data.li_attr.id.toString() : tid;
			if(tmp.length) {
				tmp.each($.proxy(function (i, v) {
					c = this._parse_model_from_html($(v), data.id, ps);
					e = this._model.data[c];
					data.children.push(c);
					if(e.children_d.length) {
						data.children_d = data.children_d.concat(e.children_d);
					}
				}, this));
				data.children_d = data.children_d.concat(data.children);
			}
			else {
				if(d.hasClass('jstree-closed')) {
					data.state.loaded = false;
				}
			}
			if(data.li_attr['class']) {
				data.li_attr['class'] = data.li_attr['class'].replace('jstree-closed','').replace('jstree-open','');
			}
			if(data.a_attr['class']) {
				data.a_attr['class'] = data.a_attr['class'].replace('jstree-clicked','').replace('jstree-disabled','');
			}
			m[data.id] = data;
			if(data.state.selected) {
				this._data.core.selected.push(data.id);
			}
			return data.id;
		},
		/**
		 * parses a node from a JSON object (used when dealing with flat data, which has no nesting of children, but has id and parent properties) and appends it to the in memory tree model. Used internally.
		 * @private
		 * @name _parse_model_from_flat_json(d [, p, ps])
		 * @param  {Object} d the JSON object to parse
		 * @param  {String} p the parent ID
		 * @param  {Array} ps list of all parents
		 * @return {String} the ID of the object added to the model
		 */
		_parse_model_from_flat_json : function (d, p, ps) {
			if(!ps) { ps = []; }
			else { ps = ps.concat(); }
			if(p) { ps.unshift(p); }
			var tid = d.id.toString(),
				m = this._model.data,
				df = this._model.default_state,
				i, j, c, e,
				tmp = {
					id			: tid,
					text		: d.text || '',
					icon		: d.icon !== undefined ? d.icon : true,
					parent		: p,
					parents		: ps,
					children	: d.children || [],
					children_d	: d.children_d || [],
					data		: d.data,
					state		: { },
					li_attr		: { id : false },
					a_attr		: { href : '#' },
					original	: false
				};
			for(i in df) {
				if(df.hasOwnProperty(i)) {
					tmp.state[i] = df[i];
				}
			}
			if(d && d.data && d.data.jstree && d.data.jstree.icon) {
				tmp.icon = d.data.jstree.icon;
			}
			if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") {
				tmp.icon = true;
			}
			if(d && d.data) {
				tmp.data = d.data;
				if(d.data.jstree) {
					for(i in d.data.jstree) {
						if(d.data.jstree.hasOwnProperty(i)) {
							tmp.state[i] = d.data.jstree[i];
						}
					}
				}
			}
			if(d && typeof d.state === 'object') {
				for (i in d.state) {
					if(d.state.hasOwnProperty(i)) {
						tmp.state[i] = d.state[i];
					}
				}
			}
			if(d && typeof d.li_attr === 'object') {
				for (i in d.li_attr) {
					if(d.li_attr.hasOwnProperty(i)) {
						tmp.li_attr[i] = d.li_attr[i];
					}
				}
			}
			if(!tmp.li_attr.id) {
				tmp.li_attr.id = tid;
			}
			if(d && typeof d.a_attr === 'object') {
				for (i in d.a_attr) {
					if(d.a_attr.hasOwnProperty(i)) {
						tmp.a_attr[i] = d.a_attr[i];
					}
				}
			}
			if(d && d.children && d.children === true) {
				tmp.state.loaded = false;
				tmp.children = [];
				tmp.children_d = [];
			}
			m[tmp.id] = tmp;
			for(i = 0, j = tmp.children.length; i < j; i++) {
				c = this._parse_model_from_flat_json(m[tmp.children[i]], tmp.id, ps);
				e = m[c];
				tmp.children_d.push(c);
				if(e.children_d.length) {
					tmp.children_d = tmp.children_d.concat(e.children_d);
				}
			}
			delete d.data;
			delete d.children;
			m[tmp.id].original = d;
			if(tmp.state.selected) {
				this._data.core.selected.push(tmp.id);
			}
			return tmp.id;
		},
		/**
		 * parses a node from a JSON object and appends it to the in memory tree model. Used internally.
		 * @private
		 * @name _parse_model_from_json(d [, p, ps])
		 * @param  {Object} d the JSON object to parse
		 * @param  {String} p the parent ID
		 * @param  {Array} ps list of all parents
		 * @return {String} the ID of the object added to the model
		 */
		_parse_model_from_json : function (d, p, ps) {
			if(!ps) { ps = []; }
			else { ps = ps.concat(); }
			if(p) { ps.unshift(p); }
			var tid = false, i, j, c, e, m = this._model.data, df = this._model.default_state, tmp;
			do {
				tid = 'j' + this._id + '_' + (++this._cnt);
			} while(m[tid]);

			tmp = {
				id			: false,
				text		: typeof d === 'string' ? d : '',
				icon		: typeof d === 'object' && d.icon !== undefined ? d.icon : true,
				parent		: p,
				parents		: ps,
				children	: [],
				children_d	: [],
				data		: null,
				state		: { },
				li_attr		: { id : false },
				a_attr		: { href : '#' },
				original	: false
			};
			for(i in df) {
				if(df.hasOwnProperty(i)) {
					tmp.state[i] = df[i];
				}
			}
			if(d && d.id) { tmp.id = d.id.toString(); }
			if(d && d.text) { tmp.text = d.text; }
			if(d && d.data && d.data.jstree && d.data.jstree.icon) {
				tmp.icon = d.data.jstree.icon;
			}
			if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") {
				tmp.icon = true;
			}
			if(d && d.data) {
				tmp.data = d.data;
				if(d.data.jstree) {
					for(i in d.data.jstree) {
						if(d.data.jstree.hasOwnProperty(i)) {
							tmp.state[i] = d.data.jstree[i];
						}
					}
				}
			}
			if(d && typeof d.state === 'object') {
				for (i in d.state) {
					if(d.state.hasOwnProperty(i)) {
						tmp.state[i] = d.state[i];
					}
				}
			}
			if(d && typeof d.li_attr === 'object') {
				for (i in d.li_attr) {
					if(d.li_attr.hasOwnProperty(i)) {
						tmp.li_attr[i] = d.li_attr[i];
					}
				}
			}
			if(tmp.li_attr.id && !tmp.id) {
				tmp.id = tmp.li_attr.id.toString();
			}
			if(!tmp.id) {
				tmp.id = tid;
			}
			if(!tmp.li_attr.id) {
				tmp.li_attr.id = tmp.id;
			}
			if(d && typeof d.a_attr === 'object') {
				for (i in d.a_attr) {
					if(d.a_attr.hasOwnProperty(i)) {
						tmp.a_attr[i] = d.a_attr[i];
					}
				}
			}
			if(d && d.children && d.children.length) {
				for(i = 0, j = d.children.length; i < j; i++) {
					c = this._parse_model_from_json(d.children[i], tmp.id, ps);
					e = m[c];
					tmp.children.push(c);
					if(e.children_d.length) {
						tmp.children_d = tmp.children_d.concat(e.children_d);
					}
				}
				tmp.children_d = tmp.children_d.concat(tmp.children);
			}
			if(d && d.children && d.children === true) {
				tmp.state.loaded = false;
				tmp.children = [];
				tmp.children_d = [];
			}
			delete d.data;
			delete d.children;
			tmp.original = d;
			m[tmp.id] = tmp;
			if(tmp.state.selected) {
				this._data.core.selected.push(tmp.id);
			}
			return tmp.id;
		},
		/**
		 * redraws all nodes that need to be redrawn. Used internally.
		 * @private
		 * @name _redraw()
		 * @trigger redraw.jstree
		 */
		_redraw : function () {
			var nodes = this._model.force_full_redraw ? this._model.data['#'].children.concat([]) : this._model.changed.concat([]),
				f = document.createElement('UL'), tmp, i, j, fe = this._data.core.focused;
			for(i = 0, j = nodes.length; i < j; i++) {
				tmp = this.redraw_node(nodes[i], true, this._model.force_full_redraw);
				if(tmp && this._model.force_full_redraw) {
					f.appendChild(tmp);
				}
			}
			if(this._model.force_full_redraw) {
				f.className = this.get_container_ul()[0].className;
				f.setAttribute('role','group');
				this.element.empty().append(f);
				//this.get_container_ul()[0].appendChild(f);
			}
			if(fe !== null) {
				tmp = this.get_node(fe, true);
				if(tmp && tmp.length && tmp.children('.jstree-anchor')[0] !== document.activeElement) {
					tmp.children('.jstree-anchor').focus();
				}
				else {
					this._data.core.focused = null;
				}
			}
			this._model.force_full_redraw = false;
			this._model.changed = [];
			/**
			 * triggered after nodes are redrawn
			 * @event
			 * @name redraw.jstree
			 * @param {array} nodes the redrawn nodes
			 */
			this.trigger('redraw', { "nodes" : nodes });
		},
		/**
		 * redraws all nodes that need to be redrawn or optionally - the whole tree
		 * @name redraw([full])
		 * @param {Boolean} full if set to `true` all nodes are redrawn.
		 */
		redraw : function (full) {
			if(full) {
				this._model.force_full_redraw = true;
			}
			//if(this._model.redraw_timeout) {
			//	clearTimeout(this._model.redraw_timeout);
			//}
			//this._model.redraw_timeout = setTimeout($.proxy(this._redraw, this),0);
			this._redraw();
		},
		/**
		 * redraws a single node's children. Used internally.
		 * @private
		 * @name draw_children(node)
		 * @param {mixed} node the node whose children will be redrawn
		 */
		draw_children : function (node) {
			var obj = this.get_node(node),
				i = false,
				j = false,
				k = false,
				d = document;
			if(!obj) { return false; }
			if(obj.id === '#') { return this.redraw(true); }
			node = this.get_node(node, true);
			if(!node || !node.length) { return false; } // TODO: quick toggle

			node.children('.jstree-children').remove();
			node = node[0];
			if(obj.children.length && obj.state.loaded) {
				k = d.createElement('UL');
				k.setAttribute('role', 'group');
				k.className = 'jstree-children';
				for(i = 0, j = obj.children.length; i < j; i++) {
					k.appendChild(this.redraw_node(obj.children[i], true, true));
				}
				node.appendChild(k);
			}
		},
		/**
		 * redraws a single node. Used internally.
		 * @private
		 * @name redraw_node(node, deep, is_callback, force_render)
		 * @param {mixed} node the node to redraw
		 * @param {Boolean} deep should child nodes be redrawn too
		 * @param {Boolean} is_callback is this a recursion call
		 * @param {Boolean} force_render should children of closed parents be drawn anyway
		 */
		redraw_node : function (node, deep, is_callback, force_render) {
			var obj = this.get_node(node),
				par = false,
				ind = false,
				old = false,
				i = false,
				j = false,
				k = false,
				c = '',
				d = document,
				m = this._model.data,
				f = false,
				s = false,
				tmp = null,
				t = 0,
				l = 0;
			if(!obj) { return false; }
			if(obj.id === '#') {  return this.redraw(true); }
			deep = deep || obj.children.length === 0;
			node = !document.querySelector ? document.getElementById(obj.id) : this.element[0].querySelector('#' + ("0123456789".indexOf(obj.id[0]) !== -1 ? '\\3' + obj.id[0] + ' ' + obj.id.substr(1).replace($.jstree.idregex,'\\$&') : obj.id.replace($.jstree.idregex,'\\$&')) ); //, this.element);
			if(!node) {
				deep = true;
				//node = d.createElement('LI');
				if(!is_callback) {
					par = obj.parent !== '#' ? $('#' + obj.parent.replace($.jstree.idregex,'\\$&'), this.element)[0] : null;
					if(par !== null && (!par || !m[obj.parent].state.opened)) {
						return false;
					}
					ind = $.inArray(obj.id, par === null ? m['#'].children : m[obj.parent].children);
				}
			}
			else {
				node = $(node);
				if(!is_callback) {
					par = node.parent().parent()[0];
					if(par === this.element[0]) {
						par = null;
					}
					ind = node.index();
				}
				// m[obj.id].data = node.data(); // use only node's data, no need to touch jquery storage
				if(!deep && obj.children.length && !node.children('.jstree-children').length) {
					deep = true;
				}
				if(!deep) {
					old = node.children('.jstree-children')[0];
				}
				f = node.children('.jstree-anchor')[0] === document.activeElement;
				node.remove();
				//node = d.createElement('LI');
				//node = node[0];
			}
			node = _node.cloneNode(true);
			// node is DOM, deep is boolean

			c = 'jstree-node ';
			for(i in obj.li_attr) {
				if(obj.li_attr.hasOwnProperty(i)) {
					if(i === 'id') { continue; }
					if(i !== 'class') {
						node.setAttribute(i, obj.li_attr[i]);
					}
					else {
						c += obj.li_attr[i];
					}
				}
			}
			if(!obj.a_attr.id) {
				obj.a_attr.id = obj.id + '_anchor';
			}
			node.setAttribute('aria-selected', !!obj.state.selected);
			node.setAttribute('aria-level', obj.parents.length);
			node.setAttribute('aria-labelledby', obj.a_attr.id);
			if(obj.state.disabled) {
				node.setAttribute('aria-disabled', true);
			}

			if(obj.state.loaded && !obj.children.length) {
				c += ' jstree-leaf';
			}
			else {
				c += obj.state.opened && obj.state.loaded ? ' jstree-open' : ' jstree-closed';
				node.setAttribute('aria-expanded', (obj.state.opened && obj.state.loaded) );
			}
			if(obj.parent !== null && m[obj.parent].children[m[obj.parent].children.length - 1] === obj.id) {
				c += ' jstree-last';
			}
			node.id = obj.id;
			node.className = c;
			c = ( obj.state.selected ? ' jstree-clicked' : '') + ( obj.state.disabled ? ' jstree-disabled' : '');
			for(j in obj.a_attr) {
				if(obj.a_attr.hasOwnProperty(j)) {
					if(j === 'href' && obj.a_attr[j] === '#') { continue; }
					if(j !== 'class') {
						node.childNodes[1].setAttribute(j, obj.a_attr[j]);
					}
					else {
						c += ' ' + obj.a_attr[j];
					}
				}
			}
			if(c.length) {
				node.childNodes[1].className = 'jstree-anchor ' + c;
			}
			if((obj.icon && obj.icon !== true) || obj.icon === false) {
				if(obj.icon === false) {
					node.childNodes[1].childNodes[0].className += ' jstree-themeicon-hidden';
				}
				else if(obj.icon.indexOf('/') === -1 && obj.icon.indexOf('.') === -1) {
					node.childNodes[1].childNodes[0].className += ' ' + obj.icon + ' jstree-themeicon-custom';
				}
				else {
					node.childNodes[1].childNodes[0].style.backgroundImage = 'url('+obj.icon+')';
					node.childNodes[1].childNodes[0].style.backgroundPosition = 'center center';
					node.childNodes[1].childNodes[0].style.backgroundSize = 'auto';
					node.childNodes[1].childNodes[0].className += ' jstree-themeicon-custom';
				}
			}

			if(this.settings.core.force_text) {
				node.childNodes[1].appendChild(d.createTextNode(obj.text));
			}
			else {
				node.childNodes[1].innerHTML += obj.text;
			}


			if(deep && obj.children.length && (obj.state.opened || force_render) && obj.state.loaded) {
				k = d.createElement('UL');
				k.setAttribute('role', 'group');
				k.className = 'jstree-children';
				for(i = 0, j = obj.children.length; i < j; i++) {
					k.appendChild(this.redraw_node(obj.children[i], deep, true));
				}
				node.appendChild(k);
			}
			if(old) {
				node.appendChild(old);
			}
			if(!is_callback) {
				// append back using par / ind
				if(!par) {
					par = this.element[0];
				}
				for(i = 0, j = par.childNodes.length; i < j; i++) {
					if(par.childNodes[i] && par.childNodes[i].className && par.childNodes[i].className.indexOf('jstree-children') !== -1) {
						tmp = par.childNodes[i];
						break;
					}
				}
				if(!tmp) {
					tmp = d.createElement('UL');
					tmp.setAttribute('role', 'group');
					tmp.className = 'jstree-children';
					par.appendChild(tmp);
				}
				par = tmp;

				if(ind < par.childNodes.length) {
					par.insertBefore(node, par.childNodes[ind]);
				}
				else {
					par.appendChild(node);
				}
				if(f) {
					t = this.element[0].scrollTop;
					l = this.element[0].scrollLeft;
					node.childNodes[1].focus();
					this.element[0].scrollTop = t;
					this.element[0].scrollLeft = l;
				}
			}
			if(obj.state.opened && !obj.state.loaded) {
				obj.state.opened = false;
				setTimeout($.proxy(function () {
					this.open_node(obj.id, false, 0);
				}, this), 0);
			}
			return node;
		},
		/**
		 * opens a node, revaling its children. If the node is not loaded it will be loaded and opened once ready.
		 * @name open_node(obj [, callback, animation])
		 * @param {mixed} obj the node to open
		 * @param {Function} callback a function to execute once the node is opened
		 * @param {Number} animation the animation duration in milliseconds when opening the node (overrides the `core.animation` setting). Use `false` for no animation.
		 * @trigger open_node.jstree, after_open.jstree, before_open.jstree
		 */
		open_node : function (obj, callback, animation) {
			var t1, t2, d, t;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.open_node(obj[t1], callback, animation);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') {
				return false;
			}
			animation = animation === undefined ? this.settings.core.animation : animation;
			if(!this.is_closed(obj)) {
				if(callback) {
					callback.call(this, obj, false);
				}
				return false;
			}
			if(!this.is_loaded(obj)) {
				if(this.is_loading(obj)) {
					return setTimeout($.proxy(function () {
						this.open_node(obj, callback, animation);
					}, this), 500);
				}
				this.load_node(obj, function (o, ok) {
					return ok ? this.open_node(o, callback, animation) : (callback ? callback.call(this, o, false) : false);
				});
			}
			else {
				d = this.get_node(obj, true);
				t = this;
				if(d.length) {
					if(animation && d.children(".jstree-children").length) {
						d.children(".jstree-children").stop(true, true);
					}
					if(obj.children.length && !this._firstChild(d.children('.jstree-children')[0])) {
						this.draw_children(obj);
						//d = this.get_node(obj, true);
					}
					if(!animation) {
						this.trigger('before_open', { "node" : obj });
						d[0].className = d[0].className.replace('jstree-closed', 'jstree-open');
						d[0].setAttribute("aria-expanded", true);
					}
					else {
						this.trigger('before_open', { "node" : obj });
						d
							.children(".jstree-children").css("display","none").end()
							.removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded", true)
							.children(".jstree-children").stop(true, true)
								.slideDown(animation, function () {
									this.style.display = "";
									t.trigger("after_open", { "node" : obj });
								});
					}
				}
				obj.state.opened = true;
				if(callback) {
					callback.call(this, obj, true);
				}
				if(!d.length) {
					/**
					 * triggered when a node is about to be opened (if the node is supposed to be in the DOM, it will be, but it won't be visible yet)
					 * @event
					 * @name before_open.jstree
					 * @param {Object} node the opened node
					 */
					this.trigger('before_open', { "node" : obj });
				}
				/**
				 * triggered when a node is opened (if there is an animation it will not be completed yet)
				 * @event
				 * @name open_node.jstree
				 * @param {Object} node the opened node
				 */
				this.trigger('open_node', { "node" : obj });
				if(!animation || !d.length) {
					/**
					 * triggered when a node is opened and the animation is complete
					 * @event
					 * @name after_open.jstree
					 * @param {Object} node the opened node
					 */
					this.trigger("after_open", { "node" : obj });
				}
			}
		},
		/**
		 * opens every parent of a node (node should be loaded)
		 * @name _open_to(obj)
		 * @param {mixed} obj the node to reveal
		 * @private
		 */
		_open_to : function (obj) {
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') {
				return false;
			}
			var i, j, p = obj.parents;
			for(i = 0, j = p.length; i < j; i+=1) {
				if(i !== '#') {
					this.open_node(p[i], false, 0);
				}
			}
			return $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element);
		},
		/**
		 * closes a node, hiding its children
		 * @name close_node(obj [, animation])
		 * @param {mixed} obj the node to close
		 * @param {Number} animation the animation duration in milliseconds when closing the node (overrides the `core.animation` setting). Use `false` for no animation.
		 * @trigger close_node.jstree, after_close.jstree
		 */
		close_node : function (obj, animation) {
			var t1, t2, t, d;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.close_node(obj[t1], animation);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') {
				return false;
			}
			if(this.is_closed(obj)) {
				return false;
			}
			animation = animation === undefined ? this.settings.core.animation : animation;
			t = this;
			d = this.get_node(obj, true);
			if(d.length) {
				if(!animation) {
					d[0].className = d[0].className.replace('jstree-open', 'jstree-closed');
					d.attr("aria-expanded", false).children('.jstree-children').remove();
				}
				else {
					d
						.children(".jstree-children").attr("style","display:block !important").end()
						.removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded", false)
						.children(".jstree-children").stop(true, true).slideUp(animation, function () {
							this.style.display = "";
							d.children('.jstree-children').remove();
							t.trigger("after_close", { "node" : obj });
						});
				}
			}
			obj.state.opened = false;
			/**
			 * triggered when a node is closed (if there is an animation it will not be complete yet)
			 * @event
			 * @name close_node.jstree
			 * @param {Object} node the closed node
			 */
			this.trigger('close_node',{ "node" : obj });
			if(!animation || !d.length) {
				/**
				 * triggered when a node is closed and the animation is complete
				 * @event
				 * @name after_close.jstree
				 * @param {Object} node the closed node
				 */
				this.trigger("after_close", { "node" : obj });
			}
		},
		/**
		 * toggles a node - closing it if it is open, opening it if it is closed
		 * @name toggle_node(obj)
		 * @param {mixed} obj the node to toggle
		 */
		toggle_node : function (obj) {
			var t1, t2;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.toggle_node(obj[t1]);
				}
				return true;
			}
			if(this.is_closed(obj)) {
				return this.open_node(obj);
			}
			if(this.is_open(obj)) {
				return this.close_node(obj);
			}
		},
		/**
		 * opens all nodes within a node (or the tree), revaling their children. If the node is not loaded it will be loaded and opened once ready.
		 * @name open_all([obj, animation, original_obj])
		 * @param {mixed} obj the node to open recursively, omit to open all nodes in the tree
		 * @param {Number} animation the animation duration in milliseconds when opening the nodes, the default is no animation
		 * @param {jQuery} reference to the node that started the process (internal use)
		 * @trigger open_all.jstree
		 */
		open_all : function (obj, animation, original_obj) {
			if(!obj) { obj = '#'; }
			obj = this.get_node(obj);
			if(!obj) { return false; }
			var dom = obj.id === '#' ? this.get_container_ul() : this.get_node(obj, true), i, j, _this;
			if(!dom.length) {
				for(i = 0, j = obj.children_d.length; i < j; i++) {
					if(this.is_closed(this._model.data[obj.children_d[i]])) {
						this._model.data[obj.children_d[i]].state.opened = true;
					}
				}
				return this.trigger('open_all', { "node" : obj });
			}
			original_obj = original_obj || dom;
			_this = this;
			dom = this.is_closed(obj) ? dom.find('.jstree-closed').addBack() : dom.find('.jstree-closed');
			dom.each(function () {
				_this.open_node(
					this,
					function(node, status) { if(status && this.is_parent(node)) { this.open_all(node, animation, original_obj); } },
					animation || 0
				);
			});
			if(original_obj.find('.jstree-closed').length === 0) {
				/**
				 * triggered when an `open_all` call completes
				 * @event
				 * @name open_all.jstree
				 * @param {Object} node the opened node
				 */
				this.trigger('open_all', { "node" : this.get_node(original_obj) });
			}
		},
		/**
		 * closes all nodes within a node (or the tree), revaling their children
		 * @name close_all([obj, animation])
		 * @param {mixed} obj the node to close recursively, omit to close all nodes in the tree
		 * @param {Number} animation the animation duration in milliseconds when closing the nodes, the default is no animation
		 * @trigger close_all.jstree
		 */
		close_all : function (obj, animation) {
			if(!obj) { obj = '#'; }
			obj = this.get_node(obj);
			if(!obj) { return false; }
			var dom = obj.id === '#' ? this.get_container_ul() : this.get_node(obj, true),
				_this = this, i, j;
			if(!dom.length) {
				for(i = 0, j = obj.children_d.length; i < j; i++) {
					this._model.data[obj.children_d[i]].state.opened = false;
				}
				return this.trigger('close_all', { "node" : obj });
			}
			dom = this.is_open(obj) ? dom.find('.jstree-open').addBack() : dom.find('.jstree-open');
			$(dom.get().reverse()).each(function () { _this.close_node(this, animation || 0); });
			/**
			 * triggered when an `close_all` call completes
			 * @event
			 * @name close_all.jstree
			 * @param {Object} node the closed node
			 */
			this.trigger('close_all', { "node" : obj });
		},
		/**
		 * checks if a node is disabled (not selectable)
		 * @name is_disabled(obj)
		 * @param  {mixed} obj
		 * @return {Boolean}
		 */
		is_disabled : function (obj) {
			obj = this.get_node(obj);
			return obj && obj.state && obj.state.disabled;
		},
		/**
		 * enables a node - so that it can be selected
		 * @name enable_node(obj)
		 * @param {mixed} obj the node to enable
		 * @trigger enable_node.jstree
		 */
		enable_node : function (obj) {
			var t1, t2;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.enable_node(obj[t1]);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') {
				return false;
			}
			obj.state.disabled = false;
			this.get_node(obj,true).children('.jstree-anchor').removeClass('jstree-disabled').attr('aria-disabled', false);
			/**
			 * triggered when an node is enabled
			 * @event
			 * @name enable_node.jstree
			 * @param {Object} node the enabled node
			 */
			this.trigger('enable_node', { 'node' : obj });
		},
		/**
		 * disables a node - so that it can not be selected
		 * @name disable_node(obj)
		 * @param {mixed} obj the node to disable
		 * @trigger disable_node.jstree
		 */
		disable_node : function (obj) {
			var t1, t2;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.disable_node(obj[t1]);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') {
				return false;
			}
			obj.state.disabled = true;
			this.get_node(obj,true).children('.jstree-anchor').addClass('jstree-disabled').attr('aria-disabled', true);
			/**
			 * triggered when an node is disabled
			 * @event
			 * @name disable_node.jstree
			 * @param {Object} node the disabled node
			 */
			this.trigger('disable_node', { 'node' : obj });
		},
		/**
		 * called when a node is selected by the user. Used internally.
		 * @private
		 * @name activate_node(obj, e)
		 * @param {mixed} obj the node
		 * @param {Object} e the related event
		 * @trigger activate_node.jstree, changed.jstree
		 */
		activate_node : function (obj, e) {
			if(this.is_disabled(obj)) {
				return false;
			}

			// ensure last_clicked is still in the DOM, make it fresh (maybe it was moved?) and make sure it is still selected, if not - make last_clicked the last selected node
			this._data.core.last_clicked = this._data.core.last_clicked && this._data.core.last_clicked.id !== undefined ? this.get_node(this._data.core.last_clicked.id) : null;
			if(this._data.core.last_clicked && !this._data.core.last_clicked.state.selected) { this._data.core.last_clicked = null; }
			if(!this._data.core.last_clicked && this._data.core.selected.length) { this._data.core.last_clicked = this.get_node(this._data.core.selected[this._data.core.selected.length - 1]); }

			if(!this.settings.core.multiple || (!e.metaKey && !e.ctrlKey && !e.shiftKey) || (e.shiftKey && (!this._data.core.last_clicked || !this.get_parent(obj) || this.get_parent(obj) !== this._data.core.last_clicked.parent ) )) {
				if(!this.settings.core.multiple && (e.metaKey || e.ctrlKey || e.shiftKey) && this.is_selected(obj)) {
					this.deselect_node(obj, false, e);
				}
				else {
					this.deselect_all(true);
					this.select_node(obj, false, false, e);
					this._data.core.last_clicked = this.get_node(obj);
				}
			}
			else {
				if(e.shiftKey) {
					var o = this.get_node(obj).id,
						l = this._data.core.last_clicked.id,
						p = this.get_node(this._data.core.last_clicked.parent).children,
						c = false,
						i, j;
					for(i = 0, j = p.length; i < j; i += 1) {
						// separate IFs work whem o and l are the same
						if(p[i] === o) {
							c = !c;
						}
						if(p[i] === l) {
							c = !c;
						}
						if(!this.is_disabled(p[i]) && (c || p[i] === o || p[i] === l)) {
							this.select_node(p[i], true, false, e);
						}
						else {
							this.deselect_node(p[i], true, e);
						}
					}
					this.trigger('changed', { 'action' : 'select_node', 'node' : this.get_node(obj), 'selected' : this._data.core.selected, 'event' : e });
				}
				else {
					if(!this.is_selected(obj)) {
						this.select_node(obj, false, false, e);
					}
					else {
						this.deselect_node(obj, false, e);
					}
				}
			}
			/**
			 * triggered when an node is clicked or intercated with by the user
			 * @event
			 * @name activate_node.jstree
			 * @param {Object} node
			 */
			this.trigger('activate_node', { 'node' : this.get_node(obj) });
		},
		/**
		 * applies the hover state on a node, called when a node is hovered by the user. Used internally.
		 * @private
		 * @name hover_node(obj)
		 * @param {mixed} obj
		 * @trigger hover_node.jstree
		 */
		hover_node : function (obj) {
			obj = this.get_node(obj, true);
			if(!obj || !obj.length || obj.children('.jstree-hovered').length) {
				return false;
			}
			var o = this.element.find('.jstree-hovered'), t = this.element;
			if(o && o.length) { this.dehover_node(o); }

			obj.children('.jstree-anchor').addClass('jstree-hovered');
			/**
			 * triggered when an node is hovered
			 * @event
			 * @name hover_node.jstree
			 * @param {Object} node
			 */
			this.trigger('hover_node', { 'node' : this.get_node(obj) });
			setTimeout(function () { t.attr('aria-activedescendant', obj[0].id); }, 0);
		},
		/**
		 * removes the hover state from a nodecalled when a node is no longer hovered by the user. Used internally.
		 * @private
		 * @name dehover_node(obj)
		 * @param {mixed} obj
		 * @trigger dehover_node.jstree
		 */
		dehover_node : function (obj) {
			obj = this.get_node(obj, true);
			if(!obj || !obj.length || !obj.children('.jstree-hovered').length) {
				return false;
			}
			obj.children('.jstree-anchor').removeClass('jstree-hovered');
			/**
			 * triggered when an node is no longer hovered
			 * @event
			 * @name dehover_node.jstree
			 * @param {Object} node
			 */
			this.trigger('dehover_node', { 'node' : this.get_node(obj) });
		},
		/**
		 * select a node
		 * @name select_node(obj [, supress_event, prevent_open])
		 * @param {mixed} obj an array can be used to select multiple nodes
		 * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered
		 * @param {Boolean} prevent_open if set to `true` parents of the selected node won't be opened
		 * @trigger select_node.jstree, changed.jstree
		 */
		select_node : function (obj, supress_event, prevent_open, e) {
			var dom, t1, t2, th;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.select_node(obj[t1], supress_event, prevent_open, e);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') {
				return false;
			}
			dom = this.get_node(obj, true);
			if(!obj.state.selected) {
				obj.state.selected = true;
				this._data.core.selected.push(obj.id);
				if(!prevent_open) {
					dom = this._open_to(obj);
				}
				if(dom && dom.length) {
					dom.attr('aria-selected', true).children('.jstree-anchor').addClass('jstree-clicked');
				}
				/**
				 * triggered when an node is selected
				 * @event
				 * @name select_node.jstree
				 * @param {Object} node
				 * @param {Array} selected the current selection
				 * @param {Object} event the event (if any) that triggered this select_node
				 */
				this.trigger('select_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });
				if(!supress_event) {
					/**
					 * triggered when selection changes
					 * @event
					 * @name changed.jstree
					 * @param {Object} node
					 * @param {Object} action the action that caused the selection to change
					 * @param {Array} selected the current selection
					 * @param {Object} event the event (if any) that triggered this changed event
					 */
					this.trigger('changed', { 'action' : 'select_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });
				}
			}
		},
		/**
		 * deselect a node
		 * @name deselect_node(obj [, supress_event])
		 * @param {mixed} obj an array can be used to deselect multiple nodes
		 * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered
		 * @trigger deselect_node.jstree, changed.jstree
		 */
		deselect_node : function (obj, supress_event, e) {
			var t1, t2, dom;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.deselect_node(obj[t1], supress_event, e);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') {
				return false;
			}
			dom = this.get_node(obj, true);
			if(obj.state.selected) {
				obj.state.selected = false;
				this._data.core.selected = $.vakata.array_remove_item(this._data.core.selected, obj.id);
				if(dom.length) {
					dom.attr('aria-selected', false).children('.jstree-anchor').removeClass('jstree-clicked');
				}
				/**
				 * triggered when an node is deselected
				 * @event
				 * @name deselect_node.jstree
				 * @param {Object} node
				 * @param {Array} selected the current selection
				 * @param {Object} event the event (if any) that triggered this deselect_node
				 */
				this.trigger('deselect_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });
				if(!supress_event) {
					this.trigger('changed', { 'action' : 'deselect_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });
				}
			}
		},
		/**
		 * select all nodes in the tree
		 * @name select_all([supress_event])
		 * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered
		 * @trigger select_all.jstree, changed.jstree
		 */
		select_all : function (supress_event) {
			var tmp = this._data.core.selected.concat([]), i, j;
			this._data.core.selected = this._model.data['#'].children_d.concat();
			for(i = 0, j = this._data.core.selected.length; i < j; i++) {
				if(this._model.data[this._data.core.selected[i]]) {
					this._model.data[this._data.core.selected[i]].state.selected = true;
				}
			}
			this.redraw(true);
			/**
			 * triggered when all nodes are selected
			 * @event
			 * @name select_all.jstree
			 * @param {Array} selected the current selection
			 */
			this.trigger('select_all', { 'selected' : this._data.core.selected });
			if(!supress_event) {
				this.trigger('changed', { 'action' : 'select_all', 'selected' : this._data.core.selected, 'old_selection' : tmp });
			}
		},
		/**
		 * deselect all selected nodes
		 * @name deselect_all([supress_event])
		 * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered
		 * @trigger deselect_all.jstree, changed.jstree
		 */
		deselect_all : function (supress_event) {
			var tmp = this._data.core.selected.concat([]), i, j;
			for(i = 0, j = this._data.core.selected.length; i < j; i++) {
				if(this._model.data[this._data.core.selected[i]]) {
					this._model.data[this._data.core.selected[i]].state.selected = false;
				}
			}
			this._data.core.selected = [];
			this.element.find('.jstree-clicked').removeClass('jstree-clicked').parent().attr('aria-selected', false);
			/**
			 * triggered when all nodes are deselected
			 * @event
			 * @name deselect_all.jstree
			 * @param {Object} node the previous selection
			 * @param {Array} selected the current selection
			 */
			this.trigger('deselect_all', { 'selected' : this._data.core.selected, 'node' : tmp });
			if(!supress_event) {
				this.trigger('changed', { 'action' : 'deselect_all', 'selected' : this._data.core.selected, 'old_selection' : tmp });
			}
		},
		/**
		 * checks if a node is selected
		 * @name is_selected(obj)
		 * @param  {mixed}  obj
		 * @return {Boolean}
		 */
		is_selected : function (obj) {
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') {
				return false;
			}
			return obj.state.selected;
		},
		/**
		 * get an array of all selected nodes
		 * @name get_selected([full])
		 * @param  {mixed}  full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
		 * @return {Array}
		 */
		get_selected : function (full) {
			return full ? $.map(this._data.core.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.core.selected.slice();
		},
		/**
		 * get an array of all top level selected nodes (ignoring children of selected nodes)
		 * @name get_top_selected([full])
		 * @param  {mixed}  full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
		 * @return {Array}
		 */
		get_top_selected : function (full) {
			var tmp = this.get_selected(true),
				obj = {}, i, j, k, l;
			for(i = 0, j = tmp.length; i < j; i++) {
				obj[tmp[i].id] = tmp[i];
			}
			for(i = 0, j = tmp.length; i < j; i++) {
				for(k = 0, l = tmp[i].children_d.length; k < l; k++) {
					if(obj[tmp[i].children_d[k]]) {
						delete obj[tmp[i].children_d[k]];
					}
				}
			}
			tmp = [];
			for(i in obj) {
				if(obj.hasOwnProperty(i)) {
					tmp.push(i);
				}
			}
			return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp;
		},
		/**
		 * get an array of all bottom level selected nodes (ignoring selected parents)
		 * @name get_bottom_selected([full])
		 * @param  {mixed}  full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
		 * @return {Array}
		 */
		get_bottom_selected : function (full) {
			var tmp = this.get_selected(true),
				obj = [], i, j;
			for(i = 0, j = tmp.length; i < j; i++) {
				if(!tmp[i].children.length) {
					obj.push(tmp[i].id);
				}
			}
			return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj;
		},
		/**
		 * gets the current state of the tree so that it can be restored later with `set_state(state)`. Used internally.
		 * @name get_state()
		 * @private
		 * @return {Object}
		 */
		get_state : function () {
			var state	= {
				'core' : {
					'open' : [],
					'scroll' : {
						'left' : this.element.scrollLeft(),
						'top' : this.element.scrollTop()
					},
					/*!
					'themes' : {
						'name' : this.get_theme(),
						'icons' : this._data.core.themes.icons,
						'dots' : this._data.core.themes.dots
					},
					*/
					'selected' : []
				}
			}, i;
			for(i in this._model.data) {
				if(this._model.data.hasOwnProperty(i)) {
					if(i !== '#') {
						if(this._model.data[i].state.opened) {
							state.core.open.push(i);
						}
						if(this._model.data[i].state.selected) {
							state.core.selected.push(i);
						}
					}
				}
			}
			return state;
		},
		/**
		 * sets the state of the tree. Used internally.
		 * @name set_state(state [, callback])
		 * @private
		 * @param {Object} state the state to restore
		 * @param {Function} callback an optional function to execute once the state is restored.
		 * @trigger set_state.jstree
		 */
		set_state : function (state, callback) {
			if(state) {
				if(state.core) {
					var res, n, t, _this, i;
					if(state.core.open) {
						if(!$.isArray(state.core.open) || !state.core.open.length) {
							delete state.core.open;
							this.set_state(state, callback);
						}
						else {
							this._load_nodes(state.core.open, function (nodes) {
								this.open_node(nodes, false, 0);
								delete state.core.open;
								this.set_state(state, callback);
							}, true);
						}
						return false;
					}
					if(state.core.scroll) {
						if(state.core.scroll && state.core.scroll.left !== undefined) {
							this.element.scrollLeft(state.core.scroll.left);
						}
						if(state.core.scroll && state.core.scroll.top !== undefined) {
							this.element.scrollTop(state.core.scroll.top);
						}
						delete state.core.scroll;
						this.set_state(state, callback);
						return false;
					}
					if(state.core.selected) {
						_this = this;
						this.deselect_all();
						$.each(state.core.selected, function (i, v) {
							_this.select_node(v, false, true);
						});
						delete state.core.selected;
						this.set_state(state, callback);
						return false;
					}
					for(i in state) {
						if(state.hasOwnProperty(i) && i !== "core" && $.inArray(i, this.settings.plugins) === -1) {
							delete state[i];
						}
					}
					if($.isEmptyObject(state.core)) {
						delete state.core;
						this.set_state(state, callback);
						return false;
					}
				}
				if($.isEmptyObject(state)) {
					state = null;
					if(callback) { callback.call(this); }
					/**
					 * triggered when a `set_state` call completes
					 * @event
					 * @name set_state.jstree
					 */
					this.trigger('set_state');
					return false;
				}
				return true;
			}
			return false;
		},
		/**
		 * refreshes the tree - all nodes are reloaded with calls to `load_node`.
		 * @name refresh()
		 * @param {Boolean} skip_loading an option to skip showing the loading indicator
		 * @param {Mixed} forget_state if set to `true` state will not be reapplied, if set to a function (receiving the current state as argument) the result of that function will be used as state
		 * @trigger refresh.jstree
		 */
		refresh : function (skip_loading, forget_state) {
			this._data.core.state = forget_state === true ? {} : this.get_state();
			if(forget_state && $.isFunction(forget_state)) { this._data.core.state = forget_state.call(this, this._data.core.state); }
			this._cnt = 0;
			this._model.data = {
				'#' : {
					id : '#',
					parent : null,
					parents : [],
					children : [],
					children_d : [],
					state : { loaded : false }
				}
			};
			var c = this.get_container_ul()[0].className;
			if(!skip_loading) {
				this.element.html("<"+"ul class='"+c+"' role='group'><"+"li class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='treeitem' id='j"+this._id+"_loading'><i class='jstree-icon jstree-ocl'></i><"+"a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>" + this.get_string("Loading ...") + "</a></li></ul>");
				this.element.attr('aria-activedescendant','j'+this._id+'_loading');
			}
			this.load_node('#', function (o, s) {
				if(s) {
					this.get_container_ul()[0].className = c;
					if(this._firstChild(this.get_container_ul()[0])) {
						this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id);
					}
					this.set_state($.extend(true, {}, this._data.core.state), function () {
						/**
						 * triggered when a `refresh` call completes
						 * @event
						 * @name refresh.jstree
						 */
						this.trigger('refresh');
					});
				}
				this._data.core.state = null;
			});
		},
		/**
		 * refreshes a node in the tree (reload its children) all opened nodes inside that node are reloaded with calls to `load_node`.
		 * @name refresh_node(obj)
		 * @param  {mixed} obj the node
		 * @trigger refresh_node.jstree
		 */
		refresh_node : function (obj) {
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') { return false; }
			var opened = [], to_load = [], s = this._data.core.selected.concat([]);
			to_load.push(obj.id);
			if(obj.state.opened === true) { opened.push(obj.id); }
			this.get_node(obj, true).find('.jstree-open').each(function() { opened.push(this.id); });
			this._load_nodes(to_load, $.proxy(function (nodes) {
				this.open_node(opened, false, 0);
				this.select_node(this._data.core.selected);
				/**
				 * triggered when a node is refreshed
				 * @event
				 * @name refresh_node.jstree
				 * @param {Object} node - the refreshed node
				 * @param {Array} nodes - an array of the IDs of the nodes that were reloaded
				 */
				this.trigger('refresh_node', { 'node' : obj, 'nodes' : nodes });
			}, this));
		},
		/**
		 * set (change) the ID of a node
		 * @name set_id(obj, id)
		 * @param  {mixed} obj the node
		 * @param  {String} id the new ID
		 * @return {Boolean}
		 */
		set_id : function (obj, id) {
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') { return false; }
			var i, j, m = this._model.data;
			id = id.toString();
			// update parents (replace current ID with new one in children and children_d)
			m[obj.parent].children[$.inArray(obj.id, m[obj.parent].children)] = id;
			for(i = 0, j = obj.parents.length; i < j; i++) {
				m[obj.parents[i]].children_d[$.inArray(obj.id, m[obj.parents[i]].children_d)] = id;
			}
			// update children (replace current ID with new one in parent and parents)
			for(i = 0, j = obj.children.length; i < j; i++) {
				m[obj.children[i]].parent = id;
			}
			for(i = 0, j = obj.children_d.length; i < j; i++) {
				m[obj.children_d[i]].parents[$.inArray(obj.id, m[obj.children_d[i]].parents)] = id;
			}
			i = $.inArray(obj.id, this._data.core.selected);
			if(i !== -1) { this._data.core.selected[i] = id; }
			// update model and obj itself (obj.id, this._model.data[KEY])
			i = this.get_node(obj.id, true);
			if(i) {
				i.attr('id', id).children('.jstree-anchor').attr('id', id + '_anchor').end().attr('aria-labelledby', id + '_anchor');
				if(this.element.attr('aria-activedescendant') === obj.id) {
					this.element.attr('aria-activedescendant', id);
				}
			}
			delete m[obj.id];
			obj.id = id;
			obj.li_attr.id = id;
			m[id] = obj;
			return true;
		},
		/**
		 * get the text value of a node
		 * @name get_text(obj)
		 * @param  {mixed} obj the node
		 * @return {String}
		 */
		get_text : function (obj) {
			obj = this.get_node(obj);
			return (!obj || obj.id === '#') ? false : obj.text;
		},
		/**
		 * set the text value of a node. Used internally, please use `rename_node(obj, val)`.
		 * @private
		 * @name set_text(obj, val)
		 * @param  {mixed} obj the node, you can pass an array to set the text on multiple nodes
		 * @param  {String} val the new text value
		 * @return {Boolean}
		 * @trigger set_text.jstree
		 */
		set_text : function (obj, val) {
			var t1, t2;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.set_text(obj[t1], val);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') { return false; }
			obj.text = val;
			if(this.get_node(obj, true).length) {
				this.redraw_node(obj.id);
			}
			/**
			 * triggered when a node text value is changed
			 * @event
			 * @name set_text.jstree
			 * @param {Object} obj
			 * @param {String} text the new value
			 */
			this.trigger('set_text',{ "obj" : obj, "text" : val });
			return true;
		},
		/**
		 * gets a JSON representation of a node (or the whole tree)
		 * @name get_json([obj, options])
		 * @param  {mixed} obj
		 * @param  {Object} options
		 * @param  {Boolean} options.no_state do not return state information
		 * @param  {Boolean} options.no_id do not return ID
		 * @param  {Boolean} options.no_children do not include children
		 * @param  {Boolean} options.no_data do not include node data
		 * @param  {Boolean} options.flat return flat JSON instead of nested
		 * @return {Object}
		 */
		get_json : function (obj, options, flat) {
			obj = this.get_node(obj || '#');
			if(!obj) { return false; }
			if(options && options.flat && !flat) { flat = []; }
			var tmp = {
				'id' : obj.id,
				'text' : obj.text,
				'icon' : this.get_icon(obj),
				'li_attr' : $.extend(true, {}, obj.li_attr),
				'a_attr' : $.extend(true, {}, obj.a_attr),
				'state' : {},
				'data' : options && options.no_data ? false : $.extend(true, {}, obj.data)
				//( this.get_node(obj, true).length ? this.get_node(obj, true).data() : obj.data ),
			}, i, j;
			if(options && options.flat) {
				tmp.parent = obj.parent;
			}
			else {
				tmp.children = [];
			}
			if(!options || !options.no_state) {
				for(i in obj.state) {
					if(obj.state.hasOwnProperty(i)) {
						tmp.state[i] = obj.state[i];
					}
				}
			}
			if(options && options.no_id) {
				delete tmp.id;
				if(tmp.li_attr && tmp.li_attr.id) {
					delete tmp.li_attr.id;
				}
				if(tmp.a_attr && tmp.a_attr.id) {
					delete tmp.a_attr.id;
				}
			}
			if(options && options.flat && obj.id !== '#') {
				flat.push(tmp);
			}
			if(!options || !options.no_children) {
				for(i = 0, j = obj.children.length; i < j; i++) {
					if(options && options.flat) {
						this.get_json(obj.children[i], options, flat);
					}
					else {
						tmp.children.push(this.get_json(obj.children[i], options));
					}
				}
			}
			return options && options.flat ? flat : (obj.id === '#' ? tmp.children : tmp);
		},
		/**
		 * create a new node (do not confuse with load_node)
		 * @name create_node([obj, node, pos, callback, is_loaded])
		 * @param  {mixed}   par       the parent node (to create a root node use either "#" (string) or `null`)
		 * @param  {mixed}   node      the data for the new node (a valid JSON object, or a simple string with the name)
		 * @param  {mixed}   pos       the index at which to insert the node, "first" and "last" are also supported, default is "last"
		 * @param  {Function} callback a function to be called once the node is created
		 * @param  {Boolean} is_loaded internal argument indicating if the parent node was succesfully loaded
		 * @return {String}            the ID of the newly create node
		 * @trigger model.jstree, create_node.jstree
		 */
		create_node : function (par, node, pos, callback, is_loaded) {
			if(par === null) { par = "#"; }
			par = this.get_node(par);
			if(!par) { return false; }
			pos = pos === undefined ? "last" : pos;
			if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
				return this.load_node(par, function () { this.create_node(par, node, pos, callback, true); });
			}
			if(!node) { node = { "text" : this.get_string('New node') }; }
			if(typeof node === "string") { node = { "text" : node }; }
			if(node.text === undefined) { node.text = this.get_string('New node'); }
			var tmp, dpc, i, j;

			if(par.id === '#') {
				if(pos === "before") { pos = "first"; }
				if(pos === "after") { pos = "last"; }
			}
			switch(pos) {
				case "before":
					tmp = this.get_node(par.parent);
					pos = $.inArray(par.id, tmp.children);
					par = tmp;
					break;
				case "after" :
					tmp = this.get_node(par.parent);
					pos = $.inArray(par.id, tmp.children) + 1;
					par = tmp;
					break;
				case "inside":
				case "first":
					pos = 0;
					break;
				case "last":
					pos = par.children.length;
					break;
				default:
					if(!pos) { pos = 0; }
					break;
			}
			if(pos > par.children.length) { pos = par.children.length; }
			if(!node.id) { node.id = true; }
			if(!this.check("create_node", node, par, pos)) {
				this.settings.core.error.call(this, this._data.core.last_error);
				return false;
			}
			if(node.id === true) { delete node.id; }
			node = this._parse_model_from_json(node, par.id, par.parents.concat());
			if(!node) { return false; }
			tmp = this.get_node(node);
			dpc = [];
			dpc.push(node);
			dpc = dpc.concat(tmp.children_d);
			this.trigger('model', { "nodes" : dpc, "parent" : par.id });

			par.children_d = par.children_d.concat(dpc);
			for(i = 0, j = par.parents.length; i < j; i++) {
				this._model.data[par.parents[i]].children_d = this._model.data[par.parents[i]].children_d.concat(dpc);
			}
			node = tmp;
			tmp = [];
			for(i = 0, j = par.children.length; i < j; i++) {
				tmp[i >= pos ? i+1 : i] = par.children[i];
			}
			tmp[pos] = node.id;
			par.children = tmp;

			this.redraw_node(par, true);
			if(callback) { callback.call(this, this.get_node(node)); }
			/**
			 * triggered when a node is created
			 * @event
			 * @name create_node.jstree
			 * @param {Object} node
			 * @param {String} parent the parent's ID
			 * @param {Number} position the position of the new node among the parent's children
			 */
			this.trigger('create_node', { "node" : this.get_node(node), "parent" : par.id, "position" : pos });
			return node.id;
		},
		/**
		 * set the text value of a node
		 * @name rename_node(obj, val)
		 * @param  {mixed} obj the node, you can pass an array to rename multiple nodes to the same name
		 * @param  {String} val the new text value
		 * @return {Boolean}
		 * @trigger rename_node.jstree
		 */
		rename_node : function (obj, val) {
			var t1, t2, old;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.rename_node(obj[t1], val);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') { return false; }
			old = obj.text;
			if(!this.check("rename_node", obj, this.get_parent(obj), val)) {
				this.settings.core.error.call(this, this._data.core.last_error);
				return false;
			}
			this.set_text(obj, val); // .apply(this, Array.prototype.slice.call(arguments))
			/**
			 * triggered when a node is renamed
			 * @event
			 * @name rename_node.jstree
			 * @param {Object} node
			 * @param {String} text the new value
			 * @param {String} old the old value
			 */
			this.trigger('rename_node', { "node" : obj, "text" : val, "old" : old });
			return true;
		},
		/**
		 * remove a node
		 * @name delete_node(obj)
		 * @param  {mixed} obj the node, you can pass an array to delete multiple nodes
		 * @return {Boolean}
		 * @trigger delete_node.jstree, changed.jstree
		 */
		delete_node : function (obj) {
			var t1, t2, par, pos, tmp, i, j, k, l, c;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.delete_node(obj[t1]);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') { return false; }
			par = this.get_node(obj.parent);
			pos = $.inArray(obj.id, par.children);
			c = false;
			if(!this.check("delete_node", obj, par, pos)) {
				this.settings.core.error.call(this, this._data.core.last_error);
				return false;
			}
			if(pos !== -1) {
				par.children = $.vakata.array_remove(par.children, pos);
			}
			tmp = obj.children_d.concat([]);
			tmp.push(obj.id);
			for(k = 0, l = tmp.length; k < l; k++) {
				for(i = 0, j = obj.parents.length; i < j; i++) {
					pos = $.inArray(tmp[k], this._model.data[obj.parents[i]].children_d);
					if(pos !== -1) {
						this._model.data[obj.parents[i]].children_d = $.vakata.array_remove(this._model.data[obj.parents[i]].children_d, pos);
					}
				}
				if(this._model.data[tmp[k]].state.selected) {
					c = true;
					pos = $.inArray(tmp[k], this._data.core.selected);
					if(pos !== -1) {
						this._data.core.selected = $.vakata.array_remove(this._data.core.selected, pos);
					}
				}
			}
			/**
			 * triggered when a node is deleted
			 * @event
			 * @name delete_node.jstree
			 * @param {Object} node
			 * @param {String} parent the parent's ID
			 */
			this.trigger('delete_node', { "node" : obj, "parent" : par.id });
			if(c) {
				this.trigger('changed', { 'action' : 'delete_node', 'node' : obj, 'selected' : this._data.core.selected, 'parent' : par.id });
			}
			for(k = 0, l = tmp.length; k < l; k++) {
				delete this._model.data[tmp[k]];
			}
			this.redraw_node(par, true);
			return true;
		},
		/**
		 * check if an operation is premitted on the tree. Used internally.
		 * @private
		 * @name check(chk, obj, par, pos)
		 * @param  {String} chk the operation to check, can be "create_node", "rename_node", "delete_node", "copy_node" or "move_node"
		 * @param  {mixed} obj the node
		 * @param  {mixed} par the parent
		 * @param  {mixed} pos the position to insert at, or if "rename_node" - the new name
		 * @param  {mixed} more some various additional information, for example if a "move_node" operations is triggered by DND this will be the hovered node
		 * @return {Boolean}
		 */
		check : function (chk, obj, par, pos, more) {
			obj = obj && obj.id ? obj : this.get_node(obj);
			par = par && par.id ? par : this.get_node(par);
			var tmp = chk.match(/^move_node|copy_node|create_node$/i) ? par : obj,
				chc = this.settings.core.check_callback;
			if(chk === "move_node" || chk === "copy_node") {
				if((!more || !more.is_multi) && (obj.id === par.id || $.inArray(obj.id, par.children) === pos || $.inArray(par.id, obj.children_d) !== -1)) {
					this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_01', 'reason' : 'Moving parent inside child', 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
					return false;
				}
			}
			if(tmp && tmp.data) { tmp = tmp.data; }
			if(tmp && tmp.functions && (tmp.functions[chk] === false || tmp.functions[chk] === true)) {
				if(tmp.functions[chk] === false) {
					this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_02', 'reason' : 'Node data prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
				}
				return tmp.functions[chk];
			}
			if(chc === false || ($.isFunction(chc) && chc.call(this, chk, obj, par, pos, more) === false) || (chc && chc[chk] === false)) {
				this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_03', 'reason' : 'User config for core.check_callback prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
				return false;
			}
			return true;
		},
		/**
		 * get the last error
		 * @name last_error()
		 * @return {Object}
		 */
		last_error : function () {
			return this._data.core.last_error;
		},
		/**
		 * move a node to a new parent
		 * @name move_node(obj, par [, pos, callback, is_loaded])
		 * @param  {mixed} obj the node to move, pass an array to move multiple nodes
		 * @param  {mixed} par the new parent
		 * @param  {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0`
		 * @param  {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position
		 * @param  {Boolean} is_loaded internal parameter indicating if the parent node has been loaded
		 * @param  {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn
		 * @param  {Boolean} instance internal parameter indicating if the node comes from another instance
		 * @trigger move_node.jstree
		 */
		move_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) {
			var t1, t2, old_par, old_pos, new_par, old_ins, is_multi, dpc, tmp, i, j, k, l, p;

			par = this.get_node(par);
			pos = pos === undefined ? 0 : pos;
			if(!par) { return false; }
			if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
				return this.load_node(par, function () { this.move_node(obj, par, pos, callback, true, false, origin); });
			}

			if($.isArray(obj)) {
				if(obj.length === 1) {
					obj = obj[0];
				}
				else {
					//obj = obj.slice();
					for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
						if((tmp = this.move_node(obj[t1], par, pos, callback, is_loaded, false, origin))) {
							par = tmp;
							pos = "after";
						}
					}
					this.redraw();
					return true;
				}
			}
			obj = obj && obj.id ? obj : this.get_node(obj);

			if(!obj || obj.id === '#') { return false; }

			old_par = (obj.parent || '#').toString();
			new_par = (!pos.toString().match(/^(before|after)$/) || par.id === '#') ? par : this.get_node(par.parent);
			old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id));
			is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id);
			old_pos = old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1;
			if(old_ins && old_ins._id) {
				obj = old_ins._model.data[obj.id];
			}

			if(is_multi) {
				if((tmp = this.copy_node(obj, par, pos, callback, is_loaded, false, origin))) {
					if(old_ins) { old_ins.delete_node(obj); }
					return tmp;
				}
				return false;
			}
			//var m = this._model.data;
			if(par.id === '#') {
				if(pos === "before") { pos = "first"; }
				if(pos === "after") { pos = "last"; }
			}
			switch(pos) {
				case "before":
					pos = $.inArray(par.id, new_par.children);
					break;
				case "after" :
					pos = $.inArray(par.id, new_par.children) + 1;
					break;
				case "inside":
				case "first":
					pos = 0;
					break;
				case "last":
					pos = new_par.children.length;
					break;
				default:
					if(!pos) { pos = 0; }
					break;
			}
			if(pos > new_par.children.length) { pos = new_par.children.length; }
			if(!this.check("move_node", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) {
				this.settings.core.error.call(this, this._data.core.last_error);
				return false;
			}
			if(obj.parent === new_par.id) {
				dpc = new_par.children.concat();
				tmp = $.inArray(obj.id, dpc);
				if(tmp !== -1) {
					dpc = $.vakata.array_remove(dpc, tmp);
					if(pos > tmp) { pos--; }
				}
				tmp = [];
				for(i = 0, j = dpc.length; i < j; i++) {
					tmp[i >= pos ? i+1 : i] = dpc[i];
				}
				tmp[pos] = obj.id;
				new_par.children = tmp;
				this._node_changed(new_par.id);
				this.redraw(new_par.id === '#');
			}
			else {
				// clean old parent and up
				tmp = obj.children_d.concat();
				tmp.push(obj.id);
				for(i = 0, j = obj.parents.length; i < j; i++) {
					dpc = [];
					p = old_ins._model.data[obj.parents[i]].children_d;
					for(k = 0, l = p.length; k < l; k++) {
						if($.inArray(p[k], tmp) === -1) {
							dpc.push(p[k]);
						}
					}
					old_ins._model.data[obj.parents[i]].children_d = dpc;
				}
				old_ins._model.data[old_par].children = $.vakata.array_remove_item(old_ins._model.data[old_par].children, obj.id);

				// insert into new parent and up
				for(i = 0, j = new_par.parents.length; i < j; i++) {
					this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(tmp);
				}
				dpc = [];
				for(i = 0, j = new_par.children.length; i < j; i++) {
					dpc[i >= pos ? i+1 : i] = new_par.children[i];
				}
				dpc[pos] = obj.id;
				new_par.children = dpc;
				new_par.children_d.push(obj.id);
				new_par.children_d = new_par.children_d.concat(obj.children_d);

				// update object
				obj.parent = new_par.id;
				tmp = new_par.parents.concat();
				tmp.unshift(new_par.id);
				p = obj.parents.length;
				obj.parents = tmp;

				// update object children
				tmp = tmp.concat();
				for(i = 0, j = obj.children_d.length; i < j; i++) {
					this._model.data[obj.children_d[i]].parents = this._model.data[obj.children_d[i]].parents.slice(0,p*-1);
					Array.prototype.push.apply(this._model.data[obj.children_d[i]].parents, tmp);
				}

				if(old_par === '#' || new_par.id === '#') {
					this._model.force_full_redraw = true;
				}
				if(!this._model.force_full_redraw) {
					this._node_changed(old_par);
					this._node_changed(new_par.id);
				}
				if(!skip_redraw) {
					this.redraw();
				}
			}
			if(callback) { callback.call(this, obj, new_par, pos); }
			/**
			 * triggered when a node is moved
			 * @event
			 * @name move_node.jstree
			 * @param {Object} node
			 * @param {String} parent the parent's ID
			 * @param {Number} position the position of the node among the parent's children
			 * @param {String} old_parent the old parent of the node
			 * @param {Number} old_position the old position of the node
			 * @param {Boolean} is_multi do the node and new parent belong to different instances
			 * @param {jsTree} old_instance the instance the node came from
			 * @param {jsTree} new_instance the instance of the new parent
			 */
			this.trigger('move_node', { "node" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_pos, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this });
			return obj.id;
		},
		/**
		 * copy a node to a new parent
		 * @name copy_node(obj, par [, pos, callback, is_loaded])
		 * @param  {mixed} obj the node to copy, pass an array to copy multiple nodes
		 * @param  {mixed} par the new parent
		 * @param  {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0`
		 * @param  {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position
		 * @param  {Boolean} is_loaded internal parameter indicating if the parent node has been loaded
		 * @param  {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn
		 * @param  {Boolean} instance internal parameter indicating if the node comes from another instance
		 * @trigger model.jstree copy_node.jstree
		 */
		copy_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) {
			var t1, t2, dpc, tmp, i, j, node, old_par, new_par, old_ins, is_multi;

			par = this.get_node(par);
			pos = pos === undefined ? 0 : pos;
			if(!par) { return false; }
			if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
				return this.load_node(par, function () { this.copy_node(obj, par, pos, callback, true, false, origin); });
			}

			if($.isArray(obj)) {
				if(obj.length === 1) {
					obj = obj[0];
				}
				else {
					//obj = obj.slice();
					for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
						if((tmp = this.copy_node(obj[t1], par, pos, callback, is_loaded, true, origin))) {
							par = tmp;
							pos = "after";
						}
					}
					this.redraw();
					return true;
				}
			}
			obj = obj && obj.id ? obj : this.get_node(obj);
			if(!obj || obj.id === '#') { return false; }

			old_par = (obj.parent || '#').toString();
			new_par = (!pos.toString().match(/^(before|after)$/) || par.id === '#') ? par : this.get_node(par.parent);
			old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id));
			is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id);

			if(old_ins && old_ins._id) {
				obj = old_ins._model.data[obj.id];
			}

			if(par.id === '#') {
				if(pos === "before") { pos = "first"; }
				if(pos === "after") { pos = "last"; }
			}
			switch(pos) {
				case "before":
					pos = $.inArray(par.id, new_par.children);
					break;
				case "after" :
					pos = $.inArray(par.id, new_par.children) + 1;
					break;
				case "inside":
				case "first":
					pos = 0;
					break;
				case "last":
					pos = new_par.children.length;
					break;
				default:
					if(!pos) { pos = 0; }
					break;
			}
			if(pos > new_par.children.length) { pos = new_par.children.length; }
			if(!this.check("copy_node", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) {
				this.settings.core.error.call(this, this._data.core.last_error);
				return false;
			}
			node = old_ins ? old_ins.get_json(obj, { no_id : true, no_data : true, no_state : true }) : obj;
			if(!node) { return false; }
			if(node.id === true) { delete node.id; }
			node = this._parse_model_from_json(node, new_par.id, new_par.parents.concat());
			if(!node) { return false; }
			tmp = this.get_node(node);
			if(obj && obj.state && obj.state.loaded === false) { tmp.state.loaded = false; }
			dpc = [];
			dpc.push(node);
			dpc = dpc.concat(tmp.children_d);
			this.trigger('model', { "nodes" : dpc, "parent" : new_par.id });

			// insert into new parent and up
			for(i = 0, j = new_par.parents.length; i < j; i++) {
				this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(dpc);
			}
			dpc = [];
			for(i = 0, j = new_par.children.length; i < j; i++) {
				dpc[i >= pos ? i+1 : i] = new_par.children[i];
			}
			dpc[pos] = tmp.id;
			new_par.children = dpc;
			new_par.children_d.push(tmp.id);
			new_par.children_d = new_par.children_d.concat(tmp.children_d);

			if(new_par.id === '#') {
				this._model.force_full_redraw = true;
			}
			if(!this._model.force_full_redraw) {
				this._node_changed(new_par.id);
			}
			if(!skip_redraw) {
				this.redraw(new_par.id === '#');
			}
			if(callback) { callback.call(this, tmp, new_par, pos); }
			/**
			 * triggered when a node is copied
			 * @event
			 * @name copy_node.jstree
			 * @param {Object} node the copied node
			 * @param {Object} original the original node
			 * @param {String} parent the parent's ID
			 * @param {Number} position the position of the node among the parent's children
			 * @param {String} old_parent the old parent of the node
			 * @param {Number} old_position the position of the original node
			 * @param {Boolean} is_multi do the node and new parent belong to different instances
			 * @param {jsTree} old_instance the instance the node came from
			 * @param {jsTree} new_instance the instance of the new parent
			 */
			this.trigger('copy_node', { "node" : tmp, "original" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1,'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this });
			return tmp.id;
		},
		/**
		 * cut a node (a later call to `paste(obj)` would move the node)
		 * @name cut(obj)
		 * @param  {mixed} obj multiple objects can be passed using an array
		 * @trigger cut.jstree
		 */
		cut : function (obj) {
			if(!obj) { obj = this._data.core.selected.concat(); }
			if(!$.isArray(obj)) { obj = [obj]; }
			if(!obj.length) { return false; }
			var tmp = [], o, t1, t2;
			for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
				o = this.get_node(obj[t1]);
				if(o && o.id && o.id !== '#') { tmp.push(o); }
			}
			if(!tmp.length) { return false; }
			ccp_node = tmp;
			ccp_inst = this;
			ccp_mode = 'move_node';
			/**
			 * triggered when nodes are added to the buffer for moving
			 * @event
			 * @name cut.jstree
			 * @param {Array} node
			 */
			this.trigger('cut', { "node" : obj });
		},
		/**
		 * copy a node (a later call to `paste(obj)` would copy the node)
		 * @name copy(obj)
		 * @param  {mixed} obj multiple objects can be passed using an array
		 * @trigger copy.jstree
		 */
		copy : function (obj) {
			if(!obj) { obj = this._data.core.selected.concat(); }
			if(!$.isArray(obj)) { obj = [obj]; }
			if(!obj.length) { return false; }
			var tmp = [], o, t1, t2;
			for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
				o = this.get_node(obj[t1]);
				if(o && o.id && o.id !== '#') { tmp.push(o); }
			}
			if(!tmp.length) { return false; }
			ccp_node = tmp;
			ccp_inst = this;
			ccp_mode = 'copy_node';
			/**
			 * triggered when nodes are added to the buffer for copying
			 * @event
			 * @name copy.jstree
			 * @param {Array} node
			 */
			this.trigger('copy', { "node" : obj });
		},
		/**
		 * get the current buffer (any nodes that are waiting for a paste operation)
		 * @name get_buffer()
		 * @return {Object} an object consisting of `mode` ("copy_node" or "move_node"), `node` (an array of objects) and `inst` (the instance)
		 */
		get_buffer : function () {
			return { 'mode' : ccp_mode, 'node' : ccp_node, 'inst' : ccp_inst };
		},
		/**
		 * check if there is something in the buffer to paste
		 * @name can_paste()
		 * @return {Boolean}
		 */
		can_paste : function () {
			return ccp_mode !== false && ccp_node !== false; // && ccp_inst._model.data[ccp_node];
		},
		/**
		 * copy or move the previously cut or copied nodes to a new parent
		 * @name paste(obj [, pos])
		 * @param  {mixed} obj the new parent
		 * @param  {mixed} pos the position to insert at (besides integer, "first" and "last" are supported), defaults to integer `0`
		 * @trigger paste.jstree
		 */
		paste : function (obj, pos) {
			obj = this.get_node(obj);
			if(!obj || !ccp_mode || !ccp_mode.match(/^(copy_node|move_node)$/) || !ccp_node) { return false; }
			if(this[ccp_mode](ccp_node, obj, pos, false, false, false, ccp_inst)) {
				/**
				 * triggered when paste is invoked
				 * @event
				 * @name paste.jstree
				 * @param {String} parent the ID of the receiving node
				 * @param {Array} node the nodes in the buffer
				 * @param {String} mode the performed operation - "copy_node" or "move_node"
				 */
				this.trigger('paste', { "parent" : obj.id, "node" : ccp_node, "mode" : ccp_mode });
			}
			ccp_node = false;
			ccp_mode = false;
			ccp_inst = false;
		},
		/**
		 * clear the buffer of previously copied or cut nodes
		 * @name clear_buffer()
		 * @trigger clear_buffer.jstree
		 */
		clear_buffer : function () {
			ccp_node = false;
			ccp_mode = false;
			ccp_inst = false;
			/**
			 * triggered when the copy / cut buffer is cleared
			 * @event
			 * @name clear_buffer.jstree
			 */
			this.trigger('clear_buffer');
		},
		/**
		 * put a node in edit mode (input field to rename the node)
		 * @name edit(obj [, default_text, callback])
		 * @param  {mixed} obj
		 * @param  {String} default_text the text to populate the input with (if omitted or set to a non-string value the node's text value is used)
		 * @param  {Function} callback a function to be called once the text box is blurred, it is called in the instance's scope and receives the node and a status parameter - true if the rename is successful, false otherwise. You can access the node's title using .text
		 */
		edit : function (obj, default_text, callback) {
			var rtl, w, a, s, t, h1, h2, fn, tmp;
			obj = this.get_node(obj);
			if(!obj) { return false; }
			if(this.settings.core.check_callback === false) {
				this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_07', 'reason' : 'Could not edit node because of check_callback' };
				this.settings.core.error.call(this, this._data.core.last_error);
				return false;
			}
			tmp = obj;
			default_text = typeof default_text === 'string' ? default_text : obj.text;
			this.set_text(obj, "");
			obj = this._open_to(obj);
			tmp.text = default_text;

			rtl = this._data.core.rtl;
			w  = this.element.width();
			a  = obj.children('.jstree-anchor');
			s  = $('<span>');
			/*!
			oi = obj.children("i:visible"),
			ai = a.children("i:visible"),
			w1 = oi.width() * oi.length,
			w2 = ai.width() * ai.length,
			*/
			t  = default_text;
			h1 = $("<"+"div />", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo("body");
			h2 = $("<"+"input />", {
						"value" : t,
						"class" : "jstree-rename-input",
						// "size" : t.length,
						"css" : {
							"padding" : "0",
							"border" : "1px solid silver",
							"box-sizing" : "border-box",
							"display" : "inline-block",
							"height" : (this._data.core.li_height) + "px",
							"lineHeight" : (this._data.core.li_height) + "px",
							"width" : "150px" // will be set a bit further down
						},
						"blur" : $.proxy(function () {
							var i = s.children(".jstree-rename-input"),
								v = i.val(),
								f = this.settings.core.force_text,
								nv;
							if(v === "") { v = t; }
							h1.remove();
							s.replaceWith(a);
							s.remove();
							t = f ? t : $('<div></div>').append($.parseHTML(t)).html();
							this.set_text(obj, t);
							nv = !!this.rename_node(obj, f ? $('<div></div>').text(v).text() : $('<div></div>').append($.parseHTML(v)).html());
							if(!nv) {
								this.set_text(obj, t); // move this up? and fix #483
							}
							if(callback) {
								callback.call(this, tmp, nv);
							}
						}, this),
						"keydown" : function (event) {
							var key = event.which;
							if(key === 27) {
								this.value = t;
							}
							if(key === 27 || key === 13 || key === 37 || key === 38 || key === 39 || key === 40 || key === 32) {
								event.stopImmediatePropagation();
							}
							if(key === 27 || key === 13) {
								event.preventDefault();
								this.blur();
							}
						},
						"click" : function (e) { e.stopImmediatePropagation(); },
						"mousedown" : function (e) { e.stopImmediatePropagation(); },
						"keyup" : function (event) {
							h2.width(Math.min(h1.text("pW" + this.value).width(),w));
						},
						"keypress" : function(event) {
							if(event.which === 13) { return false; }
						}
					});
				fn = {
						fontFamily		: a.css('fontFamily')		|| '',
						fontSize		: a.css('fontSize')			|| '',
						fontWeight		: a.css('fontWeight')		|| '',
						fontStyle		: a.css('fontStyle')		|| '',
						fontStretch		: a.css('fontStretch')		|| '',
						fontVariant		: a.css('fontVariant')		|| '',
						letterSpacing	: a.css('letterSpacing')	|| '',
						wordSpacing		: a.css('wordSpacing')		|| ''
				};
			s.attr('class', a.attr('class')).append(a.contents().clone()).append(h2);
			a.replaceWith(s);
			h1.css(fn);
			h2.css(fn).width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select();
		},


		/**
		 * changes the theme
		 * @name set_theme(theme_name [, theme_url])
		 * @param {String} theme_name the name of the new theme to apply
		 * @param {mixed} theme_url  the location of the CSS file for this theme. Omit or set to `false` if you manually included the file. Set to `true` to autoload from the `core.themes.dir` directory.
		 * @trigger set_theme.jstree
		 */
		set_theme : function (theme_name, theme_url) {
			if(!theme_name) { return false; }
			if(theme_url === true) {
				var dir = this.settings.core.themes.dir;
				if(!dir) { dir = $.jstree.path + '/themes'; }
				theme_url = dir + '/' + theme_name + '/style.css';
			}
			if(theme_url && $.inArray(theme_url, themes_loaded) === -1) {
				$('head').append('<'+'link rel="stylesheet" href="' + theme_url + '" type="text/css" />');
				themes_loaded.push(theme_url);
			}
			if(this._data.core.themes.name) {
				this.element.removeClass('jstree-' + this._data.core.themes.name);
			}
			this._data.core.themes.name = theme_name;
			this.element.addClass('jstree-' + theme_name);
			this.element[this.settings.core.themes.responsive ? 'addClass' : 'removeClass' ]('jstree-' + theme_name + '-responsive');
			/**
			 * triggered when a theme is set
			 * @event
			 * @name set_theme.jstree
			 * @param {String} theme the new theme
			 */
			this.trigger('set_theme', { 'theme' : theme_name });
		},
		/**
		 * gets the name of the currently applied theme name
		 * @name get_theme()
		 * @return {String}
		 */
		get_theme : function () { return this._data.core.themes.name; },
		/**
		 * changes the theme variant (if the theme has variants)
		 * @name set_theme_variant(variant_name)
		 * @param {String|Boolean} variant_name the variant to apply (if `false` is used the current variant is removed)
		 */
		set_theme_variant : function (variant_name) {
			if(this._data.core.themes.variant) {
				this.element.removeClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant);
			}
			this._data.core.themes.variant = variant_name;
			if(variant_name) {
				this.element.addClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant);
			}
		},
		/**
		 * gets the name of the currently applied theme variant
		 * @name get_theme()
		 * @return {String}
		 */
		get_theme_variant : function () { return this._data.core.themes.variant; },
		/**
		 * shows a striped background on the container (if the theme supports it)
		 * @name show_stripes()
		 */
		show_stripes : function () { this._data.core.themes.stripes = true; this.get_container_ul().addClass("jstree-striped"); },
		/**
		 * hides the striped background on the container
		 * @name hide_stripes()
		 */
		hide_stripes : function () { this._data.core.themes.stripes = false; this.get_container_ul().removeClass("jstree-striped"); },
		/**
		 * toggles the striped background on the container
		 * @name toggle_stripes()
		 */
		toggle_stripes : function () { if(this._data.core.themes.stripes) { this.hide_stripes(); } else { this.show_stripes(); } },
		/**
		 * shows the connecting dots (if the theme supports it)
		 * @name show_dots()
		 */
		show_dots : function () { this._data.core.themes.dots = true; this.get_container_ul().removeClass("jstree-no-dots"); },
		/**
		 * hides the connecting dots
		 * @name hide_dots()
		 */
		hide_dots : function () { this._data.core.themes.dots = false; this.get_container_ul().addClass("jstree-no-dots"); },
		/**
		 * toggles the connecting dots
		 * @name toggle_dots()
		 */
		toggle_dots : function () { if(this._data.core.themes.dots) { this.hide_dots(); } else { this.show_dots(); } },
		/**
		 * show the node icons
		 * @name show_icons()
		 */
		show_icons : function () { this._data.core.themes.icons = true; this.get_container_ul().removeClass("jstree-no-icons"); },
		/**
		 * hide the node icons
		 * @name hide_icons()
		 */
		hide_icons : function () { this._data.core.themes.icons = false; this.get_container_ul().addClass("jstree-no-icons"); },
		/**
		 * toggle the node icons
		 * @name toggle_icons()
		 */
		toggle_icons : function () { if(this._data.core.themes.icons) { this.hide_icons(); } else { this.show_icons(); } },
		/**
		 * set the node icon for a node
		 * @name set_icon(obj, icon)
		 * @param {mixed} obj
		 * @param {String} icon the new icon - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class
		 */
		set_icon : function (obj, icon) {
			var t1, t2, dom, old;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.set_icon(obj[t1], icon);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') { return false; }
			old = obj.icon;
			obj.icon = icon === true || icon === null || icon === undefined || icon === '' ? true : icon;
			dom = this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon");
			if(icon === false) {
				this.hide_icon(obj);
			}
			else if(icon === true || icon === null || icon === undefined || icon === '') {
				dom.removeClass('jstree-themeicon-custom ' + old).css("background","").removeAttr("rel");
				if(old === false) { this.show_icon(obj); }
			}
			else if(icon.indexOf("/") === -1 && icon.indexOf(".") === -1) {
				dom.removeClass(old).css("background","");
				dom.addClass(icon + ' jstree-themeicon-custom').attr("rel",icon);
				if(old === false) { this.show_icon(obj); }
			}
			else {
				dom.removeClass(old).css("background","");
				dom.addClass('jstree-themeicon-custom').css("background", "url('" + icon + "') center center no-repeat").attr("rel",icon);
				if(old === false) { this.show_icon(obj); }
			}
			return true;
		},
		/**
		 * get the node icon for a node
		 * @name get_icon(obj)
		 * @param {mixed} obj
		 * @return {String}
		 */
		get_icon : function (obj) {
			obj = this.get_node(obj);
			return (!obj || obj.id === '#') ? false : obj.icon;
		},
		/**
		 * hide the icon on an individual node
		 * @name hide_icon(obj)
		 * @param {mixed} obj
		 */
		hide_icon : function (obj) {
			var t1, t2;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.hide_icon(obj[t1]);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj === '#') { return false; }
			obj.icon = false;
			this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon").addClass('jstree-themeicon-hidden');
			return true;
		},
		/**
		 * show the icon on an individual node
		 * @name show_icon(obj)
		 * @param {mixed} obj
		 */
		show_icon : function (obj) {
			var t1, t2, dom;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.show_icon(obj[t1]);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj === '#') { return false; }
			dom = this.get_node(obj, true);
			obj.icon = dom.length ? dom.children(".jstree-anchor").children(".jstree-themeicon").attr('rel') : true;
			if(!obj.icon) { obj.icon = true; }
			dom.children(".jstree-anchor").children(".jstree-themeicon").removeClass('jstree-themeicon-hidden');
			return true;
		}
	};

	// helpers
	$.vakata = {};
	// collect attributes
	$.vakata.attributes = function(node, with_values) {
		node = $(node)[0];
		var attr = with_values ? {} : [];
		if(node && node.attributes) {
			$.each(node.attributes, function (i, v) {
				if($.inArray(v.name.toLowerCase(),['style','contenteditable','hasfocus','tabindex']) !== -1) { return; }
				if(v.value !== null && $.trim(v.value) !== '') {
					if(with_values) { attr[v.name] = v.value; }
					else { attr.push(v.name); }
				}
			});
		}
		return attr;
	};
	$.vakata.array_unique = function(array) {
		var a = [], i, j, l, o = {};
		for(i = 0, l = array.length; i < l; i++) {
			if(o[array[i]] === undefined) {
				a.push(array[i]);
				o[array[i]] = true;
			}
		}
		return a;
	};
	// remove item from array
	$.vakata.array_remove = function(array, from, to) {
		var rest = array.slice((to || from) + 1 || array.length);
		array.length = from < 0 ? array.length + from : from;
		array.push.apply(array, rest);
		return array;
	};
	// remove item from array
	$.vakata.array_remove_item = function(array, item) {
		var tmp = $.inArray(item, array);
		return tmp !== -1 ? $.vakata.array_remove(array, tmp) : array;
	};


/**
 * ### Checkbox plugin
 *
 * This plugin renders checkbox icons in front of each node, making multiple selection much easier.
 * It also supports tri-state behavior, meaning that if a node has a few of its children checked it will be rendered as undetermined, and state will be propagated up.
 */

	var _i = document.createElement('I');
	_i.className = 'jstree-icon jstree-checkbox';
	_i.setAttribute('role', 'presentation');
	/**
	 * stores all defaults for the checkbox plugin
	 * @name $.jstree.defaults.checkbox
	 * @plugin checkbox
	 */
	$.jstree.defaults.checkbox = {
		/**
		 * a boolean indicating if checkboxes should be visible (can be changed at a later time using `show_checkboxes()` and `hide_checkboxes`). Defaults to `true`.
		 * @name $.jstree.defaults.checkbox.visible
		 * @plugin checkbox
		 */
		visible				: true,
		/**
		 * a boolean indicating if checkboxes should cascade down and have an undetermined state. Defaults to `true`.
		 * @name $.jstree.defaults.checkbox.three_state
		 * @plugin checkbox
		 */
		three_state			: true,
		/**
		 * a boolean indicating if clicking anywhere on the node should act as clicking on the checkbox. Defaults to `true`.
		 * @name $.jstree.defaults.checkbox.whole_node
		 * @plugin checkbox
		 */
		whole_node			: true,
		/**
		 * a boolean indicating if the selected style of a node should be kept, or removed. Defaults to `true`.
		 * @name $.jstree.defaults.checkbox.keep_selected_style
		 * @plugin checkbox
		 */
		keep_selected_style	: true,
		/**
		 * This setting controls how cascading and undetermined nodes are applied.
		 * If 'up' is in the string - cascading up is enabled, if 'down' is in the string - cascading down is enabled, if 'undetermined' is in the string - undetermined nodes will be used.
		 * If `three_state` is set to `true` this setting is automatically set to 'up+down+undetermined'. Defaults to ''.
		 * @name $.jstree.defaults.checkbox.cascade
		 * @plugin checkbox
		 */
		cascade				: '',
		/**
		 * This setting controls if checkbox are bound to the general tree selection or to an internal array maintained by the checkbox plugin. Defaults to `true`, only set to `false` if you know exactly what you are doing.
		 * @name $.jstree.defaults.checkbox.tie_selection
		 * @plugin checkbox
		 */
		tie_selection		: true
	};
	$.jstree.plugins.checkbox = function (options, parent) {
		this.bind = function () {
			parent.bind.call(this);
			this._data.checkbox.uto = false;
			this._data.checkbox.selected = [];
			if(this.settings.checkbox.three_state) {
				this.settings.checkbox.cascade = 'up+down+undetermined';
			}
			this.element
				.on("init.jstree", $.proxy(function () {
						this._data.checkbox.visible = this.settings.checkbox.visible;
						if(!this.settings.checkbox.keep_selected_style) {
							this.element.addClass('jstree-checkbox-no-clicked');
						}
						if(this.settings.checkbox.tie_selection) {
							this.element.addClass('jstree-checkbox-selection');
						}
					}, this))
				.on("loading.jstree", $.proxy(function () {
						this[ this._data.checkbox.visible ? 'show_checkboxes' : 'hide_checkboxes' ]();
					}, this));
			if(this.settings.checkbox.cascade.indexOf('undetermined') !== -1) {
				this.element
					.on('changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree', $.proxy(function () {
							// only if undetermined is in setting
							if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); }
							this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50);
						}, this));
			}
			if(!this.settings.checkbox.tie_selection) {
				this.element
					.on('model.jstree', $.proxy(function (e, data) {
						var m = this._model.data,
							p = m[data.parent],
							dpc = data.nodes,
							i, j;
						for(i = 0, j = dpc.length; i < j; i++) {
							m[dpc[i]].state.checked = (m[dpc[i]].original && m[dpc[i]].original.state && m[dpc[i]].original.state.checked);
							if(m[dpc[i]].state.checked) {
								this._data.checkbox.selected.push(dpc[i]);
							}
						}
					}, this));
			}
			if(this.settings.checkbox.cascade.indexOf('up') !== -1 || this.settings.checkbox.cascade.indexOf('down') !== -1) {
				this.element
					.on('model.jstree', $.proxy(function (e, data) {
							var m = this._model.data,
								p = m[data.parent],
								dpc = data.nodes,
								chd = [],
								c, i, j, k, l, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection;

							if(s.indexOf('down') !== -1) {
								// apply down
								if(p.state[ t ? 'selected' : 'checked' ]) {
									for(i = 0, j = dpc.length; i < j; i++) {
										m[dpc[i]].state[ t ? 'selected' : 'checked' ] = true;
									}
									this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(dpc);
								}
								else {
									for(i = 0, j = dpc.length; i < j; i++) {
										if(m[dpc[i]].state[ t ? 'selected' : 'checked' ]) {
											for(k = 0, l = m[dpc[i]].children_d.length; k < l; k++) {
												m[m[dpc[i]].children_d[k]].state[ t ? 'selected' : 'checked' ] = true;
											}
											this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(m[dpc[i]].children_d);
										}
									}
								}
							}

							if(s.indexOf('up') !== -1) {
								// apply up
								for(i = 0, j = p.children_d.length; i < j; i++) {
									if(!m[p.children_d[i]].children.length) {
										chd.push(m[p.children_d[i]].parent);
									}
								}
								chd = $.vakata.array_unique(chd);
								for(k = 0, l = chd.length; k < l; k++) {
									p = m[chd[k]];
									while(p && p.id !== '#') {
										c = 0;
										for(i = 0, j = p.children.length; i < j; i++) {
											c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
										}
										if(c === j) {
											p.state[ t ? 'selected' : 'checked' ] = true;
											this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
											tmp = this.get_node(p, true);
											if(tmp && tmp.length) {
												tmp.attr('aria-selected', true).children('.jstree-anchor').addClass( t ? 'jstree-clicked' : 'jstree-checked');
											}
										}
										else {
											break;
										}
										p = this.get_node(p.parent);
									}
								}
							}

							this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected);
						}, this))
					.on(this.settings.checkbox.tie_selection ? 'select_node.jstree' : 'check_node.jstree', $.proxy(function (e, data) {
							var obj = data.node,
								m = this._model.data,
								par = this.get_node(obj.parent),
								dom = this.get_node(obj, true),
								i, j, c, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection;

							// apply down
							if(s.indexOf('down') !== -1) {
								this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected.concat(obj.children_d));
								for(i = 0, j = obj.children_d.length; i < j; i++) {
									tmp = m[obj.children_d[i]];
									tmp.state[ t ? 'selected' : 'checked' ] = true;
									if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
										tmp.original.state.undetermined = false;
									}
								}
							}

							// apply up
							if(s.indexOf('up') !== -1) {
								while(par && par.id !== '#') {
									c = 0;
									for(i = 0, j = par.children.length; i < j; i++) {
										c += m[par.children[i]].state[ t ? 'selected' : 'checked' ];
									}
									if(c === j) {
										par.state[ t ? 'selected' : 'checked' ] = true;
										this._data[ t ? 'core' : 'checkbox' ].selected.push(par.id);
										tmp = this.get_node(par, true);
										if(tmp && tmp.length) {
											tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
										}
									}
									else {
										break;
									}
									par = this.get_node(par.parent);
								}
							}

							// apply down (process .children separately?)
							if(s.indexOf('down') !== -1 && dom.length) {
								dom.find('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked').parent().attr('aria-selected', true);
							}
						}, this))
					.on(this.settings.checkbox.tie_selection ? 'deselect_all.jstree' : 'uncheck_all.jstree', $.proxy(function (e, data) {
							var obj = this.get_node('#'),
								m = this._model.data,
								i, j, tmp;
							for(i = 0, j = obj.children_d.length; i < j; i++) {
								tmp = m[obj.children_d[i]];
								if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
									tmp.original.state.undetermined = false;
								}
							}
						}, this))
					.on(this.settings.checkbox.tie_selection ? 'deselect_node.jstree' : 'uncheck_node.jstree', $.proxy(function (e, data) {
							var obj = data.node,
								dom = this.get_node(obj, true),
								i, j, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection;
							if(obj && obj.original && obj.original.state && obj.original.state.undetermined) {
								obj.original.state.undetermined = false;
							}

							// apply down
							if(s.indexOf('down') !== -1) {
								for(i = 0, j = obj.children_d.length; i < j; i++) {
									tmp = this._model.data[obj.children_d[i]];
									tmp.state[ t ? 'selected' : 'checked' ] = false;
									if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
										tmp.original.state.undetermined = false;
									}
								}
							}

							// apply up
							if(s.indexOf('up') !== -1) {
								for(i = 0, j = obj.parents.length; i < j; i++) {
									tmp = this._model.data[obj.parents[i]];
									tmp.state[ t ? 'selected' : 'checked' ] = false;
									if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
										tmp.original.state.undetermined = false;
									}
									tmp = this.get_node(obj.parents[i], true);
									if(tmp && tmp.length) {
										tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked');
									}
								}
							}
							tmp = [];
							for(i = 0, j = this._data[ t ? 'core' : 'checkbox' ].selected.length; i < j; i++) {
								// apply down + apply up
								if(
									(s.indexOf('down') === -1 || $.inArray(this._data[ t ? 'core' : 'checkbox' ].selected[i], obj.children_d) === -1) &&
									(s.indexOf('up') === -1 || $.inArray(this._data[ t ? 'core' : 'checkbox' ].selected[i], obj.parents) === -1)
								) {
									tmp.push(this._data[ t ? 'core' : 'checkbox' ].selected[i]);
								}
							}
							this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(tmp);

							// apply down (process .children separately?)
							if(s.indexOf('down') !== -1 && dom.length) {
								dom.find('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked').parent().attr('aria-selected', false);
							}
						}, this));
			}
			if(this.settings.checkbox.cascade.indexOf('up') !== -1) {
				this.element
					.on('delete_node.jstree', $.proxy(function (e, data) {
							// apply up (whole handler)
							var p = this.get_node(data.parent),
								m = this._model.data,
								i, j, c, tmp, t = this.settings.checkbox.tie_selection;
							while(p && p.id !== '#') {
								c = 0;
								for(i = 0, j = p.children.length; i < j; i++) {
									c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
								}
								if(c === j) {
									p.state[ t ? 'selected' : 'checked' ] = true;
									this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
									tmp = this.get_node(p, true);
									if(tmp && tmp.length) {
										tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
									}
								}
								else {
									break;
								}
								p = this.get_node(p.parent);
							}
						}, this))
					.on('move_node.jstree', $.proxy(function (e, data) {
							// apply up (whole handler)
							var is_multi = data.is_multi,
								old_par = data.old_parent,
								new_par = this.get_node(data.parent),
								m = this._model.data,
								p, c, i, j, tmp, t = this.settings.checkbox.tie_selection;
							if(!is_multi) {
								p = this.get_node(old_par);
								while(p && p.id !== '#') {
									c = 0;
									for(i = 0, j = p.children.length; i < j; i++) {
										c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
									}
									if(c === j) {
										p.state[ t ? 'selected' : 'checked' ] = true;
										this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
										tmp = this.get_node(p, true);
										if(tmp && tmp.length) {
											tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
										}
									}
									else {
										break;
									}
									p = this.get_node(p.parent);
								}
							}
							p = new_par;
							while(p && p.id !== '#') {
								c = 0;
								for(i = 0, j = p.children.length; i < j; i++) {
									c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
								}
								if(c === j) {
									if(!p.state[ t ? 'selected' : 'checked' ]) {
										p.state[ t ? 'selected' : 'checked' ] = true;
										this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
										tmp = this.get_node(p, true);
										if(tmp && tmp.length) {
											tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
										}
									}
								}
								else {
									if(p.state[ t ? 'selected' : 'checked' ]) {
										p.state[ t ? 'selected' : 'checked' ] = false;
										this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_remove_item(this._data[ t ? 'core' : 'checkbox' ].selected, p.id);
										tmp = this.get_node(p, true);
										if(tmp && tmp.length) {
											tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked');
										}
									}
									else {
										break;
									}
								}
								p = this.get_node(p.parent);
							}
						}, this));
			}
		};
		/**
		 * set the undetermined state where and if necessary. Used internally.
		 * @private
		 * @name _undetermined()
		 * @plugin checkbox
		 */
		this._undetermined = function () {
			if(this.element === null) { return; }
			var i, j, k, l, o = {}, m = this._model.data, t = this.settings.checkbox.tie_selection, s = this._data[ t ? 'core' : 'checkbox' ].selected, p = [], tt = this;
			for(i = 0, j = s.length; i < j; i++) {
				if(m[s[i]] && m[s[i]].parents) {
					for(k = 0, l = m[s[i]].parents.length; k < l; k++) {
						if(o[m[s[i]].parents[k]] === undefined && m[s[i]].parents[k] !== '#') {
							o[m[s[i]].parents[k]] = true;
							p.push(m[s[i]].parents[k]);
						}
					}
				}
			}
			// attempt for server side undetermined state
			this.element.find('.jstree-closed').not(':has(.jstree-children)')
				.each(function () {
					var tmp = tt.get_node(this), tmp2;
					if(!tmp.state.loaded) {
						if(tmp.original && tmp.original.state && tmp.original.state.undetermined && tmp.original.state.undetermined === true) {
							if(o[tmp.id] === undefined && tmp.id !== '#') {
								o[tmp.id] = true;
								p.push(tmp.id);
							}
							for(k = 0, l = tmp.parents.length; k < l; k++) {
								if(o[tmp.parents[k]] === undefined && tmp.parents[k] !== '#') {
									o[tmp.parents[k]] = true;
									p.push(tmp.parents[k]);
								}
							}
						}
					}
					else {
						for(i = 0, j = tmp.children_d.length; i < j; i++) {
							tmp2 = m[tmp.children_d[i]];
							if(!tmp2.state.loaded && tmp2.original && tmp2.original.state && tmp2.original.state.undetermined && tmp2.original.state.undetermined === true) {
								if(o[tmp2.id] === undefined && tmp2.id !== '#') {
									o[tmp2.id] = true;
									p.push(tmp2.id);
								}
								for(k = 0, l = tmp2.parents.length; k < l; k++) {
									if(o[tmp2.parents[k]] === undefined && tmp2.parents[k] !== '#') {
										o[tmp2.parents[k]] = true;
										p.push(tmp2.parents[k]);
									}
								}
							}
						}
					}
				});

			this.element.find('.jstree-undetermined').removeClass('jstree-undetermined');
			for(i = 0, j = p.length; i < j; i++) {
				if(!m[p[i]].state[ t ? 'selected' : 'checked' ]) {
					s = this.get_node(p[i], true);
					if(s && s.length) {
						s.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-undetermined');
					}
				}
			}
		};
		this.redraw_node = function(obj, deep, is_callback, force_render) {
			obj = parent.redraw_node.apply(this, arguments);
			if(obj) {
				var i, j, tmp = null;
				for(i = 0, j = obj.childNodes.length; i < j; i++) {
					if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) {
						tmp = obj.childNodes[i];
						break;
					}
				}
				if(tmp) {
					if(!this.settings.checkbox.tie_selection && this._model.data[obj.id].state.checked) { tmp.className += ' jstree-checked'; }
					tmp.insertBefore(_i.cloneNode(false), tmp.childNodes[0]);
				}
			}
			if(!is_callback && this.settings.checkbox.cascade.indexOf('undetermined') !== -1) {
				if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); }
				this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50);
			}
			return obj;
		};
		/**
		 * show the node checkbox icons
		 * @name show_checkboxes()
		 * @plugin checkbox
		 */
		this.show_checkboxes = function () { this._data.core.themes.checkboxes = true; this.get_container_ul().removeClass("jstree-no-checkboxes"); };
		/**
		 * hide the node checkbox icons
		 * @name hide_checkboxes()
		 * @plugin checkbox
		 */
		this.hide_checkboxes = function () { this._data.core.themes.checkboxes = false; this.get_container_ul().addClass("jstree-no-checkboxes"); };
		/**
		 * toggle the node icons
		 * @name toggle_checkboxes()
		 * @plugin checkbox
		 */
		this.toggle_checkboxes = function () { if(this._data.core.themes.checkboxes) { this.hide_checkboxes(); } else { this.show_checkboxes(); } };
		/**
		 * checks if a node is in an undetermined state
		 * @name is_undetermined(obj)
		 * @param  {mixed} obj
		 * @return {Boolean}
		 */
		this.is_undetermined = function (obj) {
			obj = this.get_node(obj);
			var s = this.settings.checkbox.cascade, i, j, t = this.settings.checkbox.tie_selection, d = this._data[ t ? 'core' : 'checkbox' ].selected, m = this._model.data;
			if(!obj || obj.state[ t ? 'selected' : 'checked' ] === true || s.indexOf('undetermined') === -1 || (s.indexOf('down') === -1 && s.indexOf('up') === -1)) {
				return false;
			}
			if(!obj.state.loaded && obj.original.state.undetermined === true) {
				return true;
			}
			for(i = 0, j = obj.children_d.length; i < j; i++) {
				if($.inArray(obj.children_d[i], d) !== -1 || (!m[obj.children_d[i]].state.loaded && m[obj.children_d[i]].original.state.undetermined)) {
					return true;
				}
			}
			return false;
		};

		this.activate_node = function (obj, e) {
			if(this.settings.checkbox.tie_selection && (this.settings.checkbox.whole_node || $(e.target).hasClass('jstree-checkbox'))) {
				e.ctrlKey = true;
			}
			if(this.settings.checkbox.tie_selection || (!this.settings.checkbox.whole_node && !$(e.target).hasClass('jstree-checkbox'))) {
				return parent.activate_node.call(this, obj, e);
			}
			if(this.is_disabled(obj)) {
				return false;
			}
			if(this.is_checked(obj)) {
				this.uncheck_node(obj, e);
			}
			else {
				this.check_node(obj, e);
			}
			this.trigger('activate_node', { 'node' : this.get_node(obj) });
		};

		/**
		 * check a node (only if tie_selection in checkbox settings is false, otherwise select_node will be called internally)
		 * @name check_node(obj)
		 * @param {mixed} obj an array can be used to check multiple nodes
		 * @trigger check_node.jstree
		 * @plugin checkbox
		 */
		this.check_node = function (obj, e) {
			if(this.settings.checkbox.tie_selection) { return this.select_node(obj, false, true, e); }
			var dom, t1, t2, th;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.check_node(obj[t1], e);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') {
				return false;
			}
			dom = this.get_node(obj, true);
			if(!obj.state.checked) {
				obj.state.checked = true;
				this._data.checkbox.selected.push(obj.id);
				if(dom && dom.length) {
					dom.children('.jstree-anchor').addClass('jstree-checked');
				}
				/**
				 * triggered when an node is checked (only if tie_selection in checkbox settings is false)
				 * @event
				 * @name check_node.jstree
				 * @param {Object} node
				 * @param {Array} selected the current selection
				 * @param {Object} event the event (if any) that triggered this check_node
				 * @plugin checkbox
				 */
				this.trigger('check_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e });
			}
		};
		/**
		 * uncheck a node (only if tie_selection in checkbox settings is false, otherwise deselect_node will be called internally)
		 * @name uncheck_node(obj)
		 * @param {mixed} obj an array can be used to uncheck multiple nodes
		 * @trigger uncheck_node.jstree
		 * @plugin checkbox
		 */
		this.uncheck_node = function (obj, e) {
			if(this.settings.checkbox.tie_selection) { return this.deselect_node(obj, false, e); }
			var t1, t2, dom;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.uncheck_node(obj[t1], e);
				}
				return true;
			}
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') {
				return false;
			}
			dom = this.get_node(obj, true);
			if(obj.state.checked) {
				obj.state.checked = false;
				this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, obj.id);
				if(dom.length) {
					dom.children('.jstree-anchor').removeClass('jstree-checked');
				}
				/**
				 * triggered when an node is unchecked (only if tie_selection in checkbox settings is false)
				 * @event
				 * @name uncheck_node.jstree
				 * @param {Object} node
				 * @param {Array} selected the current selection
				 * @param {Object} event the event (if any) that triggered this uncheck_node
				 * @plugin checkbox
				 */
				this.trigger('uncheck_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e });
			}
		};
		/**
		 * checks all nodes in the tree (only if tie_selection in checkbox settings is false, otherwise select_all will be called internally)
		 * @name check_all()
		 * @trigger check_all.jstree, changed.jstree
		 * @plugin checkbox
		 */
		this.check_all = function () {
			if(this.settings.checkbox.tie_selection) { return this.select_all(); }
			var tmp = this._data.checkbox.selected.concat([]), i, j;
			this._data.checkbox.selected = this._model.data['#'].children_d.concat();
			for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) {
				if(this._model.data[this._data.checkbox.selected[i]]) {
					this._model.data[this._data.checkbox.selected[i]].state.checked = true;
				}
			}
			this.redraw(true);
			/**
			 * triggered when all nodes are checked (only if tie_selection in checkbox settings is false)
			 * @event
			 * @name check_all.jstree
			 * @param {Array} selected the current selection
			 * @plugin checkbox
			 */
			this.trigger('check_all', { 'selected' : this._data.checkbox.selected });
		};
		/**
		 * uncheck all checked nodes (only if tie_selection in checkbox settings is false, otherwise deselect_all will be called internally)
		 * @name uncheck_all()
		 * @trigger uncheck_all.jstree
		 * @plugin checkbox
		 */
		this.uncheck_all = function () {
			if(this.settings.checkbox.tie_selection) { return this.deselect_all(); }
			var tmp = this._data.checkbox.selected.concat([]), i, j;
			for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) {
				if(this._model.data[this._data.checkbox.selected[i]]) {
					this._model.data[this._data.checkbox.selected[i]].state.checked = false;
				}
			}
			this._data.checkbox.selected = [];
			this.element.find('.jstree-checked').removeClass('jstree-checked');
			/**
			 * triggered when all nodes are unchecked (only if tie_selection in checkbox settings is false)
			 * @event
			 * @name uncheck_all.jstree
			 * @param {Object} node the previous selection
			 * @param {Array} selected the current selection
			 * @plugin checkbox
			 */
			this.trigger('uncheck_all', { 'selected' : this._data.checkbox.selected, 'node' : tmp });
		};
		/**
		 * checks if a node is checked (if tie_selection is on in the settings this function will return the same as is_selected)
		 * @name is_checked(obj)
		 * @param  {mixed}  obj
		 * @return {Boolean}
		 * @plugin checkbox
		 */
		this.is_checked = function (obj) {
			if(this.settings.checkbox.tie_selection) { return this.is_selected(obj); }
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') { return false; }
			return obj.state.checked;
		};
		/**
		 * get an array of all checked nodes (if tie_selection is on in the settings this function will return the same as get_selected)
		 * @name get_checked([full])
		 * @param  {mixed}  full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
		 * @return {Array}
		 * @plugin checkbox
		 */
		this.get_checked = function (full) {
			if(this.settings.checkbox.tie_selection) { return this.get_selected(full); }
			return full ? $.map(this._data.checkbox.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.checkbox.selected;
		};
		/**
		 * get an array of all top level checked nodes (ignoring children of checked nodes) (if tie_selection is on in the settings this function will return the same as get_top_selected)
		 * @name get_top_checked([full])
		 * @param  {mixed}  full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
		 * @return {Array}
		 * @plugin checkbox
		 */
		this.get_top_checked = function (full) {
			if(this.settings.checkbox.tie_selection) { return this.get_top_selected(full); }
			var tmp = this.get_checked(true),
				obj = {}, i, j, k, l;
			for(i = 0, j = tmp.length; i < j; i++) {
				obj[tmp[i].id] = tmp[i];
			}
			for(i = 0, j = tmp.length; i < j; i++) {
				for(k = 0, l = tmp[i].children_d.length; k < l; k++) {
					if(obj[tmp[i].children_d[k]]) {
						delete obj[tmp[i].children_d[k]];
					}
				}
			}
			tmp = [];
			for(i in obj) {
				if(obj.hasOwnProperty(i)) {
					tmp.push(i);
				}
			}
			return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp;
		};
		/**
		 * get an array of all bottom level checked nodes (ignoring selected parents) (if tie_selection is on in the settings this function will return the same as get_bottom_selected)
		 * @name get_bottom_checked([full])
		 * @param  {mixed}  full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
		 * @return {Array}
		 * @plugin checkbox
		 */
		this.get_bottom_checked = function (full) {
			if(this.settings.checkbox.tie_selection) { return this.get_bottom_selected(full); }
			var tmp = this.get_checked(true),
				obj = [], i, j;
			for(i = 0, j = tmp.length; i < j; i++) {
				if(!tmp[i].children.length) {
					obj.push(tmp[i].id);
				}
			}
			return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj;
		};
		this.load_node = function (obj, callback) {
			var k, l, i, j, c, tmp;
			if(!$.isArray(obj) && !this.settings.checkbox.tie_selection) {
				tmp = this.get_node(obj);
				if(tmp && tmp.state.loaded) {
					for(k = 0, l = tmp.children_d.length; k < l; k++) {
						if(this._model.data[tmp.children_d[k]].state.checked) {
							c = true;
							this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, tmp.children_d[k]);
						}
					}
				}
			}
			return parent.load_node.apply(this, arguments);
		};
		this.get_state = function () {
			var state = parent.get_state.apply(this, arguments);
			if(this.settings.checkbox.tie_selection) { return state; }
			state.checkbox = this._data.checkbox.selected.slice();
			return state;
		};
		this.set_state = function (state, callback) {
			var res = parent.set_state.apply(this, arguments);
			if(res && state.checkbox) {
				if(!this.settings.checkbox.tie_selection) {
					this.uncheck_all();
					var _this = this;
					$.each(state.checkbox, function (i, v) {
						_this.check_node(v);
					});
				}
				delete state.checkbox;
				this.set_state(state, callback);
				return false;
			}
			return res;
		};
	};

	// include the checkbox plugin by default
	// $.jstree.defaults.plugins.push("checkbox");

/**
 * ### Contextmenu plugin
 *
 * Shows a context menu when a node is right-clicked.
 */

	/**
	 * stores all defaults for the contextmenu plugin
	 * @name $.jstree.defaults.contextmenu
	 * @plugin contextmenu
	 */
	$.jstree.defaults.contextmenu = {
		/**
		 * a boolean indicating if the node should be selected when the context menu is invoked on it. Defaults to `true`.
		 * @name $.jstree.defaults.contextmenu.select_node
		 * @plugin contextmenu
		 */
		select_node : true,
		/**
		 * a boolean indicating if the menu should be shown aligned with the node. Defaults to `true`, otherwise the mouse coordinates are used.
		 * @name $.jstree.defaults.contextmenu.show_at_node
		 * @plugin contextmenu
		 */
		show_at_node : true,
		/**
		 * an object of actions, or a function that accepts a node and a callback function and calls the callback function with an object of actions available for that node (you can also return the items too).
		 *
		 * Each action consists of a key (a unique name) and a value which is an object with the following properties (only label and action are required):
		 *
		 * * `separator_before` - a boolean indicating if there should be a separator before this item
		 * * `separator_after` - a boolean indicating if there should be a separator after this item
		 * * `_disabled` - a boolean indicating if this action should be disabled
		 * * `label` - a string - the name of the action (could be a function returning a string)
		 * * `action` - a function to be executed if this item is chosen
		 * * `icon` - a string, can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class
		 * * `shortcut` - keyCode which will trigger the action if the menu is open (for example `113` for rename, which equals F2)
		 * * `shortcut_label` - shortcut label (like for example `F2` for rename)
		 *
		 * @name $.jstree.defaults.contextmenu.items
		 * @plugin contextmenu
		 */
		items : function (o, cb) { // Could be an object directly
			return {
				"create" : {
					"separator_before"	: false,
					"separator_after"	: true,
					"_disabled"			: false, //(this.check("create_node", data.reference, {}, "last")),
					"label"				: "Create",
					"action"			: function (data) {
						var inst = $.jstree.reference(data.reference),
							obj = inst.get_node(data.reference);
						inst.create_node(obj, {}, "last", function (new_node) {
							setTimeout(function () { inst.edit(new_node); },0);
						});
					}
				},
				"rename" : {
					"separator_before"	: false,
					"separator_after"	: false,
					"_disabled"			: false, //(this.check("rename_node", data.reference, this.get_parent(data.reference), "")),
					"label"				: "Rename",
					/*
					"shortcut"			: 113,
					"shortcut_label"	: 'F2',
					"icon"				: "glyphicon glyphicon-leaf",
					*/
					"action"			: function (data) {
						var inst = $.jstree.reference(data.reference),
							obj = inst.get_node(data.reference);
						inst.edit(obj);
					}
				},
				"remove" : {
					"separator_before"	: false,
					"icon"				: false,
					"separator_after"	: false,
					"_disabled"			: false, //(this.check("delete_node", data.reference, this.get_parent(data.reference), "")),
					"label"				: "Delete",
					"action"			: function (data) {
						var inst = $.jstree.reference(data.reference),
							obj = inst.get_node(data.reference);
						if(inst.is_selected(obj)) {
							inst.delete_node(inst.get_selected());
						}
						else {
							inst.delete_node(obj);
						}
					}
				},
				"ccp" : {
					"separator_before"	: true,
					"icon"				: false,
					"separator_after"	: false,
					"label"				: "Edit",
					"action"			: false,
					"submenu" : {
						"cut" : {
							"separator_before"	: false,
							"separator_after"	: false,
							"label"				: "Cut",
							"action"			: function (data) {
								var inst = $.jstree.reference(data.reference),
									obj = inst.get_node(data.reference);
								if(inst.is_selected(obj)) {
									inst.cut(inst.get_top_selected());
								}
								else {
									inst.cut(obj);
								}
							}
						},
						"copy" : {
							"separator_before"	: false,
							"icon"				: false,
							"separator_after"	: false,
							"label"				: "Copy",
							"action"			: function (data) {
								var inst = $.jstree.reference(data.reference),
									obj = inst.get_node(data.reference);
								if(inst.is_selected(obj)) {
									inst.copy(inst.get_top_selected());
								}
								else {
									inst.copy(obj);
								}
							}
						},
						"paste" : {
							"separator_before"	: false,
							"icon"				: false,
							"_disabled"			: function (data) {
								return !$.jstree.reference(data.reference).can_paste();
							},
							"separator_after"	: false,
							"label"				: "Paste",
							"action"			: function (data) {
								var inst = $.jstree.reference(data.reference),
									obj = inst.get_node(data.reference);
								inst.paste(obj);
							}
						}
					}
				}
			};
		}
	};

	$.jstree.plugins.contextmenu = function (options, parent) {
		this.bind = function () {
			parent.bind.call(this);

			var last_ts = 0, cto = null, ex, ey;
			this.element
				.on("contextmenu.jstree", ".jstree-anchor", $.proxy(function (e, data) {
						e.preventDefault();
						last_ts = e.ctrlKey ? +new Date() : 0;
						if(data || cto) {
							last_ts = (+new Date()) + 10000;
						}
						if(cto) {
							clearTimeout(cto);
						}
						if(!this.is_loading(e.currentTarget)) {
							this.show_contextmenu(e.currentTarget, e.pageX, e.pageY, e);
						}
					}, this))
				.on("click.jstree", ".jstree-anchor", $.proxy(function (e) {
						if(this._data.contextmenu.visible && (!last_ts || (+new Date()) - last_ts > 250)) { // work around safari & macOS ctrl+click
							$.vakata.context.hide();
						}
						last_ts = 0;
					}, this))
				.on("touchstart.jstree", ".jstree-anchor", function (e) {
						if(!e.originalEvent || !e.originalEvent.changedTouches || !e.originalEvent.changedTouches[0]) {
							return;
						}
						ex = e.pageX;
						ey = e.pageY;
						cto = setTimeout(function () {
							$(e.currentTarget).trigger('contextmenu', true);
						}, 750);
					})
				.on('touchmove.vakata.jstree', function (e) {
						if(cto && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0] && (Math.abs(ex - e.pageX) > 50 || Math.abs(ey - e.pageY) > 50)) {
							clearTimeout(cto);
						}
					})
				.on('touchend.vakata.jstree', function (e) {
						if(cto) {
							clearTimeout(cto);
						}
					});

			/*
			if(!('oncontextmenu' in document.body) && ('ontouchstart' in document.body)) {
				var el = null, tm = null;
				this.element
					.on("touchstart", ".jstree-anchor", function (e) {
						el = e.currentTarget;
						tm = +new Date();
						$(document).one("touchend", function (e) {
							e.target = document.elementFromPoint(e.originalEvent.targetTouches[0].pageX - window.pageXOffset, e.originalEvent.targetTouches[0].pageY - window.pageYOffset);
							e.currentTarget = e.target;
							tm = ((+(new Date())) - tm);
							if(e.target === el && tm > 600 && tm < 1000) {
								e.preventDefault();
								$(el).trigger('contextmenu', e);
							}
							el = null;
							tm = null;
						});
					});
			}
			*/
			$(document).on("context_hide.vakata.jstree", $.proxy(function () { this._data.contextmenu.visible = false; }, this));
		};
		this.teardown = function () {
			if(this._data.contextmenu.visible) {
				$.vakata.context.hide();
			}
			parent.teardown.call(this);
		};

		/**
		 * prepare and show the context menu for a node
		 * @name show_contextmenu(obj [, x, y])
		 * @param {mixed} obj the node
		 * @param {Number} x the x-coordinate relative to the document to show the menu at
		 * @param {Number} y the y-coordinate relative to the document to show the menu at
		 * @param {Object} e the event if available that triggered the contextmenu
		 * @plugin contextmenu
		 * @trigger show_contextmenu.jstree
		 */
		this.show_contextmenu = function (obj, x, y, e) {
			obj = this.get_node(obj);
			if(!obj || obj.id === '#') { return false; }
			var s = this.settings.contextmenu,
				d = this.get_node(obj, true),
				a = d.children(".jstree-anchor"),
				o = false,
				i = false;
			if(s.show_at_node || x === undefined || y === undefined) {
				o = a.offset();
				x = o.left;
				y = o.top + this._data.core.li_height;
			}
			if(this.settings.contextmenu.select_node && !this.is_selected(obj)) {
				this.activate_node(obj, e);
			}

			i = s.items;
			if($.isFunction(i)) {
				i = i.call(this, obj, $.proxy(function (i) {
					this._show_contextmenu(obj, x, y, i);
				}, this));
			}
			if($.isPlainObject(i)) {
				this._show_contextmenu(obj, x, y, i);
			}
		};
		/**
		 * show the prepared context menu for a node
		 * @name _show_contextmenu(obj, x, y, i)
		 * @param {mixed} obj the node
		 * @param {Number} x the x-coordinate relative to the document to show the menu at
		 * @param {Number} y the y-coordinate relative to the document to show the menu at
		 * @param {Number} i the object of items to show
		 * @plugin contextmenu
		 * @trigger show_contextmenu.jstree
		 * @private
		 */
		this._show_contextmenu = function (obj, x, y, i) {
			var d = this.get_node(obj, true),
				a = d.children(".jstree-anchor");
			$(document).one("context_show.vakata.jstree", $.proxy(function (e, data) {
				var cls = 'jstree-contextmenu jstree-' + this.get_theme() + '-contextmenu';
				$(data.element).addClass(cls);
			}, this));
			this._data.contextmenu.visible = true;
			$.vakata.context.show(a, { 'x' : x, 'y' : y }, i);
			/**
			 * triggered when the contextmenu is shown for a node
			 * @event
			 * @name show_contextmenu.jstree
			 * @param {Object} node the node
			 * @param {Number} x the x-coordinate of the menu relative to the document
			 * @param {Number} y the y-coordinate of the menu relative to the document
			 * @plugin contextmenu
			 */
			this.trigger('show_contextmenu', { "node" : obj, "x" : x, "y" : y });
		};
	};

	// contextmenu helper
	(function ($) {
		var right_to_left = false,
			vakata_context = {
				element		: false,
				reference	: false,
				position_x	: 0,
				position_y	: 0,
				items		: [],
				html		: "",
				is_visible	: false
			};

		$.vakata.context = {
			settings : {
				hide_onmouseleave	: 0,
				icons				: true
			},
			_trigger : function (event_name) {
				$(document).triggerHandler("context_" + event_name + ".vakata", {
					"reference"	: vakata_context.reference,
					"element"	: vakata_context.element,
					"position"	: {
						"x" : vakata_context.position_x,
						"y" : vakata_context.position_y
					}
				});
			},
			_execute : function (i) {
				i = vakata_context.items[i];
				return i && (!i._disabled || ($.isFunction(i._disabled) && !i._disabled({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }))) && i.action ? i.action.call(null, {
							"item"		: i,
							"reference"	: vakata_context.reference,
							"element"	: vakata_context.element,
							"position"	: {
								"x" : vakata_context.position_x,
								"y" : vakata_context.position_y
							}
						}) : false;
			},
			_parse : function (o, is_callback) {
				if(!o) { return false; }
				if(!is_callback) {
					vakata_context.html		= "";
					vakata_context.items	= [];
				}
				var str = "",
					sep = false,
					tmp;

				if(is_callback) { str += "<"+"ul>"; }
				$.each(o, function (i, val) {
					if(!val) { return true; }
					vakata_context.items.push(val);
					if(!sep && val.separator_before) {
						str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + ">&#160;<"+"/a><"+"/li>";
					}
					sep = false;
					str += "<"+"li class='" + (val._class || "") + (val._disabled === true || ($.isFunction(val._disabled) && val._disabled({ "item" : val, "reference" : vakata_context.reference, "element" : vakata_context.element })) ? " vakata-contextmenu-disabled " : "") + "' "+(val.shortcut?" data-shortcut='"+val.shortcut+"' ":'')+">";
					str += "<"+"a href='#' rel='" + (vakata_context.items.length - 1) + "'>";
					if($.vakata.context.settings.icons) {
						str += "<"+"i ";
						if(val.icon) {
							if(val.icon.indexOf("/") !== -1 || val.icon.indexOf(".") !== -1) { str += " style='background:url(\"" + val.icon + "\") center center no-repeat' "; }
							else { str += " class='" + val.icon + "' "; }
						}
						str += "><"+"/i><"+"span class='vakata-contextmenu-sep'>&#160;<"+"/span>";
					}
					str += ($.isFunction(val.label) ? val.label({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }) : val.label) + (val.shortcut?' <span class="vakata-contextmenu-shortcut vakata-contextmenu-shortcut-'+val.shortcut+'">'+ (val.shortcut_label || '') +'</span>':'') + "<"+"/a>";
					if(val.submenu) {
						tmp = $.vakata.context._parse(val.submenu, true);
						if(tmp) { str += tmp; }
					}
					str += "<"+"/li>";
					if(val.separator_after) {
						str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + ">&#160;<"+"/a><"+"/li>";
						sep = true;
					}
				});
				str  = str.replace(/<li class\='vakata-context-separator'\><\/li\>$/,"");
				if(is_callback) { str += "</ul>"; }
				/**
				 * triggered on the document when the contextmenu is parsed (HTML is built)
				 * @event
				 * @plugin contextmenu
				 * @name context_parse.vakata
				 * @param {jQuery} reference the element that was right clicked
				 * @param {jQuery} element the DOM element of the menu itself
				 * @param {Object} position the x & y coordinates of the menu
				 */
				if(!is_callback) { vakata_context.html = str; $.vakata.context._trigger("parse"); }
				return str.length > 10 ? str : false;
			},
			_show_submenu : function (o) {
				o = $(o);
				if(!o.length || !o.children("ul").length) { return; }
				var e = o.children("ul"),
					x = o.offset().left + o.outerWidth(),
					y = o.offset().top,
					w = e.width(),
					h = e.height(),
					dw = $(window).width() + $(window).scrollLeft(),
					dh = $(window).height() + $(window).scrollTop();
				// може да се спести е една проверка - дали няма някой от класовете вече нагоре
				if(right_to_left) {
					o[x - (w + 10 + o.outerWidth()) < 0 ? "addClass" : "removeClass"]("vakata-context-left");
				}
				else {
					o[x + w + 10 > dw ? "addClass" : "removeClass"]("vakata-context-right");
				}
				if(y + h + 10 > dh) {
					e.css("bottom","-1px");
				}
				e.show();
			},
			show : function (reference, position, data) {
				var o, e, x, y, w, h, dw, dh, cond = true;
				if(vakata_context.element && vakata_context.element.length) {
					vakata_context.element.width('');
				}
				switch(cond) {
					case (!position && !reference):
						return false;
					case (!!position && !!reference):
						vakata_context.reference	= reference;
						vakata_context.position_x	= position.x;
						vakata_context.position_y	= position.y;
						break;
					case (!position && !!reference):
						vakata_context.reference	= reference;
						o = reference.offset();
						vakata_context.position_x	= o.left + reference.outerHeight();
						vakata_context.position_y	= o.top;
						break;
					case (!!position && !reference):
						vakata_context.position_x	= position.x;
						vakata_context.position_y	= position.y;
						break;
				}
				if(!!reference && !data && $(reference).data('vakata_contextmenu')) {
					data = $(reference).data('vakata_contextmenu');
				}
				if($.vakata.context._parse(data)) {
					vakata_context.element.html(vakata_context.html);
				}
				if(vakata_context.items.length) {
					vakata_context.element.appendTo("body");
					e = vakata_context.element;
					x = vakata_context.position_x;
					y = vakata_context.position_y;
					w = e.width();
					h = e.height();
					dw = $(window).width() + $(window).scrollLeft();
					dh = $(window).height() + $(window).scrollTop();
					if(right_to_left) {
						x -= (e.outerWidth() - $(reference).outerWidth());
						if(x < $(window).scrollLeft() + 20) {
							x = $(window).scrollLeft() + 20;
						}
					}
					if(x + w + 20 > dw) {
						x = dw - (w + 20);
					}
					if(y + h + 20 > dh) {
						y = dh - (h + 20);
					}

					vakata_context.element
						.css({ "left" : x, "top" : y })
						.show()
						.find('a').first().focus().parent().addClass("vakata-context-hover");
					vakata_context.is_visible = true;
					/**
					 * triggered on the document when the contextmenu is shown
					 * @event
					 * @plugin contextmenu
					 * @name context_show.vakata
					 * @param {jQuery} reference the element that was right clicked
					 * @param {jQuery} element the DOM element of the menu itself
					 * @param {Object} position the x & y coordinates of the menu
					 */
					$.vakata.context._trigger("show");
				}
			},
			hide : function () {
				if(vakata_context.is_visible) {
					vakata_context.element.hide().find("ul").hide().end().find(':focus').blur().end().detach();
					vakata_context.is_visible = false;
					/**
					 * triggered on the document when the contextmenu is hidden
					 * @event
					 * @plugin contextmenu
					 * @name context_hide.vakata
					 * @param {jQuery} reference the element that was right clicked
					 * @param {jQuery} element the DOM element of the menu itself
					 * @param {Object} position the x & y coordinates of the menu
					 */
					$.vakata.context._trigger("hide");
				}
			}
		};
		$(function () {
			right_to_left = $("body").css("direction") === "rtl";
			var to = false;

			vakata_context.element = $("<ul class='vakata-context'></ul>");
			vakata_context.element
				.on("mouseenter", "li", function (e) {
					e.stopImmediatePropagation();

					if($.contains(this, e.relatedTarget)) {
						// премахнато заради delegate mouseleave по-долу
						// $(this).find(".vakata-context-hover").removeClass("vakata-context-hover");
						return;
					}

					if(to) { clearTimeout(to); }
					vakata_context.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end();

					$(this)
						.siblings().find("ul").hide().end().end()
						.parentsUntil(".vakata-context", "li").addBack().addClass("vakata-context-hover");
					$.vakata.context._show_submenu(this);
				})
				// тестово - дали не натоварва?
				.on("mouseleave", "li", function (e) {
					if($.contains(this, e.relatedTarget)) { return; }
					$(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover");
				})
				.on("mouseleave", function (e) {
					$(this).find(".vakata-context-hover").removeClass("vakata-context-hover");
					if($.vakata.context.settings.hide_onmouseleave) {
						to = setTimeout(
							(function (t) {
								return function () { $.vakata.context.hide(); };
							}(this)), $.vakata.context.settings.hide_onmouseleave);
					}
				})
				.on("click", "a", function (e) {
					e.preventDefault();
				//})
				//.on("mouseup", "a", function (e) {
					if(!$(this).blur().parent().hasClass("vakata-context-disabled") && $.vakata.context._execute($(this).attr("rel")) !== false) {
						$.vakata.context.hide();
					}
				})
				.on('keydown', 'a', function (e) {
						var o = null;
						switch(e.which) {
							case 13:
							case 32:
								e.type = "mouseup";
								e.preventDefault();
								$(e.currentTarget).trigger(e);
								break;
							case 37:
								if(vakata_context.is_visible) {
									vakata_context.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children('a').focus();
									e.stopImmediatePropagation();
									e.preventDefault();
								}
								break;
							case 38:
								if(vakata_context.is_visible) {
									o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first();
									if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last(); }
									o.addClass("vakata-context-hover").children('a').focus();
									e.stopImmediatePropagation();
									e.preventDefault();
								}
								break;
							case 39:
								if(vakata_context.is_visible) {
									vakata_context.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children('a').focus();
									e.stopImmediatePropagation();
									e.preventDefault();
								}
								break;
							case 40:
								if(vakata_context.is_visible) {
									o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first();
									if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first(); }
									o.addClass("vakata-context-hover").children('a').focus();
									e.stopImmediatePropagation();
									e.preventDefault();
								}
								break;
							case 27:
								$.vakata.context.hide();
								e.preventDefault();
								break;
							default:
								//console.log(e.which);
								break;
						}
					})
				.on('keydown', function (e) {
					e.preventDefault();
					var a = vakata_context.element.find('.vakata-contextmenu-shortcut-' + e.which).parent();
					if(a.parent().not('.vakata-context-disabled')) {
						a.click();
					}
				});

			$(document)
				.on("mousedown.vakata.jstree", function (e) {
					if(vakata_context.is_visible && !$.contains(vakata_context.element[0], e.target)) {
						$.vakata.context.hide();
					}
				})
				.on("context_show.vakata.jstree", function (e, data) {
					vakata_context.element.find("li:has(ul)").children("a").addClass("vakata-context-parent");
					if(right_to_left) {
						vakata_context.element.addClass("vakata-context-rtl").css("direction", "rtl");
					}
					// also apply a RTL class?
					vakata_context.element.find("ul").hide().end();
				});
		});
	}($));
	// $.jstree.defaults.plugins.push("contextmenu");

/**
 * ### Drag'n'drop plugin
 *
 * Enables dragging and dropping of nodes in the tree, resulting in a move or copy operations.
 */

	/**
	 * stores all defaults for the drag'n'drop plugin
	 * @name $.jstree.defaults.dnd
	 * @plugin dnd
	 */
	$.jstree.defaults.dnd = {
		/**
		 * a boolean indicating if a copy should be possible while dragging (by pressint the meta key or Ctrl). Defaults to `true`.
		 * @name $.jstree.defaults.dnd.copy
		 * @plugin dnd
		 */
		copy : true,
		/**
		 * a number indicating how long a node should remain hovered while dragging to be opened. Defaults to `500`.
		 * @name $.jstree.defaults.dnd.open_timeout
		 * @plugin dnd
		 */
		open_timeout : 500,
		/**
		 * a function invoked each time a node is about to be dragged, invoked in the tree's scope and receives the nodes about to be dragged as an argument (array) - return `false` to prevent dragging
		 * @name $.jstree.defaults.dnd.is_draggable
		 * @plugin dnd
		 */
		is_draggable : true,
		/**
		 * a boolean indicating if checks should constantly be made while the user is dragging the node (as opposed to checking only on drop), default is `true`
		 * @name $.jstree.defaults.dnd.check_while_dragging
		 * @plugin dnd
		 */
		check_while_dragging : true,
		/**
		 * a boolean indicating if nodes from this tree should only be copied with dnd (as opposed to moved), default is `false`
		 * @name $.jstree.defaults.dnd.always_copy
		 * @plugin dnd
		 */
		always_copy : false,
		/**
		 * when dropping a node "inside", this setting indicates the position the node should go to - it can be an integer or a string: "first" (same as 0) or "last", default is `0`
		 * @name $.jstree.defaults.dnd.inside_pos
		 * @plugin dnd
		 */
		inside_pos : 0,
		/**
		 * when starting the drag on a node that is selected this setting controls if all selected nodes are dragged or only the single node, default is `true`, which means all selected nodes are dragged when the drag is started on a selected node
		 * @name $.jstree.defaults.dnd.drag_selection
		 * @plugin dnd
		 */
		drag_selection : true,
		/**
		 * controls whether dnd works on touch devices. If left as boolean true dnd will work the same as in desktop browsers, which in some cases may impair scrolling. If set to boolean false dnd will not work on touch devices. There is a special third option - string "selected" which means only selected nodes can be dragged on touch devices.
		 * @name $.jstree.defaults.dnd.touch
		 * @plugin dnd
		 */
		touch : true,
		/**
		 * controls whether items can be dropped anywhere on the node, not just on the anchor, by default only the node anchor is a valid drop target. Works best with the wholerow plugin. If enabled on mobile depending on the interface it might be hard for the user to cancel the drop, since the whole tree container will be a valid drop target.
		 * @name $.jstree.defaults.dnd.large_drop_target
		 * @plugin dnd
		 */
		large_drop_target : false,
		/**
		 * controls whether a drag can be initiated from any part of the node and not just the text/icon part, works best with the wholerow plugin. Keep in mind it can cause problems with tree scrolling on mobile depending on the interface - in that case set the touch option to "selected".
		 * @name $.jstree.defaults.dnd.large_drag_target
		 * @plugin dnd
		 */
		large_drag_target : false
	};
	// TODO: now check works by checking for each node individually, how about max_children, unique, etc?
	$.jstree.plugins.dnd = function (options, parent) {
		this.bind = function () {
			parent.bind.call(this);

			this.element
				.on('mousedown.jstree touchstart.jstree', this.settings.dnd.large_drag_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) {
					if(this.settings.dnd.large_drag_target && $(e.target).closest('.jstree-node')[0] !== e.currentTarget) {
						return true;
					}
					if(e.type === "touchstart" && (!this.settings.dnd.touch || (this.settings.dnd.touch === 'selected' && !$(e.currentTarget).closest('.jstree-node').children('.jstree-anchor').hasClass('jstree-clicked')))) {
						return true;
					}
					var obj = this.get_node(e.target),
						mlt = this.is_selected(obj) && this.settings.dnd.drag_selection ? this.get_top_selected().length : 1,
						txt = (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget));
					if(this.settings.core.force_text) {
						txt = $.vakata.html.escape(txt);
					}
					if(obj && obj.id && obj.id !== "#" && (e.which === 1 || e.type === "touchstart") &&
						(this.settings.dnd.is_draggable === true || ($.isFunction(this.settings.dnd.is_draggable) && this.settings.dnd.is_draggable.call(this, (mlt > 1 ? this.get_top_selected(true) : [obj]))))
					) {
						this.element.trigger('mousedown.jstree');
						return $.vakata.dnd.start(e, { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_top_selected() : [obj.id] }, '<div id="jstree-dnd" class="jstree-' + this.get_theme() + ' jstree-' + this.get_theme() + '-' + this.get_theme_variant() + ' ' + ( this.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ) + '"><i class="jstree-icon jstree-er"></i>' + txt + '<ins class="jstree-copy" style="display:none;">+</ins></div>');
					}
				}, this));
		};
	};

	$(function() {
		// bind only once for all instances
		var lastmv = false,
			laster = false,
			opento = false,
			marker = $('<div id="jstree-marker">&#160;</div>').hide(); //.appendTo('body');

		$(document)
			.on('dnd_start.vakata.jstree', function (e, data) {
				lastmv = false;
				if(!data || !data.data || !data.data.jstree) { return; }
				marker.appendTo('body'); //.show();
			})
			.on('dnd_move.vakata.jstree', function (e, data) {
				if(opento) { clearTimeout(opento); }
				if(!data || !data.data || !data.data.jstree) { return; }

				// if we are hovering the marker image do nothing (can happen on "inside" drags)
				if(data.event.target.id && data.event.target.id === 'jstree-marker') {
					return;
				}

				var ins = $.jstree.reference(data.event.target),
					ref = false,
					off = false,
					rel = false,
					tmp, l, t, h, p, i, o, ok, t1, t2, op, ps, pr, ip, tm;
				// if we are over an instance
				if(ins && ins._data && ins._data.dnd) {
					marker.attr('class', 'jstree-' + ins.get_theme() + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ));
					data.helper
						.children().attr('class', 'jstree-' + ins.get_theme() + ' jstree-' + ins.get_theme() + '-' + ins.get_theme_variant() + ' ' + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ))
						.find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'show' : 'hide' ]();


					// if are hovering the container itself add a new root node
					if( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && ins.get_container_ul().children().length === 0) {
						ok = true;
						for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) {
							ok = ok && ins.check( (data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey)) ) ? "copy_node" : "move_node"), (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), '#', 'last', { 'dnd' : true, 'ref' : ins.get_node('#'), 'pos' : 'i', 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) });
							if(!ok) { break; }
						}
						if(ok) {
							lastmv = { 'ins' : ins, 'par' : '#', 'pos' : 'last' };
							marker.hide();
							data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok');
							return;
						}
					}
					else {
						// if we are hovering a tree node
						ref = ins.settings.dnd.large_drop_target ? $(data.event.target).closest('.jstree-node').children('.jstree-anchor') : $(data.event.target).closest('.jstree-anchor');
						if(ref && ref.length && ref.parent().is('.jstree-closed, .jstree-open, .jstree-leaf')) {
							off = ref.offset();
							rel = data.event.pageY - off.top;
							h = ref.outerHeight();
							if(rel < h / 3) {
								o = ['b', 'i', 'a'];
							}
							else if(rel > h - h / 3) {
								o = ['a', 'i', 'b'];
							}
							else {
								o = rel > h / 2 ? ['i', 'a', 'b'] : ['i', 'b', 'a'];
							}
							$.each(o, function (j, v) {
								switch(v) {
									case 'b':
										l = off.left - 6;
										t = off.top;
										p = ins.get_parent(ref);
										i = ref.parent().index();
										break;
									case 'i':
										ip = ins.settings.dnd.inside_pos;
										tm = ins.get_node(ref.parent());
										l = off.left - 2;
										t = off.top + h / 2 + 1;
										p = tm.id;
										i = ip === 'first' ? 0 : (ip === 'last' ? tm.children.length : Math.min(ip, tm.children.length));
										break;
									case 'a':
										l = off.left - 6;
										t = off.top + h;
										p = ins.get_parent(ref);
										i = ref.parent().index() + 1;
										break;
								}
								ok = true;
								for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) {
									op = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? "copy_node" : "move_node";
									ps = i;
									if(op === "move_node" && v === 'a' && (data.data.origin && data.data.origin === ins) && p === ins.get_parent(data.data.nodes[t1])) {
										pr = ins.get_node(p);
										if(ps > $.inArray(data.data.nodes[t1], pr.children)) {
											ps -= 1;
										}
									}
									ok = ok && ( (ins && ins.settings && ins.settings.dnd && ins.settings.dnd.check_while_dragging === false) || ins.check(op, (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), p, ps, { 'dnd' : true, 'ref' : ins.get_node(ref.parent()), 'pos' : v, 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }) );
									if(!ok) {
										if(ins && ins.last_error) { laster = ins.last_error(); }
										break;
									}
								}
								if(v === 'i' && ref.parent().is('.jstree-closed') && ins.settings.dnd.open_timeout) {
									opento = setTimeout((function (x, z) { return function () { x.open_node(z); }; }(ins, ref)), ins.settings.dnd.open_timeout);
								}
								if(ok) {
									lastmv = { 'ins' : ins, 'par' : p, 'pos' : v === 'i' && ip === 'last' && i === 0 && !ins.is_loaded(tm) ? 'last' : i };
									marker.css({ 'left' : l + 'px', 'top' : t + 'px' }).show();
									data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok');
									laster = {};
									o = true;
									return false;
								}
							});
							if(o === true) { return; }
						}
					}
				}
				lastmv = false;
				data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er');
				marker.hide();
			})
			.on('dnd_scroll.vakata.jstree', function (e, data) {
				if(!data || !data.data || !data.data.jstree) { return; }
				marker.hide();
				lastmv = false;
				data.helper.find('.jstree-icon').first().removeClass('jstree-ok').addClass('jstree-er');
			})
			.on('dnd_stop.vakata.jstree', function (e, data) {
				if(opento) { clearTimeout(opento); }
				if(!data || !data.data || !data.data.jstree) { return; }
				marker.hide().detach();
				var i, j, nodes = [];
				if(lastmv) {
					for(i = 0, j = data.data.nodes.length; i < j; i++) {
						nodes[i] = data.data.origin ? data.data.origin.get_node(data.data.nodes[i]) : data.data.nodes[i];
					}
					lastmv.ins[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'copy_node' : 'move_node' ](nodes, lastmv.par, lastmv.pos, false, false, false, data.data.origin);
				}
				else {
					i = $(data.event.target).closest('.jstree');
					if(i.length && laster && laster.error && laster.error === 'check') {
						i = i.jstree(true);
						if(i) {
							i.settings.core.error.call(this, laster);
						}
					}
				}
			})
			.on('keyup.jstree keydown.jstree', function (e, data) {
				data = $.vakata.dnd._get();
				if(data && data.data && data.data.jstree) {
					data.helper.find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (e.metaKey || e.ctrlKey))) ? 'show' : 'hide' ]();
				}
			});
	});

	// helpers
	(function ($) {
		$.vakata.html = {
			div : $('<div />'),
			escape : function (str) {
				return $.vakata.html.div.text(str).html();
			},
			strip : function (str) {
				return $.vakata.html.div.empty().append($.parseHTML(str)).text();
			}
		};
		// private variable
		var vakata_dnd = {
			element	: false,
			target	: false,
			is_down	: false,
			is_drag	: false,
			helper	: false,
			helper_w: 0,
			data	: false,
			init_x	: 0,
			init_y	: 0,
			scroll_l: 0,
			scroll_t: 0,
			scroll_e: false,
			scroll_i: false,
			is_touch: false
		};
		$.vakata.dnd = {
			settings : {
				scroll_speed		: 10,
				scroll_proximity	: 20,
				helper_left			: 5,
				helper_top			: 10,
				threshold			: 5,
				threshold_touch		: 50
			},
			_trigger : function (event_name, e) {
				var data = $.vakata.dnd._get();
				data.event = e;
				$(document).triggerHandler("dnd_" + event_name + ".vakata", data);
			},
			_get : function () {
				return {
					"data"		: vakata_dnd.data,
					"element"	: vakata_dnd.element,
					"helper"	: vakata_dnd.helper
				};
			},
			_clean : function () {
				if(vakata_dnd.helper) { vakata_dnd.helper.remove(); }
				if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; }
				vakata_dnd = {
					element	: false,
					target	: false,
					is_down	: false,
					is_drag	: false,
					helper	: false,
					helper_w: 0,
					data	: false,
					init_x	: 0,
					init_y	: 0,
					scroll_l: 0,
					scroll_t: 0,
					scroll_e: false,
					scroll_i: false,
					is_touch: false
				};
				$(document).off("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag);
				$(document).off("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop);
			},
			_scroll : function (init_only) {
				if(!vakata_dnd.scroll_e || (!vakata_dnd.scroll_l && !vakata_dnd.scroll_t)) {
					if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; }
					return false;
				}
				if(!vakata_dnd.scroll_i) {
					vakata_dnd.scroll_i = setInterval($.vakata.dnd._scroll, 100);
					return false;
				}
				if(init_only === true) { return false; }

				var i = vakata_dnd.scroll_e.scrollTop(),
					j = vakata_dnd.scroll_e.scrollLeft();
				vakata_dnd.scroll_e.scrollTop(i + vakata_dnd.scroll_t * $.vakata.dnd.settings.scroll_speed);
				vakata_dnd.scroll_e.scrollLeft(j + vakata_dnd.scroll_l * $.vakata.dnd.settings.scroll_speed);
				if(i !== vakata_dnd.scroll_e.scrollTop() || j !== vakata_dnd.scroll_e.scrollLeft()) {
					/**
					 * triggered on the document when a drag causes an element to scroll
					 * @event
					 * @plugin dnd
					 * @name dnd_scroll.vakata
					 * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
					 * @param {DOM} element the DOM element being dragged
					 * @param {jQuery} helper the helper shown next to the mouse
					 * @param {jQuery} event the element that is scrolling
					 */
					$.vakata.dnd._trigger("scroll", vakata_dnd.scroll_e);
				}
			},
			start : function (e, data, html) {
				if(e.type === "touchstart" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {
					e.pageX = e.originalEvent.changedTouches[0].pageX;
					e.pageY = e.originalEvent.changedTouches[0].pageY;
					e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);
				}
				if(vakata_dnd.is_drag) { $.vakata.dnd.stop({}); }
				try {
					e.currentTarget.unselectable = "on";
					e.currentTarget.onselectstart = function() { return false; };
					if(e.currentTarget.style) { e.currentTarget.style.MozUserSelect = "none"; }
				} catch(ignore) { }
				vakata_dnd.init_x	= e.pageX;
				vakata_dnd.init_y	= e.pageY;
				vakata_dnd.data		= data;
				vakata_dnd.is_down	= true;
				vakata_dnd.element	= e.currentTarget;
				vakata_dnd.target	= e.target;
				vakata_dnd.is_touch	= e.type === "touchstart";
				if(html !== false) {
					vakata_dnd.helper = $("<div id='vakata-dnd'></div>").html(html).css({
						"display"		: "block",
						"margin"		: "0",
						"padding"		: "0",
						"position"		: "absolute",
						"top"			: "-2000px",
						"lineHeight"	: "16px",
						"zIndex"		: "10000"
					});
				}
				$(document).on("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag);
				$(document).on("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop);
				return false;
			},
			drag : function (e) {
				if(e.type === "touchmove" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {
					e.pageX = e.originalEvent.changedTouches[0].pageX;
					e.pageY = e.originalEvent.changedTouches[0].pageY;
					e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);
				}
				if(!vakata_dnd.is_down) { return; }
				if(!vakata_dnd.is_drag) {
					if(
						Math.abs(e.pageX - vakata_dnd.init_x) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) ||
						Math.abs(e.pageY - vakata_dnd.init_y) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold)
					) {
						if(vakata_dnd.helper) {
							vakata_dnd.helper.appendTo("body");
							vakata_dnd.helper_w = vakata_dnd.helper.outerWidth();
						}
						vakata_dnd.is_drag = true;
						/**
						 * triggered on the document when a drag starts
						 * @event
						 * @plugin dnd
						 * @name dnd_start.vakata
						 * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
						 * @param {DOM} element the DOM element being dragged
						 * @param {jQuery} helper the helper shown next to the mouse
						 * @param {Object} event the event that caused the start (probably mousemove)
						 */
						$.vakata.dnd._trigger("start", e);
					}
					else { return; }
				}

				var d  = false, w  = false,
					dh = false, wh = false,
					dw = false, ww = false,
					dt = false, dl = false,
					ht = false, hl = false;

				vakata_dnd.scroll_t = 0;
				vakata_dnd.scroll_l = 0;
				vakata_dnd.scroll_e = false;
				$($(e.target).parentsUntil("body").addBack().get().reverse())
					.filter(function () {
						return	(/^auto|scroll$/).test($(this).css("overflow")) &&
								(this.scrollHeight > this.offsetHeight || this.scrollWidth > this.offsetWidth);
					})
					.each(function () {
						var t = $(this), o = t.offset();
						if(this.scrollHeight > this.offsetHeight) {
							if(o.top + t.height() - e.pageY < $.vakata.dnd.settings.scroll_proximity)	{ vakata_dnd.scroll_t = 1; }
							if(e.pageY - o.top < $.vakata.dnd.settings.scroll_proximity)				{ vakata_dnd.scroll_t = -1; }
						}
						if(this.scrollWidth > this.offsetWidth) {
							if(o.left + t.width() - e.pageX < $.vakata.dnd.settings.scroll_proximity)	{ vakata_dnd.scroll_l = 1; }
							if(e.pageX - o.left < $.vakata.dnd.settings.scroll_proximity)				{ vakata_dnd.scroll_l = -1; }
						}
						if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) {
							vakata_dnd.scroll_e = $(this);
							return false;
						}
					});

				if(!vakata_dnd.scroll_e) {
					d  = $(document); w = $(window);
					dh = d.height(); wh = w.height();
					dw = d.width(); ww = w.width();
					dt = d.scrollTop(); dl = d.scrollLeft();
					if(dh > wh && e.pageY - dt < $.vakata.dnd.settings.scroll_proximity)		{ vakata_dnd.scroll_t = -1;  }
					if(dh > wh && wh - (e.pageY - dt) < $.vakata.dnd.settings.scroll_proximity)	{ vakata_dnd.scroll_t = 1; }
					if(dw > ww && e.pageX - dl < $.vakata.dnd.settings.scroll_proximity)		{ vakata_dnd.scroll_l = -1; }
					if(dw > ww && ww - (e.pageX - dl) < $.vakata.dnd.settings.scroll_proximity)	{ vakata_dnd.scroll_l = 1; }
					if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) {
						vakata_dnd.scroll_e = d;
					}
				}
				if(vakata_dnd.scroll_e) { $.vakata.dnd._scroll(true); }

				if(vakata_dnd.helper) {
					ht = parseInt(e.pageY + $.vakata.dnd.settings.helper_top, 10);
					hl = parseInt(e.pageX + $.vakata.dnd.settings.helper_left, 10);
					if(dh && ht + 25 > dh) { ht = dh - 50; }
					if(dw && hl + vakata_dnd.helper_w > dw) { hl = dw - (vakata_dnd.helper_w + 2); }
					vakata_dnd.helper.css({
						left	: hl + "px",
						top		: ht + "px"
					});
				}
				/**
				 * triggered on the document when a drag is in progress
				 * @event
				 * @plugin dnd
				 * @name dnd_move.vakata
				 * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
				 * @param {DOM} element the DOM element being dragged
				 * @param {jQuery} helper the helper shown next to the mouse
				 * @param {Object} event the event that caused this to trigger (most likely mousemove)
				 */
				$.vakata.dnd._trigger("move", e);
				return false;
			},
			stop : function (e) {
				if(e.type === "touchend" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {
					e.pageX = e.originalEvent.changedTouches[0].pageX;
					e.pageY = e.originalEvent.changedTouches[0].pageY;
					e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);
				}
				if(vakata_dnd.is_drag) {
					/**
					 * triggered on the document when a drag stops (the dragged element is dropped)
					 * @event
					 * @plugin dnd
					 * @name dnd_stop.vakata
					 * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
					 * @param {DOM} element the DOM element being dragged
					 * @param {jQuery} helper the helper shown next to the mouse
					 * @param {Object} event the event that caused the stop
					 */
					$.vakata.dnd._trigger("stop", e);
				}
				else {
					if(e.type === "touchend" && e.target === vakata_dnd.target) {
						var to = setTimeout(function () { $(e.target).click(); }, 100);
						$(e.target).one('click', function() { if(to) { clearTimeout(to); } });
					}
				}
				$.vakata.dnd._clean();
				return false;
			}
		};
	}($));

	// include the dnd plugin by default
	// $.jstree.defaults.plugins.push("dnd");


/**
 * ### Massload plugin
 *
 * Adds massload functionality to jsTree, so that multiple nodes can be loaded in a single request (only useful with lazy loading).
 */

	/**
	 * massload configuration
	 *
	 * It is possible to set this to a standard jQuery-like AJAX config.
	 * In addition to the standard jQuery ajax options here you can supply functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node IDs need to be loaded, the return value of those functions will be used.
	 *
	 * You can also set this to a function, that function will receive the node IDs being loaded as argument and a second param which is a function (callback) which should be called with the result.
	 *
	 * Both the AJAX and the function approach rely on the same return value - an object where the keys are the node IDs, and the value is the children of that node as an array.
	 *
	 *	{
	 *		"id1" : [{ "text" : "Child of ID1", "id" : "c1" }, { "text" : "Another child of ID1", "id" : "c2" }],
	 *		"id2" : [{ "text" : "Child of ID2", "id" : "c3" }]
	 *	}
	 * 
	 * @name $.jstree.defaults.massload
	 * @plugin massload
	 */
	$.jstree.defaults.massload = null;
	$.jstree.plugins.massload = function (options, parent) {
		this.init = function (el, options) {
			parent.init.call(this, el, options);
			this._data.massload = {};
		};
		this._load_nodes = function (nodes, callback, is_callback) {
			var s = this.settings.massload;
			if(is_callback && !$.isEmptyObject(this._data.massload)) {
				return parent._load_nodes.call(this, nodes, callback, is_callback);
			}
			if($.isFunction(s)) {
				return s.call(this, nodes, $.proxy(function (data) {
					if(data) {
						for(var i in data) {
							if(data.hasOwnProperty(i)) {
								this._data.massload[i] = data[i];
							}
						}
					}
					parent._load_nodes.call(this, nodes, callback, is_callback);
				}, this));
			}
			if(typeof s === 'object' && s && s.url) {
				s = $.extend(true, {}, s);
				if($.isFunction(s.url)) {
					s.url = s.url.call(this, nodes);
				}
				if($.isFunction(s.data)) {
					s.data = s.data.call(this, nodes);
				}
				return $.ajax(s)
					.done($.proxy(function (data,t,x) {
							if(data) {
								for(var i in data) {
									if(data.hasOwnProperty(i)) {
										this._data.massload[i] = data[i];
									}
								}
							}
							parent._load_nodes.call(this, nodes, callback, is_callback);
						}, this))
					.fail($.proxy(function (f) {
							parent._load_nodes.call(this, nodes, callback, is_callback);
						}, this));
			}
			return parent._load_nodes.call(this, nodes, callback, is_callback);
		};
		this._load_node = function (obj, callback) {
			var d = this._data.massload[obj.id];
			if(d) {
				return this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $($.parseHTML(d)).filter(function () { return this.nodeType !== 3; }) : d, function (status) {
					callback.call(this, status);
					delete this._data.massload[obj.id];
				});
			}
			return parent._load_node.call(this, obj, callback);
		};
	};

/**
 * ### Search plugin
 *
 * Adds search functionality to jsTree.
 */

	/**
	 * stores all defaults for the search plugin
	 * @name $.jstree.defaults.search
	 * @plugin search
	 */
	$.jstree.defaults.search = {
		/**
		 * a jQuery-like AJAX config, which jstree uses if a server should be queried for results. 
		 * 
		 * A `str` (which is the search string) parameter will be added with the request, an optional `inside` parameter will be added if the search is limited to a node id. The expected result is a JSON array with nodes that need to be opened so that matching nodes will be revealed.
		 * Leave this setting as `false` to not query the server. You can also set this to a function, which will be invoked in the instance's scope and receive 3 parameters - the search string, the callback to call with the array of nodes to load, and the optional node ID to limit the search to 
		 * @name $.jstree.defaults.search.ajax
		 * @plugin search
		 */
		ajax : false,
		/**
		 * Indicates if the search should be fuzzy or not (should `chnd3` match `child node 3`). Default is `false`.
		 * @name $.jstree.defaults.search.fuzzy
		 * @plugin search
		 */
		fuzzy : false,
		/**
		 * Indicates if the search should be case sensitive. Default is `false`.
		 * @name $.jstree.defaults.search.case_sensitive
		 * @plugin search
		 */
		case_sensitive : false,
		/**
		 * Indicates if the tree should be filtered (by default) to show only matching nodes (keep in mind this can be a heavy on large trees in old browsers). 
		 * This setting can be changed at runtime when calling the search method. Default is `false`.
		 * @name $.jstree.defaults.search.show_only_matches
		 * @plugin search
		 */
		show_only_matches : false,
		/**
		 * Indicates if the children of matched element are shown (when show_only_matches is true)
		 * This setting can be changed at runtime when calling the search method. Default is `false`.
		 * @name $.jstree.defaults.search.show_only_matches_children
		 * @plugin search
		 */
		show_only_matches_children : false,
		/**
		 * Indicates if all nodes opened to reveal the search result, should be closed when the search is cleared or a new search is performed. Default is `true`.
		 * @name $.jstree.defaults.search.close_opened_onclear
		 * @plugin search
		 */
		close_opened_onclear : true,
		/**
		 * Indicates if only leaf nodes should be included in search results. Default is `false`.
		 * @name $.jstree.defaults.search.search_leaves_only
		 * @plugin search
		 */
		search_leaves_only : false,
		/**
		 * If set to a function it wil be called in the instance's scope with two arguments - search string and node (where node will be every node in the structure, so use with caution).
		 * If the function returns a truthy value the node will be considered a match (it might not be displayed if search_only_leaves is set to true and the node is not a leaf). Default is `false`.
		 * @name $.jstree.defaults.search.search_callback
		 * @plugin search
		 */
		search_callback : false
	};

	$.jstree.plugins.search = function (options, parent) {
		this.bind = function () {
			parent.bind.call(this);

			this._data.search.str = "";
			this._data.search.dom = $();
			this._data.search.res = [];
			this._data.search.opn = [];
			this._data.search.som = false;
			this._data.search.smc = false;

			this.element
				.on('before_open.jstree', $.proxy(function (e, data) {
						var i, j, f, r = this._data.search.res, s = [], o = $();
						if(r && r.length) {
							this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #')));
							this._data.search.dom.children(".jstree-anchor").addClass('jstree-search');
							if(this._data.search.som && this._data.search.res.length) {
								for(i = 0, j = r.length; i < j; i++) {
									s = s.concat(this.get_node(r[i]).parents);
								}
								s = $.vakata.array_remove_item($.vakata.array_unique(s),'#');
								o = s.length ? $(this.element[0].querySelectorAll('#' + $.map(s, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #'))) : $();

								this.element.find(".jstree-node").hide().filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
								o = o.add(this._data.search.dom);
								if(this._data.search.smc) {
									this._data.search.dom.children(".jstree-children").find(".jstree-node").show();
								}
								o.parentsUntil(".jstree").addBack().show()
									.filter(".jstree-children").each(function () { $(this).children(".jstree-node:visible").eq(-1).addClass("jstree-last"); });
							}
						}
					}, this))
				.on("search.jstree", $.proxy(function (e, data) {
						if(this._data.search.som) {
							if(data.nodes.length) {
								this.element.find(".jstree-node").hide().filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
								if(this._data.search.smc) {
									data.nodes.children(".jstree-children").find(".jstree-node").show();
								}
								data.nodes.parentsUntil(".jstree").addBack().show()
									.filter(".jstree-children").each(function () { $(this).children(".jstree-node:visible").eq(-1).addClass("jstree-last"); });
							}
						}
					}, this))
				.on("clear_search.jstree", $.proxy(function (e, data) {
						if(this._data.search.som && data.nodes.length) {
							this.element.find(".jstree-node").css("display","").filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
						}
					}, this));
		};
		/**
		 * used to search the tree nodes for a given string
		 * @name search(str [, skip_async])
		 * @param {String} str the search string
		 * @param {Boolean} skip_async if set to true server will not be queried even if configured
		 * @param {Boolean} show_only_matches if set to true only matching nodes will be shown (keep in mind this can be very slow on large trees or old browsers)
		 * @param {mixed} inside an optional node to whose children to limit the search
		 * @param {Boolean} append if set to true the results of this search are appended to the previous search
		 * @plugin search
		 * @trigger search.jstree
		 */
		this.search = function (str, skip_async, show_only_matches, inside, append, show_only_matches_children) {
			if(str === false || $.trim(str.toString()) === "") {
				return this.clear_search();
			}
			inside = this.get_node(inside);
			inside = inside && inside.id ? inside.id : null;
			str = str.toString();
			var s = this.settings.search,
				a = s.ajax ? s.ajax : false,
				m = this._model.data,
				f = null,
				r = [],
				p = [], i, j;
			if(this._data.search.res.length && !append) {
				this.clear_search();
			}
			if(show_only_matches === undefined) {
				show_only_matches = s.show_only_matches;
			}
			if(show_only_matches_children === undefined) {
				show_only_matches_children = s.show_only_matches_children;
			}
			if(!skip_async && a !== false) {
				if($.isFunction(a)) {
					return a.call(this, str, $.proxy(function (d) {
							if(d && d.d) { d = d.d; }
							this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () {
								this.search(str, true, show_only_matches, inside, append);
							}, true);
						}, this), inside);
				}
				else {
					a = $.extend({}, a);
					if(!a.data) { a.data = {}; }
					a.data.str = str;
					if(inside) {
						a.data.inside = inside;
					}
					return $.ajax(a)
						.fail($.proxy(function () {
							this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'search', 'id' : 'search_01', 'reason' : 'Could not load search parents', 'data' : JSON.stringify(a) };
							this.settings.core.error.call(this, this._data.core.last_error);
						}, this))
						.done($.proxy(function (d) {
							if(d && d.d) { d = d.d; }
							this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () {
								this.search(str, true, show_only_matches, inside, append);
							}, true);
						}, this));
				}
			}
			if(!append) {
				this._data.search.str = str;
				this._data.search.dom = $();
				this._data.search.res = [];
				this._data.search.opn = [];
				this._data.search.som = show_only_matches;
				this._data.search.smc = show_only_matches_children;
			}

			f = new $.vakata.search(str, true, { caseSensitive : s.case_sensitive, fuzzy : s.fuzzy });
			$.each(m[inside ? inside : '#'].children_d, function (ii, i) {
				var v = m[i];
				if(v.text && ( (s.search_callback && s.search_callback.call(this, str, v)) || (!s.search_callback && f.search(v.text).isMatch) ) && (!s.search_leaves_only || (v.state.loaded && v.children.length === 0)) ) {
					r.push(i);
					p = p.concat(v.parents);
				}
			});
			if(r.length) {
				p = $.vakata.array_unique(p);
				this._search_open(p);
				if(!append) {
					this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #')));
					this._data.search.res = r;
				}
				else {
					this._data.search.dom = this._data.search.dom.add($(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #'))));
					this._data.search.res = $.vakata.array_unique(this._data.search.res.concat(r));
				}
				this._data.search.dom.children(".jstree-anchor").addClass('jstree-search');
			}
			/**
			 * triggered after search is complete
			 * @event
			 * @name search.jstree
			 * @param {jQuery} nodes a jQuery collection of matching nodes
			 * @param {String} str the search string
			 * @param {Array} res a collection of objects represeing the matching nodes
			 * @plugin search
			 */
			this.trigger('search', { nodes : this._data.search.dom, str : str, res : this._data.search.res, show_only_matches : show_only_matches });
		};
		/**
		 * used to clear the last search (removes classes and shows all nodes if filtering is on)
		 * @name clear_search()
		 * @plugin search
		 * @trigger clear_search.jstree
		 */
		this.clear_search = function () {
			this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search");
			if(this.settings.search.close_opened_onclear) {
				this.close_node(this._data.search.opn, 0);
			}
			/**
			 * triggered after search is complete
			 * @event
			 * @name clear_search.jstree
			 * @param {jQuery} nodes a jQuery collection of matching nodes (the result from the last search)
			 * @param {String} str the search string (the last search string)
			 * @param {Array} res a collection of objects represeing the matching nodes (the result from the last search)
			 * @plugin search
			 */
			this.trigger('clear_search', { 'nodes' : this._data.search.dom, str : this._data.search.str, res : this._data.search.res });
			this._data.search.str = "";
			this._data.search.res = [];
			this._data.search.opn = [];
			this._data.search.dom = $();
		};
		/**
		 * opens nodes that need to be opened to reveal the search results. Used only internally.
		 * @private
		 * @name _search_open(d)
		 * @param {Array} d an array of node IDs
		 * @plugin search
		 */
		this._search_open = function (d) {
			var t = this;
			$.each(d.concat([]), function (i, v) {
				if(v === "#") { return true; }
				try { v = $('#' + v.replace($.jstree.idregex,'\\$&'), t.element); } catch(ignore) { }
				if(v && v.length) {
					if(t.is_closed(v)) {
						t._data.search.opn.push(v[0].id);
						t.open_node(v, function () { t._search_open(d); }, 0);
					}
				}
			});
		};
	};

	// helpers
	(function ($) {
		// from http://kiro.me/projects/fuse.html
		$.vakata.search = function(pattern, txt, options) {
			options = options || {};
			options = $.extend({}, $.vakata.search.defaults, options);
			if(options.fuzzy !== false) {
				options.fuzzy = true;
			}
			pattern = options.caseSensitive ? pattern : pattern.toLowerCase();
			var MATCH_LOCATION	= options.location,
				MATCH_DISTANCE	= options.distance,
				MATCH_THRESHOLD	= options.threshold,
				patternLen = pattern.length,
				matchmask, pattern_alphabet, match_bitapScore, search;
			if(patternLen > 32) {
				options.fuzzy = false;
			}
			if(options.fuzzy) {
				matchmask = 1 << (patternLen - 1);
				pattern_alphabet = (function () {
					var mask = {},
						i = 0;
					for (i = 0; i < patternLen; i++) {
						mask[pattern.charAt(i)] = 0;
					}
					for (i = 0; i < patternLen; i++) {
						mask[pattern.charAt(i)] |= 1 << (patternLen - i - 1);
					}
					return mask;
				}());
				match_bitapScore = function (e, x) {
					var accuracy = e / patternLen,
						proximity = Math.abs(MATCH_LOCATION - x);
					if(!MATCH_DISTANCE) {
						return proximity ? 1.0 : accuracy;
					}
					return accuracy + (proximity / MATCH_DISTANCE);
				};
			}
			search = function (text) {
				text = options.caseSensitive ? text : text.toLowerCase();
				if(pattern === text || text.indexOf(pattern) !== -1) {
					return {
						isMatch: true,
						score: 0
					};
				}
				if(!options.fuzzy) {
					return {
						isMatch: false,
						score: 1
					};
				}
				var i, j,
					textLen = text.length,
					scoreThreshold = MATCH_THRESHOLD,
					bestLoc = text.indexOf(pattern, MATCH_LOCATION),
					binMin, binMid,
					binMax = patternLen + textLen,
					lastRd, start, finish, rd, charMatch,
					score = 1,
					locations = [];
				if (bestLoc !== -1) {
					scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold);
					bestLoc = text.lastIndexOf(pattern, MATCH_LOCATION + patternLen);
					if (bestLoc !== -1) {
						scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold);
					}
				}
				bestLoc = -1;
				for (i = 0; i < patternLen; i++) {
					binMin = 0;
					binMid = binMax;
					while (binMin < binMid) {
						if (match_bitapScore(i, MATCH_LOCATION + binMid) <= scoreThreshold) {
							binMin = binMid;
						} else {
							binMax = binMid;
						}
						binMid = Math.floor((binMax - binMin) / 2 + binMin);
					}
					binMax = binMid;
					start = Math.max(1, MATCH_LOCATION - binMid + 1);
					finish = Math.min(MATCH_LOCATION + binMid, textLen) + patternLen;
					rd = new Array(finish + 2);
					rd[finish + 1] = (1 << i) - 1;
					for (j = finish; j >= start; j--) {
						charMatch = pattern_alphabet[text.charAt(j - 1)];
						if (i === 0) {
							rd[j] = ((rd[j + 1] << 1) | 1) & charMatch;
						} else {
							rd[j] = ((rd[j + 1] << 1) | 1) & charMatch | (((lastRd[j + 1] | lastRd[j]) << 1) | 1) | lastRd[j + 1];
						}
						if (rd[j] & matchmask) {
							score = match_bitapScore(i, j - 1);
							if (score <= scoreThreshold) {
								scoreThreshold = score;
								bestLoc = j - 1;
								locations.push(bestLoc);
								if (bestLoc > MATCH_LOCATION) {
									start = Math.max(1, 2 * MATCH_LOCATION - bestLoc);
								} else {
									break;
								}
							}
						}
					}
					if (match_bitapScore(i + 1, MATCH_LOCATION) > scoreThreshold) {
						break;
					}
					lastRd = rd;
				}
				return {
					isMatch: bestLoc >= 0,
					score: score
				};
			};
			return txt === true ? { 'search' : search } : search(txt);
		};
		$.vakata.search.defaults = {
			location : 0,
			distance : 100,
			threshold : 0.6,
			fuzzy : false,
			caseSensitive : false
		};
	}($));

	// include the search plugin by default
	// $.jstree.defaults.plugins.push("search");

/**
 * ### Sort plugin
 *
 * Automatically sorts all siblings in the tree according to a sorting function.
 */

	/**
	 * the settings function used to sort the nodes.
	 * It is executed in the tree's context, accepts two nodes as arguments and should return `1` or `-1`.
	 * @name $.jstree.defaults.sort
	 * @plugin sort
	 */
	$.jstree.defaults.sort = function (a, b) {
		//return this.get_type(a) === this.get_type(b) ? (this.get_text(a) > this.get_text(b) ? 1 : -1) : this.get_type(a) >= this.get_type(b);
		return this.get_text(a) > this.get_text(b) ? 1 : -1;
	};
	$.jstree.plugins.sort = function (options, parent) {
		this.bind = function () {
			parent.bind.call(this);
			this.element
				.on("model.jstree", $.proxy(function (e, data) {
						this.sort(data.parent, true);
					}, this))
				.on("rename_node.jstree create_node.jstree", $.proxy(function (e, data) {
						this.sort(data.parent || data.node.parent, false);
						this.redraw_node(data.parent || data.node.parent, true);
					}, this))
				.on("move_node.jstree copy_node.jstree", $.proxy(function (e, data) {
						this.sort(data.parent, false);
						this.redraw_node(data.parent, true);
					}, this));
		};
		/**
		 * used to sort a node's children
		 * @private
		 * @name sort(obj [, deep])
		 * @param  {mixed} obj the node
		 * @param {Boolean} deep if set to `true` nodes are sorted recursively.
		 * @plugin sort
		 * @trigger search.jstree
		 */
		this.sort = function (obj, deep) {
			var i, j;
			obj = this.get_node(obj);
			if(obj && obj.children && obj.children.length) {
				obj.children.sort($.proxy(this.settings.sort, this));
				if(deep) {
					for(i = 0, j = obj.children_d.length; i < j; i++) {
						this.sort(obj.children_d[i], false);
					}
				}
			}
		};
	};

	// include the sort plugin by default
	// $.jstree.defaults.plugins.push("sort");

/**
 * ### State plugin
 *
 * Saves the state of the tree (selected nodes, opened nodes) on the user's computer using available options (localStorage, cookies, etc)
 */

	var to = false;
	/**
	 * stores all defaults for the state plugin
	 * @name $.jstree.defaults.state
	 * @plugin state
	 */
	$.jstree.defaults.state = {
		/**
		 * A string for the key to use when saving the current tree (change if using multiple trees in your project). Defaults to `jstree`.
		 * @name $.jstree.defaults.state.key
		 * @plugin state
		 */
		key		: 'jstree',
		/**
		 * A space separated list of events that trigger a state save. Defaults to `changed.jstree open_node.jstree close_node.jstree`.
		 * @name $.jstree.defaults.state.events
		 * @plugin state
		 */
		events	: 'changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree',
		/**
		 * Time in milliseconds after which the state will expire. Defaults to 'false' meaning - no expire.
		 * @name $.jstree.defaults.state.ttl
		 * @plugin state
		 */
		ttl		: false,
		/**
		 * A function that will be executed prior to restoring state with one argument - the state object. Can be used to clear unwanted parts of the state.
		 * @name $.jstree.defaults.state.filter
		 * @plugin state
		 */
		filter	: false
	};
	$.jstree.plugins.state = function (options, parent) {
		this.bind = function () {
			parent.bind.call(this);
			var bind = $.proxy(function () {
				this.element.on(this.settings.state.events, $.proxy(function () {
					if(to) { clearTimeout(to); }
					to = setTimeout($.proxy(function () { this.save_state(); }, this), 100);
				}, this));
				/**
				 * triggered when the state plugin is finished restoring the state (and immediately after ready if there is no state to restore).
				 * @event
				 * @name state_ready.jstree
				 * @plugin state
				 */
				this.trigger('state_ready');
			}, this);
			this.element
				.on("ready.jstree", $.proxy(function (e, data) {
						this.element.one("restore_state.jstree", bind);
						if(!this.restore_state()) { bind(); }
					}, this));
		};
		/**
		 * save the state
		 * @name save_state()
		 * @plugin state
		 */
		this.save_state = function () {
			var st = { 'state' : this.get_state(), 'ttl' : this.settings.state.ttl, 'sec' : +(new Date()) };
			$.vakata.storage.set(this.settings.state.key, JSON.stringify(st));
		};
		/**
		 * restore the state from the user's computer
		 * @name restore_state()
		 * @plugin state
		 */
		this.restore_state = function () {
			var k = $.vakata.storage.get(this.settings.state.key);
			if(!!k) { try { k = JSON.parse(k); } catch(ex) { return false; } }
			if(!!k && k.ttl && k.sec && +(new Date()) - k.sec > k.ttl) { return false; }
			if(!!k && k.state) { k = k.state; }
			if(!!k && $.isFunction(this.settings.state.filter)) { k = this.settings.state.filter.call(this, k); }
			if(!!k) {
				this.element.one("set_state.jstree", function (e, data) { data.instance.trigger('restore_state', { 'state' : $.extend(true, {}, k) }); });
				this.set_state(k);
				return true;
			}
			return false;
		};
		/**
		 * clear the state on the user's computer
		 * @name clear_state()
		 * @plugin state
		 */
		this.clear_state = function () {
			return $.vakata.storage.del(this.settings.state.key);
		};
	};

	(function ($, undefined) {
		$.vakata.storage = {
			// simply specifying the functions in FF throws an error
			set : function (key, val) { return window.localStorage.setItem(key, val); },
			get : function (key) { return window.localStorage.getItem(key); },
			del : function (key) { return window.localStorage.removeItem(key); }
		};
	}($));

	// include the state plugin by default
	// $.jstree.defaults.plugins.push("state");

/**
 * ### Types plugin
 *
 * Makes it possible to add predefined types for groups of nodes, which make it possible to easily control nesting rules and icon for each group.
 */

	/**
	 * An object storing all types as key value pairs, where the key is the type name and the value is an object that could contain following keys (all optional).
	 *
	 * * `max_children` the maximum number of immediate children this node type can have. Do not specify or set to `-1` for unlimited.
	 * * `max_depth` the maximum number of nesting this node type can have. A value of `1` would mean that the node can have children, but no grandchildren. Do not specify or set to `-1` for unlimited.
	 * * `valid_children` an array of node type strings, that nodes of this type can have as children. Do not specify or set to `-1` for no limits.
	 * * `icon` a string - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class. Omit to use the default icon from your theme.
	 *
	 * There are two predefined types:
	 *
	 * * `#` represents the root of the tree, for example `max_children` would control the maximum number of root nodes.
	 * * `default` represents the default node - any settings here will be applied to all nodes that do not have a type specified.
	 *
	 * @name $.jstree.defaults.types
	 * @plugin types
	 */
	$.jstree.defaults.types = {
		'#' : {},
		'default' : {}
	};

	$.jstree.plugins.types = function (options, parent) {
		this.init = function (el, options) {
			var i, j;
			if(options && options.types && options.types['default']) {
				for(i in options.types) {
					if(i !== "default" && i !== "#" && options.types.hasOwnProperty(i)) {
						for(j in options.types['default']) {
							if(options.types['default'].hasOwnProperty(j) && options.types[i][j] === undefined) {
								options.types[i][j] = options.types['default'][j];
							}
						}
					}
				}
			}
			parent.init.call(this, el, options);
			this._model.data['#'].type = '#';
		};
		this.refresh = function (skip_loading, forget_state) {
			parent.refresh.call(this, skip_loading, forget_state);
			this._model.data['#'].type = '#';
		};
		this.bind = function () {
			this.element
				.on('model.jstree', $.proxy(function (e, data) {
						var m = this._model.data,
							dpc = data.nodes,
							t = this.settings.types,
							i, j, c = 'default';
						for(i = 0, j = dpc.length; i < j; i++) {
							c = 'default';
							if(m[dpc[i]].original && m[dpc[i]].original.type && t[m[dpc[i]].original.type]) {
								c = m[dpc[i]].original.type;
							}
							if(m[dpc[i]].data && m[dpc[i]].data.jstree && m[dpc[i]].data.jstree.type && t[m[dpc[i]].data.jstree.type]) {
								c = m[dpc[i]].data.jstree.type;
							}
							m[dpc[i]].type = c;
							if(m[dpc[i]].icon === true && t[c].icon !== undefined) {
								m[dpc[i]].icon = t[c].icon;
							}
						}
						m['#'].type = '#';
					}, this));
			parent.bind.call(this);
		};
		this.get_json = function (obj, options, flat) {
			var i, j,
				m = this._model.data,
				opt = options ? $.extend(true, {}, options, {no_id:false}) : {},
				tmp = parent.get_json.call(this, obj, opt, flat);
			if(tmp === false) { return false; }
			if($.isArray(tmp)) {
				for(i = 0, j = tmp.length; i < j; i++) {
					tmp[i].type = tmp[i].id && m[tmp[i].id] && m[tmp[i].id].type ? m[tmp[i].id].type : "default";
					if(options && options.no_id) {
						delete tmp[i].id;
						if(tmp[i].li_attr && tmp[i].li_attr.id) {
							delete tmp[i].li_attr.id;
						}
						if(tmp[i].a_attr && tmp[i].a_attr.id) {
							delete tmp[i].a_attr.id;
						}
					}
				}
			}
			else {
				tmp.type = tmp.id && m[tmp.id] && m[tmp.id].type ? m[tmp.id].type : "default";
				if(options && options.no_id) {
					tmp = this._delete_ids(tmp);
				}
			}
			return tmp;
		};
		this._delete_ids = function (tmp) {
			if($.isArray(tmp)) {
				for(var i = 0, j = tmp.length; i < j; i++) {
					tmp[i] = this._delete_ids(tmp[i]);
				}
				return tmp;
			}
			delete tmp.id;
			if(tmp.li_attr && tmp.li_attr.id) {
				delete tmp.li_attr.id;
			}
			if(tmp.a_attr && tmp.a_attr.id) {
				delete tmp.a_attr.id;
			}
			if(tmp.children && $.isArray(tmp.children)) {
				tmp.children = this._delete_ids(tmp.children);
			}
			return tmp;
		};
		this.check = function (chk, obj, par, pos, more) {
			if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; }
			obj = obj && obj.id ? obj : this.get_node(obj);
			par = par && par.id ? par : this.get_node(par);
			var m = obj && obj.id ? (more && more.origin ? more.origin : $.jstree.reference(obj.id)) : null, tmp, d, i, j;
			m = m && m._model && m._model.data ? m._model.data : null;
			switch(chk) {
				case "create_node":
				case "move_node":
				case "copy_node":
					if(chk !== 'move_node' || $.inArray(obj.id, par.children) === -1) {
						tmp = this.get_rules(par);
						if(tmp.max_children !== undefined && tmp.max_children !== -1 && tmp.max_children === par.children.length) {
							this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_01', 'reason' : 'max_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
							return false;
						}
						if(tmp.valid_children !== undefined && tmp.valid_children !== -1 && $.inArray((obj.type || 'default'), tmp.valid_children) === -1) {
							this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_02', 'reason' : 'valid_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
							return false;
						}
						if(m && obj.children_d && obj.parents) {
							d = 0;
							for(i = 0, j = obj.children_d.length; i < j; i++) {
								d = Math.max(d, m[obj.children_d[i]].parents.length);
							}
							d = d - obj.parents.length + 1;
						}
						if(d <= 0 || d === undefined) { d = 1; }
						do {
							if(tmp.max_depth !== undefined && tmp.max_depth !== -1 && tmp.max_depth < d) {
								this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_03', 'reason' : 'max_depth prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
								return false;
							}
							par = this.get_node(par.parent);
							tmp = this.get_rules(par);
							d++;
						} while(par);
					}
					break;
			}
			return true;
		};
		/**
		 * used to retrieve the type settings object for a node
		 * @name get_rules(obj)
		 * @param {mixed} obj the node to find the rules for
		 * @return {Object}
		 * @plugin types
		 */
		this.get_rules = function (obj) {
			obj = this.get_node(obj);
			if(!obj) { return false; }
			var tmp = this.get_type(obj, true);
			if(tmp.max_depth === undefined) { tmp.max_depth = -1; }
			if(tmp.max_children === undefined) { tmp.max_children = -1; }
			if(tmp.valid_children === undefined) { tmp.valid_children = -1; }
			return tmp;
		};
		/**
		 * used to retrieve the type string or settings object for a node
		 * @name get_type(obj [, rules])
		 * @param {mixed} obj the node to find the rules for
		 * @param {Boolean} rules if set to `true` instead of a string the settings object will be returned
		 * @return {String|Object}
		 * @plugin types
		 */
		this.get_type = function (obj, rules) {
			obj = this.get_node(obj);
			return (!obj) ? false : ( rules ? $.extend({ 'type' : obj.type }, this.settings.types[obj.type]) : obj.type);
		};
		/**
		 * used to change a node's type
		 * @name set_type(obj, type)
		 * @param {mixed} obj the node to change
		 * @param {String} type the new type
		 * @plugin types
		 */
		this.set_type = function (obj, type) {
			var t, t1, t2, old_type, old_icon;
			if($.isArray(obj)) {
				obj = obj.slice();
				for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
					this.set_type(obj[t1], type);
				}
				return true;
			}
			t = this.settings.types;
			obj = this.get_node(obj);
			if(!t[type] || !obj) { return false; }
			old_type = obj.type;
			old_icon = this.get_icon(obj);
			obj.type = type;
			if(old_icon === true || (t[old_type] && t[old_type].icon !== undefined && old_icon === t[old_type].icon)) {
				this.set_icon(obj, t[type].icon !== undefined ? t[type].icon : true);
			}
			return true;
		};
	};
	// include the types plugin by default
	// $.jstree.defaults.plugins.push("types");

/**
 * ### Unique plugin
 *
 * Enforces that no nodes with the same name can coexist as siblings.
 */

	/**
	 * stores all defaults for the unique plugin
	 * @name $.jstree.defaults.unique
	 * @plugin unique
	 */
	$.jstree.defaults.unique = {
		/**
		 * Indicates if the comparison should be case sensitive. Default is `false`.
		 * @name $.jstree.defaults.unique.case_sensitive
		 * @plugin unique
		 */
		case_sensitive : false,
		/**
		 * A callback executed in the instance's scope when a new node is created and the name is already taken, the two arguments are the conflicting name and the counter. The default will produce results like `New node (2)`.
		 * @name $.jstree.defaults.unique.duplicate
		 * @plugin unique
		 */
		duplicate : function (name, counter) {
			return name + ' (' + counter + ')';
		}
	};

	$.jstree.plugins.unique = function (options, parent) {
		this.check = function (chk, obj, par, pos, more) {
			if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; }
			obj = obj && obj.id ? obj : this.get_node(obj);
			par = par && par.id ? par : this.get_node(par);
			if(!par || !par.children) { return true; }
			var n = chk === "rename_node" ? pos : obj.text,
				c = [],
				s = this.settings.unique.case_sensitive,
				m = this._model.data, i, j;
			for(i = 0, j = par.children.length; i < j; i++) {
				c.push(s ? m[par.children[i]].text : m[par.children[i]].text.toLowerCase());
			}
			if(!s) { n = n.toLowerCase(); }
			switch(chk) {
				case "delete_node":
					return true;
				case "rename_node":
					i = ($.inArray(n, c) === -1 || (obj.text && obj.text[ s ? 'toString' : 'toLowerCase']() === n));
					if(!i) {
						this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_01', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
					}
					return i;
				case "create_node":
					i = ($.inArray(n, c) === -1);
					if(!i) {
						this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_04', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
					}
					return i;
				case "copy_node":
					i = ($.inArray(n, c) === -1);
					if(!i) {
						this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_02', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
					}
					return i;
				case "move_node":
					i = ( (obj.parent === par.id && (!more || !more.is_multi)) || $.inArray(n, c) === -1);
					if(!i) {
						this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_03', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
					}
					return i;
			}
			return true;
		};
		this.create_node = function (par, node, pos, callback, is_loaded) {
			if(!node || node.text === undefined) {
				if(par === null) {
					par = "#";
				}
				par = this.get_node(par);
				if(!par) {
					return parent.create_node.call(this, par, node, pos, callback, is_loaded);
				}
				pos = pos === undefined ? "last" : pos;
				if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
					return parent.create_node.call(this, par, node, pos, callback, is_loaded);
				}
				if(!node) { node = {}; }
				var tmp, n, dpc, i, j, m = this._model.data, s = this.settings.unique.case_sensitive, cb = this.settings.unique.duplicate;
				n = tmp = this.get_string('New node');
				dpc = [];
				for(i = 0, j = par.children.length; i < j; i++) {
					dpc.push(s ? m[par.children[i]].text : m[par.children[i]].text.toLowerCase());
				}
				i = 1;
				while($.inArray(s ? n : n.toLowerCase(), dpc) !== -1) {
					n = cb.call(this, tmp, (++i)).toString();
				}
				node.text = n;
			}
			return parent.create_node.call(this, par, node, pos, callback, is_loaded);
		};
	};

	// include the unique plugin by default
	// $.jstree.defaults.plugins.push("unique");


/**
 * ### Wholerow plugin
 *
 * Makes each node appear block level. Making selection easier. May cause slow down for large trees in old browsers.
 */

	var div = document.createElement('DIV');
	div.setAttribute('unselectable','on');
	div.setAttribute('role','presentation');
	div.className = 'jstree-wholerow';
	div.innerHTML = '&#160;';
	$.jstree.plugins.wholerow = function (options, parent) {
		this.bind = function () {
			parent.bind.call(this);

			this.element
				.on('ready.jstree set_state.jstree', $.proxy(function () {
						this.hide_dots();
					}, this))
				.on("init.jstree loading.jstree ready.jstree", $.proxy(function () {
						//div.style.height = this._data.core.li_height + 'px';
						this.get_container_ul().addClass('jstree-wholerow-ul');
					}, this))
				.on("deselect_all.jstree", $.proxy(function (e, data) {
						this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked');
					}, this))
				.on("changed.jstree", $.proxy(function (e, data) {
						this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked');
						var tmp = false, i, j;
						for(i = 0, j = data.selected.length; i < j; i++) {
							tmp = this.get_node(data.selected[i], true);
							if(tmp && tmp.length) {
								tmp.children('.jstree-wholerow').addClass('jstree-wholerow-clicked');
							}
						}
					}, this))
				.on("open_node.jstree", $.proxy(function (e, data) {
						this.get_node(data.node, true).find('.jstree-clicked').parent().children('.jstree-wholerow').addClass('jstree-wholerow-clicked');
					}, this))
				.on("hover_node.jstree dehover_node.jstree", $.proxy(function (e, data) {
						if(e.type === "hover_node" && this.is_disabled(data.node)) { return; }
						this.get_node(data.node, true).children('.jstree-wholerow')[e.type === "hover_node"?"addClass":"removeClass"]('jstree-wholerow-hovered');
					}, this))
				.on("contextmenu.jstree", ".jstree-wholerow", $.proxy(function (e) {
						e.preventDefault();
						var tmp = $.Event('contextmenu', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey, pageX : e.pageX, pageY : e.pageY });
						$(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp);
					}, this))
				/*!
				.on("mousedown.jstree touchstart.jstree", ".jstree-wholerow", function (e) {
						if(e.target === e.currentTarget) {
							var a = $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor");
							e.target = a[0];
							a.trigger(e);
						}
					})
				*/
				.on("click.jstree", ".jstree-wholerow", function (e) {
						e.stopImmediatePropagation();
						var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });
						$(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus();
					})
				.on("click.jstree", ".jstree-leaf > .jstree-ocl", $.proxy(function (e) {
						e.stopImmediatePropagation();
						var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });
						$(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus();
					}, this))
				.on("mouseover.jstree", ".jstree-wholerow, .jstree-icon", $.proxy(function (e) {
						e.stopImmediatePropagation();
						if(!this.is_disabled(e.currentTarget)) {
							this.hover_node(e.currentTarget);
						}
						return false;
					}, this))
				.on("mouseleave.jstree", ".jstree-node", $.proxy(function (e) {
						this.dehover_node(e.currentTarget);
					}, this));
		};
		this.teardown = function () {
			if(this.settings.wholerow) {
				this.element.find(".jstree-wholerow").remove();
			}
			parent.teardown.call(this);
		};
		this.redraw_node = function(obj, deep, callback, force_render) {
			obj = parent.redraw_node.apply(this, arguments);
			if(obj) {
				var tmp = div.cloneNode(true);
				//tmp.style.height = this._data.core.li_height + 'px';
				if($.inArray(obj.id, this._data.core.selected) !== -1) { tmp.className += ' jstree-wholerow-clicked'; }
				if(this._data.core.focused && this._data.core.focused === obj.id) { tmp.className += ' jstree-wholerow-hovered'; }
				obj.insertBefore(tmp, obj.childNodes[0]);
			}
			return obj;
		};
	};
	// include the wholerow plugin by default
	// $.jstree.defaults.plugins.push("wholerow");
	if(document.customElements && Object && Object.create) {
		var proto = Object.create(HTMLElement.prototype);
		proto.createdCallback = function () {
			var c = { core : {}, plugins : [] }, i;
			for(i in $.jstree.plugins) {
				if($.jstree.plugins.hasOwnProperty(i) && this.attributes[i]) {
					c.plugins.push(i);
					if(this.getAttribute(i) && JSON.parse(this.getAttribute(i))) {
						c[i] = JSON.parse(this.getAttribute(i));
					}
				}
			}
			for(i in $.jstree.defaults.core) {
				if($.jstree.defaults.core.hasOwnProperty(i) && this.attributes[i]) {
					c.core[i] = JSON.parse(this.getAttribute(i)) || this.getAttribute(i);
				}
			}
			$(this).jstree(c);
		};
		// proto.attributeChangedCallback = function (name, previous, value) { };
		try {
			document.document.customElements.define("vakata-jstree", { prototype: proto });
		} catch(ignore) { }
	}

}));

// Opera 8.0+
var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;

// Firefox 1.0+
var isFirefox = typeof InstallTrigger !== 'undefined';

// Safari 3.0+ "[object HTMLElementConstructor]"
var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification));

// Internet Explorer 6-11
var isIE = /*@cc_on!@*/false || !!document.documentMode;

// Edge 20+
var isEdge = !isIE && !!window.StyleMedia;

// Chrome 1+
var isChrome = !!window.chrome && !!window.chrome.webstore;

// Blink engine detection
var isBlink = (isChrome || isOpera) && !!window.CSS;

(function (window) {
  $type = String;
  $type.__typeName = 'String';
  $type.__class = true;

  $prototype = $type.prototype;
  $prototype.endsWith = function String$endsWith(suffix) {
    /// <summary>Determines whether the end of this instance matches the specified string.</summary>
    /// <param name="suffix" type="String">A string to compare to.</param>
    /// <returns type="Boolean">true if suffix matches the end of this instance; otherwise, false.</returns>
    return (this.substr(this.length - suffix.length) === suffix);
  }

  $prototype.startsWith = function String$startsWith(prefix) {
    /// <summary >Determines whether the beginning of this instance matches the specified string.</summary>
    /// <param name="prefix" type="String">The String to compare.</param>
    /// <returns type="Boolean">true if prefix matches the beginning of this string; otherwise, false.</returns>
    return (this.substr(0, prefix.length) === prefix);
  }

  $prototype.trim = function String$trim() {
    /// <summary >Removes all leading and trailing white-space characters from the current String object.</summary>
    /// <returns type="String">The string that remains after all white-space characters are removed from the start and end of the current String object.</returns>
    return this.replace(/^\s+|\s+$/g, '');
  }

  $prototype.trimEnd = function String$trimEnd() {
    /// <summary >Removes all trailing white spaces from the current String object.</summary>
    /// <returns type="String">The string that remains after all white-space characters are removed from the end of the current String object.</returns>
    return this.replace(/\s+$/, '');
  }

  $prototype.trimStart = function String$trimStart() {
    /// <summary >Removes all leading white spaces from the current String object.</summary>
    /// <returns type="String">The string that remains after all white-space characters are removed from the start of the current String object.</returns>
    return this.replace(/^\s+/, '');
  }

  $type.format = function String$format(format, args) {
    /// <summary>Replaces the format items in a specified String with the text equivalents of the values of   corresponding object instances. The invariant culture will be used to format dates and numbers.</summary>
    /// <param name="format" type="String">A format string.</param>
    /// <param name="args" parameterArray="true" mayBeNull="true">The objects to format.</param>
    /// <returns type="String">A copy of format in which the format items have been replaced by the   string equivalent of the corresponding instances of object arguments.</returns>
    return String._toFormattedString(false, arguments);
  }

  $type._toFormattedString = function String$_toFormattedString(useLocale, args) {
    var result = '';
    var format = args[0];

    for (var i = 0; ;) {
      // Find the next opening or closing brace
      var open = format.indexOf('{', i);
      var close = format.indexOf('}', i);
      if ((open < 0) && (close < 0)) {
        // Not found: copy the end of the string and break
        result += format.slice(i);
        break;
      }
      if ((close > 0) && ((close < open) || (open < 0))) {
        if (format.charAt(close + 1) !== '}') {
          throw new Error('format stringFormatBraceMismatch');
        }

        result += format.slice(i, close + 1);
        i = close + 2;
        continue;
      }

      // Copy the string before the brace
      result += format.slice(i, open);
      i = open + 1;

      // Check for double braces (which display as one and are not arguments)
      if (format.charAt(i) === '{') {
        result += '{';
        i++;
        continue;
      }

      if (close < 0) throw new Error('format stringFormatBraceMismatch');

      // Find the closing brace

      // Get the string between the braces, and split it around the ':' (if any)
      var brace = format.substring(i, close);
      var colonIndex = brace.indexOf(':');
      var argNumber = parseInt((colonIndex < 0) ? brace : brace.substring(0, colonIndex), 10) + 1;

      if (isNaN(argNumber)) throw new Error('format stringFormatInvalid');

      var argFormat = (colonIndex < 0) ? '' : brace.substring(colonIndex + 1);

      var arg = args[argNumber];
      if (typeof (arg) === "undefined" || arg === null) {
        arg = '';
      }

      // If it has a toFormattedString method, call it.  Otherwise, call toString()
      if (arg.toFormattedString) {
        result += arg.toFormattedString(argFormat);
      }
      else if (useLocale && arg.localeFormat) {
        result += arg.localeFormat(argFormat);
      }
      else if (arg.format) {
        result += arg.format(argFormat);
      }
      else
        result += arg.toString();

      i = close + 1;
    }

    return result;
  }
})(window);

// "/Date(1224043200000)/" gibi json date i "Wed Oct 15 2008 07:00:00 GMT+0300 (GTB Daylight Time)" halindeki js date e cevirir.
String.prototype.toJsDate = function () {
  return moment(this)._d;
};

String.prototype.toJsonDate = function () {
  return JSON.parse(JSON.stringify(this));
};
Date.prototype.toJsonDate = function () {
  return JSON.parse(JSON.stringify(this));
};

//js date in kısa tarih biçimini verir. 01.01.2015 gibi
String.prototype.convert2ShortDateString = function () {
  var result = "";
  if (this != null && this != "") {
    result = moment(this.toString()).format("DD.MM.YYYY");
    //var cdaty = new Date(this);
    //result = cdaty.toLocaleDateString();
  }
  return result;
};
Date.prototype.convert2ShortDateString = function () {
  var result = "";
  if (this != null && this != "") {
    result = moment(this).format("DD.MM.YYYY");
  }
  return result;
};

//js date in kısa saat biçimini verir. 10:00 gibi
String.prototype.convert2TimeString = function () {
  var result = "";
  if (this != null && this != "") {
    //var cdaty = new Date(this);
    //var dp2 = cdaty.getUTCHours();
    //var dp3 = cdaty.getMinutes();
    //if (parseInt(dp2) < 10) { dp2 = "0" + dp2; }
    //if (parseInt(dp3) < 10) { dp3 = "0" + dp3; }
    //result = dp2 + ":" + dp3;
    result = moment(this.toString()).format("HH:mm");
  }
  return result;
};
Date.prototype.convert2TimeString = function () {
  var result = "";
  if (this != null && this != "") {
    result = moment(this).format("HH:mm");
  }
  return result;
};

//js date in uzun tarih biçimini verir. 01.01.2015 10:00 gibi
String.prototype.convert2LongDateString = function () {
  var result = "";
  if (this != null && this != "") {
    //var cdaty = new Date(this);
    //var dp1 = cdaty.toLocaleDateString();
    //var dp2 = cdaty.getHours();
    //var dp3 = cdaty.getMinutes();
    //if (parseInt(dp2) < 10) { dp2 = "0" + dp2; }
    //if (parseInt(dp3) < 10) { dp3 = "0" + dp3; }
    //result = dp1 + " " + dp2 + ":" + dp3;
    result = moment(this.toString()).format("DD.MM.YYYY HH:mm");
  }
  return result;
};
Date.prototype.convert2LongDateString = function () {
  var result = "";
  if (this != null && this != "") {
    result = moment(this).format("DD.MM.YYYY HH:mm");
  }
  return result;
};

//gün ekleyip cıkarmaya yarar. js             "new Date().addDays(5);" gibi kullanılır.
Date.prototype.addDays = function (days) {
  var dat = new Date(this.valueOf());
  dat.setDate(dat.getDate() + days);
  return dat;
}

//array i clonlamak için kullanılır.
Array.prototype.cloneArray = function () {
  return JSON.parse(JSON.stringify(this));
};

//tek nesneyi clonlamak için kullanılır.
function cloneObject(obj) {
  return jQuery.extend(true, {}, obj);
}

// kullanım şekli "{0} {1} {2}".format("MVC", "Razor","Is The Best")
String.prototype.format = function () {
  var formatted = this;
  for (var arg in arguments) {
    formatted = formatted.replace("{" + arg + "}", arguments[arg]);
  }
  return formatted;
};

////türkçe karakterlerde I ve İ harflerini küçük / büyük harfe çevirirken hata oluşuyor genelde. bu hatayı engellemek için eklendi.
//String.prototype.toLCase = function () {
//	var result = this;
//	result = result.replace("I", "ı");
//	result = result.replace("İ", "i");
//	result = result.toLowerCase();
//	return result
//};
//String.prototype.toUCase = function () {
//	var result = this;
//	result = result.replace("ı", "I");
//	result = result.replace("i", "İ");
//	result = result.toUpperCase();
//	return result
//};



//portalda tutulan culturu bulup id sini verir.
function currentCultureId() {
  var result = 1;

  // alttaki local storage den gelicek. portal dan oraya koyuluyor.
  switch (localStorage.Culture) {
    case "tr-TR": result = 1; break;
    case "en-US": result = 2; break;
    case "de-DE": result = 3; break;
    default: result = 1; break;
  }

  return result;
}

//gelen e-mail in geçerli olup olmadıgını kontrol eder. bool sonuc doner.
function validateEmail(email) {
  var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
  return re.test(email);
}

//gelen string uzunlugunu belirtilen uzunluga getirir. telefon numaraları için kullanılır. kısa string geldiğinde basını 0 ile doldurur.
String.prototype.fixLen = function (len) {
  var str = this;
  if (str != null && str.length > 0) {
    if (str.length > len) {
      str = str.slice(str.length - len, str.length);
    }
    else if (str.length < len) {
      for (var i = 0; i < len - str.length; i++)
        str = "0" + str;
    }
  }
  else {
    for (var i = 0; i < len; i++)
      str += "0";
  }
  return str;
};

function validateTelephone(tel) {
  tel = tel != null && tel.length > 0 ? tel.replace(/ /g, "").replace('(', '').replace(')', '') : "";
  var re = /\d\d\d\d\d\d\d\d\d\d\d/;
  return re.test(tel);
}

//iki js tarih aralıgını gün, saat, dakika veya saniye olarak döner.
function timeSpan(startDate, endDate, format) {
  var diff = parseInt(endDate - startDate);
  switch (format) {
    case "d": return Math.floor(diff / (1000 * 60 * 60 * 24)); break;//gün
    case "h": return Math.floor(diff / (1000 * 60 * 60)); break;//saat
    case "m": return Math.floor(diff / (1000 * 60)); break;//dakika
    case "s": return Math.floor(diff / (1000)); break;//saniye
    case "": return 0; break;
  }
}


function fixStudentStatus(status, detailStatus) {
  if (detailStatus == 27 || detailStatus == 535 || detailStatus == 10302001) {
    return "Pasif";
  } else {
    switch (status) {
      case 10301: return "Kayıtlanmadı";
      case 10302: return "Aktif";
      case 10303: return "Mezun";
      case 10304: return "İlişigi Kesilmiş";
      case 10305: return "Kayıt Dondurma";
      case 10306: return "Lisans Programından Önlisans Derecesi ile Mezun";
      case 10307: return "Hazırlıktan Muaf";
    }
  }
}

//********************************************************//
//RANDOM GUID AND ID GENERATORS
//********************************************************//
function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  }
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
    s4() + '-' + s4() + s4() + s4();
}

//********************************************************//
//randomString(10);        // "4Z8iNQag9v"
//randomString(10, "A");   // "aUkZuHNcWw"
//randomString(10, "N");   // "9055739230"
//********************************************************//
function randomString(len, an) {
  an = an && an.toLowerCase();
  var str = "", i = 0, min = an == "a" ? 10 : 0, max = an == "n" ? 10 : 62;
  for (i; i++ < len;) {
    var rOk = false;
    while (!rOk) {
      var r = Math.random() * (max - min) + min << 0;
      var temp = String.fromCharCode(r += r > 9 ? r < 36 ? 55 : 61 : 48);
      if (an != "n" || !(i == 1 && temp == "0")) {//numericte ilk rakam sıfır gelirse yenisini bulana kadar dön.
        str += temp;
        rOk = true;
      }
    }
  }
  return str;
}

/*****************************/

//Tablo.toExcel("SayfaAdı","DosyaAdı.xls") //tabloyu excel olarak download eder.
$.fn.toExcel = function (name, filename) {
  var _table = $(this);

  var template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">';
  template += '<head><meta name="content-disposition" content="attachment; filename="' + filename + '">';
  template += '<meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8">';
  template += '<!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]-->';
  template += '<style>td.no-number {mso-number-format:"\@" } </style > ';
  template += '</head><body><table>{table}</table></body></html>';

  var format = function (s, c) { return s.replace(/{(\w+)}/g, function (m, p) { return c[p]; }) };
  var ctx = { worksheet: name || 'Worksheet', table: _table.html() };

  saveAs(new Blob([format(template, ctx)], { type: "application/octet-stream" }), filename)
  //download(format(template, ctx), filename);
}

function downloadFromUrl(path, filename, postdata, pathFileName) {
  if (pathFileName == "" || pathFileName == undefined) { showError("Dosya indirme sırasında hata oluştu!"); return; }
  let pathFileRoot = "";
  let pathCorrect = "";
  if (path == "CommonExportPDF") {
    pathCorrect = "/AIS/Common/ExportPDF/";
  } else if (path == "BackofficeContent") {
    pathCorrect = "/AIS/Backoffice/Content/";
  } else if (path == "ReportsReport") {
    pathCorrect = "/AIS/Reports/Report/";
  }

  pathFileName = pathFileName.replace('/', '+');
  pathFileName = pathFileName.replace(' ', '+');

  pathFileRoot = pathCorrect + pathFileName;

  if (pathFileRoot == "" || pathCorrect == "") { showError("Dosya indirme sırasında hata oluştu!"); return; }
  pathFileRoot = location.origin + pathFileRoot;

  var xhr = new XMLHttpRequest();
  xhr.open('POST', pathFileRoot, true);
  xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
  xhr.responseType = 'blob';

  xhr.onload = function (e) {
    if (this.status == 200) {
      if (navigator.appVersion.toString().indexOf('.NET') > 0) {
        //IE 10+
        var blob = this.response;
        window.navigator.msSaveBlob(blob, filename);
      }
      else {
        var blob = new Blob([xhr.response], { type: 'application/octet-stream' });
        //var blobUrl = window.URL.createObjectURL(blob);
        var fileName = filename ? filename : xhr.getResponseHeader("filename");
        var reader = new FileReader();
        reader.onload = function (e) {
          showAISIndicator("Dosya yükleniyor...");
          var a = document.createElement("a");
          document.body.appendChild(a);
          a.style = "display: none";
          a.href = reader.result;
          a.download = fileName;
          a.click();
          setTimeout(function () {
            document.body.removeChild(a);
            hideAISIndicator();
            //window.URL.revokeObjectURL(blobUrl);
          }, 300);
        }
        reader.readAsDataURL(blob);
      }
    }
    else {
      showError("Dosya indirme sırasında hata oluştu!");
    }
    hideAISIndicator();
  };
  xhr.onprogress = function (e) {
    if (typeof e !== "undefined" && e && e.lengthComputable) {
      showAISIndicator(Math.floor((e.loaded / e.total) * 100) + '% indirme devam ediyor... Lütfen bekleyiniz...');
    }
  };
  showAISIndicator("Dosya hazırlanıyor.");
  xhr.send(JSON.stringify(postdata));
}

//DOWNLOAD
function download(data, strFileName, strMimeType) {
  var self = window, // this script is only for browsers anyway...
    u = "application/octet-stream", // this default mime also triggers iframe downloads
    m = strMimeType || u,
    x = data,
    D = document,
    a = D.createElement("a"),
    z = function (a) { return String(a); },

    B = self.Blob || self.MozBlob || self.WebKitBlob || z,
    BB = self.MSBlobBuilder || self.WebKitBlobBuilder || self.BlobBuilder,
    fn = strFileName || "download",
    blob,
    b,
    ua,
    fr;

  //if(typeof B.bind === 'function' ){ B=B.bind(self); }

  if (String(this) === "true") { //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
    x = [x, m];
    m = x[0];
    x = x[1];
  }

  //go ahead and download dataURLs right away
  if (String(x).match(/^data\:[\w+\-]+\/[\w+\-]+[,;]/)) {
    return navigator.msSaveBlob ?  // IE10 can't do a[download], only Blobs:
      navigator.msSaveBlob(d2b(x), fn) :
      saver(x); // everyone else can save dataURLs un-processed
  }//end if dataURL passed?

  try {
    blob = x instanceof B ?
      x :
      new B([x], { type: m });
  } catch (y) {
    if (BB) {
      b = new BB();
      b.append([x]);
      blob = b.getBlob(m); // the blob
    }
  }

  function d2b(u) {
    var p = u.split(/[:;,]/),
      t = p[1],
      dec = p[2] == "base64" ? atob : decodeURIComponent,
      bin = dec(p.pop()),
      mx = bin.length,
      i = 0,
      uia = new Uint8Array(mx);

    for (i; i < mx; ++i) uia[i] = bin.charCodeAt(i);

    return new B([uia], { type: t });
  }

  function saver(url, winMode) {
    if ('download' in a) { //html5 A[download]
      a.href = url;
      a.setAttribute("download", fn);
      a.innerHTML = "downloading...";
      D.body.appendChild(a);
      setTimeout(function () {
        a.click();
        D.body.removeChild(a);
        if (winMode === true) { setTimeout(function () { self.URL.revokeObjectURL(a.href); }, 250); }
      }, 66);
      return true;
    }

    //do iframe dataURL download (old ch+FF):
    var f = D.createElement("iframe");
    D.body.appendChild(f);
    if (!winMode) { // force a mime that will download:
      url = "data:" + url.replace(/^data:([\w\/\-\+]+)/, u);
    }

    f.src = url;
    setTimeout(function () { D.body.removeChild(f); }, 333);
  }//end saver

  if (navigator.msSaveBlob) { // IE10+ : (has Blob, but not a[download] or URL)
    return navigator.msSaveBlob(blob, fn);
  }

  if (self.URL) { // simple fast and modern way using Blob and URL:
    saver(self.URL.createObjectURL(blob), true);
  } else {
    // handle non-Blob()+non-URL browsers:
    if (typeof blob === "string" || blob.constructor === z) {
      try {
        return saver("data:" + m + ";base64," + self.btoa(blob));
      } catch (y) {
        return saver("data:" + m + "," + encodeURIComponent(blob));
      }
    }

    // Blob but not URL:
    fr = new FileReader();
    fr.onload = function (e) {
      saver(this.result);
    };
    fr.readAsDataURL(blob);
  }
  return true;
} /* end download() */

//TEST EDİLECEK KULLANMAYIN SİLMEYİN GELİŞTİRİLİYOR:
//Serialize form to Object
$.fn.serializeObject = function () {
  var o = {};
  var a = this.serializeArray();
  $.each(a, function () {
    if (o[this.name] !== undefined) {
      if (!o[this.name].push) {
        o[this.name] = [o[this.name]];
      }
      if (this.value == 'on') {
        o[this.name].push((this.value == 'on' ? true : false) || '');
      } else {
        o[this.name].push(this.value || '');
      }
    } else {
      if (this.value == 'on') {
        o[this.name] = (this.value == 'on' ? true : false) || '';
      } else {
        o[this.name] = this.value || '';
      }
    }
  });
  return o;
};

function gotoUrl(url, target) {
  var a = document.createElement("A");
  a.setAttribute("href", url);
  a.setAttribute("target", target != undefined ? target : "_blank");
  $("body").append(a);
  a.click();
  if (!isIE) {
    a.remove();
  }
}

function fixTooltip() {
  $(".tooltip").remove();
  initTooltipFix();
}

///order => [[ 0, 'desc' ], [ 1, 'asc' ]]
///pageLength => 10,20 veya 30 gibi
function loadDataTable(selector, disablePaging, pageLength, dontAddLengthMenuString, order, scrollX, scrollY) {
  if ($.fn.dataTable.isDataTable($(this))) {
    $(selector).DataTable().destroy();
  }

  var options = {};
  options.paging = disablePaging ? false : true;
  options.bPaginate = disablePaging ? false : true;

  options.lengthMenu = [[10, 25, 50, 100, -1], [10, 25, 50, 100, "Hepsi"]];
  options.pageLength = pageLength ? pageLength : -1;

  if (order) {
    options.order = order;
  }

  options.language = {
    "sProcessing": "İşleniyor...",
    "sLengthMenu": !dontAddLengthMenuString ? "Sayfada _MENU_ Kayıt Göster" : "_MENU_",
    "sZeroRecords": "Eşleşen Kayıt Bulunmadı",
    "sInfo": "  _TOTAL_ Kayıttan _START_ - _END_ Arası Kayıtlar",
    "sInfoEmpty": "Kayıt Yok",
    "sInfoFiltered": "( _MAX_ Kayıt İçerisinden Bulunan)",
    "sInfoPostFix": "",
    "sSearch": "Bul:",
    "sUrl": "",
    "oPaginate": {
      "sFirst": "|<",
      "sPrevious": "<<",
      "sNext": ">>",
      "sLast": ">|"
    }
  };

  if (scrollX) {
    options.scrollX = scrollX;
  }

  if (scrollY) {
    options.scrollY = scrollY;
    options.scrollCollapse = true;
    options.paging = false;
  }


  $(selector).each(function () {
    if (!$.fn.dataTable.isDataTable($(this))) {
      $(this).DataTable(options).columns().every(function () {
        var that = this;
        $('input', this.header()).on('keyup change', function () {
          if (this.type != 'checkbox' && that.search() !== this.value) {
            that.search($(this).val()).draw();
          }
        });
      });
    }
  });
}

/**
 * @param refresh
 * @param title
 * @param showContent
 * @param width
 * @param _class
 * @param liveSearch
 * @param actionsBox
 * @returns {}
 */
$.fn.toSelectpicker = function (refresh, title, container, width, _class, liveSearch, actionsBox) {
  if (refresh != undefined && refresh) {
    //value setlendiğinde basmaz refresh etmen lazım.
    $(this).selectpicker('refresh');
  }
  else {
    if (_class != undefined) {
      $(this).prop("class", "selectpicker" + _class);
    } else {
      $(this).prop("class", "selectpicker");
    }

    //$(this).attr("data-title", title != undefined ? title : "Seçiniz");
    //$(this).attr("data-live-search", liveSearch == undefined ? "true" : liveSearch);
    //$(this).attr("data-size", "10");
    //$(this).attr("data-actions-box", actionsBox == undefined ? "true" : actionsBox);
    //$(this).attr("data-width", width != undefined ? width : "100%");
    //$(this).attr("data-container", container != undefined ? container : "body");
    $(this).selectpicker({
      liveSearch: liveSearch == undefined ? true : liveSearch,
      title: title ? title : "Seçiniz",
      size: 10,
      actionsBox: actionsBox == undefined ? true : actionsBox,
      width: width ? width : "100%",
      container: container ? container : "body"
    });
  }
}

function showBasicPopup(html, title) {
  BootstrapDialog.show({
    closable: true,
    type: BootstrapDialog.TYPE_DEFAULT,
    title: title !== undefined && title !== '' ? title : '',
    message: html,
    buttons: []
  });
}

//image dosyasına canvas yapma
/// Örnek kullanım
//var _imageUrl = location.origin + $(".selected-student-img img").attr("src");
//convertToDataURLviaCanvas(_imageUrl, function (base64Img) {
//  $(".selected-student-img img").attr("src", base64Img);
//});

function convertToDataURLviaCanvas(url, callback, outputFormat) {
  var img = new Image();
  img.crossOrigin = 'Anonymous';
  img.onload = function () {
    var canvas = document.createElement('CANVAS');
    var ctx = canvas.getContext('2d');
    var dataURL;
    canvas.height = this.height;
    canvas.width = this.width;
    ctx.drawImage(this, 0, 0);
    dataURL = canvas.toDataURL(outputFormat);
    callback(dataURL);
    canvas = null;
  };
  img.src = url;
}

function convertFileToDataURLviaFileReader(url, callback) {
  var xhr = new XMLHttpRequest();
  xhr.responseType = 'blob';
  xhr.onload = function () {
    var reader = new FileReader();
    reader.onloadend = function () {
      callback(reader.result);
    }
    reader.readAsDataURL(xhr.response);
  };
  xhr.open('GET', url);
  xhr.send();
}

//random renk oluşturur
function randomColor() {
  return '#' + (0x1000000 + (Math.random()) * 0xffffff).toString(16).substr(1, 6);
  jQuery(".font-style").animate({ color: newColor }, 2000);
}

/***************************/
/* WORD EXPORT
/***************************/
//loadWordFile("examples/tagExample.docx", function (err, content) {
//  if (err) { throw e };
//  doc = new Docxtemplater(content);
//  doc.setData({
//    "first_name": "Hipp",
//    "last_name": "Edgar",
//    "phone": "0652455478",
//    "description": "New Website"
//  }
//  ) //set the templateVariables
//  doc.render() //apply them (replace all occurences of {first_name} by Hipp, ...)
//  out = doc.getZip().generate({ type: "blob" }) //Output the document using Data-URI
//  saveAs(out, "output.docx")
//})

//sadece bir içeriği dışarı aktarmak isterseniz
//$("#printDiv").wordExport(); da kullanılabilir

//var loadWordFile = function (templateUrl, callback) {
//  JSZipUtils.getBinaryContent(templateUrl, callback);
//}
function loadWordFile(url, callback) {
  JSZipUtils.getBinaryContent(url, function (err, data) {
    callback(null, data)
  });
}
/***************************/
/***************************/

function encodeURIComponent4Image(image) {
  if (image == undefined || image == "") {
    return "data:image/png;base64," + encodeURIComponent("iVBORw0KGgoAAAANSUhEUgAAAOgAAADoCAMAAADSd1hKAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAALHUExURRZWjhdXjhhXjxlYjxpZkBtakBxakR1bkR5bkR5ckh9ckiBdkiFekyJekyNfkyNflCRglCVhlSZhlSdilShilihjliljlipklytllyxlly1mmC5nmS9omTBomTFpmjJpmjJqmjNqmzRrmzVsmzZsnDdtnDdtnThunTlvnTpvnjtwnjxxnz1xnz5yoD9zoEBzoEF0oUJ1oUN2okR2okV3okZ3o0Z4o0d4pEh5pEl6pEp6pUt7pUx8pk19pk59pk9+p1B+p1B/qFKAqFOBqVSBqVWCqVWCqlaDqleEqliEq1mFq1qFrFqGrFuGrFyHrV6IrV+JrmCJrmGLr2KLr2OMsGSMsGWNsGWOsWePsWiPsmmQsmqRs2uSs2yStG2TtG6TtG+VtXCVtXGWtnKWtnOXtnSXt3SYt3WZuHaZuHeauHiauXmbuXmcuXqcunudunydun2eu36eu36fvH+gvICgvIGhvYKhvYOivYOjvoSjvoWkv4akv4ilwIimwImnwIuowYyowY2pwo2qwo6qw4+rw5Crw5GsxJKsxJKtxJOuxZSuxZWvxZavxpexx5ixx5myx5qyyJuzyJyzyJy0yZ21yZ61yZ+2yqC2yqG3y6G4y6K4y6O5zKS5zKW6zKa7zae8zai8zqm9zqq9z6u+z6y/z6y/0K3A0K7A0K/B0bDC0bHC0bHD0rLD0rPE07TE07XF07bG1LfH1LjH1bnI1brJ1bvJ1rvK1rzK173L177L17/M2MDN2MHO2cLO2cPP2cTQ2sXQ2sXR28bR28fS28jS3MnT3MrU3MrU3cvV3czV3s3W3s7X3s/X38/Y39DY39HZ4NLZ4NPa4NTb4dXc4tbc4tfd4tje49ne49nf49rf5Nvg5Nzg5N3h5d7i5d7i5t/j5uDj5uHk5+Ll5+Pl5+Pm6OTm6OXn6Obn6efo6ejp6unq6urq6+vr68Hc1GAAAAeqSURBVHja7dz7W0x5HMDxTzORRBSJii5ikFJam7RmybqV+/2yu1q3ELIXuy6tyC7WCmvZhE21uy6tO7FMlFxK6R6GiknT5cycP2Kt59lnn93FoznfT32+c877h36e1zM9c+Z8vp8zIMokUKAKVIEqUAWqQBWoAlWgClSBKlAFqkAVqAJVoApUgSpQBapAFagCVaAKVIEqUAWqQBWoApURtK6xeEVM6YtKXlaavHKnvtHqoEL95WUbdqltvb29vTxf5t3F1nV+3J26BmuCVmfNHtUXXpXfiGWm7CLrgNal753hC6+t09geY/VJp/iH5h1wU8Gbs3FX91j7RYbRzC/UXJQSCm+Zs3Z5iYHbd3RCR2hGAet1TRxCzUVxI9TQrNr13XTBzN87usYNml/Qqrt1nEEz3wNLsg36+FgNL9Am4cWfBBuwMM9vG3mANqTP1U5MPpPQGyxOPS5ZIA+t3N8LJKcO/Y06VJ/UBRhkMz6fOPRMV2DT9ybK0IbDfRk5wT7hMWFobbiaFRR88whDDzoAuxZUkoWWRzN0gvM6qlDzeReWUAjKM9OEFr3L1AnqCfdpQjO6s4VC56M0oattGENhWDZFaEUIayeoFgoEoT86MYeCY3IDOej5EYDQ4EJy0P0YTlDNEIhBa1egQGHgJWLQ8kAcqE00Lah5rRoHClNrSUFrw5CcYJdECmoMx4Kqj5CCVvqhQX8mBU0FtGIFStDteNCQRkrQNXhQTQkl6FY8aO8CStBjeFC/SkrQB++gQQP1lKCm6WjQAWWUoMI0NKhvISVoYyQa1PMOqbuXbW1kAi3pgwXtmUsK+jgQC+qWTQpa2k8mUP1ALKj7TVrDsc9l8mEkHsGapXjl0YL+3g4J2reIFvSiAxLUr4IW9HpHJOggPS1oJtY7qimmBT1uhwT1LqAFTcf6shtupAW91B7pTGInsdO0cmccaJt0YlBBiwNtd4oYVJyJA22bQQ0ajQN1uUENuhkHutREDRqPA2X0ocsQmoxz+7KVHPTZSBToenJQMQrD6XiZGrToVAgG1L+BGPTRJEcVymU0dvFFEyWozgWwCntCCXrXE+/I+yklaEFvNOiUJkrQ+31kAi30RYOOqacEzfNCgy4i9albosFyOp4jdR0V0JYB3XJIQU2rsaDUJvUHVEhQ/4e0oKexzl76l9GCXsKa1FMbYP+K9a8bQWyAnY10fVEfpHbjvQEH2v48Neg2HKg9OWgi0qT+CjVoBc6m0bgGalBxFgo0gdwU0IRz+LKDHhTn8OVrenPd3F4ITm0lPWjVYAToPJEe9IE/AnQNQWjDFIRFwNsEoWIG+/M0rZEi9A/mI09WmxqMoTWpHoyho3JJQkXxZKhXB4bOyNsmolChpvDU+s6MmEGx9xi+NISfy5vDZMiZkfmI6atCgDJ5lrTHA8avCgF6mAk0nz70Kouf+1ki0oeKKxlAf+ABuooBNJUHKIvnoA/xAL0nfZ+hQy4PUH2QZOgEMw9Qw3DJ0MUiD9BnYfSuLijQh9InvDFcQOslP/DtcoULqHhc6lnpkBo+oNlSf054uIEP6HWp33aHVvEBrf9K4ploqsAHVPxF2oNq3sUiJ9ACaWvnWw28QMV8KQ9wRdwVuYE+vzrVYmdotsgPVBSbEiw8ihmZJXIFFcUci+7WJueJvEGNMyxwup4VuYNatJATXM0hdIcFUE0xX9DywnL9CYsenFjNE7Rgb4DngOA+Fq1BDr1cUarnBNq0UcrubhdfL20eH1Cdj9Qb70lGLqDLJE9Sgrm4H70YIBnaM0GgDy37gMGgfnAmeWh1HJPdlAgDdWjhADYH+5/WEodGMfoVnK5xz0lD7/VntZLiHv+UMPTxcnbLN64baslCG9I6s4NCp1XVVKHF77NdBww/XksTmmjPeEcuaFsjQaghbRjz9U6fPQIxaJUueogXwmZyx9nn6ghBTyeHuwJS3WcfKqMBfZa0upctIGYbsv5GY2tDy3OXhdkDel6RCQXG1oPWndgb6A4tk53vnHRdq0CFsu9md1BBC2Y34MuMxpaG1qRM94OWr+PYmFtVLQctOrlxjBO0Uj7alAstAhWS4oLbQ2vWxmVRcjUy9Glx/GRnaP1sQhece4QHzT46WgNU6hG8/VIVBvRJ4mc9HYBUThP3ljCG1lyP1aqAYP3mH6xlBhV0u8LcgWoOEVsyC1lADWlRrm2BcmpnbWK2RGhT2Z5IFXCQZmGKwXJocea8fg7ASd20u3OMFkFrzo52AZ6y7/XNzWZDjfnrxncD3lIN3ZRlbA608uSEAOAzj3FpBW8Lzd3t3wn4rdOgxNy3gOo3zdOogO9UYfvLTW+ENuUkRNiAFWQfGKUTXgsVrn7kpgZryePD4+Wvhl5b4gJWlf3cfcL/oYZ4H7C6nKJu/Rd6eaEKrDHfnbf+BdWNBCtNFXa+/h+obiJYb5rtFX9DdZFgzXn8JLyECtemgHWnyTX9Bc0ZAdberPoXUHOMyuqhPnkvoPvUYP1tBrEsRAZOiAGLNt/5KxAeDwR59MBDJtBCN5lA73SXCTTLRSbQTCeZQE86yAR6tI1MoFtsZAJdKhMnfCIX6DS5QGfKBTpVLtCxcoEOlws0WC7Q/nKBusoF6usqj/4E7AeOhK7YZosAAAAASUVORK5CYII=");
  } else {
    return "data:image/png;base64," + encodeURIComponent(image);
  }
}



function showPopup(message, title, type) {
  if (!type) { type = "primary"; }
  BootstrapDialog.show({
    closable: false,
    type: swichMessageType(type),
    title: title !== undefined && title !== '' ? title : _resx.Warning,
    message: message !== undefined && message !== '' ? message : 'Pencereyi Kapatınız',
    buttons: [{
      cssClass: 'btn-' + type,
      label: _resx.Close,
      action: function (dialogItself) {
        dialogItself.close();
      }
    }]
  });
}

function swichMessageType(type) {
  switch (type) {
    case "info": return BootstrapDialog.TYPE_INFO
      break;
    case "primary": return BootstrapDialog.TYPE_PRIMARY
      break;
    case "success": return BootstrapDialog.TYPE_SUCCESS
      break;
    case "warning": return BootstrapDialog.TYPE_WARNING
      break;
    case "danger": return BootstrapDialog.TYPE_DANGER
      break;
    default: return BootstrapDialog.TYPE_DEFAULT
      break;
  }
}

function GetYearSemesterList() {
  var result = [];
  //sonra get year a ceviririz simdilik iş görür
  var Id = 1;
  for (var i = 2018 - 50; i < 2018 + 50; i++) {
    result.push({ Id: Id, Year: i, SemesterId: 10400 });
    result.push({ Id: Id + 1, Year: i, SemesterId: 10401 });
    Id += 2;
  }

  return result;
}

function isFloat(n) {
  return n === +n && n !== (n | 0);
}

function isInteger(n) {
  return n === +n && n === (n | 0);
}

//js cache teki nesnenin boyutunu görmek için kullanılır.
function memorySizeOf(obj) {
  var bytes = 0;

  function sizeOf(obj) {
    if (obj !== null && obj !== undefined) {
      switch (typeof obj) {
        case 'number':
          bytes += 8;
          break;
        case 'string':
          bytes += obj.length * 2;
          break;
        case 'boolean':
          bytes += 4;
          break;
        case 'object':
          var objClass = Object.prototype.toString.call(obj).slice(8, -1);
          if (objClass === 'Object' || objClass === 'Array') {
            for (var key in obj) {
              if (!obj.hasOwnProperty(key)) continue;
              sizeOf(obj[key]);
            }
          } else bytes += obj.toString().length * 2;
          break;
      }
    }
    return bytes;
  };

  function formatByteSize(bytes) {
    if (bytes < 1024) return bytes + " bytes";
    else if (bytes < 1048576) return (bytes / 1024).toFixed(3) + " KB";
    else if (bytes < 1073741824) return (bytes / 1048576).toFixed(3) + " MB";
    else return (bytes / 1073741824).toFixed(3) + " GB";
  };

  return formatByteSize(sizeOf(obj));
};

///adından belli E*** G****** gibi dönemesini sağlıyor.
function metniSansurle(data, isIdentity) {
  var result = "";
  if (isIdentity) {
    result = data.substring(0, 2) + "*******" + data.substring(9, 12);
  }
  else {
    var parts = data.split(" ");
    if (parts && parts.length > 0)
      $.Enumerable.From(parts).ForEach(function (x) {
        if (x != "") {
          if (x.length == 1) {
            result += x + " ";
          }
          else {
            result += x.substring(0, 1);
            for (var i = 0; i < x.length - 1; i++) {
              result += "*";
            }
            result += " ";
          }
        }
      });


  }

  return result;
}

//************************************************************************
//*************************************   Enumlar ************************
//************************************************************************

function getUniversityName() {
    switch (_customerId) {
        case 3: return "İZMİR KATİP ÇELEBİ ÜNİVERSİTESİ";
        case 102: return "BARTIN ÜNİVERSİTESİ";
        case 103: return "ARDAHAN ÜNİVERSİTESİ";
        case 104: return "YALOVA ÜNİVERSİTESİ";
        case 105: return "ÇANAKKALE ONSEKİZ MART ÜNİVERSİTESİ";
        case 106: return "OSTİM TEKNİK ÜNİVERSİTESİ";
        case 107: return "GAZİANTEP İSLAM BİLİM VE TEKNOLOJİ ÜNİVERSİTESİ";
    }
}

//lookupları ve  LookupListItemId alarak seçili dildeki adı döner.
function getLookupName(lookUps, Id) {
    var result = "";
    if (lookUps != null && lookUps.length > 0 && $.Enumerable.From(lookUps).Any(function (x) { return x.Id == Id })) {
        var item = $.Enumerable.From(lookUps).Where(function (x) { return x.Id == Id }).FirstOrDefault();
        result = item.Name;
        if (currentCultureId() != 1 && item.Languages != null && $.Enumerable.From(item.Languages).Any(function (x) { return x.CultureId == currentCultureId() })) {
            result = $.Enumerable.From(item.Languages).Where(function (x) { return x.CultureId == currentCultureId() }).FirstOrDefault().Name;
        }
    }
    return result;
}

//lookupları ve  LookupListItemId alarak seçili dildeki kodu döner.
function getLookupCode(lookUps, Id) {
    var result = "";
    if (lookUps != null && lookUps.length > 0 && $.Enumerable.From(lookUps).Any(function (x) { return x.Id == Id })) {
        var item = $.Enumerable.From(lookUps).Where(function (x) { return x.Id == Id }).FirstOrDefault();
        result = item.Code;
        if (currentCultureId() != 1 && item.Languages != null && $.Enumerable.From(item.Languages).Any(function (x) { return x.CultureId == currentCultureId() })) {
            result = $.Enumerable.From(item.Languages).Where(function (x) { return x.CultureId == currentCultureId() }).FirstOrDefault().Code;
        }
    }
    return result;
}

function getDayName(day, long) {
    var result = day;
    switch (parseInt(day)) {
        case 1: result = long ? "Pazartesi" : "Pzt"; break;
        case 2: result = long ? "Salı" : "Sal"; break;
        case 3: result = long ? "Çarşamba" : "Çar"; break;
        case 4: result = long ? "Perşembe" : "Per"; break;
        case 5: result = long ? "Cuma" : "Cum"; break;
        case 6: result = long ? "Cumartesi" : "Cts"; break;
        case 7: result = long ? "Pazar" : "Paz"; break;
    }
    return result;
}

//lookupta olmayan enumlar için
function getEnumDisplayName(enumName, enumId) {
    enumId = parseInt(enumId);
    var result = "";

    switch (enumName) {
        case "RegistrationPhase":
            switch (enumId) {
                case -2: result = _resx.KayitlanmaDonemiDisinda; break;
                case -1: result = _resx.SistemeGirmemis; break;
                case 1: result = _resx.DersSecimi; break;
                case 2: result = _resx.DanismanOnayinda; break;
                case 3: result = _resx.DanismanInceleme; break;
                case 4: result = _resx.OgrenciOnayinda; break;
                case 5: result = _resx.DanismanOnayladi; break;
                case 6: result = _resx.KayitTamamlandi; break;
                case 7: result = _resx.YazOkuluOnKayit; break;
                case 8: result = _resx.YazOkulKesinKayit; break;
            }
            break;
        case "EAcademicSemester":
            switch (enumId) {
                case 10400: result = "Güz"; break;
                case 10401: result = "Bahar"; break;
                case 10402: result = "Yaz"; break;
                case 10403: result = "Güz Tek Ders"; break;
                case 10404: result = "Bahar Tek Ders"; break;
                case 10405: result = "Güz Ek Sınav"; break;
                case 10406: result = "Bahar Ek Sınav"; break;
                case 10411: result = "Yaz Tek Ders"; break;
            }
            break;
        case "EStudentApplicationAdresssType":
            switch (enumId) {
                case 1: result = _resx.Home; break;
                case 2: result = _resx.Job; break;
            }
            break;
        case "EStudentApplicationContactType":
            switch (enumId) {
                case 1: result = _resx.Telephone; break;
                case 2: result = _resx.EMail; break;
                case 3: result = _resx.Cellular; break;
                case 4: result = _resx.Public_Application_FriendsPhone; break;
                case 5: result = _resx.Public_Application_VizeUlke; break;
                case 6: result = _resx.Public_Application_ForeignPhone; break;
            }
            break;
        case "EActivityPackageType":
            switch (enumId) {
                case 18401: result = "Scorm"; break;
                case 18402: result = "Video"; break;
            }
            break;
        case "EStudentCourseSuccessStatus":
            switch (enumId) {
                case 13301: result = "Başarılı"; break;
                case 13302: result = "Başarısız"; break;
                case 13303: result = "Koşullu Başarılı"; break;
                case 13304: result = "Muaf"; break;
                case 13305: result = "Devamsız"; break;
                case 13306: result = "Durumu Netleşmemiş"; break;
                case 13307: result = "Yetmiş Ortalama İle Başarılı"; break;
                case 13308: result = "Transfer"; break;
            }
            break;
        case "EStudentTransferType":
            switch (enumId) {
                case 14701: result = "DGS"; break;
                case 14702: result = "Yatay Geçis"; break;
                case 14703: result = "Erasmus"; break;
                case 14704: result = "Yaz Okulu"; break;
                case 14705: result = "2.Üniversite"; break;
                case 14706: result = "Farabi"; break;
                case 14707: result = "Diğer Üniversite"; break;
                case 14708: result = "Mevlana"; break;
                case 14709: result = "667 ve 669 Sayılı KHK"; break;
                case 14710: result = "İlahiyat Lisans Tamamlama"; break;
                case 14711: result = "Öğrenci Affı"; break;
                case 14712: result = "Özel Öğrenci"; break;
                case 14799: result = "Diğer"; break;
            }
            break;

        case "ECourseRegistrationPhase":
            switch (enumId) {
                case 0: result = "Seçilmedi"; break;
                case 1: result = "Öğrenci Ekledi"; break;
                case 2: result = "Danışman Onayında"; break;
                case 3: result = "Danışman EKledi"; break;
                case 4: result = "Kayıt Tamamlandı"; break;
                case 5: result = "Yaz Okulu Ön Kayıt"; break;
                case 6: result = "Kayıtlanılan Ama Açılmayan Ders"; break;
            }
            break;

        case "ECourseStatusDetail":
            switch (enumId) {
                case 12201: result = "Kapanmış Ders Öğrenciler Muaf"; break;
                case 12202: result = "Kapanmış Ders Eski Öğrenciler Dersten Sorumlu"; break;
                case 12203: result = "Yerine Ders Açıldı"; break;
                case 12204: result = "Yerine Ders Açıldı Eski Öğrenciler Eski Dersi Okuyacak"; break;
                case 12205: result = "Yerine Ders Açıldı Eski Dersi Alanlar Bu Dersi Almış Görünecekler"; break;
            }
            break;

        case "EYoksisServiceType":
            switch (enumId) {
                case 19301: result = "Veri Aktarımı"; break;
                case 19302: result = "Öğrenci Sil"; break;
                case 19303: result = "Yök No ile TC Kimlik Numarası Güncelle"; break;
                case 19304: result = "Yök No ile YU Numarası Güncelle"; break;
                case 19305: result = "Yök Yabancı Öğrenci Ekle"; break;
                case 19306: result = "YU/TC Kimlik Numarası Güncelle"; break;
                case 19307: result = "Teyitleşme"; break;
                case 19308: result = "Statüye Göre Öğrenci Sayısı"; break;
                case 19309: result = "Statüye Göre Öğrenciler"; break;
                case 19310: result = "Statüye ve Birime Göre Öğrenciler"; break;
                case 19311: result = "Transkript Gönderimi"; break;
                case 19312: result = "Öğrenci İletişim Bilgisi Gönderimi"; break;
                case 19313: result = "Formasyon Veri Aktarımı"; break;
                case 19314: result = "Kabul Mektubu Ekle"; break;
                case 19315: result = "Kabul Mektubu Sil"; break;
                case 19316: result = "Hazırlık Veri Aktarımı"; break;
            }
            break;

        case "EYoksisResultType":
            switch (enumId) {
                case 20603: result = "Sistem Bildirimi"; break;
                default: result = "Başarısız"; break;
            }
            break;

        case "EStudentStatus":
            switch (enumId) {
                case 10301: result = "Kayıtlanmadı"; break;
                case 10302: result = "Aktif"; break;
                case 10303: result = "Mezun"; break;
                case 10304: result = "İlişigi Kesilmiş"; break;
                case 10305: result = "Kayıt Dondurma"; break;
                case 10306: result = "Lisans Programından Önlisans Derecesi ile Mezun"; break;
                case 10307: result = "Hazırlıktan Muaf"; break;
            }
            break;

        case "EStudentStatusDetail":
            switch (enumId) {
                case 3: result = "Kayıt Dondurmuş"; break;
                case 5: result = "(Ayrıldı) Mezun"; break;
                case 6: result = "(Ayrıldı) Kendi İsteği İle"; break;
                case 7: result = "(Ayrıldı) Yatay Geçiş İle-Üniversite Dışı"; break;
                case 8: result = "(Ayrıldı) Yatay Geçiş-Üniversite İçi"; break;
                case 9: result = "(Ayrıldı) Yönetim Kurulu Kararı İle"; break;
                case 10: result = "(Ayrıldı) Hazırlıktan Başarısızlık Nedeni İle"; break;
                case 11: result = "(Ayrıldı) Disiplinsizlik Nedeni İle"; break;
                case 12: result = "(Ayrıldı) Harç Yatırmadığı İçin"; break;
                case 13: result = "(Ayrıldı) Vefat"; break;
                case 14: result = "(Ayrıldı) Lisans Okurken Önlisans Derecli Mezun"; break;
                case 15: result = "(Ayrıldı) Diğer"; break;
                case 16: result = "Aktif"; break;
                case 17: result = "Kayıtlanmadı"; break;
                case 18: result = "Ders Kaydı Yaptı"; break;
                case 19: result = "Hazırlık Öğrencisi"; break;
                case 20: result = "Erasmus (Giden)"; break;
                case 21: result = "Farabi (Giden)"; break;
                case 22: result = "Mevlana (Giden)"; break;
                case 23: result = "E-Devlet Kayıt"; break;
                case 24: result = "Muaf"; break;
                case 25: result = "Anadal Programına Başladı"; break;
                case 26: result = "Özel Öğrenci (Giden)"; break;
                case 27: result = "Ders Kaydı Yapmadı"; break;
                case 28: result = "%10 a Giren Öğrenci"; break;
                case 29: result = "Zorunlu Yabancı Dil Hazırlık Sınıflarında Başarısız Olan Öğrencilerin Türkçe Öğretim Yapan Yükseköğretim Programlarına Yerleştirilmeleri nedeniyle ayrılanlar"; break;
                case 30: result = "Geçici kayıt (Lise Diploması Olmayanlar) ile kayıtlananların belirtilen tarihe kadar diplomalarını getirememesi"; break;
                case 31: result = "Yatay Geçiş - Üniversite İçi-Ek Madde 1"; break;
                case 32: result = "Yatay Geçiş - Üniversite Dışı-Ek Madde 1"; break;
                case 33: result = "YÖK Kararı ile aktarma"; break;
                case 34: result = "Yatay geçişten kendi isteği ile vazgeçme"; break;
                case 35: result = "Bilimsel Hazırlık Sınıfında Başarısızlık"; break;
                case 37: result = "TEBİB Özel Öğrenci"; break;
                case 38: result = "Gençlik, Spor Hizmet ve Faaliyetlerinde İşbirliği Protokolü"; break;
                case 39: result = "Azami Süre Sonunda Mezun Olamadı"; break;

                case 517: result = "Ek Sınav / Not Yükseltme Sınavı Hakkını Kullandı"; break;
                case 518: result = "(Ayrıldı) Lisans Derecesi İle Mezun Oldu"; break;
                case 519: result = "(Ayrıldı) İkinci Öğretimden Birinci Öğretime Geçti"; break;
                case 520: result = "Aktarım"; break;
                case 521: result = "(Kayıtlanmadı) Başvuru Kazanan (Asil)"; break;
                case 522: result = "(Kayıtlanmadı) Başvuru Kazanan (Yedek)"; break;
                case 525: result = "Tezli YüksekLisans Programından Tezsiz YüksekLisans Diploması Alarak Mezuniyet	"; break;
                case 526: result = "(Ayrıldı) Sahte Belge Sebebi İle Kayıt İptali	"; break;
                case 527: result = "Üniversite/Fakülte/MYO/YO/Bölüm isim değişikliğinden dolayı aktarım	"; break;
                case 528: result = "667 KHK kapsamında ÖSYM ve YÖK tarafından yerleştirilen öğrencilerin koordinatör üniversitelerden ilişik kesmeleri"; break;
                case 532: result = "Bakanlar Kurulu kararı ile aktarma	"; break;
                case 10302001: result = "İzinli(Türkçe Yeterlilik Seviyesi Nedeniyle)"; break;
            }
            break;

        case "ECourseType":
            switch (enumId) {
                case 12301: result = "Ders"; break;
                case 12302: result = "Yök Dersi"; break;
                case 12303: result = "Staj Dersi"; break;
                case 12304: result = "Tez Dersi"; break;
                case 12305: result = "Seminer Dersi"; break;
                case 12306: result = "Yabancı Dil Dersi"; break;
                case 12307: result = "Hazırlık Dersi"; break;
                case 12308: result = "Entegre Ders"; break;
                case 12309: result = "Uzmanlık Alan Dersi"; break;
                case 12310: result = "Kurum Dışı Ders"; break;
                case 12311: result = "Danışmanlık Dersi"; break;
            }
            break;

        case "EWorkcenterType":
            switch (enumId) {
                case 14401: result = "Sınıf"; break;
                case 14402: result = "Anfi"; break;
                case 14403: result = "Laboratuar"; break;
                case 14404: result = "Salon"; break;
                case 14405: result = "Seminer Odası"; break;
                case 14406: result = "Klinik"; break;
                case 14407: result = "Ö.Ü. Odası"; break;
                case 14408: result = "Atölye"; break;
            }
            break;

        case "EPrepExemptResult":
            switch (enumId) {
                case 16401: result = "Hazırlıktan Muaf"; break;
                case 16402: result = "Ortak Zorunlu Derslerden Muaf"; break;
                case 16403: result = "Hazırlık Ve Ortak Zorunlu Derslerden Muaf"; break;
            }
            break;
        case "EPrepExemptType":
            switch (enumId) {
                case 16201: result = "Muafiyet Sınavi İle Muaf"; break;
                case 16202: result = "Belge İle Muaf"; break;
                case 16203: result = "Anadili İngilizce"; break;
                case 16204: result = "İngilizce Program Hazırlıgını Okudu"; break;
                case 16205: result = "Turkçe Program Hazırlıgını Okudu"; break;
                case 16206: result = "Anadili Almanca"; break;
                case 16207: result = "Almanca Program Hazırlıgını Okudu"; break;
            }
            break;

        case "EDay":
            switch (enumId) {
                case 1: result = "Pazartesi"; break;
                case 2: result = "Salı"; break;
                case 3: result = "Çarşamba"; break;
                case 4: result = "Perşembe"; break;
                case 5: result = "Cuma"; break;
                case 6: result = "Cumartesi"; break;
                case 7: result = "Pazar"; break;
            }
            break;

        case "ECourseStudyType":
            switch (enumId) {
                case 16501: result = "Teorik"; break;
                case 16502: result = "Uygulama"; break;
                case 16503: result = "Laboratuvar"; break;
            }
            break;
        case "EStudentPermissionType":
            switch (enumId) {
                case 17401: result = "Mazeretli(Kayıt Dondurma)"; break;
                case 17402: result = "Raporlu"; break;
                case 17403: result = "Görevli"; break;
                case 17407: result = "Salgın Nedeniyle"; break;
                case 17408: result = "İzinli(Türkçe Yeterlilik Seviyesi Nedeniyle)"; break;
            }
            break;

        case "EStatus":
            switch (enumId) {
                case 10201: result = "Aktif"; break;
                case 10202: result = "Kapalı"; break;
            }
            break;

        case "EModeOfInstruction":
            switch (enumId) {
                case 10701: result = "Birinci Öğretim"; break;
                case 10702: result = "İkinci Öğretim"; break;
                case 10703: result = "Uzaktan Eğitim"; break;
            }
            break;

        case "EActivityType":
            switch (enumId) {
                case 1: result = "Vize"; break;
                case 2: result = "Ödev"; break;
                case 3: result = "Quiz"; break;
                case 4: result = "Proje"; break;
                case 5: result = "Final"; break;
                case 7: result = "Deney"; break;
                case 21: result = "Gelişim Sınavı"; break;
                case 22: result = "Bütünleme"; break;
                case 24: result = "Vize (Büt)"; break;
                case 45: result = "Alt Final"; break;
            }
            break;
        case "EInstitutionType":
            switch (enumId) {
                case 20101: result = "ASAL"; break;
                case 20102: result = "ÖSYM"; break;
                case 20103: result = "KYK"; break;
                case 20104: result = "YÖK"; break;
                case 20105: result = "MEB"; break;
            }
            break;

        case "PunishmentType":
            switch (enumId) {
                case 12401: result = "Uyarma"; break;
                case 12402: result = "Kınama"; break;
                case 12403: result = "Uzaklaştırma"; break;
                case 12404: result = "Çıkarma"; break;
            }
            break;
        case "TimeDescription":
            switch (enumId) {
                case 12501: result = "Gün"; break;
                case 12502: result = "Hafta"; break;
                case 12503: result = "Ay"; break;
                case 12504: result = "Dönem"; break;
                case 12505: result = "Yıl"; break;
            }
            break;
        case "EDebtType":
            switch (enumId) {
                case 13201: result = "Harç"; break;
                case 13202: result = "Kimlik Ücreti"; break;
                case 13203: result = "Harç Faizi"; break;
                case 13204: result = "Sınav Ücreti"; break;
                case 13205: result = "Enstitü Harç"; break;
                case 13206: result = "İkinci Öğretim Harç"; break;
                case 13207: result = "Uzaktan Eğitim Harç"; break;
                case 13208: result = "Sigorta Bedeli"; break;
                case 13209: result = "Yabancı Uyruklu Başvuru Ücreti"; break;
                case 13210: result = "Materyal Ücreti"; break;
                case 13211: result = "Kredi Harç Farkı"; break;
                case 13212: result = "Uzaktan Eğitim Ders Ücreti"; break;
            }
            break;
        case "EDebtTypes":
            switch (enumId) {
                case 32002001: result = "Harç"; break;
                case 32002002: result = "Yurt"; break;
                case 32002003: result = "Depozito"; break;
                case 32002004: result = "Eğitim Bakiye"; break;
                case 32002005: result = "AKTS-1"; break;
                case 32002006: result = "AKTS-2"; break;
                case 32002007: result = "Yaz Okulu"; break;
                case 32002008: result = "667 KHK"; break;
                case 32002009: result = "Ders Ücreti-1"; break;
                case 32002010: result = "Bilimsel Hazırlık"; break;
                case 32002011: result = "Tez Ücreti"; break;
                case 32002012: result = "Hazırlık Kur"; break;
                case 32002013: result = "Ders Ücreti-2"; break;
                case 32002014: result = "Çap"; break;
                case 32002015: result = "Yandal"; break;
                case 32002016: result = "Tez Fark Ücreti"; break;
                case 32002017: result = "Yurt Yaz Okulu"; break;
                case 32002018: result = "Sertifika Programı"; break;
                case 32002019: result = "Ücret Farkı"; break;
                case 32002020: result = "Yurt Yemek Kahvaltı"; break;
                case 32002021: result = "Diğer"; break;
                case 32002022: result = "Eğitim İade"; break;
                case 32002023: result = "Cübbe Kiralama"; break;
                case 32002024: result = "Besyo Sınav"; break;
                case 32002025: result = "Yurt Günlük"; break;
                case 32002026: result = "İzutem-Kur"; break;
                case 32002027: result = "İzutem-Sınav"; break;
                case 32002028: result = "İzutem-Sınav Tekrarı"; break;
            }
            break;
        case "PermissionAuthorityType":
            switch (enumId) {
                case 17501: result = "Rektörlük Oluru"; break;
                case 17502: result = "YKK"; break;
            }
            break;

        case "ESuccessStatus":
            switch (enumId) {
                case 1: result = "Asil Kazandı"; break;
                case 2: result = "Yedek Kazandı"; break;
                default: result = "Kazanamadı"; break;
            }
            break;

        case "EStudentRegistrationPhase":
            switch (enumId) {
                case -2: result = "Kayıtlanma Dönemi Dışında"; break;
                case -1: result = "Sisteme Girmemiş"; break;
                case 1: result = "Ders Seçimi"; break;
                case 2: result = "Danışman Onayında"; break;
                case 3: result = "Danışman İnceleme"; break;
                case 4: result = "Öğrenci Onayında"; break;
                case 5: result = "Danışman Onayladı"; break;
                case 6: result = "Kayıt Tamamlandı"; break;
                case 7: result = "Yaz Okulu Ön Kayıt"; break;
                case 8: result = "Yaz Okulu Kesin Kayıt"; break;
            }
            break;
        case "EStudentAttendanceStatus":
            switch (enumId) {
                case 14201: result = "Devamlı"; break;
                case 14202: result = "Devamsız"; break;
            }
            break;

        case "EPrepStudentSuccessStatus":
            switch (enumId) {
                case 19001: result = "Başarılı"; break;
                case 19002: result = "Başarısız"; break;
                case 19003: result = "Muaf"; break;
            }
            break;

        case "EPrepForeignLanguageExamType":
            switch (enumId) {
                case 11901: result = "Dinleme-Anlama"; break;
                case 11902: result = "Yazma"; break;
                case 11903: result = "Okuma-Anlama"; break;
                case 11904: result = "Dil Yapısı"; break;
                case 11905: result = "Konuşma"; break;
            }
            break;
        case "EFormObjectType":
            switch (enumId) {
                case 15709:
                    result = "Sorular";
                    break;
                case 15706:
                    result = "Kitapçık Kodu";
                    break;
                case 15703:
                    result = "Sınıf Kodu";
                    break;
                case 15707:
                    result = "Sınav Kodu";
                    break;
                case 15708:
                    result = "Sınav Tarihi";
                    break;
                case 15702:
                    result = "Kimlik No";
                    break;
                case 15704:
                    result = "Ad";
                    break;
                case 15701:
                    result = "Öğrenci No";
                    break;
                case 15705:
                    result = "Soyad";
                    break;
                default:
                    break;
            }
            break;

        case "EEducationQualificationDegree":
            switch (enumId) {
                case 10601: return "Ön Lisans";
                case 10602: return "Lisans";
                case 10603: return "Tezli Yüksek Lisans";
                case 10604: return "Doktora";
                case 10605: return "Tezsiz Yüksek Lisans";
                case 10606: return "Hazırlık";
                case 1000000179: return "Uzmanlık";
            }
            break;

        case "EApplicationType":
            switch (enumId) {
                case 1: return "Enstitü";
                case 2: return "Uluslararası Öğrenci";
                case 3: return "Lisansüstü Yatay Geçiş";
                case 31: return "Tezsiz Lisansüstünden Tezliye Yatay Geçiş";
                case 4: return "Lisans Yatay Geçiş";
                case 41: return "Kurumlararası Yatay Geçiş";
                case 42: return "Kurumiçi Yatay Geçiş";
                case 43: return "Merkezi Yerleştirme Yatay Geçiş";
                case 44: return "Yurtdışı Üniversiteden Yatay Geçiş";
                case 5: return "ÇAP Başvurusu";
                case 7: return "Farabi Başvurusu";
                case 8: return "Mevlana Başvurusu";
                case 9: return "Erasmus Başvurusu";
                case 10: return "Formasyon Başvurusu";
                case 11: return "Özel Yetenek Sınavı";
                case 12: return "Güzel Sanatlar Yetenek Sınavı Başvurusu";
                case 13: return "Yaz Okulu Misafir Öğrenci Başvurusu";
                case 14: return "Yabancı Dil Sınavı Başvurusu";
                case 19: return "Eğitim Fakültesi Özel Yetenek Sınavı Başvurusu";
                case 20: return "Devlet Konservatuvarı Yetenek Sınavı";
            }
            break;

        case "EStudentDocumentRequestStatus":
            switch (enumId) {
                case 19901: return "Beklemede";
                case 19902: return "Onaylandı";
                case 19903: return "Reddedildi";
                case 19904: return "İptal Edildi";
            }
            break;

        case "EAdvisoryEventType":
            switch (enumId) {
                case 21301: return "Danışmanlık Toplantısı";
            }
            break;

        case "EFiscalRequestStatus":
            switch (enumId) {
                case 32000401: return "Değerlendiriliyor";
                case 32000402: return "Reddedildi";
                case 32000403: return "Onaylandı";
                case 32000404: return "Yeni";
            }
            break;
        case "ERebateRequestStatus":
            switch (enumId) {
                case 32000501: return "Değerlendiriliyor";
                case 32000502: return "Reddedildi";
                case 32000503: return "Onaylandı";
                case 32000504: return "Yeni";
            }
            break;
        case "EPaymentBankType":
            switch (enumId) {
                case 32000701: return "Ots";
                case 32000702: return "Havale";
                case 32000703: return "Pos";
                case 32000705: return "Mali Onay Taksit";
            }
            break;
        case "EPaymentType":
            switch (enumId) {
                case 32000601: return "Peşin";
                case 32000602: return "Taksit";
            }
            break;
        case "ERebateType":
            switch (enumId) {
                case 32002101: return "İlişik Kesme";
                case 32002102: return "Sehven Ödeme";
                case 32002103: return "Fazla Ödeme";
            }
            break;

        case "ECancelBankStatus":
            switch (enumId) {
                case 32002401: return "Bekliyor";
                case 32002402: return "Başarılı";
                case 32002403: return "Başarısız";
                case 32002404: return "GünSonuTekrarDenenecek";
                case 32002405: return "İşlemde";
                case 32002406: return "Havale/Eft ile Ödenecek";
                case 32002407: return "Havale/Eft ile Ödendi";
            }
            break;

        case "ECurrencyType":
            switch (enumId) {
                case 32001501: return "TRY";
                case 32001502: return "EUR";
                case 32001503: return "USD";
            }
            break;
        case "EScholarshipAssigmentStatus":
            switch (enumId) {
                case 32003100: return "Burs kesildi";
                case 32003101: return "Burs Aktif";
                case 32003102: return "Burs Verilme Süresi Sona Ermiştir";
            }
            break;

        case "EEducationQualify":
            switch (enumId) {
                case 10601: result = "Önlisans"; break;
                case 10602: result = "Lisans"; break;
                case 10603: result = "Tezli Yüksek Lisans"; break;
                case 10604: result = "Doktora"; break;
                case 10605: result = "Tezsiz Yüksek Lisans"; break;
                case 10606: result = "Hazırlık"; break;
                case 10608: result = "Formasyon"; break;
                case 10609: result = "Tömer"; break;
                case 10610: result = "Lisans Bilimsel Hazırlık"; break;
                case 10611: result = "Yaz Okulu"; break;
                case 1000000179: result = "Uzmanlık"; break;
            }
            break;

        case "EProcessStatus":
            switch (enumId) {
                case 32003001: result = "Bekliyor"; break;
                case 32003002: result = "Başarılı"; break;
                case 32003003: result = "Başarısız"; break;
                case 32003004: result = "İşlemde"; break;
                case 32003005: result = "İptal Edilemez"; break;
                case 32003006: result = "Uyumda Burs Bulunamadı"; break;
                case 32003007: result = "Tekrar Gönderilecek"; break;

                default: result = "Bekliyor"; break;
            }
            break;
    }
    return result;
}

function getEnumDescription(enumName, enumId) {
    enumId = parseInt(enumId);
    var result = "";

    switch (enumName) {
        case "RegistrationPhase":
            switch (enumId) {
                case -2: result = _resx.KayitlanmaDonemiDisinda; break;
                case -1: result = "Öğrenci Henüz Üniversite Bilgi Yönetim Sistemine Girmemiştir."; break;
                case 1: result = "Öğrenci Ders Seçimi Aşamasındadır."; break;
                case 2: result = "Danışman Henüz Onay Vermedi."; break;
                case 3: result = "Danışman Öğrencinin Dersleri Üzerinde Değişiklik Yapıyor."; break;
                case 4: result = "Danışman Yaptığı Değşiklikleri Öğrencinin Onayına Gönderdi. Öğrenciden Onay Bekleniyor. "; break;
                case 5: result = "Danışman Öğrencinin Ders Seçimlerini Onayladı."; break;
                case 6: result = _resx.KayitTamamlandi; break;
                case 7: result = _resx.YazOkuluOnKayit; break;
                case 8: result = _resx.YazOkulKesinKayit; break;
            }
            break;
    }
    return result;
}

function getExamName(typeId) {
    var result = "";
    switch (typeId) {
        case 1: result = "Giriş Sınavı"; break;
        case 2: result = "Yabancı Dil Sınavı"; break;
        case 3: result = "Mülakat"; break;
        case 4: result = "Diploma Lisans"; break;
        case 5: result = "Diploma Yüksek Lisans"; break;
        case 6: result = "Bilim Sınavı"; break;
        case 7: result = "Türkçe Sınavı"; break;
        case 8: result = "Yabancı Uyruklu Sınavları"; break;
        case 9: result = "Lisans - Yüksek Lisans Diploma Notu"; break;
        case 10: result = "Mühendislik Tamamlama"; break;
        case 11: result = "Branş Sınavı"; break;
        case 12: result = "Güzel Sanatlar Yetenek Sınavı"; break;
        case 13: result = "İngilizce Sınavı"; break;
        case 14: result = "Almanca Sınavı"; break;
        case 15: result = "Fransızca Sınavı"; break;
        case 16: result = "Arapça Sınavı"; break;
        case 17: result = "Portfolyo Değerlendirmesi"; break;
        case 18: result = "BAİBU ULÖS"; break;
        case 19: result = "Eğitim Fakültesi Özel Yetenek Sınavı Başvurusu"; break;
        case 20: return "Devlet Konservatuvarı Yetenek Sınavı"; break;
    }
    return result;
}

function getSuccessStatusName(statusId) {
    if (currentCultureId() == 2) {
        return $.Enumerable.From(InstituteSuccessStatuses).Any(function (x) { return x.Id == statusId })
            ? $.Enumerable.From(InstituteSuccessStatuses).Where(function (x) { return x.Id == statusId }).FirstOrDefault().engName : "";
    }
    else {
        return $.Enumerable.From(InstituteSuccessStatuses).Any(function (x) { return x.Id == statusId })
            ? $.Enumerable.From(InstituteSuccessStatuses).Where(function (x) { return x.Id == statusId }).FirstOrDefault().Name : "";
    }
}

//EInstituteClass içeriği direk enum karşılığı
function getClassString(_class) {
    var result = "";
    if (_class > 0 && _class < 9) { result = _class.toString(); }
    else {
        switch (parseInt(_class)) {
            case 0: result = "Yabancı Dil Hazırlık"; break;
            case 9: result = "Ders Aşaması"; break;
            case 10: result = "Tez Aşaması"; break;
            case 11: result = "Doktora Yeterlik Aşaması"; break;
            case 12: result = "Lisansüstü Bilimsel Hazırlık"; break;
            case 13: result = "Özel Öğrenci"; break;
            case 14: result = "Proje Aşaması"; break;
            case 15: result = "Türkçe Dil Hazırlık"; break;
            case 16: result = "Lisans Bilimsel Hazırlık"; break;
            case 17: result = "Türkçe Hazırlık"; break;
            case 18: result = "Yabancı Dil Hazırlık"; break;
        }
    }
    return result;
}

//sınıfın manipüle edilmiş hali. //manipülasyon yok kaldırıyoruz.
function getManipulatedClassString(_class, mainEduDegree, prepEduDegree, prepProgramType, prepLangId) {
    var result = _class.toString();
    var isInstitute = mainEduDegree == 10603 || mainEduDegree == 10604 || mainEduDegree == 10605;
    if (_class == 9 && isInstitute)
        result = "Ders Aşaması";
    else if (_class == 10 && isInstitute)
        result = "Tez Aşaması";
    else if (_class == 11 && isInstitute)
        result = "Doktora Yeterlilik";
    else if (_class == 12 && isInstitute)
        result = "Lisansüstü Bilimsel Hazırlık";
    else if (_class == 13)
        result = "Özel Öğrenci";
    else if (_class == 14)
        result = "Proje Aşaması";
    else if (_class == 15)
        result = "Türkçe Dil Hazırlık";
    else if (_class == 16)
        result = "Lisans Bilimsel Hazırlık";
    else if (prepProgramType == 10506)
        result = "Bilimsel Hazırlık";
    else if ((prepEduDegree == 10609) || (prepEduDegree == 10606 && prepLangId == 18801))
        result = "Türkçe Dil Hazırlık";
    else if (prepEduDegree == 10606)
        result = "Yabancı Dil Hazırlık";

    return result;
}

var InstituteSuccessStatuses = [
    { Id: 1, Name: "Kazandı", engName: "Won" },
    { Id: 2, Name: "Yedek", engName: "Replacement" },
    { Id: 3, Name: "Kazanamadı (Mülakat Notu Yetersiz)", engName: "Not Won (Interview Score Not Enough)" },
    { Id: 4, Name: "Kazanamadı (Başarı Notu Yetersiz)", engName: "Not Won (Success Score Not Enough)" },
    { Id: 5, Name: "Kazanamadı", engName: "Not Won" },
    { Id: 6, Name: "Mülakata Girmedi", engName: "Not Entered Interview Score Not Enough" },
    { Id: 7, Name: "Başvuru Reddedildi", engName: "Application Rejected" },
    { Id: 8, Name: "Mülakata Girmedi Başarısız", engName: "Not Attended to Interview, unsuccessful" },
    { Id: 9, Name: "Bilim Sınava Girmedi", engName: "Did not entered The science exam, unsuccessful" },
    { Id: 10, Name: "Bilim Sınavı Yetersiz", engName: "The science exam score not enough" },
    { Id: 11, Name: "Mülakata Girecek", engName: "Will be Interview" },
    { Id: 12, Name: "Türkçe Sınavına Girmedi", engName: "Did not entered The Turkish exam, unsuccessful" },
    { Id: 13, Name: "Türkçe Sınavı Yetersiz", engName: "The Turkish exam score not enough" },
    { Id: 14, Name: "Portfolyo Sınavına Girmedi", engName: "Did not entered The Portfolyo exam, unsuccessful" },
    { Id: 15, Name: "Portfolyo Sınavı Yetersiz", engName: "The Portfolyo exam score not enough" },
    { Id: 16, Name: "Yabancı Dil Sınavına Girmedi", engName: "Did not entered The Foreign Language exam, unsuccessful" },
    { Id: 17, Name: "Yabancı Dil Sınavı Yetersiz", engName: "The Foreign Language exam score not enough" },
    { Id: 18, Name: "Kesin Kayıt Yapmadı", engName: "Not completed regsitration" },
    { Id: 19, Name: "Kazanamadı (Farklı programı kazandı)", engName: "Not Won (You won anothor application)" },
    { Id: 20, Name: "Başvuru Kabul Edildi", engName: "Application Accepted" }


];

function getAppliedClassName(id) {
    switch (parseInt(id)) {

        case 99: return "Hazırlık Sınıfı";
        case 1: return "1. Sınıf Güz Dönemi";
        case 2: return "1. Sınıf Bahar Dönemi";
        case 3: return "2. Sınıf Güz Dönemi";
        case 4: return "2. Sınıf Bahar Dönemi";
        case 5: return "3. Sınıf Güz Dönemi";
        case 6: return "3. Sınıf Bahar Dönemi";
        case 7: return "4. Sınıf Güz Dönemi";
        case 8: return "4. Sınıf Bahar Dönemi";
        case 9: return "5. Sınıf Güz Dönemi";
        case 10: return "5. Sınıf Bahar Dönemi";
        case 11: return "6. Sınıf Güz Dönemi";
        case 12: return "6. Sınıf Bahar Dönemi";
    }
    return id;
}

function getMilliStr(id) {
    var milli = "";
    if (id) {
        if (_customerId == 113) {
            switch (id) {
                case 1: milli = "(A Sınıfı) İlk üç derece"; break;
                case 2: milli = "(A Sınıfı) Katılma"; break;
                case 3: milli = "(B Sınıfı) Birinci"; break;
                case 4: milli = "(B Sınıfı) İkinci"; break;
                case 5: milli = "(B Sınıfı) Üçüncü"; break;
                case 6: milli = "(C Sınıfı) Birinci"; break;
                case 7: milli = "(C Sınıfı) İkinci"; break;
                case 8: milli = "(C Sınıfı) Üçüncü"; break;
                case 9: milli = "(B Sınıfı) Katılım"; break;
                case 10: milli = "(C Sınıfı) Katılım"; break;
            }
        }
        else if (_customerId == 102) {
            switch (id) {
                case 1: milli = "A MİLLİ"; break;
                case 2: milli = "B MİLLİ"; break;
                case 3: milli = "C MİLLİ"; break;
                case 4: milli = "2 Yıl ve üzeri tescilli lisansı olanlar"; break;
                case 5: milli = "3 Yıl ve üzeri tescilli lisansı olanlar"; break;
                case 6: milli = "4 Yıl ve üzeri tescilli lisansı olanlar"; break;
                case 11: milli = "5 Yıl ve üzeri tescilli lisansı olanlar"; break;
                case 7: milli = "Spor lisansı olmayan adaylar"; break;
            }

        }
        else {
            switch (id) {
                case 1: milli = "A Milli"; break;
                case 2: milli = "B Milli"; break;
                case 3: milli = "C Milli"; break;
            }
        }
    }
    return milli;
}

//************************************************************************
//*************************************   Enumlar ************************
//************************************************************************

//************************************************************************
//*************************************   Enumsal Combo ******************
//************************************************************************

//verilen lookup tipinde comboBoc doner
function getLookupCombo(lookupListItems, lookupListId, selectedId, thisId, addSelect) {
    var result = "<select id='" + thisId + "' class='form-control input-sm'>";
    if (addSelect) {
        result += "<option value='0'>" + _resx.Select + "</option>";
    }
    if (lookupListItems != nulll && lookupListItems.length > 0 && lookupListId && parseInt(lookupListId) > 0 && $.Enumerable.From(lookupListItems).Any(function (x) { return x.LookupListId == lookupListId })) {
        $.Enumerable.From(lookupListItems).Where(function (x) { return x.LookupListId == lookupListId }).ForEach(function (item) {
            var name = item.Name;

            if (currentCultureId() != 1 && item.Languages != null && $.Enumerable.From(item.Languages).Any(function (x) { return x.CultureId == currentCultureId() })) {
                name = $.Enumerable.From(item.Languages).Where(function (x) { return x.CultureId == currentCultureId() }).FirstOrDefault().Name;
            }
            result += "<option value='" + item.Id + "' " + (selectedId && parseInt(selectedId) == item.Id ? "selected='selected'" : "") + ">" + name + "</option>";
        });
    }
    result += "</select>";
    return result;
}

//verilen limit kadar sayı içeren comboBox doner
function getNumberCombo(itemId, selectedId, limit, dontAddSelect, onchange) {
    var result = "<select id='" + itemId + "' class='form-control input-sm'" + (onchange ? "onchange='" + onchange + "(\"" + itemId + "\")'" : "") + ">";
    if (!dontAddSelect) {
        result += "<option value='0'>" + _resx.Select + "</option>";
    }

    for (var i = 1; i <= limit; i++) {
        result += "<option value='" + i + "' " + (selectedId && parseInt(selectedId) == i ? "selected='selected'" : "") + ">" + i.toString() + "</option>";
    }

    result += "</select>";
    return result;
}

//basvuru basarı durumu comboBox ı doner
function getSuccessStatusCombo(itemId, selectedId, onchange) {
    var result = "<select id='" + itemId + "' class='form-control input-sm' " + (onchange ? "onchange='" + onchange + "(\"" + itemId + "\")'" : "") + ">";
    result += "<option value='0'>" + _resx.Select + "</option>";
    $.Enumerable.From(InstituteSuccessStatuses).ForEach(function (item) {
        result += "<option value='" + item.Id + "' " + (selectedId && selectedId == item.Id ? "selected='selected'" : "") + ">" + item.Name + "</option>";
    });
    result += "</select>";
    return result;
}

//************************************************************************
//*************************************   Enumsal Combo ******************
//************************************************************************


//************************************************************************
//***************************  Yöksis Aktarım Enumları *******************
//************************************************************************
var YoksisBelgeTuru = [
    { Id: 0, Name: "Umuma Mahsus Pasaport" },
    { Id: 1, Name: "Hususi Pasaport" },
    { Id: 2, Name: "Hizmet Pasaport" },
    { Id: 3, Name: "Diplomatik Pasaport" },
    { Id: 4, Name: "Mültecilere Mahsus Seyahat Belgesi" },
    { Id: 5, Name: "Ulusal Kimlik Kartı" },
    { Id: 6, Name: "Diğer" },
];
function getYoksisStatusName(id) {
    var result = "";
    if (id != undefined && id != "" && parseInt(id) > 0) {
        result = id.toString();
        switch (parseInt(id)) {
            case 1: result = "Aktif Öğrenci"; break;
            case 2: result = "İzinli/Kayıt Dondurma"; break;
            case 3: result = "Cezalı"; break;
            case 7: result = "Beklemeli"; break;
            case 10: result = "Pasif Öğrenciler (Kayıt Yenilememiş)"; break;
            case 11: result = "Farabi(Giden)"; break;
            case 12: result = "Farabi(Gelen)"; break;
            case 13: result = "Mevlana(Giden)"; break;
            case 14: result = "Mevlana(Gelen)"; break;
            case 15: result = "Erasmus(Giden)"; break;
            case 16: result = "Erasmus(Gelen)"; break;
            case 17: result = "Özel Öğrenci(Giden)"; break;
            case 18: result = "Özel Öğrenci(Gelen)"; break;
            case 19: result = "Diğer değişimler-Yurtdışı (Giden)"; break;
            case 20: result = "Diğer değişimler-Yurtdışı (Gelen)"; break;
            case 21: result = "Kaydı silinen öğrenciler"; break;
        }
    }
    return result;
}
function getYoksisClass(id) {
    var result = "";
    if (id != undefined && id != "" && parseInt(id) > 0) {
        result = id.toString();
        switch (parseInt(id)) {
            case 1: result = "Hazırlık"; break;
            case 2: result = "1.Sınıf"; break;
            case 3: result = "2.Sınıf"; break;
            case 4: result = "3.Sınıf"; break;
            case 5: result = "4.Sınıf"; break;
            case 6: result = "5.Sınıf"; break;
            case 7: result = "6.Sınıf"; break;
            case 8: result = "İntibak"; break;
            case 9: result = "Ders Aşaması"; break;
            case 10: result = "Tez Aşaması"; break;
            case 11: result = "Doktora Yeterlik"; break;
            case 12: result = "Bilimsel Hazırlık"; break;
            case 13: result = "Özel Öğrenci"; break;
            case 14: result = "Proje Aşaması"; break;
            case 15: result = "Türkçe Dil Hazırlık"; break;
            case 16: result = "Lisans Bilimsel Hazırlık"; break;
        }
    }
    return result;
}
function getYoksisBitStatusName(id, VarYok) {
    var result = "";
    if (id != undefined && id != "" && parseInt(id) > 0) {
        result = id.toString();
        if (parseInt(id) == 1) {
            if (VarYok) {
                result = "Var";
            }
            else {
                result = "Evet";
            }
        }
        else {
            if (VarYok) {
                result = "Yok";
            }
            else {
                result = "Hayır";
            }
        }
    }
    return result;
}
function getYoksisDOYKM(id) {
    var result = "";
    if (id != undefined && id != "" && parseInt(id) > 0) {
        result = id.toString();
        switch (parseInt(id)) {
            case 2: result = "Hayır"; break;
            case 3: result = "ÖnLisans"; break;
            case 4: result = "Lisans"; break;
            case 5: result = "Yüksek Lisans"; break;
            case 6: result = "Doktora"; break;
            case 7: result = "Sanatta Yeterlilik"; break;
            case 8: result = "Tıpta Uzmanlık"; break;
            case 9: result = "Diş Hekimliğinde Uzmanlık"; break;
        }
    }
    return result;
}
function getYoksisDisabledName(id) {
    var result = "";
    if (id != undefined && id != "" && parseInt(id) > 0) {
        result = id.toString();
        switch (parseInt(id)) {
            case 1: result = "Görme Engelliler "; break;
            case 2: result = "İşitme Engelliler "; break;
            case 3: result = "Fiziksel Engelliler"; break;
            case 4: result = "Dil ve Konuşma Problemliler"; break;
            case 5: result = "Dikkat Eksikliği (Hiperaktif)"; break;
            case 6: result = "Psikolojik Problemliler"; break;
            case 7: result = "Zihinsel Engelliler"; break;
            case 8: result = "Öğrenme Güçlüğü"; break;
            case 9: result = "Kronik Sağlık Sorunları"; break;
            case 10: result = "Asperger veya Yüksek Fonksiyonlu Otistik Bireyler"; break;
            case 11: result = "Geçici Yetersizlikleri Olanlar"; break;
            case 12: result = "Diğer "; break;
        }
    }
    return result;
}
function getYoksisLeaveReasonName(id) {
    var result = "";
    if (id != undefined && id != "" && parseInt(id) > 0) {
        result = id.toString();
        switch (parseInt(id)) {
            case 4: result = "Disiplin cezası"; break;
            case 5: result = "Kendi isteği"; break;
            case 6: result = "Diğer"; break;
            case 8: result = "Vefat"; break;
            case 9: result = "Mezuniyet"; break;
            case 11: result = "Yatay Geçiş - Üniversite İçi"; break;
            case 12: result = "Yatay Geçiş - Üniversite Dışı"; break;
            case 13: result = "Yabancı Dil Hazırlık Sınıfında Başarısızlık"; break;
            case 14: result = "Lisans Programından Önlisans Diploması Alarak Mezuniyet"; break;
            case 15: result = "Zorunlu Yabancı Dil Hazırlık Sınıflarında Başarısız Olan Öğrenci"; break;
            case 16: result = "Farabi"; break;
            case 17: result = "Mevlana"; break;
            case 18: result = "Erasmus"; break;
            case 19: result = "Özel Öğrenci"; break;
            case 20: result = "Diğer Değişimler-Yurtdışı"; break;
            case 21: result = "Denklik Lisans tamamlaması sona eren"; break;
            case 22: result = "İzinli/Kayıt Dondurma"; break;
            case 23: result = "667 sayılı KHK kapsamında"; break;
            case 24: result = "Geçici kayıt (Lise Diploması Olmayanlar) ile kayıtlananların belirtilen tarihe kadar diplomalarını getirememesi"; break;
            case 25: result = "Üniversite/Fakülte/MYO/YO/Bölüm isim değişikliğinden dolayı aktarım"; break;
            case 26: result = "667 KHK kapsamında ÖSYM tarafından yerleştirilen öğrencilerin koordinatör üniversitelerden ilişik kesmeleri"; break;
            case 27: result = "Yatay Geçiş - Üniversite İçi-Ek Madde 1"; break;
            case 28: result = "Yatay Geçiş - Üniversite Dışı-Ek Madde 1"; break;
            case 29: result = "Tezli YüksekLisans Programından Tezsiz YüksekLisans Diploması Alarak Mezuniyet"; break;
            case 30: result = "Sahte Belge Sebebi İle Kayıt İptali"; break;
            case 31: result = "YÖK Kararı ile aktarma"; break;
            case 32: result = "Bakanlar Kurulu kararı ile aktarma"; break;
            case 33: result = "Bilimsel Hazırlık Sınıfında Başarısızlık"; break;
            case 34: result = "Yatay geçişten kendi isteği ile vazgeçme"; break;
            case 35: result = "TEBİB Özel Öğrenci"; break;
            case 36: result = "Gençlik, Spor Hizmet ve Faaliyetlerinde İşbirliği Protokolü"; break;
            case 37: result = "Internal Transfer"; break;
        }
    }
    return result;
}
function getYoksisEntryPointType(id) {
    var result = "";
    if (id != undefined && id != "" && parseInt(id) > 0) {
        result = id.toString();
        switch (parseInt(id)) {
            case 1: result = "YGS 1"; break;
            case 2: result = "YGS 2"; break;
            case 3: result = "YGS 3"; break;
            case 4: result = "YGS 4"; break;
            case 5: result = "YGS 5"; break;
            case 6: result = "YGS 6"; break;
            case 7: result = "DİL 1"; break;
            case 8: result = "DİL 2"; break;
            case 9: result = "DİL 3"; break;
            case 10: result = "TM 1"; break;
            case 11: result = "TM 2"; break;
            case 12: result = "TM 3"; break;
            case 13: result = "MF 1"; break;
            case 14: result = "MF 2"; break;
            case 15: result = "MF 3"; break;
            case 16: result = "MF 4"; break;
            case 17: result = "TS1"; break;
            case 18: result = "TS2"; break;
            case 19: result = "SAY 1"; break;
            case 20: result = "SAY 2"; break;
            case 21: result = "SÖZ 1"; break;
            case 22: result = "SÖZ 2"; break;
            case 23: result = "EA 1"; break;
            case 24: result = "EA 2"; break;
            case 25: result = "SAT 1 "; break;
            case 26: result = "ACT"; break;
            case 27: result = "Abitur"; break;
            case 28: result = "GCE  A Level Sertifika"; break;
            case 29: result = "DİĞER"; break;
        }
    }
    return result;
}
function getYoksisRecordType(id, recordOriginal = 0) {
    var result = "";
    if (id != undefined && id != "" && parseInt(id) > 0) {
        result = id.toString();
        switch (parseInt(id)) {
            case 1: result = "ÖSYS"; break;
            case 2: result = "Sınavsız Geçiş"; break;
            case 3: result = "Yatay Geçiş - Kurumiçi"; break;
            case 4: result = "Yatay Geçiş - Kurumlararası-Yurtiçi"; break;
            case 5: result = "DGS"; break;
            case 6: result = "Yetenek Sınavı"; break;
            case 13: result = "Erasmus"; break;
            case 14: result = "Leonardo"; break;
            case 18: result = "Diğer Değişimler-Yurtdışı İşbirliği Protokolü"; break;
            case 19: result = "Özel Öğrenci"; break;
            case 20: result = "Zorunlu Yabancı Dil Hazırlık Sınıflarında Başarısız Olan Öğrencilerin Türkçe Öğretim Yapan Yükseköğretim Programlarına Yerleştirilmeleri"; break;
            case 21: result = "Milli Sporcu"; break;
            case 23: result = "Farabi"; break;
            case 24: result = "KKTC Yerleştirme (YÖK)"; break;
            case 27: result = "Sınavsız İkinci üniversite"; break;
            case 28: result = "Mevlana"; break;
            case 29: result = "Ortak Programdan Diploma Programına Geçiş"; break;
            case 30: result = "Yatay Geçiş - Kurumlararası-Yurtdışı"; break;
            case 31: result = "Türkiye Burslusu"; break;
            case 33: result = "İslam Kalkınma Bankası Burslusu"; break;
            case 35: result = "İkili Anlaşma (Hükümetler arası)"; break;
            case 36: result = "İkili Anlaşma (Üniversiteler arası)"; break;
            case 37: result = "Doktora"; break;
            case 38: result = "Çift Anadal"; break;
            case 39: result = "Sanatta Yeterlilik"; break;
            case 40: result = "KKTC Devlet Burslusu"; break;
            case 43: result = "Denklik Lisans tamamlama programı ile gelen öğrenciler"; break;
            case 45: result = "6353 sayılı Kanun 12.07.2012"; break;
            case 46: result = "Üniversite içi İç Sınav (Galatasaray)"; break;
            case 47: result = "Mühendislik Lisans Tamamlama"; break;
            case 48: result = "TUBİTAK ile Yerleşenler"; break;
            case 53: result = "3804 sayılı Kanun 01.06.1992"; break;
            case 54: result = "3908 sayılı Kanun 12.05.1995"; break;
            case 55: result = "4111 sayılı Kanun 12.06.1995"; break;
            case 56: result = "4305 sayılı Kanun 18.08.1997"; break;
            case 57: result = "4584 sayılı Kanun 28.06.2000"; break;
            case 58: result = "5316 sayılı Kanun 18.03.2005"; break;
            case 59: result = "5806 sayılı Kanun 22.10.2008"; break;
            case 60: result = "6111 sayılı Kanun 25.02.2011"; break;
            case 61: result = "Yüksek Lisans"; break;
            case 62: result = "ÖYP"; break;
            case 63: result = "Bütünleşik Doktora"; break;
            case 64:
                switch (parseInt(recordOriginal)) {
                    case 20709: result = "Tekrardan aynı programa Kayıt (AGNO)"; break;
                    case 20710: result = "Tekrardan aynı programa Kayıt (Af)"; break;
                    case 20711: result = "Tekrardan aynı programa Kayıt (Ek Madde-1)"; break;
                    default: result = "Yatay Geçiş Ek Madde-1"; break;
                }
                break;
            case 65: result = "Mütabakat zabtı / Uluslararası ikili anlaşmalar (Afganistan, Libya, Suudi Arabistan, Yemen hükümet burslusu)"; break;
            case 66: result = "Uluslararası İlahiyat Projesi"; break;
            case 67: result = "Yurt dışından kabul edilen öğrenci kontenjanlarına başvurup kendi imkanlarıyla eğitim almak isteyen öğrenci "; break;
            case 69: result = "Sınavsız Dikey Geçiş"; break;
            case 70: result = "Yatay Geçiş Ek Madde-2"; break;
            case 71: result = "YÖK Kararı ile aktarma"; break;
            case 72: result = "6569 Sayılı Kanun 26.11.2014"; break;
            case 73: result = "YÖK Polis Akademisi Öğrencileri Yerleştirme"; break;
            case 74: result = "Sağlık Alanında Lisans Tamamlama"; break;
            case 75: result = "Araştırma Görevlisi"; break;
            case 76: result = "YÖS-Af ile Gelenler"; break;
            case 77: result = "Türkiye Burslusu-Af ile Gelenler"; break;
            case 78: result = "Yurtdışı üniversitelerine ÖSYS dışı yerleştirme (KKTC üniversiteleri, Hoca Ahmet Yesevi vb.)"; break;
            case 79: result = "667 sayılı KHK kapsamında (Önlisans veya Lisans)"; break;
            case 80: result = "667 sayılı KHK kapsamında (Yükseklisans)"; break;
            case 81: result = "Geçici kayıt (Lise Diploması Olmayanlar)"; break;
            case 82: result = "3511 Sayılı Kanun 10.12.1988"; break;
            case 83: result = "3248 Sayılı Kanun 25.12.1985"; break;
            case 84: result = "667 sayılı KHK kapsamında kapatılan vakıf yükseköğretim kurumları öğrencilerinin ÖSYM Tarafından Yerleştirilmesi"; break;
            case 85: result = "Yatay Geçiş ile ayrılan ve sonradan geri dönüş yaparak tekrar kayıt olan öğrenciler"; break;
            case 86: result = "Mühendislik Lisans Tamamlama - Yatay Geçiş"; break;
            case 87: result = "667 KHK kapsamında Kapatılan Yükseköğretim Kurumları Öğrencilerinin Özel Öğrenci Olarak Kayıtlanması"; break;
            case 88: result = "669 KHK kapsamında Farklı Bir Yükseköğretim Kurumuna Aktarılan Askeri Öğrencilerin Kayıtlanması (Mezunlar)"; break;
            case 89: result = "44. Madde ile Eğitimine Geri Dönen Öğrenciler"; break;
            case 90: result = "669 KHK kapsamında ÖSYM tarafından yerleştirilen Askeri Lise Öğrencilerin Kayıtlanması ALÜGS"; break;
            case 91: result = "667 KHK kapsamında Kapatılan Yükseköğretim Kurumları Yabancı Kontenjanından Kayıtlanan Öğrencilerinin Kayıtlanması"; break;
            case 92: result = "669 KHK kapsamında Kapatılan Askeri Yükseköğretim Kurumları Öğrencilerinin YÖK tarafından yerleştirilerek Kayıtlanması"; break;
            case 93: result = "677 KHK Yüksek Lisans, Doktora Öğrenci yerleştirmeleri"; break;
            case 94: result = "100/2000 Doktora Bursu"; break;
            case 95: result = "Lisans Tamamlama"; break;
            case 96: result = "Gerekli çalışmalarını kapatılan üniversitede başarıyla tamamlayarak mezun olan öğrenciler"; break;
            case 97: result = "2984 Sayılı Kanun 04.11.1981"; break;
            case 98: result = "Üniversitelerarası Giriş İmtihanı"; break;
            case 99: result = "3713 Özel Öğrenci Statüsü"; break;
            case 100: result = "Diğer yükseköğretim kurumlarından yatay geçiş"; break;
            case 101: result = "Öncelikli Alanlar Araştırma Görevlileri"; break;
            case 102: result = "Hazırlık sınıfında 2 yıl başarısız olup ilişiği kesildikten sonra 3 sınav hakkından birinde başarılı olan öğrencinin aynı programa tekrar kayıt olması"; break;
            case 103: result = "ASELSAN Protokolü ile yerleşen öğrenci"; break;
            case 104: result = "TEBİB ÖZel Öğrenci"; break;
            case 105: result = "Gençlik, Spor Hizmet ve Faaliyetlerinde İşbirliği Protokolü ile yerleşen öğrenci"; break;
            case 106: result = "Denklik Belgesi olmadan Tanınırlık Belgesi ile Kayıt"; break;
            case 107: result = "Internal Transfer"; break;
            case 108: result = "YÖK Makedonya Burslusu"; break;
            case 109: result = "YÖK Kosova Burslusu"; break;
            case 110: result = "YÖK Arnavutluk Burslusu"; break;
            case 111: result = "Yüksek Lisans (Yurtdışı kontenjan)"; break;
            case 112: result = "Doktora (Yurtdışı kontenjan)"; break;
            case 113: result = "Bütünleşik Doktora (Yurtdışı kontenjan)"; break;
            case 114: result = "Sanatta Yeterlilik (Yurtdışı kontenjan)"; break;
            case 115: result = "Somali Uyruklu Öğrenciler (03.05.2017 tarihli resmi yazı ile Sağlık Bilimleri Üniversitesine verilen izin)"; break;
            case 116: result = "Klasik Yerleşen (Uluslararası Saraybosna Üniversitesi)"; break;
            case 117: result = "Eşdeğer Sınav ile Yerleşen Öğrenciler (Uluslararası Saraybosna Üniversitesi)"; break;
            case 118: result = "Koşullu Yerleşen Öğrenciler (Uluslararası Saraybosna Üniversitesi)"; break;
            case 119: result = "Eşdeğer Sınav ile Koşullu Yerleşen Öğrenciler (Uluslararası Saraybosna Üniversitesi)"; break;
            case 120: result = "YÖKSİS'e henüz entegre olamayan yurtiçi yükseköğretim kurumlarından yatay geçiş (TSK, GATA, Polis Akademisi vb)"; break;
            case 121: result = "Bütünleşik Sanatta Yeterlilik (Yurtiçi kontenjan)"; break;
            case 122: result = "Bütünleşik Sanatta Yeterlilik (Yurtdışı kontenjan)"; break;
            case 181: result = "06 Şubat 2023 Depremi Nedeniyle Özel Öğrencilik (YÖK Kararı)"; break;
            case 182: result = "06 Şubat 2023 Depremi Nedeniyle Öğretmenlik Uygulaması 2 dersi için Özel Öğrencilik (YÖK Kararı)"; break;
            case 183: result = "06 Şubat 2023 Depremi Nedeniyle Öğretmenlik uygulaması 2 dersi için Özel Öğrencilik"; break;
        }
    }
    return result;
}
function getYoksisHazirlikSinifiOkudumu(id) {
    var result = "";
    if (id != undefined && id != "" && parseInt(id) > 0) {
        result = id.toString();
        switch (id) {
            case 1: result = "Evet"; break;
            case 2: result = "Hayır"; break;
            case 3: result = "Muaf"; break;
            case 4: result = "Okuyor"; break;
        }
    }
    return result;
}
function getYoksisRestCezaId(id) {
    var result = "";
    if (id && parseInt(id) > 0) {
        result = id.toString();
        switch (id) {
            case 1: result = "Uyarma"; break;
            case 2: result = "Kınama"; break;
            case 3: result = "Yükseköğretim Kurumundan bir haftadan bir aya kadar uzaklaştırma"; break;
            case 4: result = "Yükseköğretim Kurumundan bir veya iki yarıyıl için uzaklaştırma"; break;
            case 5: result = "Yükseköğretim Kurumundan Çıkarılma"; break;
            case 6: result = "Hükümlü/Tutuklu"; break;
            case 7: result = "Yükseköğretim Kurumundan bir hafta uzaklaştırma"; break;
            case 8: result = "Yükseköğretim Kurumundan bir ay uzaklaştırma"; break;
            case 9: result = "Yükseköğretim Kurumundan bir yarıyıl uzaklaştırma"; break;
            case 10: result = "Yükseköğretim Kurumundan iki yarıyıl uzaklaştırma"; break;
            case 11: result = "Adli yargı hükmünün beklenilmesi ve adli yargı hükmü kesinleşene kadar üniversiteden uzaklaştırılması"; break;
        }
    }
    return result;
}
function getTeyitOgrenciDurum(id) {
    var result = "";
    if (id && parseInt(id) > 0) {
        result = id.toString();
        switch (id) {
            case 1: result = "Übysde olup Yöksiste Olmayan Öğrenci"; break;
            case 2: result = "Yöksiste olup Übys Sisteminde Olmayan Öğrenci"; break;
            case 3: result = "Öğrencinin Übys ve Yöksis durumları birbirinden farklıdır"; break;
            case 4: result = "Öğrencinin Yöksis üzerinde aynı birim için birden fazla kaydı bulunmaktadır"; break;
        }
    }
    return result;
}
function getYoksisBelgeTuru(id) {
    var result = "";
    if (id && parseInt(id) > 0) {
        result = id.toString();
        switch (id) {
            case 0: result = "Umuma Mahsus Pasaport"; break;
            case 1: result = "Hususi Pasaport"; break;
            case 2: result = "Hizmet Pasaport"; break;
            case 3: result = "Diplomatik Pasaport"; break;
            case 4: result = "Mültecilere Mahsus Seyahat Belgesi"; break;
            case 5: result = "Ulusal Kimlik Kartı"; break;
            case 6: result = "Diğer"; break;
        }
    }
    return result;
}
function getYoksisBelgeTuruCombo(itemId, selectedId, onchange) {
    var result = "<select id='" + itemId + "' class='form-control input-sm' " + (onchange ? "onchange='" + onchange + "(\"" + itemId + "\")'" : "") + ">";
    result += "<option value=''>" + _resx.Select + "</option>";
    $.Enumerable.From(YoksisBelgeTuru).ForEach(function (item) {
        result += "<option value='" + item.Id + "' " + (selectedId && selectedId == item.Id ? "selected='selected'" : "") + ">" + item.Name + "</option>";
    });
    result += "</select>";
    return result;
}
//************************************************************************
//***************************  Yöksis Aktarım Enumları *******************
//************************************************************************



//************************************************************************
//***************************  Yöksis Asal Enumları **********************
//************************************************************************
function getTabloName(id, tabloNo) {
    var res = "";
    if (id && !isNaN(id) && parseInt(id) > 0) {
        var items = [];
        switch (tabloNo) {
            case 1: items = getErtelemeSebepleriTablo1(); break;
            case 2: items = getErtelemeIptalSebepleriTablo2(); break;
            case 3: items = getSureUzatimSebepleriTablo3(); break;
            case 4: items = getRedSebepleriTablo4(); break;
        }
        var ras = $.Enumerable.From(items).FirstOrDefault(null, function (x) { return x.Id == id });
        if (ras != null) {
            res = ras.Name;
        }
        else { res = id.toString() + " (Bulunamadı)"; }
    }
    return res;
}
//ERTELEME_TEKLIF_NEDENLERI
function getErtelemeSebepleriTablo1(id) {
    var result = [];
    result.push({ Id: 501, Name: "YENİ KAYIT", Code: "10601,10602" });
    result.push({ Id: 502, Name: "AF KANUNU", Code: "10601,10602" });
    result.push({ Id: 503, Name: "UZATMA", Code: "10601,10602" });
    result.push({ Id: 504, Name: "YATAY GEÇİŞ", Code: "10601,10602" });
    result.push({ Id: 505, Name: "DİKEY GEÇİŞ", Code: "10601,10602" });
    result.push({ Id: 506, Name: "İKİ YIL ÜSTÜSTE SINIFTA KALDIKTAN SONRA BİR ÜST SINIFA GEÇENLER", Code: "10601,10602" });
    result.push({ Id: 507, Name: "DEVAM", Code: "10601,10602" });
    result.push({ Id: 508, Name: "MAHKEME KARARI", Code: "10601,10602" });
    result.push({ Id: 509, Name: "AZAMİ ÖĞRENİM SÜRESİ SONRASI", Code: "10601,10602" });
    result.push({ Id: 510, Name: "YENİ KAYIT (LİSE)", Code: "10601,10602" });
    result.push({ Id: 511, Name: "UZATMA (LİSE)", Code: "10601,10602" });
    result.push({ Id: 901, Name: "YURT İÇİ YÜKSEK LİSANS (TEZLİ)", Code: "10603,10604,10605" });
    result.push({ Id: 902, Name: "ORTA ÖĞRETİM ALAN ÖĞRETMENLİĞİ TEZSİZ YÜKSEK LİSANS", Code: "10603,10604,10605" });
    result.push({ Id: 903, Name: "YURT İÇİ DOKTORA (YÜKSEK LİSANS DERECESİ İLE)", Code: "10603,10604,10605" });
    result.push({ Id: 904, Name: "YURT İÇİ SANATTA YETERLİK (YÜKSEK LİSANS DERECESİ İLE)", Code: "10603,10604,10605" });
    result.push({ Id: 905, Name: "YURT İÇİ DİL ÖĞRENİMİ", Code: "10603,10604,10605" });
    result.push({ Id: 906, Name: "YURT İÇİ BİLİMSEL HAZIRLIK", Code: "10603,10604,10605" });
    result.push({ Id: 907, Name: "YURT İÇİ DOKTORA (LİSANS DERECESİ İLE)", Code: "10603,10604,10605" });
    result.push({ Id: 908, Name: "YURT İÇİ SANATTA YETERLİK (LİSANS DERECESİ İLE)", Code: "10603,10604,10605" });
    result.push({ Id: 909, Name: "YURT İÇİ YÜKSEK LİSANS (TEZSİZ)", Code: "10603,10604,10605" });
    result.push({ Id: 910, Name: "YURT İÇİ YÜKSEK LİSANS YENİ (TEZSİZ)", Code: "10603,10604,10605" });
    result.push({ Id: 911, Name: "YURT İÇİ DOKTORA YENİ  (LİSANS DERECESİ İLE)", Code: "10603,10604,10605" });
    result.push({ Id: 913, Name: "YURT İÇİ SANATTA YETERLİK YENİ (LİSANS DERECESİ İLE)", Code: "10603,10604,10605" });
    result.push({ Id: 914, Name: "UZATMA", Code: "10603,10604,10605" });
    result.push({ Id: 1301, Name: "TUS", Code: "TUS" });
    result.push({ Id: 1302, Name: "ADLİ TIP", Code: "TUS" });
    result.push({ Id: 1303, Name: "ADLİ TIP-TOKSİKOLOJİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1304, Name: "ANATOMİ", Code: "TUS" });
    result.push({ Id: 1305, Name: "AİLE HEKİMLİĞİ", Code: "TUS" });
    result.push({ Id: 1306, Name: "ANESTEZİYOLOJİ VE REANİMASYON", Code: "TUS" });
    result.push({ Id: 1307, Name: "ANESTEZİYOLOJİ VE REANİMASYON -ALGOLOJİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1308, Name: "ASKERİ SAHRA HEKİMLİĞİ", Code: "TUS" });
    result.push({ Id: 1309, Name: "BEYİN VE SİNİR CERRAHİSİ", Code: "TUS" });
    result.push({ Id: 1310, Name: "ÇOCUK CERRAHİSİ", Code: "TUS" });
    result.push({ Id: 1311, Name: "ÇOCUK CERRAHİSİ-COCUK ÜROLOJİSİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1312, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI", Code: "TUS" });
    result.push({ Id: 1313, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK KARDİYOLOJİSİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1314, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK METABOLİZME HST. YAN DALI", Code: "TUS" });
    result.push({ Id: 1315, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK ENDOKRİNOLOJİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1316, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK HEMATOLOJİSİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1317, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK NEFROLOJİSİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1318, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK NÖROLOJİSİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1319, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK ALERJİSİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1320, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK ONKOLOJİSİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1321, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK GASTRO YAN DALI", Code: "TUS" });
    result.push({ Id: 1322, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK HEPATOLOJİ VE BESLENME YAN DALI", Code: "TUS" });
    result.push({ Id: 1323, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK ENFEKSİYON HST. YAN DALI", Code: "TUS" });
    result.push({ Id: 1324, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK NEONATOLOJİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1325, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK GENETİK YAN DALI", Code: "TUS" });
    result.push({ Id: 1326, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK GÖGÜS HST. YAN DALI", Code: "TUS" });
    result.push({ Id: 1327, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK İMMÜNOLOJİSİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1328, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK YOGUN BAKIM YAN DALI", Code: "TUS" });
    result.push({ Id: 1329, Name: "ÇOCUK PSİKİYATRİSİ", Code: "TUS" });
    result.push({ Id: 1330, Name: "DERMATOLOJİ", Code: "TUS" });
    result.push({ Id: 1331, Name: "ENFEKSİYON HASTALIKLARI", Code: "TUS" });
    result.push({ Id: 1332, Name: "EMBRİYOLOJİ VE HİSTOLOJİ", Code: "TUS" });
    result.push({ Id: 1333, Name: "FİZİKSEL TIP VE REHABİLİTASYON", Code: "TUS" });
    result.push({ Id: 1334, Name: "FİZİKSEL TIP VE REHABİLİTASYON-RAMOTOLOJİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1335, Name: "FİZYOLOJİ", Code: "TUS" });
    result.push({ Id: 1336, Name: "GENEL CERRAHİ", Code: "TUS" });
    result.push({ Id: 1337, Name: "GENEL CERRAHİ-GASTROENTOLOJİ CERRAHİSİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1338, Name: "GÖĞÜS CERRAHİSİ", Code: "TUS" });
    result.push({ Id: 1339, Name: "GÖĞÜS HASTALIKLARI", Code: "TUS" });
    result.push({ Id: 1340, Name: "GÖĞÜS HASTALIKLARI-ALERJİK GÖGÜS HST.YAN DALI", Code: "TUS" });
    result.push({ Id: 1341, Name: "GÖĞÜS HASTALIKLARI-YOGUN BAKIM YAN DALI", Code: "TUS" });
    result.push({ Id: 1342, Name: "GÖZ HASTALIKLARI", Code: "TUS" });
    result.push({ Id: 1343, Name: "HALK SAĞLIĞI", Code: "TUS" });
    result.push({ Id: 1344, Name: "HALK SAĞLIĞI-EPİDEMİYOLOJİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1345, Name: "HALK SAĞLIĞI-ÇEVRE SAĞLIĞI YAN DALI", Code: "TUS" });
    result.push({ Id: 1346, Name: "HALK SAĞLIĞI-İŞYERİ HEKİMLİĞİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1347, Name: "HALK SAĞLIĞI-OKUL HEKİMLİĞİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1348, Name: "HAVA VE UZAY HEKİMLİĞİ", Code: "TUS" });
    result.push({ Id: 1349, Name: "İÇ HASTALIKLARI", Code: "TUS" });
    result.push({ Id: 1350, Name: "İÇ HASTALIKLARI-ALERJİ HST. YAN DALI", Code: "TUS" });
    result.push({ Id: 1351, Name: "İÇ HASTALIKLARI-Endokrinoloji ve Metabolizma Hst. YAN DALI", Code: "TUS" });
    result.push({ Id: 1352, Name: "İÇ HASTALIKLARI-Gastroenteroloji. YAN DALI", Code: "TUS" });
    result.push({ Id: 1353, Name: "İÇ HASTALIKLARI-Nefroloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1354, Name: "İÇ HASTALIKLARI-Romatoloji. YAN DALI", Code: "TUS" });
    result.push({ Id: 1355, Name: "İÇ HASTALIKLARI-İş ve Meslek Hst. YAN DALI", Code: "TUS" });
    result.push({ Id: 1356, Name: "İÇ HASTALIKLARI-İmmünoloji, YAN DALI", Code: "TUS" });
    result.push({ Id: 1357, Name: "İÇ HASTALIKLARI-Hematoloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1358, Name: "İÇ HASTALIKLARI- Geriatri YAN DALI", Code: "TUS" });
    result.push({ Id: 1359, Name: "İÇ HASTALIKLARI-Tıbbi Onkoloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1360, Name: "İÇ HASTALIKLARI-Yoğun BakımYAN DALI", Code: "TUS" });
    result.push({ Id: 1361, Name: "KADIN HASTALIKLARI VE DOĞUM", Code: "TUS" });
    result.push({ Id: 1362, Name: "KADIN HASTALIKLARI VE DOĞUM-Üreme Endokrinolojisi ve İnfertilite YAN DALI", Code: "TUS" });
    result.push({ Id: 1363, Name: "KADIN HASTALIKLARI VE DOĞUM-Perinatoloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1364, Name: "KALP VE DAMAR CERRAHİSİ", Code: "TUS" });
    result.push({ Id: 1365, Name: "KALP VE DAMAR CERRAHİSİ-Çocuk Kalp ve Damar Cerrahisi YAN DALI", Code: "TUS" });
    result.push({ Id: 1366, Name: "KARDİYOLOJİ", Code: "TUS" });
    result.push({ Id: 1367, Name: "KULAK-BURUN-BOĞAZ HASTALIKLARI", Code: "TUS" });
    result.push({ Id: 1368, Name: "NÖROLOJİ", Code: "TUS" });
    result.push({ Id: 1369, Name: "NÜKLEER TIP", Code: "TUS" });
    result.push({ Id: 1370, Name: "ORTOPEDİ VE TRAVMATOLOJİ", Code: "TUS" });
    result.push({ Id: 1371, Name: "ORTOPEDİ VE TRAVMATOLOJİ-EL CERRAHİSİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1372, Name: "PSİKİYATRİ", Code: "TUS" });
    result.push({ Id: 1373, Name: "PLASTİK VE REKONSTRÜKTİF VE ESTETİK CERRAHİSİ", Code: "TUS" });
    result.push({ Id: 1374, Name: "PLASTİK VE REKONSTRÜKTİF VE ESTETİK CERRAHİSİ-EL CERRAHİSİ YAN DALI", Code: "TUS" });
    result.push({ Id: 1375, Name: "RADYASYON ONKOLOJİSİ", Code: "TUS" });
    result.push({ Id: 1376, Name: "RADYOLOJİ", Code: "TUS" });
    result.push({ Id: 1377, Name: "RADYOLOJİ-Nöroradyoloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1378, Name: "RADYOLOJİ-Girişimsel Radyoloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1379, Name: "RADYOLOJİ-Pediyatrik RadyolojiYAN DALI", Code: "TUS" });
    result.push({ Id: 1380, Name: "SPOR HEKİMLİĞİ", Code: "TUS" });
    result.push({ Id: 1381, Name: "SUALTI HEKİMLİĞİ VE HİPERBARİK TIP", Code: "TUS" });
    result.push({ Id: 1382, Name: "TIBBİ BİYOKİMYA", Code: "TUS" });
    result.push({ Id: 1383, Name: "TIBBİ FARMAKOLOJİ", Code: "TUS" });
    result.push({ Id: 1384, Name: "TIBBİ FARMAKOLOJİ-Toksikoloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1385, Name: "TIBBİ GENETİK", Code: "TUS" });
    result.push({ Id: 1386, Name: "TIBBİ GENETİK-Klinik Sitogenetik YAN DALI", Code: "TUS" });
    result.push({ Id: 1387, Name: "TIBBİ GENETİK-Klinik Moleküler Genetik YAN DALI", Code: "TUS" });
    result.push({ Id: 1388, Name: "TIBBİ GENETİK-Klinik Genetik YAN DALI", Code: "TUS" });
    result.push({ Id: 1389, Name: "TIBBİ MİKROBİYOLOJİ", Code: "TUS" });
    result.push({ Id: 1390, Name: "TIBBİ MİKROBİYOLOJİ-Tıbbi Parazitoloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1391, Name: "TIBBİ MİKROBİYOLOJİ- Viroloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1392, Name: "TIBBİ MİKROBİYOLOJİ-İmmünoloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1393, Name: "TIBBİ MİKROBİYOLOJİ-Mikoloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1394, Name: "TIBBİ PATOLOJİ", Code: "TUS" });
    result.push({ Id: 1395, Name: "TIBBİ PATOLOJİ-Sitopatoloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1396, Name: "TIBBİ PATOLOJİ-Dermatopatoloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1397, Name: "TIBBİ PATOLOJİ-Nöropatoloji YAN DALI", Code: "TUS" });
    result.push({ Id: 1398, Name: "ÜROLOJİ", Code: "TUS" });
    result.push({ Id: 1399, Name: "ÜROLOJİ-Çocuk Ürolojisi YAN DALI", Code: "TUS" });
    result.push({ Id: 13100, Name: "ÜROLOJİ- Androloji YAN DALI", Code: "TUS" });
    result.push({ Id: 13101, Name: "YURTİÇİ DOKTORA", Code: "TUS" });
    result.push({ Id: 13102, Name: "ACİL TIP (YENİ)", Code: "TUS" });
    result.push({ Id: 13103, Name: "ADLİ TIP (YENİ)", Code: "TUS" });
    result.push({ Id: 13104, Name: "ADLİ TIP-TOKSİKOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13105, Name: "AĞIZ, YÜZ VE ÇENE CERRAHİSİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13106, Name: "DİŞ HEKİMLERİ İÇİN AĞIZ, DİŞ VE ÇENE CERRAHİSİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13107, Name: "DİŞ HEKİMLERİ İÇİN ENDODONTİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13108, Name: "DİŞ HEKİMLERİ İÇİN ORTODONTİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13109, Name: "DİŞ HEKİMLERİ İÇİN PEDODONTİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13110, Name: "DİŞ HEKİMLERİ İÇİN PERİODONTOLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13111, Name: "DİŞ HEKİMLERİ İÇİN PROTETİK DİŞ TEDAVİSİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13112, Name: "ANATOMİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13113, Name: "AİLE HEKİMLİĞİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13114, Name: "ANESTEZİYOLOJİ VE REANİMASYON (YENİ)", Code: "TUS" });
    result.push({ Id: 13115, Name: "ANESTEZİYOLOJİ VE REANİMASYON -ALGOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13116, Name: "ANESTEZİYOLOJİ VE REANİMASYON -YOĞUN BAKIM YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13117, Name: "ASKERİ SAĞLIK HİZMETLERİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13118, Name: "BEYİN VE SİNİR CERRAHİSİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13119, Name: "ÇOCUK CERRAHİSİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13120, Name: "ÇOCUK CERRAHİSİ-COCUK ÜROLOJİSİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13121, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI (YENİ)", Code: "TUS" });
    result.push({ Id: 13122, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK KARDİYOLOJİSİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13123, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK METABOLİZME HST. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13124, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK ENDOKRİNOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13125, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK HEMATOLOJİSİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13126, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK NEFROLOJİSİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13127, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK NÖROLOJİSİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13128, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK ALERJİ HAST. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13129, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK ONKOLOJİSİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13130, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK GASTRO YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13131, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK ENFEKSİYON HST. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13132, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK NEONATOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13133, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK GENETİK YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13134, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK GÖGÜS HST. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13135, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK İMMÜNOLOJİSİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13136, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK YOGUN BAKIM YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13137, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK KALP-DAMAR CERR. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13138, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK RADYOLOJİSİ. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13139, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK RAMATALOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13140, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK ÜROLOJİSİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13141, Name: "ÇOCUK PSİKİYATRİSİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13142, Name: "DERMATOLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13143, Name: "DERMATOLOJİ -İMMÜNOLOJİ VE ALERJİ HASTALIKLARI (YENİ) ", Code: "TUS" });
    result.push({ Id: 13144, Name: "ENFEKSİYON HASTALIKLARI VE KLİNİK MİKROBİYOLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13145, Name: "ENFEKSİYON HAST.VE KLİNİK MİKROBİYOLOJİ-YOĞUN BAKIM YAN DALI(YENİ) ", Code: "TUS" });
    result.push({ Id: 13146, Name: "FİZİKSEL TIP VE REHABİLİTASYON (YENİ)", Code: "TUS" });
    result.push({ Id: 13147, Name: "FİZİKSEL TIP VE REHABİLİTASYON-RAMOTOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13148, Name: "FİZİKSEL TIP VE REHABİLİTASYON-ALGOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13149, Name: "FİZYOLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13150, Name: "GENEL CERRAHİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13151, Name: "GENEL CERRAHİ-YOĞUN BAKIM YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13152, Name: "GENEL CERRAHİ-GASTROENTOLOJİ CERRAHİSİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13153, Name: "GENEL CERRAHİ-CERRAHİ ONKOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13154, Name: "GENEL CERRAHİ-HARP CERRAHİSİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13155, Name: "GENEL CERRAHİ-PERİFORİK DAMAR CERRAHİSİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13156, Name: "GÖĞÜS CERRAHİSİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13157, Name: "GÖĞÜS HASTALIKLARI (YENİ)", Code: "TUS" });
    result.push({ Id: 13158, Name: "GÖĞÜS HASTALIKLARI-İMMÜNOLOJİ VE ALERJİ HST.YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13159, Name: "GÖĞÜS HASTALIKLARI-YOGUN BAKIM YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13160, Name: "GÖĞÜS HASTALIKLARI-İŞ VE MESLEK HASTALIKLARI YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13161, Name: "GÖZ HASTALIKLARI (YENİ)", Code: "TUS" });
    result.push({ Id: 13162, Name: "HALK SAĞLIĞI (YENİ)", Code: "TUS" });
    result.push({ Id: 13163, Name: "HALK SAĞLIĞI-EPİDEMİYOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13164, Name: "HALK SAĞLIĞI-ÇEVRE SAĞLIĞI YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13165, Name: "HALK SAĞLIĞI-İŞ VE MESLEK HASTALIKLARI YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13166, Name: "HAVA VE UZAY HEKİMLİĞİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13167, Name: "HİSTOLOJİ VE EMBRİYOLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13168, Name: "İÇ HASTALIKLARI (YENİ)", Code: "TUS" });
    result.push({ Id: 13169, Name: "İÇ HASTALIKLARI-ALERJİ HST. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13170, Name: "İÇ HASTALIKLARI-ENDOKRİNOLOJİ VE METABOLİZMA HST. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13171, Name: "İÇ HASTALIKLARI-GASTROENTEROLOJİ. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13172, Name: "İÇ HASTALIKLARI-NEFROLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13173, Name: "İÇ HASTALIKLARI-ROMATOLOJİ. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13174, Name: "İÇ HASTALIKLARI-İŞ VE MESLEK HAST. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13175, Name: "İÇ HASTALIKLARI-İMMÜNOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13176, Name: "İÇ HASTALIKLARI-HEMATOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13177, Name: "İÇ HASTALIKLARI-GERİATRİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13178, Name: "İÇ HASTALIKLARI-TIBBİ ONKOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13179, Name: "İÇ HASTALIKLARI-YOĞUN BAKIM YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13180, Name: "KADIN HASTALIKLARI VE DOĞUM (YENİ)", Code: "TUS" });
    result.push({ Id: 13181, Name: "KADIN HAST. VE DOĞUM-JİNEKOLOJİK ONKOLOJİ CERR. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13182, Name: "KADIN HASTALIKLARI VE DOĞUM-PERİNATOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13183, Name: "KALP VE DAMAR CERRAHİSİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13184, Name: "KALP VE DAMAR CERRAHİSİ-ÇOÇUK KALP VE DAMAR CERR. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13185, Name: "KARDİYOLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13186, Name: "KULAK-BURUN-BOĞAZ HASTALIKLARI (YENİ)", Code: "TUS" });
    result.push({ Id: 13187, Name: "NÖROLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13188, Name: "NÖROLOJİ-YOĞUN BAKIM YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13189, Name: "NÖROLOJİ-ALGOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13190, Name: "NÖROLOJİ-KLİNİK NÖROFİZYOLOJİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13191, Name: "NÜKLEER TIP (YENİ)", Code: "TUS" });
    result.push({ Id: 13192, Name: "ORTOPEDİ VE TRAVMATOLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13193, Name: "ORTOPEDİ VE TRAVMATOLOJİ-EL CERRAHİSİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13194, Name: "PSİKİYATRİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13195, Name: "PSİKİYATRİ-ASKERİ PSİKİYATRİ YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13196, Name: "PLASTİK VE REKONSTRÜKTİF VE ESTETİK CERRAHİSİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13197, Name: "PLASTİK VE REKONSTRÜKTİF VE ESTETİK CERR.-EL CERR. YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13198, Name: "RADYASYON ONKOLOJİSİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13199, Name: "RADYOLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13200, Name: "RADYOLOJİ-Nöroradyoloji YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13201, Name: "RADYOLOJİ-Girişimsel Radyoloji YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13202, Name: "RADYOLOJİ-Pediyatrik RadyolojiYAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13203, Name: "SPOR HEKİMLİĞİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13204, Name: "SUALTI HEKİMLİĞİ VE HİPERBARİK TIP (YENİ)", Code: "TUS" });
    result.push({ Id: 13205, Name: "TIBBİ BİYOKİMYA (YENİ)", Code: "TUS" });
    result.push({ Id: 13206, Name: "TIBBİ EKOLOJİ VE HİDROKLİMATOLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13207, Name: "TIBBİ FARMAKOLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13208, Name: "TIBBİ FARMAKOLOJİ-Toksikoloji YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13209, Name: "TIBBİ GENETİK (YENİ)", Code: "TUS" });
    result.push({ Id: 13210, Name: "TIBBİ GENETİK-Klinik Sitogenetik YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13211, Name: "TIBBİ GENETİK-Klinik Moleküler Genetik YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13212, Name: "TIBBİ GENETİK-Klinik Genetik YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13213, Name: "TIBBİ MİKROBİYOLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13214, Name: "TIBBİ MİKROBİYOLOJİ-Tıbbi Parazitoloji YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13215, Name: "TIBBİ MİKROBİYOLOJİ- Viroloji YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13216, Name: "TIBBİ MİKROBİYOLOJİ-İmmünoloji YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13217, Name: "TIBBİ MİKROBİYOLOJİ-Mikoloji YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13218, Name: "TIBBİ PATOLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13219, Name: "TIBBİ PATOLOJİ-Sitopatoloji YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13220, Name: "ÜROLOJİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13221, Name: "ÜROLOJİ-Çocuk Ürolojisi YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13222, Name: "ACİL TIP", Code: "TUS" });
    result.push({ Id: 13223, Name: "ÇOCUK SAĞLIĞI VE HASTALIKLARI-ÇOCUK ACİL YAN DALI (YENİ)", Code: "TUS" });
    result.push({ Id: 13224, Name: "AĞIZ, DİŞ VE ÇENE CERRAHİSİ (YENİ)", Code: "TUS" });
    result.push({ Id: 13225, Name: "DİŞ HEKİMLERİ İÇİN AĞIZ, DİŞ VE ÇENE RADYOLOJİSİ", Code: "TUS" });
    result.push({ Id: 13226, Name: "DİŞ HEKİMLERİ İÇİN RESTARAKTİF DİŞ TEDAVİSİ", Code: "TUS" });



    if (id != undefined && id && !isNaN(id) && parseInt(id) > 0 && $.Enumerable.From(result).Any(function (x) { return x.Id == parseInt(id) })) {
        return $.Enumerable.From(result).FirstOrDefault(null, function (x) { return x.Id == parseInt(id) }).Name;
    }
    return result;
}
//ERTELEME_IPTAL_NEDENLERI
function getErtelemeIptalSebepleriTablo2(id) {
    var result = [];
    result.push({ Id: 501, Name: "MEZUN OLDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 502, Name: "TERK OLDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 503, Name: "2 YIL ÜST ÜSTE KALDIGINDAN", Code: "10601,10602" });
    result.push({ Id: 504, Name: "YATAY GEÇİŞ", Code: "10601,10602" });
    result.push({ Id: 505, Name: "HEM OKUYUP HEM ASKERE GİTMEK İSTEDİĞİNDEN", Code: "10601,10602" });
    result.push({ Id: 506, Name: "SAHTE BELGE/İDAREYİ KANDIRMA ", Code: "10601,10602" });
    result.push({ Id: 507, Name: "SEHVEN KAYIT", Code: "10601,10602" });
    result.push({ Id: 508, Name: "VEFAT", Code: "10601,10602" });
    result.push({ Id: 509, Name: "BEDELLİ ASKERLİK", Code: "10601,10602" });
    result.push({ Id: 510, Name: "KAYIT YENİLETMEDİĞİNDEN", Code: "10601,10602" });
    result.push({ Id: 511, Name: "BAŞKA NEDENLE ERTELEME TALEP EDİLDİĞİNDEN", Code: "10601,10602" });
    result.push({ Id: 512, Name: "DİĞER", Code: "10601,10602" });
    result.push({ Id: 513, Name: "KANUN HÜKMÜNDE KARARNAME", Code: "10601,10602" });
    result.push({ Id: 901, Name: "MEZUN OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 902, Name: "KAYDI SİLİNDİĞİNDEN / İLİŞİĞİ KESİLDİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 903, Name: "ASKERE GİTMEK İSTEDİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 904, Name: "BAŞKA NEDENLE ERTELEME TALEP EDİLDİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 905, Name: "SAHTE BELGE/İDAREYİ KANDIRMA", Code: "10603,10604,10605" });
    result.push({ Id: 906, Name: "SEHVEN KAYIT", Code: "10603,10604,10605" });
    result.push({ Id: 907, Name: "ASKERLİĞE ELVERİŞLİ DEĞİLDİR RAPORU ALDIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 908, Name: "VEFAT ETTİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 909, Name: "POLİS ADAYI/POLİS MESLEK MEMURU OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 910, Name: "BEDELLİ ASKERLİK", Code: "10603,10604,10605" });
    result.push({ Id: 911, Name: "SÖZLEŞMELİ/MUVAZZAF SUBAY/ASTSUBAY OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 912, Name: "KAYDINI YENİLEMEDİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 913, Name: "KAYDINI YENİLETMEDİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 914, Name: "KANUN HÜKMÜNDE KARARNAME", Code: "10603,10604,10605" });
    result.push({ Id: 915, Name: "DAHA ÖNCE AYNI SEVİYEDEKİ LİSANSÜSTÜ EĞİTİMDEN MEZUN OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 916, Name: "YATAY GEÇİŞ", Code: "10603,10604,10605" });
    result.push({ Id: 1301, Name: "MEZUN OLDUĞUNDAN", Code: "TUS" });
    result.push({ Id: 1302, Name: "İSTİFA ETTİĞİNDEN", Code: "TUS" });
    result.push({ Id: 1303, Name: "ASKERE GİTMEK İSTEDİĞİNDEN", Code: "TUS" });
    result.push({ Id: 1304, Name: "BAŞKA NEDENLE ERTELEME TALEP EDİLDİĞİNDEN", Code: "TUS" });
    result.push({ Id: 1305, Name: "SEHVEN KAYIT", Code: "TUS" });
    result.push({ Id: 1306, Name: "SAHTE BELGE/İDAREYİ KANDIRMA", Code: "TUS" });
    result.push({ Id: 1307, Name: "İLİŞİĞİ KESİLDİĞİNDEN", Code: "TUS" });
    result.push({ Id: 1308, Name: "ASKERLİĞE ELVERİŞLİ DEĞİLDİR RAPORU ALDIĞINDAN", Code: "TUS" });
    result.push({ Id: 1309, Name: "VEFAT ETTİĞİNDEN", Code: "TUS" });
    result.push({ Id: 1310, Name: "BEDELLİ ASKERLİK", Code: "TUS" });
    result.push({ Id: 1311, Name: "NAKLEN AYRILDIĞINDAN", Code: "TUS" });
    result.push({ Id: 1312, Name: "MAHKEME KARARIYLA", Code: "TUS" });
    result.push({ Id: 1313, Name: "KANUN HÜKMÜNDE KARARNAME", Code: "TUS" });



    if (id != undefined && id && !isNaN(id) && parseInt(id) > 0 && $.Enumerable.From(result).Any(function (x) { return x.Id == parseInt(id) })) {
        return $.Enumerable.From(result).FirstOrDefault(null, function (x) { return x.Id == parseInt(id) }).Name;
    }
    return result;
}
//AZAMI_SURE_ASMA_NEDENLERI
function getSureUzatimSebepleriTablo3(id) {
    var result = [];
    result.push({ Id: 1, Name: "KAYIT DURDURMA (LİSANS)", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 2, Name: "OKULDAN UZAKLAŞTIRMA", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 3, Name: "2547/44.MAD.3 DERS BAŞARISIZ", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 4, Name: "2547/44.MAD.4-5 DERS BAŞARISIZ", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 5, Name: "2547/4111 S.K. DEĞİŞİKLİĞİ", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 6, Name: "ÇİFT ANADAL", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 7, Name: "HAZIRLIK SINIFI", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 8, Name: "AF KANUNU", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 9, Name: "KAYDI DONDURMA (YL)", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 10, Name: "OKULDAN UZAKLAŞTIRMA", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 11, Name: "AF KANUNU", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 12, Name: "HAZIRLIK EĞİTİMİ", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 13, Name: "DİL EĞİTİMİ", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 14, Name: "ÖĞRENİM SÜRESİ FARKLILIK GÖSTEREN ÜLKE VE ÜNV.", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 15, Name: "AZAMİ ÖĞRENİM SÜRESİ SONRASI", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 35, Name: "EĞİTİM SÜRESİ İÇİNDE İZİNLİ SAYILMA", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 42, Name: "2547/44.MAD.5 DERS ÜSTÜ BAŞARISIZ", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 55, Name: "AÇIKTA KALMA NEDENİYLE", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 62, Name: "SALGIN HASTALIK", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 75, Name: "TEZ ÇALIŞMALARI", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 95, Name: "2547/GEÇİCİ 67.MADDE", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 96, Name: "SAĞLIK RAPORU", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 115, Name: "YETERLİLİK SINAVI", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 135, Name: "TIPTA UZMANLIK KURULU KARARI GEREĞİ", Code: "10601,10602,10603,10604,10605,TUS" });
    result.push({ Id: 155, Name: "YASAL NEDENLERLE SÜRESİ UZAMIŞTIR", Code: "10601,10602,10603,10604,10605,TUS" });



    if (id != undefined && id && !isNaN(id) && parseInt(id) > 0 && $.Enumerable.From(result).Any(function (x) { return x.Id == parseInt(id) })) {
        return $.Enumerable.From(result).FirstOrDefault(null, function (x) { return x.Id == parseInt(id) }).Name;
    }
    return result;
}
//RED_NEDENLERI
function getRedSebepleriTablo4(id) {
    var result = [];
    result.push({ Id: 501, Name: "OKULA KAYIT TARİHİ BAKAYA KALDIĞI TARİHTEN SONRA OLDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 502, Name: "OKULA KAYIT TARİHİ YOKLAMA KAÇAĞI OLDUĞU  TARİHTEN SONRA OLDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 503, Name: "MEVCUT ÖĞRENİM SEVİYESİNDE AZAMİ ÖĞRENİM SÜRESİNİ TAMAMLADIĞINDAN", Code: "10601,10602" });
    result.push({ Id: 504, Name: "TALEP EDİLEN ERTELEME  DIŞINDA, BAŞKA NEDENLE HALİ HAZIRDA ERTELİ OLDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 505, Name: "36. MADDE KAPSAMINDA ERTELEMESİ UYGUN GÖRÜLMEDİĞİNDEN", Code: "10601,10602" });
    result.push({ Id: 506, Name: "ASKERLİK YÜKÜMLÜLÜĞÜ BULUNMADIĞINDAN (YASADA YAZILI YAŞ SINIRINI TAMAMLADIĞINDAN)", Code: "10601,10602" });
    result.push({ Id: 507, Name: "AYNI VEYA DAHA AŞAĞI SEVİYEDE ÖĞRENİM GÖRDÜĞÜNDEN", Code: "10601,10602" });
    result.push({ Id: 508, Name: "AYNI ÖĞRENİM SEVİYESİNDE BAŞKA BİR ERTELEME TEKLİFİ BULUNDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 510, Name: "YÜKÜMLÜNÜN ASKERLİK İŞLEMİ BAŞLADIĞINDAN", Code: "10601,10602" });
    result.push({ Id: 511, Name: "ASKERLİK YÜKÜMLÜLÜĞÜ OLMADIĞINDAN", Code: "10601,10602" });
    result.push({ Id: 512, Name: "ASKERLİĞE ELVERİŞLİ DEĞİLDİR KARARI BULUNDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 513, Name: "TALEP EDİLEN ERTELEME SÜRESİ GEÇTİĞİNDEN", Code: "10601,10602" });
    result.push({ Id: 514, Name: "YÜKÜMLÜNÜN ASKERLİK İŞLEMİ BAŞLADIĞINDAN", Code: "10601,10602" });
    result.push({ Id: 515, Name: "DİKEY GEÇİŞ NEDENİ İLE KAYDI GELEN YÜKÜMLÜNÜN DAHA ÖNCEKİ OKULUNDAN MEZUN KAYDININ OLMAMASI", Code: "10601,10602" });
    result.push({ Id: 516, Name: "İPTAL TEKLİFİNE İLİŞKİN, ÖNCEDEN YAPILMIŞ BİR ÖĞRENCİ ERTELEMESİ BULUNMADIĞINDAN", Code: "10601,10602" });
    result.push({ Id: 517, Name: "ERTELEMESİNE İLİŞKİN KANUNİ YAŞ SINIRINI GEÇTİĞİNDEN", Code: "10601,10602" });
    result.push({ Id: 518, Name: "TEKLİF EDİLEN ERTELEME SÜRESİNDEN DAHA UZUN SÜRELİ MEVCUT ERTELEMESİ OLDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 519, Name: "TEKLİF EDİLEN ERTELEME NEDENİ İLE ÖNCESİNDE AYNI ERTELEME NEDENİ İLE ERTELEMESİ YAPILMIŞ VE ERTELEME SÜRESİNİ DOLDURDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 520, Name: "ERTELEME TEKLİF BİLGİLERİNDE EKSİKLİK/UYUMSUZLUK BULUNDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 521, Name: "AYNI NEDENLE TEKLİF EDİLMİŞ VE HENÜZ SONUÇLANMAMIŞ KAYDI OLDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 522, Name: "SİSTEMDE İŞLENMEMİŞ BİR TEKLİFİ OLDUĞUNDAN,BU TEKLİF SONUÇLANMADAN,YENİ BİR BAŞVURU YAPILAMAZ.", Code: "10601,10602" });
    result.push({ Id: 523, Name: "ERTELEME NEDENİ GİRİLMEMİŞ VEYA HATALI ERTELEME NEDENİ İLE TEKLİF YAPILDIĞINDAN", Code: "10601,10602" });
    result.push({ Id: 524, Name: "İPTAL KAYDI OLMASINA RAĞMEN İPTAL NEDENİ GİRİLMEMİŞ VEYA HATALI İPTAL NEDENİ GÖNDERİLDİĞİNDEN", Code: "10601,10602" });
    result.push({ Id: 525, Name: "ERTELEMESİNE İLİŞKİN OKUL KODU SİSTEMDE TANIMLI OLMADIĞINDAN REDDEDİLMİŞTİR. TANIMLATMAK İÇİN YÖK İLE İRTİBATA GEÇİLMİŞTİR.", Code: "10601,10602" });
    result.push({ Id: 526, Name: "AZAMİ ÖĞRENİM SÜRESİ HATALI OLDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 527, Name: "ÖĞRENİM SÜRESİ BOŞ GÖNDERİLDİĞİNDEN", Code: "10601,10602" });
    result.push({ Id: 528, Name: "BEDELLİ ASKERLİK MÜRACAATI BULUNDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 529, Name: "ERTELEMESİ TEKLİF EDİLEN YÜKÜMLÜNÜN SİSTEMDE KAYDI YOKTUR.", Code: "10601,10602" });
    result.push({ Id: 530, Name: "DİPLOMA SEVİYESİ BOŞ OLARAK GÖNDERİLDİĞİNDEN", Code: "10601,10602" });
    result.push({ Id: 531, Name: "AZAMİ AŞMA NEDENİNE İLİŞKİN İLAVE SÜRE GİRİLMEDİĞİNDEN", Code: "10601,10602" });
    result.push({ Id: 532, Name: "OKULUN YURT İÇİ ÖĞRENCİ ERTELEMEYE UYGUN OLMAMASI", Code: "10601,10602" });
    result.push({ Id: 533, Name: "İPTAL TEKLİFİ İÇİN GÖNDERİLMİŞ OKUL BİLGİSİ İLE ÖNCEDEN ERTELEME TEKLİFİNDE BULUNULMUŞ OKUL BİLGİSİ AYNI OLMADIĞINDAN/UYUMSUZ OLDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 535, Name: "ASKERLİK YOKLAMASINI YAPTIRMADIĞINDAN", Code: "10601,10602" });
    result.push({ Id: 536, Name: "DÖRT YILDAN FAZLA SÜRELİ ÖĞRETİM KURUMUNDAN MEZUN OLDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 537, Name: "YÜKÜMLÜNÜN ASKERLİK SON DURUMUNUN ÖĞRENCİ ERTELEMESİ İÇİN UYGUN OLMADIĞINDAN", Code: "10601,10602" });
    result.push({ Id: 538, Name: "İPTAL EDİLECEK ERTELEME KAYDI OLMADIĞINDAN", Code: "10601,10602" });
    result.push({ Id: 539, Name: "MEZUN VEYA TERK DURUMUNA AİT İPTAL TEKLİFİNE İLİŞKİN MEZUN/TERK TARİHİ ALANI BOŞ OLDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 540, Name: "ÖĞRENCİNİN OKUL DURUMU ALANI (OKUYOR/MEZUN/TERK) GÖNDERİLMEDİĞİNDEN", Code: "10601,10602" });
    result.push({ Id: 541, Name: "OKULA KAYIT TARİHİ TANIMLI OLMADIĞINDAN", Code: "10601,10602" });
    result.push({ Id: 542, Name: "KAYIT YENİLEME TARİHİ İTİBARİYLE ERTELEMESİ YAPILAMAZ", Code: "10601,10602" });
    result.push({ Id: 543, Name: "AYNI VEYA DAHA AŞAĞI SEVİYEDE MEZUN KAYDI OLDUĞUNDAN ERTELEME YAPILAMAZ", Code: "10601,10602" });
    result.push({ Id: 544, Name: "AYNI OKUL BİLGİSİ ILE ERTELİ OLDUĞUNDAN", Code: "10601,10602" });
    result.push({ Id: 545, Name: "DİĞER NEDENLERLE", Code: "10601,10602" });
    result.push({ Id: 901, Name: "ASKERLİK YÜKÜMLÜLÜĞÜ BULUNMADIĞINDAN (YASADA YAZILI YAŞ SINIRINI TAMAMLADIĞINDAN)", Code: "10603,10604,10605" });
    result.push({ Id: 902, Name: "ASKERLİK YOKLAMASINI YAPTIRMADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 903, Name: "OKULA KAYIT TARİHİ YOKLAMA KAÇAĞI OLDUĞU  TARİHTEN SONRA OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 904, Name: "OKULA KAYIT TARİHİ BAKAYA KALDIĞI TARİHTEN SONRA OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 905, Name: "BAKAYA KALMAK SUÇUNDAN MAHKEMESİ DEVAM ETTİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 906, Name: "YOKLAMA KAÇAĞI VE/VEYA BAKAYA KALMAK SUÇUNDAN CEZA ALDIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 908, Name: "YÜKÜMLÜNÜN ASKERLİK İŞLEMİ BAŞLADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 909, Name: "KURUM, 217 SAYILI K.H.K. KAPSAMINA GİREN KAMU KURUMLARI ARASINDA OLMADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 910, Name: "TALEP EDİLEN ERTELEME  DIŞINDA, BAŞKA NEDENLE HALİ HAZIRDA ERTELİ OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 911, Name: "ASKERLİĞE ELVERİŞLİ DEĞİLDİR KARARI BULUNDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 912, Name: "MEVCUT ÖĞRENİM SEVİYESİNDE AZAMİ ÖĞRENİM SÜRESİNİ TAMAMLADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 913, Name: "LİSANSÜSTÜ EĞİTİM ÖĞRETİM YÖNETMELİĞİNDE BELİRTİLEN SÜREYİ AŞTIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 914, Name: "DÖRT YILDAN FAZLA SÜRELİ ÖĞRETİM KURUMUNDAN MEZUN OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 915, Name: "FİİLEN EĞİTİME BAŞLAMADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 916, Name: "AYNI DÜZEYDE LİSANSÜSTÜ EĞİTİMDEN MEZUN OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 917, Name: "YETKİLİ KURUM TEKLİF YAPMADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 919, Name: "BAKAYA KALMAK SUÇUNDAN CEZA ALDIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 920, Name: "ASKERLİK YÜKÜMLÜLÜĞÜ OLMADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 921, Name: "TALEP EDİLEN ERTELEME SÜRESİ GEÇTİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 923, Name: "İSTENİLEN TARİHE KADAR ASKERE SEVK EDİLMEYECEĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 924, Name: "TEKLİF YAZISI İMZASIZ GELDİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 925, Name: "YETKİLİ KURUM AMİRİ İMZALAMADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 926, Name: "YÖNETMELİĞE UYGUN TEKLİF YAPILMADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 927, Name: "ERTELEMESİNİN YAPILMASINA YASAL İMKAN OLMADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 928, Name: "BU KONUDA DAHA ÖNCE GÖNDERİLEN TEKLİFİNİZE TIPKIÇEKİMİ EK'TE GÖNDERİLEN YAZIMIZ İLE CEVAP VERİLMİŞTİR.", Code: "10603,10604,10605" });
    result.push({ Id: 929, Name: "YOKLAMA KAÇAĞI SUÇUNDAN MAHKEMESİ DEVAM ETTİĞİNDEN.", Code: "10603,10604,10605" });
    result.push({ Id: 930, Name: "MUHTELİF YAZIŞMA", Code: "10603,10604,10605" });
    result.push({ Id: 931, Name: "ERTELEME TEKLİF BİLGİLERİNDE EKSİKLİK/UYUMSUZLUK BULUNDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 932, Name: "TEKLİF FORMU MÜHÜRSÜZ GÖNDERİLDİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 933, Name: "YOKLAMA KAÇAĞI KALMAK SUÇUNDAN CEZA ALDIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 934, Name: "AYNI ÖĞRENİM SEVİYESİNDE MEZUNİYET BİLGİSİ BULUNDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 935, Name: "AF KANUNU KAPSAMINDA ÖĞRENCİLİK SAFAHATI AÇIKLANMADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 936, Name: "MSB SEVK TEHİRİ İŞLEMLERİ YÖNETMELİĞİ'NİN 7.MADDE 16.FIKRASI GEREĞİ, TEKLİF FORMU KAŞE İMZALI OLARAK GÖNDERİLDİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 937, Name: "POLİS MESLEK MEMURU/POLİS ADAYI OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 938, Name: "BEDELLİ ASKERLİK MÜRACAATI BULUNDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 939, Name: "YÜKÜMLÜNÜN ASKERLİK İŞLEMİ BAŞLADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 940, Name: "KİMLİK BİLGİLERİNDE YANLIŞLIK OLDUĞU TESBİT EDİLDİĞİNDEN.", Code: "10603,10604,10605" });
    result.push({ Id: 941, Name: "BAŞKA BİR ÜNİVERSİTEDE LİSANSÜSTÜ EĞİTİME KAYITLI OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 942, Name: "BAKAYA KALMAK SUÇUNDAN KESİNLEŞMİŞ İDARİ PARA CEZASI OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 943, Name: "OKULA KAYIT TARİHİ BAKAYA KALDIĞI TARİHTEN SONRA OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 944, Name: "FARKLI BİR BÖLÜMDE LİSANSÜSTÜ EĞİTİME KAYITLI OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 945, Name: "TEKLİF FORMU E-İMZA İLE İMZALANMIŞ, EVRAK DOĞRULAMA ADRESİ TEKLİF FORMUNDA BELİRTİLMEMİŞ", Code: "10603,10604,10605" });
    result.push({ Id: 946, Name: "AYNI NEDENLE TEKLİF EDİLMİŞ, SONUÇLANMAMIŞ KAYDINIZ OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 947, Name: "SİSTEMDE İŞLENMEMİŞ BİR TEKLİFİ OLDUĞUNDAN,BU TEKLİF SONUÇLANMADAN,YENİ BİR BAŞVURU YAPILAMAZ.", Code: "10603,10604,10605" });
    result.push({ Id: 948, Name: "ERTELEME NEDENİ GİRİLMEMİŞ VEYA HATALI ERTELEME NEDENİ İLE TEKLİF YAPILDIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 949, Name: "İPTAL KAYDI OLMASINA RAĞMEN İPTAL NEDENİ GİRİLMEMİŞ VEYA HATALI İPTAL NEDENİ GÖNDERİLDİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 950, Name: "AZAMİ AŞMA NEDENİ HATALI GÖNDERİLDİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 951, Name: "ÖĞRENİM SÜRESİ BOŞ GÖNDERİLDİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 952, Name: "ERTELEMESİNE İLİŞKİN OKUL KODU SİSTEMDE TANIMLI OLMADIĞINDAN REDDEDİLMİŞTİR. TANIMLATMAK İÇİN YÖK İLE İRTİBATA GEÇİLMİŞTİR.", Code: "10603,10604,10605" });
    result.push({ Id: 953, Name: "ERTELEMESİ TEKLİF EDİLEN YÜKÜMLÜNÜN SİSTEMDE KAYDI YOKTUR.", Code: "10603,10604,10605" });
    result.push({ Id: 954, Name: "AZAMİ AŞMA NEDENİNE İLİŞKİN İLAVE SÜRE GİRİLMEDİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 955, Name: "ERTELEME TEKLİF BİLGİLERİNDE EKSİKLİK/UYUMSUZLUK BULUNDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 956, Name: "GÖNDERİLEN OKUL BİLGİSİ LİSANS ÜSTÜ SEVİYESİNDE BİR OKUA AİT DEĞİLDİR", Code: "10603,10604,10605" });
    result.push({ Id: 957, Name: "İPTAL TEKLİFİ İÇİN GÖNDERİLMİŞ OKUL BİLGİSİ İLE ÖNCEDEN ERTELEME TEKLİFİNDE BULUNULMUŞ OKUL BİLGİSİ AYNI OLMADIĞINDAN/UYUMSUZ OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 958, Name: "TUS ERTELEME NEDENİ OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 960, Name: "İPTAL EDİLECEK ERTELEME KAYDI OLMADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 961, Name: "ÖĞRENCİNİN OKUL DURUMU ALANI (OKUYOR/MEZUN/TERK) GÖNDERİLMEDİĞİNDEN", Code: "10603,10604,10605" });
    result.push({ Id: 962, Name: "OKULA KAYIT TARİHİ TANIMLI OLMADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 963, Name: "MEZUN VEYA TERK DURUMUNA AİT İPTAL TEKLİFİNE İLİŞKİN MEZUN/TERK TARİHİ ALANI BOŞ OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 964, Name: "TEKLİF EDİLEN ERTELEME SÜRESİNDEN DAHA UZUN SÜRELİ MEVCUT ERTELEMESİ OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 965, Name: "İPTAL TEKLİFİNE İLİŞKİN, ÖNCEDEN BİR YÜKSEK LİSAN ÖĞRENCİ ERTELEMESİ OLMADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 966, Name: "DAHA ONCEDEN HERHANGİ BİR YÜKSEK LİSANS ERTELEMESİ BULUNMADIĞINDAN", Code: "10603,10604,10605" });
    result.push({ Id: 967, Name: "AYNI OKUL BİLGİSİ ILE ERTELİ OLDUĞUNDAN", Code: "10603,10604,10605" });
    result.push({ Id: 968, Name: "DİĞER NEDENLERLE", Code: "10603,10604,10605" });
    result.push({ Id: 1301, Name: "YASADA YAZILI YAŞ SINIRINI TAMAMLADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1302, Name: "ERTELEME İÇİN GEREKLİ, DAHA ÖNCE YAPILMIŞ YOKLAMASI BULUNMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1303, Name: "ERTELEMESİ BAŞLADIĞINDA YOKLAMA KAÇAĞI OLDUĞUNDAN", Code: "TUS" });
    result.push({ Id: 1304, Name: "BAKAYA KALMAK SUÇUNDAN ARANDIĞINDAN", Code: "TUS" });
    result.push({ Id: 1305, Name: "BAKAYA KALMAK SUÇUNDAN MAHKEMESİ DEVAM ETTİĞİNDEN", Code: "TUS" });
    result.push({ Id: 1308, Name: "YÜKÜMLÜNÜN ASKERLİK İŞLEMİ BAŞLADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1309, Name: "KURUM 217 SAYILI K.H.K. KAPSAMINA GİREN KAMU KURUMLARI ARASINDA OLMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1310, Name: "BAŞKA BİR NEDENLE ERTELİ OLDUĞUNDAN", Code: "TUS" });
    result.push({ Id: 1311, Name: "ASKERLİĞE ELVERİŞLİ DEĞİLDİR KARARI BULUNDUĞUNDAN", Code: "TUS" });
    result.push({ Id: 1312, Name: "AZAMİ SÜRESİNİ TAMAMLADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1313, Name: "TUS KAZANANLAR LİSTESİNDE İSMİ OLMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1314, Name: "TAMAMLADIĞI UZMANLIK DALININ HARİCİNDE YAN DAL İHTİSAS YAPTIĞINDAN", Code: "TUS" });
    result.push({ Id: 1315, Name: "YOKLAMASINI YAPTIRMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1316, Name: "YOKLAMA KAÇAĞI KALMAK SUÇUNDAN CEZA ALDIĞINDAN", Code: "TUS" });
    result.push({ Id: 1317, Name: "ASKERLİK YÜKÜMLÜLÜĞÜ OLMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1318, Name: "İSTENİLEN ERTELEME SÜRESİ GEÇTİĞİNDEN", Code: "TUS" });
    result.push({ Id: 1319, Name: "AYNI DÜZEYDE LİSANSÜSTÜ EĞİTİMDEN MEZUN OLDUĞUNDAN", Code: "TUS" });
    result.push({ Id: 1320, Name: "KİMLİK BİLGİLERİ UYUŞMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1321, Name: "KAYNAKDA BULUNMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1322, Name: "İSTENİLEN TARİHE KADAR SEVKE TABÎ TUTULMAYACAĞINDAN", Code: "TUS" });
    result.push({ Id: 1323, Name: "TEKLİF YAZISI İMZASIZ GELDİĞİNDEN", Code: "TUS" });
    result.push({ Id: 1324, Name: "FİİLEN EĞİTİME BAŞLAMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1325, Name: "YETKİLİ KURUM AMİRİ İMZALAMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1326, Name: "YETKİLİ KURUM TEKLİF YAPMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1327, Name: "YÖNETMELİĞE UYGUN TEKLİF YAPILMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1328, Name: "ERTELEMESİNİN YAPILMASINA YASAL İMKAN OLMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1329, Name: "BU KONUDA DAHA ÖNCE GÖNDERİLEN TEKLİFİNİZE TIPKIÇEKİMİ EK'TE GÖNDERİLEN YAZIMIZ İLE CEVAP VERİLMİŞTİR.", Code: "TUS" });
    result.push({ Id: 1330, Name: "YOKLAMA KAÇAĞI SUÇUNDAN MAHKEMESİ DEVAM ETTİĞİNDEN.", Code: "TUS" });
    result.push({ Id: 1331, Name: "MUHTELİF YAZIŞMA", Code: "TUS" });
    result.push({ Id: 1332, Name: "TEKLİF FORMU EKSİK DOLDURULDUĞUNDAN", Code: "TUS" });
    result.push({ Id: 1333, Name: "TEKLİF FORMU MÜHÜRSÜZ GÖNDERİLDİĞİNDEN", Code: "TUS" });
    result.push({ Id: 1334, Name: "BAKAYA KALMAK SUÇUNDAN CEZA ALDIĞINDAN", Code: "TUS" });
    result.push({ Id: 1335, Name: "MSB SEVK TEHİRİ İŞLEMLERİ YÖNETMELİĞİ'NİN 7.MADDE 16.FIKRASI GEREĞİ, TEKLİF FORMU KAŞE İMZALI OLARAK GÖNDERİLDİĞİNDEN", Code: "TUS" });
    result.push({ Id: 1336, Name: "BEDELLİ ASKERLİK MÜRACAATI BULUNDUĞUNDAN", Code: "TUS" });
    result.push({ Id: 1337, Name: "KİMLİK BİLGİLERİNDE YANLIŞLIK OLDUĞU TESBİT EDİLDİĞİNDEN.", Code: "TUS" });
    result.push({ Id: 1338, Name: "HİZMET ŞEKLİ UYGUN OLMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1339, Name: "BAKAYA KALMAK SUÇUNDAN KESİNLEŞMİŞ İDARİ PARA CEZASI OLDUĞUNDAN", Code: "TUS" });
    result.push({ Id: 1340, Name: "TEKLİF FORMU E-İMZA İLE İMZALANMIŞ, EVRAK DOĞRULAMA ADRESİ TEKLİF FORMUNDA BELİRTİLMEMİŞ", Code: "TUS" });
    result.push({ Id: 1341, Name: "MEZUNİYET/TERK TARİHİ TANIMLI OLMADIĞINDAN", Code: "TUS" });
    result.push({ Id: 1342, Name: "ERTELEMESİ TEKLİF EDİLEN YÜKÜMLÜNÜN SİSTEMDE KAYDI YOKTUR.", Code: "TUS" });
    result.push({ Id: 2019, Name: "İPTAL KAYDI OLMASINA RAĞMEN İPTAL NEDENİ GİRİLMEMİŞ VEYA HATALI İPTAL NEDENİ GÖNDERİLDİĞİNDEN", Code: "10601,10602" });



    if (id != undefined && id && !isNaN(id) && parseInt(id) > 0 && $.Enumerable.From(result).Any(function (x) { return x.Id == parseInt(id) })) {
        return $.Enumerable.From(result).FirstOrDefault(null, function (x) { return x.Id == parseInt(id) }).Name;
    }
    return result;
}
//************************************************************************
//***************************  Yöksis Asal Enumları **********************
//************************************************************************




var _dataTableLang = {
    "sDecimal": ",",
    "sEmptyTable": "Tabloda herhangi bir veri mevcut deðil",
    "sInfo": "_TOTAL_ kayıttan _START_ - _END_ arasındaki kayıtlar gösteriliyor",
    "sInfoEmpty": "Kayıt yok",
    "sInfoFiltered": "(_MAX_ kayıt içerisinden bulunan)",
    "sInfoPostFix": "",
    "sInfoThousands": ".",
    "sLengthMenu": "Sayfada _MENU_ kayıt göster",
    "sLoadingRecords": "Yükleniyor...",
    "sProcessing": "ışleniyor...",
    "sSearch": "Ara:",
    "sZeroRecords": "Eşleşen kayıt bulunamadı",
    "oPaginate": {
        "sFirst": "ilk",
        "sLast": "Son",
        "sNext": "Sonraki",
        "sPrevious": "Önceki"
    },
    "oAria": {
        "sSortAscending": ": artan sütun sıralamasını aktifleştir",
        "sSortDescending": ": azalan sütun sıralamasını aktifleştir"
    }
}
