/* Minification failed. Returning unminified contents.
(6185,44-45): run-time error JS1014: Invalid character: `
(6185,45-46): run-time error JS1195: Expected expression: .
(6185,50-51): run-time error JS1193: Expected ',' or ')': {
(6185,59-60): run-time error JS1014: Invalid character: `
(6185,60-61): run-time error JS1195: Expected expression: )
(6185,67-68): run-time error JS1004: Expected ';': )
(6188,8-9): run-time error JS1002: Syntax error: }
(6189,32-33): run-time error JS1004: Expected ';': {
(6190,32-33): run-time error JS1014: Invalid character: `
(6190,33-34): run-time error JS1195: Expected expression: .
(6190,38-39): run-time error JS1004: Expected ';': {
(6190,51-52): run-time error JS1014: Invalid character: `
(6190,52-53): run-time error JS1004: Expected ';': )
(6192,27-28): run-time error JS1014: Invalid character: `
(6192,32-33): run-time error JS1004: Expected ';': :
(6192,70-71): run-time error JS1014: Invalid character: `
(6203,5-6): run-time error JS1195: Expected expression: )
(6205,1-2): run-time error JS1002: Syntax error: }
(6209,26-27): run-time error JS1004: Expected ';': :
(6211,22-23): run-time error JS1004: Expected ';': :
(6213,18-23): run-time error JS1197: Too many errors. The file might not be a JavaScript file: false
 */
/// <reference path="Artportalen.UI.js"/>
/// <reference path="../jquery/jquery-1.4.2.js"/>
$.fn.autocompleteAdd = function (options) {
    ///	<summary>
    ///     Adds "Add button" functionality to a input/select element, tracks which unique ids that has been added (cannot add same id twice).
    ///     Button is disabled on init. 
    ///     Button is enabled when value in Id changed and not 0.
    ///     Button is disabled after click.
    ///     It remembers which Id that has been added, a Id can only be added one time (button will remain disabled).
    ///     It is possible to Init the excluded ids by calling $.fn.autocompleteAddExcludeId on the same selector.
    ///     
    ///     options (object struct)
    ///            inputTextElementSelector: 'input[type=text]'     - the element to get the text from for the item that should be added.
    ///            textElementSelector: ''                          - if the inputTextElement have sub elements, use this to find the corrent one, e.g. select elements.
    ///            inputValueElementSelector: 'input[type=hidden]'  - the element to get the value from for the item that should be added.
    ///            valueElementSelector: ''                         - if the inputValueElementSelector have sub elements, use this to find the corrent one, e.g. select elements.
    ///            buttonElementSelector: 'button'                  - button element
    ///            dependentElements: []                            - other autocompleteAdd elements that should syncronize behaviour with this. Specify them as a jquery selector e.g. $('#dependent-element-id').
    ///     
    ///     Precondition HTML structure:
    ///     div (class="ap2-ui-autocomplete-add")
    ///         element for text
    ///         element for value
    ///         button
    ///
    ///     The excluded ids are held with options in jquery data object on the div (data-autocompleteAdd).
    ///
    ///     Click on button will trigger a "autocompleteAdd.click" event on the div.
    ///     Example:
    ///             $("#SightingViewModel_SearchUser_AutocompleteAdd")
    ///            .bind("autocompleteAdd.click", function(e) {
    ///                your code...
    ///            });
    ///
    ///     Events fired on DIV element:
    ///         autocompleteAdd.idExcluded.added - an excluded id has been added to the data-autocompleteAdd (jquery data)
    ///         autocompleteAdd.idExcluded.removed - an excluded id has been removed from the data-autocompleteAdd (jquery data)
    ///
    ///     Usage: Used by UserAdd.aspx and initialized in Artportalen.Initialize.js.
    ///
    ///     TODO: Needs DRY refactoring! Optimize number of times disable/enable gets called (once per item in list), optimize dependent element event binding.
    ///	</summary>

    var defaults = {
        inputTextElementSelector: 'input[type=text]',
        textElementSelector: '',
        inputValueElementSelector: 'input[type=hidden]',
        valueElementSelector: '',
        buttonElementSelector: 'button',
        dependentElements: []
    };

    var opts = $.extend(defaults, options);

    return this.each(function () {
        if (this.tagName == 'DIV') {
            var inputText = $(this).find(opts.inputTextElementSelector);
            var inputValue = $(this).find(opts.inputValueElementSelector);
            var buttonAdd = $(this).find(opts.buttonElementSelector);

            var data = { opts: opts, ids: ['0'] };

            $(this).data('data-autocompleteAdd', data);

            $(buttonAdd).attr({ disabled: true });

            $(inputValue).change(function (e) {
                var value = $(this).val();

                if (opts.valueElementSelector.length != 0) {
                    value = $(this).find(opts.valueElementSelector).val();
                }
                var dataElement = $(this).closest('div.ap2-ui-autocomplete-add');
                var data = $(dataElement).data('data-autocompleteAdd');

                if ($.inArray(value, data.ids) == -1) {
                    $(buttonAdd).removeAttr("disabled");
                }
                else {
                    $(buttonAdd).attr({ disabled: true });
                };
            });

            $(buttonAdd).click(function (e) {
                e.preventDefault(); // JSZ add - to prevent posting of the report sighting form
                var value = $(inputValue).val();

                if (opts.valueElementSelector.length != 0) {
                    value = $(inputValue).find(opts.valueElementSelector).val();
                }

                var text = '';

                if (opts.textElementSelector.length != 0) {
                    text = $(inputText).find(opts.textElementSelector).text();
                }
                else {
                    text = $(inputText).val();
                }
                var dataElement = $(this).closest('div.ap2-ui-autocomplete-add');
                var data = $(dataElement).data('data-autocompleteAdd');
                data.ids[data.ids.length] = value;
                $(dataElement).trigger({ type: "autocompleteAdd.idExcluded.added", AutocompleteAddElement: dataElement, Id: value });

                /// make sure dependent elements are in sync
                $(opts.dependentElements).each(function () {
                    var dataDependent = $(this).data('data-autocompleteAdd');
                    dataDependent.ids[dataDependent.ids.length] = value;
                    $(this).trigger({ type: "autocompleteAdd.idExcluded.added", AutocompleteAddElement: $(this), Id: value });
                });

                $(dataElement).trigger({
                    type: "autocompleteAdd.click",
                    AutocompleteAddElement: this,
                    Id: value,
                    Text: text
                });
            });

            $(this).bind("autocompleteAdd.idExcluded.removed", EnableButton);
            $(this).bind("autocompleteAdd.idExcluded.added", DisableButton);

            /// make sure dependent elements are in sync
            $(opts.dependentElements).each(function () {
                $(this).bind("autocompleteAdd.idExcluded.removed", EnableButton);
            });

            /// make sure dependent elements are in sync
            $(opts.dependentElements).each(function () {
                $(this).bind("autocompleteAdd.idExcluded.added", DisableButton);
            });
        };
    });

    function DisableButton(e) {
        var data = $(e.AutocompleteAddElement).data('data-autocompleteAdd');

        var inputValue = $(e.AutocompleteAddElement).find(data.opts.inputValueElementSelector);

        var value = $(inputValue).val();

        if (data.opts.valueElementSelector.length != 0) {
            value = $(inputValue).find(data.opts.valueElementSelector).val();
        }

        if ($.inArray(value, data.ids) != -1) {
            $(e.AutocompleteAddElement).find(data.opts.buttonElementSelector).attr({ disabled: true });
        }
    };

    function EnableButton(e) {
        var data = $(e.AutocompleteAddElement).data('data-autocompleteAdd');

        var inputValue = $(e.AutocompleteAddElement).find(data.opts.inputValueElementSelector);

        var value = $(inputValue).val();

        if (data.opts.valueElementSelector.length != 0) {
            value = $(inputValue).find(data.opts.valueElementSelector).val();
        }

        if ($.inArray(value, data.ids) == -1) {
            $(e.AutocompleteAddElement).find(data.opts.buttonElementSelector).removeAttr("disabled");
        }
    };
};
    

$.fn.autocompleteAddExcludeId = function (id) {
    /// <summary>
    /// Exclude ids for the autocompleteAdd function. Ids added will not be used to trigger enable on add button.
    /// </summary>
    ///	<param name="id" type="integer">
    /// Id to exclude.
    ///	</param>
    return this.each(function () {
        if (this.tagName == 'DIV') {
            var data = $(this).data('data-autocompleteAdd');
            data.ids[data.ids.length] = id;
            $(this).trigger({ type: "autocompleteAdd.idExcluded.added", AutocompleteAddElement: this, Id: id });
        };
    });
};

$.fn.autocompleteRemoveExcludeId = function (id) {
    /// <summary>
    /// Remove a excluded id for the autocompleteAdd function.
    /// </summary>
    ///	<param name="id" type="integer">
    /// Id to remove from exclude.
    ///	</param>
    return this.each(function () {
        if (this.tagName == 'DIV') {
            var data = $(this).data('data-autocompleteAdd');
            removeItem(data.ids, id);
            $(this).trigger({ type: "autocompleteAdd.idExcluded.removed", AutocompleteAddElement: this, Id: id });
        };
    });

    //remove item (string or number) from an array
    function removeItem(originalArray, itemToRemove) {
        var j = 0;
        while (j < originalArray.length) {
            //	alert(originalArray[j]);
            if (originalArray[j] == itemToRemove) {
                originalArray.splice(j, 1);
            } else { j++; }
        }
        return originalArray;
    }
};

$.fn.setUserAddAdded = function (options) {
    alert(options);
}

//actionPath, mainTextProperty, subTextProperty, filterByHasCollection, handleFavourites
$.fn.apautocomplete = function (options) {
    return this.each(function () {
        if (this.tagName == 'INPUT') {

            var inputBox = this; inputBox.setAttribute("autocomplete", "off"); // turn off autocomplete with JavaScript so that the XHTML is valid
            var oldValue = this.value;
            var newValue = this.value;

            // Find Include current user in search value
            var includeCurrentUserInResultFromElement = $(inputBox).parent().parent().find('#ap2-ui_input_includecurrentuser').length ? $(inputBox).parent().parent().find('#ap2-ui_input_includecurrentuser').val() : false;
            
            var settings = $.extend({
                actionPath: Artportalen_ApplicationPath + '/User/FindUsersByName',
                mainTextProperty: 'PresentationName',
                subTextProperty: 'City',
                handleFavourites: options ? options.handleFavourites : true, // default is true
                includeCurrentUserInResult: includeCurrentUserInResultFromElement
            }, options);

            var inputPosition = $(inputBox).parent().offset();
            var popupList = $("<div class='ap2-ui-autocompletelist favourite' />")
                .hide()
                .css({
                    'width': ($(inputBox).parent().outerWidth() - 2),
                    'left': inputPosition.left,
                    'z-index': 6000, 
                    'top': inputPosition.top + ($(inputBox).parent().outerHeight() - 1)
                })//'max-height' : 150,
                .data("targetposition", $(inputBox))
                .appendTo(document.body)
                .click(function (event) {
                    event.stopPropagation();
                    event.preventDefault();

                    var _target = $(event.target);
                    if (_target.hasClass("closelist")) {
                        $(this).hide();
                        return false;
                    } else if (event.target.nodeName == 'B' || event.target.nodeName == 'SPAN') {
                        _target = _target.closest("a.item");
                    } else if (event.target.nodeName == 'LI') {
                        if (_target.find("a.item").length) {
                            _target = _target.find("a.item");
                        } else {
                            return false;
                        }
                    }

                    if (_target.is(".favourite")) {
                        if (_target.is(".favourite_on")) {
                            _target.addClass("favourite_off");
                        } else {
                            _target.removeClass("favourite_off");
                        }
                        _target.addClass("favourite_loading");
                        Artportalen.ajaxPost(Artportalen_ApplicationPath + '/User/ToggleCoObserver/', { userId: _target.attr("data-id") }, function (items, code, xht) {
                            _target.siblings("a.item").effect("highlight", { color: "#90cd00" }, 2000, function () {
                                _target.removeClass("favourite_loading").toggleClass("favourite_on");
                            });
                        });
                        return false;
                    }

                var itemValue = "", userAlias = "";
                    if (_target.is(".item")) {
                        _text = _target.find(".text").text();
                        itemValue = _target.attr("data-id"); // Fetch value (id) of item
                        userAlias = _target.attr("data-useralias");
                    }

                    $(inputBox).parent().find('.ap2-ui_input_autocomplete-value').val(itemValue).change(); // Set value input box to id


                    // Set text input box to item main text
                    $(inputBox).val(_text);
                    oldValue = $(inputBox).val();

                    // Hide dropdown and empty it
                    $(this).hide().empty();

                    //$(inputBox).change();
                    var arrSelectedValues = [itemValue, _text, userAlias];

                    $(inputBox).triggerHandler("updatedAutocompleteValue", [arrSelectedValues]); // trigger this event so that the value automatically jumps away

                });


            // Adjust the tooltip position if the window is resized - uses a timer to prevent bad performance
            var adjustTimer;
            $(window).smartresize(function (event) {
                clearTimeout(adjustTimer);
                if ($(popupList).is(":visible")) {
                    adjustTimer = setTimeout(function () {
                        if ($(popupList).data("targetposition") !== undefined) {
                            $(popupList).css('left', $(popupList).data("targetposition").parent().offset().left);
                            $(popupList).css('top', $(popupList).data("targetposition").parent().offset().top + $(inputBox).parent().outerHeight() - 1);
                        }
                    }
                    , 100);
                }
            });

            // Keyboard navigation on keydown
            $(inputBox).keydown(function (event) {
                // ESCAPE - close menu
                if (event.keyCode == 27) {
                    $(popupList).hide().empty();
                }

                // Tab or Enter key - select item
                if (event.keyCode == 9 || event.keyCode == 13) {
                    if ($(popupList).is(':visible')) {
                        event.preventDefault();
                        var $selectedItem = $(popupList).find('.item-selected');
                        $selectedItem.click();
                        $(inputBox).change(); // trigger this event so that the value automatically jumps away
                    }
                }
                // Arrow down key - navigate down in the list of items
                if (event.keyCode == 40) {
                    var $selectedItem = $(popupList).find('.item-selected');
                    var $nextItem = $selectedItem.parent('li').next().find('a.item');
                    if ($nextItem.hasClass('item')) {
                        $selectedItem.removeClass('item-selected');
                        $nextItem.focus().addClass('item-selected');
                    } else if ($selectedItem.parent('li').next().hasClass('noresult')) {
                        $(popupList).find("ul").scrollTop($(popupList).find("ul")[0].scrollHeight);
                    }
                }

                // Arrow up key - navigate up in the list of items
                if (event.keyCode == 38) {
                    var $selectedItem = $(popupList).find('.item-selected');
                    var $previousItem = $selectedItem.parent('li').prev().find('a.item');
                    if ($previousItem.hasClass('item')) {
                        $selectedItem.removeClass('item-selected');
                        $previousItem.focus().addClass('item-selected');
                    }
                }

                if (jQuery.inArray(event.keyCode, [9, 13, 27, 40, 38]) == -1) {
                    if ($(this).val().length > 2) {
                        $(popupList).css({
                            'width': ($(inputBox).parent().outerWidth() - 2),
                            'left': $(inputBox).parent().offset().left,
                            'top': $(inputBox).parent().offset().top + ($(inputBox).parent().outerHeight() - 1)
                        }).html("<ul><li class='searching'>" + Artportalen.ResourceLabel("Shared_JavaScript_Searching") + "</li></ul>").show();
                    } else {
                        $(popupList).html("<ul><li class='noresult'>" + Artportalen.ResourceLabel("Shared_JavaScript_NoSearchResult") + "</li></ul><div class='closelist'><a href='#' class='closelist'>" + Artportalen.ResourceLabel("Shared_JavaScript_Close") + "</a></div>").show();
                    }
                }

                $(inputBox).focus();
            });

            var timer = 500;
            $(inputBox).keyup(function (event) {
                // Ignore escape, arrow up or arrow down
                if (event.keyCode == 38 || event.keyCode == 40 || event.keyCode == 27) return false;
                event.preventDefault();
                newValue = $(this).val();
                if (newValue == '') {
                    $(inputBox).parent().find('.ap2-ui_input_autocomplete-value').val('-1');
                    $(popupList).hide();
                    $(popupList).empty();
                    return true;
                }
                if (newValue != oldValue) {
                    if (newValue.length > 2) {
                        // Find Include old accounts in search value
                        var includeOldPortalsAccounts = $(inputBox).parent().parent().find('#ap2-ui_input_includeoldaccounts').length ? $(inputBox).parent().parent().find('#ap2-ui_input_includeoldaccounts').attr('checked') : false;
                        if (includeOldPortalsAccounts == 'checked') {
                            includeOldPortalsAccounts = true;
                        }

                        // Find Include current user in search value
                        var topListUsers = $(inputBox).parent().parent().find('#ap2-ui_input_toplistusers').length ? $(inputBox).parent().parent().find('#ap2-ui_input_toplistusers').val() : false;

                        var hasCollection = $(inputBox).parent().parent().find('#ap2-ui_input_user_has_collection_selector').length ? $(inputBox).parent().parent().find('#ap2-ui_input_user_has_collection_selector').val() : false;

                        // Wrap the server fetching in a timerCallback
                        var timerCallback = function () {
                            Artportalen.ajaxPost(settings.actionPath,
                                            {
                                                Search: newValue,
                                                FilterByHasCollection: hasCollection,
                                                IncludeAccountsFromOldPortals: includeOldPortalsAccounts,
                                                IncludeCurrentUserInResult: settings.includeCurrentUserInResult,
                                                TopListUsers: topListUsers
                                            },
                                            function (data, code, xht) {
                                                $populate(popupList, data, newValue, inputBox, settings.mainTextProperty, settings.subTextProperty, settings.handleFavourites);
                                            });
                        };
                        clearTimeout(timer);
                        timer = setTimeout(timerCallback, 500); // Wait for X ms until the AJAX is called
                    }
                    else {
                        $(popupList).hide();
                        $(popupList).empty();
                    }
                    koldValue = newValue;
                    return true;
                }
            });

            $populate = function (container, data, searchString, inputBox, mainText, subText, addFavouriteHtml) {
                $(container).empty();
                if (data.length == 0) {
                    $(container).append("<ul><li class='noresult'>" + Artportalen.ResourceLabel("Shared_JavaScript_NoSearchResult") + "</li></ul>");
                }

                var returnHTML = ["<ul>"];

                // Loop trough JSON-items
                $.each(data, function (index, itemData) {
                    // Main text for item with the entered search string higlighted
                    var nameContainer = $("<span />").addClass('ap2-ui_input_autocomplete_item-text');
                    var nameTextNode = document.createTextNode(eval('itemData.' + mainText));
                    $(nameContainer).append(nameTextNode);
                    var nameSegments = $.trim(searchString).split(' ');
                    var textToSearchForSegmentsThatMatch = $(nameContainer).html();
                    var newHtml = '';
                    var complexNewHtml = '';
                    for (var segmentIndex = 0; segmentIndex < nameSegments.length; segmentIndex++) {
                        if (newHtml.length != 0) {
                            if (segmentIndex < 2) {
                                newHtml = newHtml.replace(textToSearchForSegmentsThatMatch, '');
                            } else {
                                complexNewHtml = newHtml;
                                newHtml = newHtml.replace(new RegExp('(^|\\s)(' + nameSegments[segmentIndex-1] + ')', 'ig'), '');
                            }
                        }

                        if (segmentIndex < 2){
                            newHtml += textToSearchForSegmentsThatMatch.replace(new RegExp('(^|\\s)(' + nameSegments[segmentIndex] + ')', 'ig'), '$1<b class="marked-text">$2</b>');    
                        }
                        else if (segmentIndex >= 2) {
                            newHtml = complexNewHtml;
                        }

                        textToSearchForSegmentsThatMatch = $(nameContainer).html().replace(new RegExp('(^|\\s)(' + nameSegments[segmentIndex] + ')', 'ig'), '$1');
                    }
                    if (newHtml.length != 0) {
                        $(nameContainer).html(newHtml);
                    }

                    var oldPortalAccountItemClass = (itemData.IsOldPortalAccount) ? " oldPortalAccountItem" : "";
                    var itemClass = "item clearfix" + oldPortalAccountItemClass;
                    var aClass = (index === 0) ? "item item-selected clearfix" : itemClass;
                    var isFavourite = (itemData.IsCoObserver) ? " favourite_on" : "";
                    var liClass = "<li>";
                    if ($(inputBox).is(".ap2-ui_input_organizationselector")) {
                        returnHTML.push(liClass + "<a href='#' data-id='" + itemData.Id + "' class='" + aClass + "'><span class='subtext'>" + eval('itemData.' + subText) + "</span><span class='text'>" + nameContainer.html() + "</span></a>");
                    } else {
                        returnHTML.push(liClass + "<a href='#' data-id='" + itemData.Id + "' data-useralias='" + itemData.UserAlias + "' class='" + aClass + "'><span class='subtext'>" + eval('itemData.' + subText) + "</span><span class='text'>" + nameContainer.html() + "</span></a>");
                    }
                    if (addFavouriteHtml)
                        returnHTML.push("<a href='#' data-id='" + itemData.Id + "' class='favourite" + isFavourite + "' title='" + Artportalen.ResourceLabel("Shared_JavaScript_SaveCoObserver") + "'>&nbsp;</a>");
                    returnHTML.push("</li>");
                });
                returnHTML.push("</ul><div class='closelist'><a href='#' class='closelist'>" + Artportalen.ResourceLabel("Shared_JavaScript_Close") + "</a></div>");

                // Populate the dropdown and position it below the input
                var inputPosition = $(inputBox).parent().offset();
                var populated = $(container)
                    .css({
                        'width': ($(inputBox).parent().outerWidth() - 2),
                        'left': inputPosition.left,
                        'top': inputPosition.top + ($(inputBox).parent().outerHeight()-1)
                    })
                    .append(returnHTML.join(''))
                    .show();
                populated.find("a[data-useralias]").popupInfoTooltip({ onFocus: true });

                $(inputBox).triggerHandler("populated", [data]);
            };
        }
    });
};

$.fn.multiselect = function () {
    return this.each(function () {
        if (this.tagName == 'UL') {
            var selectionList = this;
            var outerContainer = $(selectionList).parent().parent().parent();
            var valueInputBox = $(outerContainer).find(".ap2-ui_input_multiselector-value");
            var textInputBox = $(outerContainer).find("#" + $(valueInputBox).attr("id") + "_Selector_Text");
            var addButton = $(outerContainer).find(".ap2-ui_input_multiselector-button_add");
            var selectorValue = $(outerContainer).find("#" + $(valueInputBox).attr("id") + "_Selector_Value");
            var selectorText = $(outerContainer).find("#" + $(valueInputBox).attr("id") + "_Selector_Text");
            var emptyItem = $("li.empty", selectionList);

            function setEmptyItem() {
                emptyItem.toggle(($("li:not(.empty):visible", selectionList).length == 0));
            }
            setEmptyItem();


            selectorText.bind("updatedAutocompleteValue", function (event, data) {
                event.preventDefault();
                var itemValue = data[0];
                var itemText = data[1];
                var existingIds = $(valueInputBox).val().split(",");
                itemValue = itemValue + ""; // Quirkiness! jQuery.inArray cant compare different datatypes (int vs string) so we need to convert this value to a string by adding + "" 
                if (itemValue == 0 || itemValue == "" || jQuery.inArray(itemValue, existingIds) != -1) {
                    // Display a warning if the value already exists
                    Artportalen.AlertBox({
                        textMessage: Artportalen.ResourceLabel("Shared_JavaScript_NoDuplicateValue"),
                        buttonText: "OK",
                        buttonFunction: null
                    });
                    setEmptyItem();
                    $(textInputBox).val("");
                    $(selectorValue).val("");
                } else {
                    $(selectionList).append($("<li><a href='#' data-id='" + itemValue + "'>" + itemText + "<span class='close'></span></a></li>").hide());
                    textInputBox.effect("transfer", { to: $("li:visible:last", selectionList) }, 300, function () {
                        setEmptyItem();
                        $(selectionList).find("li:hidden:not(.empty)").show();
                        serializeProjectMembers();
                        $(".user-profile").closest(".tt-popup").hide();
                    });
                }
            });

            $(".ap2-ui_input_multiselector a:not(.disabled)").live("click", function (e) {
                e.preventDefault();
                $(this).parent("li").remove();
                return serializeProjectMembers();

            });

            function serializeProjectMembers() {
                var list = '';
                $(selectionList).children("li:not(.empty)").each(function () {
                    //list += $(this).children("span").text() + ','; // <span style='display: none;'>" + selectorItemValue + "</span>
                    list += $(this).find("a").attr("data-id") + ',';
                });
                $(valueInputBox).val(list);
                setEmptyItem();
                $(textInputBox).val("");
                $(selectorValue).val("");
                return true;
            }
        }
    });
};
;
/// <reference path="Artportalen.AutoComplete.js"/>
/// <reference path="../jquery/jquery-1.4.2.js"/>

var Artportalen = Artportalen || {};


Artportalen.ActivateMultiSelect = function (element) {
    var $multiSelector = ($(element).length) ? $(element).find('ul.ap2-ui_input_multiselector') : $('ul.ap2-ui_input_multiselector');
    if ($multiSelector.length != 0) {
        $multiSelector.filter(":not(.ap2-ui_input_multiselector-disabled)").multiselect();
    }
};

Artportalen.ActivateDatePickers = function (element) {

    Artportalen.DatePickerSettings = {
        showAnim: '',
        showOtherMonths: true,
        selectOtherMonths: true,
        showOn: 'button',
        buttonText: Artportalen.ResourceLabel('Shared_JavaScript_SelectDateFromCalendar'),
        buttonImage: Artportalen_ApplicationPath + '/Content/Images/clear.gif',
        buttonImageOnly: true,
        showWeek: true,
        firstDay: 1,
        changeMonth: true,
        changeYear: true,
        duration: 0
    };

    var $datePicker = ($(element).length) ? $(element).find('input.ap2-ui_input_datepicker') : $('input.ap2-ui_input_datepicker');
    if ($datePicker.length !== 0) {
        $datePicker.datepicker(Artportalen.DatePickerSettings, $.datepicker.regional['artportalen']);
    }
};

Artportalen.ActivateAutoComplete = function (element) {
    var $userSelectorWithCurrentUserInResult = ($(element).length) ? $(element).find('input.ap2-ui_input_userselector_withcurrentuser') : $('input.ap2-ui_input_userselector_withcurrentuser');
    if ($userSelectorWithCurrentUserInResult.length != 0) {
        $userSelectorWithCurrentUserInResult.apautocomplete({
            includeCurrentUserInResult: true
        });
    }
    var $userSelectorWithCurrentUserNoFavouritesInResult =
        ($(element).length) ?
        $(element).find('input.ap2-ui_input_userselector_withcurrentuser_nofavourites') :
        $('input.ap2-ui_input_userselector_withcurrentuser_nofavourites');
    if ($userSelectorWithCurrentUserNoFavouritesInResult.length != 0) {
        $userSelectorWithCurrentUserNoFavouritesInResult.apautocomplete({
            handleFavourites: false
        });
    }
    var $userSelector = ($(element).length) ? $(element).find('input.ap2-ui_input_userselector') : $('input.ap2-ui_input_userselector');
    if ($userSelector.length != 0) {
        $userSelector.apautocomplete();
    }
    var $userConversationSelector = ($(element).length) ? $(element).find('input.ap2-ui_input_userforconversationselector') : $('input.ap2-ui_input_userforconversationselector');
    if ($userConversationSelector.length != 0) {
        $userConversationSelector.apautocomplete({ actionPath: Artportalen_ApplicationPath + '/User/FindUsersByNameForConversation' });
    }
    var $userWithCollectionSelector = ($(element).length) ? $(element).find('input.ap2-ui_input_user_with_collectionselector') : $('input.ap2-ui_input_user_with_collectionselector');
    if ($userWithCollectionSelector.length != 0) {
        $userWithCollectionSelector.apautocomplete({ filterByHasCollection: true });
    }
    var $organizationSelector = ($(element).length) ? $(element).find('input.ap2-ui_input_organizationselector') : $('input.ap2-ui_input_organizationselector');
    if ($organizationSelector.length != 0) {
        $organizationSelector.apautocomplete({
            handleFavourites : false,
            actionPath: Artportalen_ApplicationPath + '/User/FindOrganizationsByName',
            mainTextProperty: 'Name',
            subTextProperty: 'OrganizationType.OrganizationTypeName'
        });
    }
};

// Activate pickers for biotope, substrate and project
Artportalen.ActivateSimplePickers = function (element) {
    var _inputSimpleBiotopePicker = ($(element).length) ? $(element).find('input.ap2-ui_input_biotopepicker') : $('input.ap2-ui_input_biotopepicker');
    if (_inputSimpleBiotopePicker.length != 0) {
        _inputSimpleBiotopePicker.ap2Picker({
            ajaxSearchUrl: Artportalen_ApplicationPath + '/SimplePicker/SearchBiotope',
            ajaxChildrenUrl: Artportalen_ApplicationPath + '/SimplePicker/RenderBiotopeChildren',
            renderTopLevel: true,
            ajaxRenderTopLevelUrl: Artportalen_ApplicationPath + '/SimplePicker/RenderTopLevelBiotopes'
        }).bind("pickerItemSelected", function (event, data) {
            event.preventDefault();
            var itemValue = data[0];
            var itemText = data[1];
            var itemJson = jQuery.parseJSON(data[2]);
            var $wrapper = $(this).closest(".ap2picker").hide();
            $(this).simplepickerSetValues(itemJson.name, itemJson.id, false, false, null);
        });
    }

    var _inputSimpleSubstratePicker = ($(element).length) ? $(element).find('input.ap2-ui_input_substratepicker') : $('input.ap2-ui_input_substratepicker');
    if (_inputSimpleSubstratePicker.length != 0) {
        _inputSimpleSubstratePicker.ap2Picker({
            ajaxSearchUrl: Artportalen_ApplicationPath + '/SimplePicker/SearchSubstrate',
            ajaxChildrenUrl: Artportalen_ApplicationPath + '/SimplePicker/RenderSubstrateChildren',
            renderTopLevel: true,
            ajaxRenderTopLevelUrl: Artportalen_ApplicationPath + '/SimplePicker/RenderTopLevelSubstrates'
        }).bind("pickerItemSelected", function (event, data) {
            event.preventDefault();
            var itemValue = data[0];
            var itemText = data[1];
            var itemJson = jQuery.parseJSON(data[2]);
            var $wrapper = $(this).closest(".ap2picker").hide();
            $(this).simplepickerSetValues(itemJson.name, itemJson.id, false, false, null);
        });
    }

    var _inputSimpleProjectPicker = ($(element).length) ? $(element).find('input.ap2-ui_input_projectpicker') : $('input.ap2-ui_input_projectpicker');
    if (_inputSimpleProjectPicker.length != 0) {
        var renderTopLevelUrl = Artportalen_ApplicationPath + '/SimplePicker/RenderProjectCategories';
        var searchUrl = Artportalen_ApplicationPath + '/SimplePicker/SearchProject';
        var childrenUrl = Artportalen_ApplicationPath + '/SimplePicker/RenderProjects';
        var noCacheUrl = false;
        var filterSection = ['<div class="projectfilterbar"><label><input type="checkbox" class="filterprojects">&nbsp;', Artportalen.ResourceLabel("Shared_ShowPublicProjects"), '</label></div>'].join('');

        if (_inputSimpleProjectPicker.hasClass('ap2-ui-projectpicker_filter_on_user')) {
            searchUrl = Artportalen_ApplicationPath + '/SimplePicker/SearchUserProject';
            childrenUrl = Artportalen_ApplicationPath + '/SimplePicker/RenderUserProjects';
            noCacheUrl = true;
        }
        if (_inputSimpleProjectPicker.hasClass('ap2-ui-projectpicker_filter_on_atlassurvey')) {
            renderTopLevelUrl = Artportalen_ApplicationPath + '/SimplePicker/RenderAtlasSurveyProjectCategories';
            searchUrl = Artportalen_ApplicationPath + '/SimplePicker/SearchAtlasSurveyProject';
            childrenUrl = Artportalen_ApplicationPath + '/SimplePicker/RenderAtlasSurveyProjects';
            noCacheUrl = true;
            filterSection = '';
        }
        _inputSimpleProjectPicker.ap2Picker({
            ajaxSearchUrl: searchUrl,
            ajaxChildrenUrl: childrenUrl,
            renderTopLevel: true,
            noCacheUrl: true,
            ajaxRenderTopLevelUrl: renderTopLevelUrl,
            afterRenderCallback: function() {
                $("ul.ap2picker-dropdown:visible a[data-projectid]").popupInfoTooltip();
                $(".ap2picker-dropdown-wrapper:visible .filterprojects").unbind().click(function (e) {
                    var isChecked = $(this).is(":checked");
                    console.log(isChecked);
                    $("ul.ap2picker-dropdown:visible").toggleClass("hideprivate", isChecked);
                });
            },
            filterSection: filterSection
        }).bind("pickerItemSelected", function (event, data) {
            event.preventDefault();
            var itemValue = data[0];
            var itemText = data[1];
            var itemJson = jQuery.parseJSON(data[2]);     
            
            if ($("#SearchViewModel_StoredSearchCriterias_SearchCriterias_Projects").length) {
                $("#SearchViewModel_StoredSearchCriterias_SearchCriterias_Project_Name").val("")
                var currentSelection = $("#SearchViewModel_StoredSearchCriterias_SearchCriterias_Projects").val().split(",");
                if (currentSelection.indexOf(data[0].toString()) == -1) {
                    $("#selprojects").append("<li class='added-proj'><a href='#' data-id='" + data[0] + "'>" + data[1] + "</a></li>");
                    setHiddenFieldForProjects();
                    $(".added-proj").unbind().click(function (event) {
                        if (event.target.tagName != "LI") {
                            event.preventDefault();
                            $(event.target).parent().remove();
                            setHiddenFieldForProjects();
                        }
                    })
                }
            }
            else {
                var $wrapper = $(this).closest(".ap2picker").hide();
                $(this).simplepickerSetValues(itemJson.name, itemJson.id, false, false, element);
            }
            $(this).change();
        });
    }
    function setHiddenFieldForProjects() {
        let currentProjects = []
        $(".added-proj").each(function () {
            $(this).children().each(function () {
                currentProjects.push($(this).attr("data-id"))
            })
        })
        $("#SearchViewModel_StoredSearchCriterias_SearchCriterias_Projects").val(currentProjects);
    }
    var _inputSimpleCollectorPicker = ($(element).length) ? $(element).find('input.ap2-ui_input_collectorpicker') : $('input.ap2-ui_input_collectorpicker');
    if (_inputSimpleCollectorPicker.length != 0) {

        _inputSimpleCollectorPicker.ap2Picker({
            ajaxSearchUrl: Artportalen_ApplicationPath + '/SimplePicker/SearchSpeciesCollector',
            ajaxChildrenUrl: '',
            renderTopLevel: false,
            afterRenderCallback: function () {
                $("ul.ap2picker-dropdown:visible a[data-id]").popupInfoTooltip();
            },
        }).bind("pickerItemSelected", function (event, data) {
            event.preventDefault();
            var itemValue = data[0];
            var itemText = data[1];
            var itemJson = jQuery.parseJSON(data[2]);
            var $wrapper = $(this).closest(".ap2picker").hide();
            $(this).simplepickerSetValues(itemJson.name, itemJson.id, false, false, element);
            $(this).change();
        });
    }
};

Artportalen.ActivateTaxonPickers = function (element) {
    var _inputTaxonPicker = ($(element).length) ? $(element).find('input.ap2-ui_input_taxonpicker') : $('input.ap2-ui_input_taxonpicker');
    if (_inputTaxonPicker.length != 0) {
        _inputTaxonPicker.ap2Picker({
            keyUpTimeOut: 500,
            ajaxSearchUrl: Artportalen_ApplicationPath + '/Taxon/PickerSearch',
            ajaxChildrenUrl: Artportalen_ApplicationPath + '/Taxon/RenderChildren',
            renderTopLevel: false,
            noCacheUrl: true,
        }).bind("resetPickerValue", function (event, data) {
            event.preventDefault();
            var $self = $(this);
            var $pickerWrapper = $self.closest('.ap2picker');
            $pickerWrapper.find('.ap2-ui-taxonpicker-selected-taxon-label').hide();
            $self.closest(".ap2-ui-taxonpicker-wrapper").show().end();
            $pickerWrapper.find('.ap2picker_value').val("").change();
            $self.val($self.val());
            $self.trigger("pickerValueEmpty");
        }).bind("pickerItemSelected", function (event, data) {
            event.preventDefault();
            var $self = $(this);
            var $pickerWrapper = $self.closest('.ap2picker');
            var $form = $self.closest('form');
            var itemValue = data[0];
            var itemText = data[1];
            var itemJSON = jQuery.parseJSON(data[2]);

            $self.data("pickedvalues", JSON.stringify(data)); // Store values in the data attribute
            //console.log(data);
            //console.log(itemJSON);
            //console.log(itemJSON.AltTaxonName);

            var $speciesGroupId = $pickerWrapper.find('.ap2-ui_input_taxonpicker_speciesgroupid');
            if ($speciesGroupId.val() != itemJSON.speciesgroupid) {
                $speciesGroupId.val(itemJSON.speciesgroupid).change();
            }
            $pickerWrapper.find(".ap2-ui-taxonpicker_lookuptaxonname").val($self.val());
            $pickerWrapper.find(".ap2-ui-taxonpicker_selectedtaxonname").val(itemText);
            $pickerWrapper.find(".ap2-ui-taxonpicker_taxonlookupspeciesnameslanguage").val($pickerWrapper.find('.ap2-ui_input_taxonpicker_language').val());

            var $selectedTaxonLabel = $pickerWrapper.find('.ap2-ui-taxonpicker-selected-taxon-label');
            var _speciesnameScientificLabel = $selectedTaxonLabel.find("h6.speciesname_scientific");
            if (itemText != itemJSON.scientificname && _speciesnameScientificLabel.length) {
                _speciesnameScientificLabel.text(itemJSON.scientificname + " " + itemJSON.auktor).show();
            } else if (itemJSON.auktor != "") {
                _speciesnameScientificLabel.text(itemJSON.auktor).show();
            } else {
                _speciesnameScientificLabel.text("").hide();
            }

            if ($selectedTaxonLabel.length) {

                var protectionLevelHtml = itemJSON.protectionlevelid > 1 ? "<span class='UI-Icon-16 UI-Icon-16-NoFloat UI-Icon-16-ProtectedBySystem'></span>" : "";

                if (($form.prop("action").indexOf("/SubmitSighting/Report") != -1) && itemJSON.AltTaxonName.length > 0) {
                    $selectedTaxonLabel.find("h3").attr("data-taxonid", itemJSON.taxonid).html(jQuery.trim(itemJSON.AltTaxonName) + protectionLevelHtml).popupInfoTooltip();
                }
                else {
                    $selectedTaxonLabel.find("h3").attr("data-taxonid", itemJSON.taxonid).html(jQuery.trim(itemText) + protectionLevelHtml).popupInfoTooltip();
                }
                $selectedTaxonLabel.find(":checkbox").removeAttr('disabled').closest("div.ap2-ui-form-error").removeClass("ap2-ui-form-error ap2-ui-form-noneditable"); // uncheck both unsure determination and xxx

                // Store and uncheck checked checkboxes
                var checkedCheckboxes = [];
                $selectedTaxonLabel.find(":checked").each(function() {
                    checkedCheckboxes.push($(this));
                    $(this).attr('checked', false);
                });

                // Re-check checkboxes
                $.each(checkedCheckboxes, function () {
                    $(this).trigger('click');
                });
                
                $selectedTaxonLabel.find(".close-this-div").unbind().click(function (event) {
                    event.preventDefault();
                    $selectedTaxonLabel.hide();
                    $self.closest(".ap2-ui-taxonpicker-wrapper").show().end().focus();
                    $pickerWrapper.find('.ap2picker_value').val("").change();
                    $self.focus().val($self.val()).select();
                    $self.trigger("pickerValueEmpty");
                });
                $self.closest(".ap2-ui-taxonpicker-wrapper").hide();
                $selectedTaxonLabel.show();
                $selectedTaxonLabel.find(".close-this-div");
            }
        });

        // If the taxon picker only get one hit - autoselect it
        var autoselect = _inputTaxonPicker.closest(".ap2picker").find(".ap2picker_autoselect").val();
        autoselect = autoselect || "";
        if (autoselect.toLowerCase() == "true") {
            _inputTaxonPicker.bind("SimplePicker_Navigation_Applied", { requiredLength: 1, autoselectItem: 0 }, function (e, data) {
                ///	<summary>
                ///		1: Event handler for SimplePicker_Navigation_Applied event to create autoselect.
                ///     2: Will trigger an autoselect on the e.data.autoselectItem item in data.items list.
                ///	</summary>
                ///	<param name="e" type="event object">
                ///     1: event.data : { requiredLength: <restrict when to autoselect>,  autoselectItem: <item that will be selected, 0 is item 1> }
                ///	</param>
                ///	<param name="data" type="data object">
                ///		1: data object : array with items, data.items holds the resulting rows for the search expression.  }
                ///	</param>
                if (data.items.length != 0 && data.items.length <= e.data.requiredLength) {
                    $(data.items.eq(e.data.autoselectItem)).find('a').click();
                }
            });
        }
    }
};

Artportalen.EnableHistoryJS = function () {
    /* Enables History.js (https://github.com/balupton/History.js) */
    var History = window.History; // Note: We are using a capital H instead of a lower h
    if (!History.enabled) {
        // History.js is disabled for this browser.
        // This is because we can optionally choose to support HTML4 browsers or not.
        return false;
    }
};

Artportalen.Initialize = function () {

    // globally turn off all ajax cache. 
    // globally redirect to LogOn if unauthorized 
    $.ajaxSetup({
        cache: true,
        statusCode: {
            401: function () {
                location.href = Artportalen_ApplicationPath + "/LogOn";
            }
        }
    });

    // Check for notifications about new messages if the user is logged in
    if (Artportalen.IsUserLoggedIn()) {
        Artportalen.GetAjaxNotifications();
    }

    // Add popup tooltip for organisation information in the pagefooter
    $("#footer").find("a[data-organisationdetails]").popupInfoTooltip({ mouseInDelay : 1000 });

    Artportalen.FixConsole(); /* Fix the console.log() issue in IE */
//    Artportalen.LogoImageReplace(); /* Run Accessible Image Replacement for Logo */
    Artportalen.MainNavigation(); /* Init jQuery enhanced Main Navigation */
    Artportalen.FormFieldInstructions(); /* Tooltip next to forms */

    /* Activate different pickers and enhanced form inputs */
    Artportalen.ActivateDatePickers();
    Artportalen.ActivateMultiSelect();
    Artportalen.ActivateAutoComplete();
    Artportalen.ActivateSimplePickers();
    Artportalen.ActivateTaxonPickers();

    Artportalen.EnableHistoryJS();

    // Artportalen.LoginWindow(); // Inactivated
    // Artportalen.ShowGrid(); /* Debug mode fro blueprint.css, shows a grid (background-image) when key F11 is activated */
};

$(document).ready(function () {
    Artportalen.Initialize();
});





;
/// <reference name="MicrosoftAjax.js"/>
/// <reference path="../Map/OpenLayers.js"/>
/// HOEM move stuff here from local file

var oldGeometry = null;

var apMapPopupContainer;
var apMapPopup;
var apMapBussyLoaderContainer;
var apMapBussyLoader;
var apMapClusterSource;
var apAtlasLevel1 = { min: 0, max: 0, color: "#FFFFFF", opacity: 0.4 };
var apAtlasLevel2 = { min: 0, max: 0, color: "#FFFFFF", opacity: 0.4 };
var apAtlasLevel3 = { min: 0, max: 0, color: "#FFFFFF", opacity: 0.4 };
var apAtlasLevel4 = { min: 0, max: 0, color: "#FFFFFF", opacity: 0.4 };
var apAtlasLevel5 = { min: 0, max: 0, color: "#FFFFFF", opacity: 0.4 };
var apPopupOffset = [10, 10];
var highlight;
var hooverHighlight;
var showFeaturePopup;
var closeSelectPopup = true;
var currentSelectId = true;
var apFitPadding = [180, 180, 180, 180];
var unselectFeat = false;
var currentClickCoordinate;
var currentHooverCoordinate;
var apSearchDotMap;
var apSearchValidationMap;
var apTheMap;
var selectFeaturePopup = false;
var coordinateStringPresentation = "";
var previouslyFetchedMapData = null;

Artportalen.DiffusionOpacity = 0.2;
Artportalen.DiffusionColor = '255, 0, 0';

function initOpenlayersMap(divId, panelDivId, mapOption, mapLayers, mapState) {
    /// <summary>Initiates a new openlayer map in a div</summary>
    /// <return>Reference to the new openlayermap</return>
    //clean div
    $('#' + divId).html('');

    var map = new ol.Map({
        target: divId,
        view: new ol.View({
            center: [1838452, 9112665],
            zoom: 5
        }),

        controls: [
            new ol.control.Zoom(),
            new ol.control.ZoomSlider(),
            new ol.control.ScaleLine(),
            //new ol.control.MousePosition(),
            new ol.control.OverviewMap(),
            new ol.control.Attribution()
        ]

    });

    for (var i = 0; i < mapLayers.length; i++) {
        try {
            var aLayer = eval(mapLayers[i].initString);
            aLayer.dbid = mapLayers[i].name;            
            map.addLayer(aLayer);
        }
        catch (e) {console.log(e)}
    }

    if (mapState.SelectedCoordinateSystemId != null) {
        // todo: implement selecting correct active base layer on return
        map.coordinateSystem = mapState.SelectedCoordinateSystemId;
    }

    if (mapState.CurrentMapExtent != null) {
        //var bounds = new OpenLayers.Bounds.fromString(mapState.CurrentMapExtent.MinX + ',' + mapState.CurrentMapExtent.MinY + ',' + mapState.CurrentMapExtent.MaxX + ',' + mapState.CurrentMapExtent.MaxY);
        //map.zoomToExtent(bounds, false);
        map.getView().fit([mapState.CurrentMapExtent.MinX, mapState.CurrentMapExtent.MinY, mapState.CurrentMapExtent.MaxX, mapState.CurrentMapExtent.MaxY]);
    } else if (mapState.CenterX != null && mapState.CenterY != null && mapState.CenterY > 0) {
        // todo: probably unessecary - use extent instead
        //map.setCenter(new OpenLayers.LonLat(mapState.CenterX, mapState.CenterY), 14);
        map.getView().setZoom(14);
        map.getView().setCenter([mapState.CenterX, mapState.CenterY]);
    } else {
        //map.setCenter(new OpenLayers.LonLat(2000000, 9500000), 4);
        map.getView().setZoom(4);
        map.getView().setCenter([2000000, 9500000]);
    }

    map.mapOption = mapOption;

    if (localStorage.getItem('baseMapLayer') != "OpenStreetMap" && localStorage.getItem('baseMapLayer') != "Sverige" && localStorage.getItem('baseMapLayer') != "Sverige_nedtonad" && localStorage.getItem('baseMapLayer') != "SverigeOrtho") {
        setBaseLayer(map, 'Sverige');
    } else {
        setBaseLayer(map, localStorage.getItem('baseMapLayer'));
    }

    map.SiteFeatureUrl = Artportalen_ApplicationPath + '/ViewSighting/SiteFeatureAttributes'; // This will use the cached version of SFA. Override with url+NoCache if needed.
    map.temporarySite = null;

    map.featureToSelectId = null;
    map.skipSelectEvent = false;
    map.skipDeSelectEvent = false;
    map.unSelectTimeout = null;
    map.showAccuracy = true;
    map.zoomOrPanActive = false;
    map.firstDraw = true;
    map.selectAdminSighting = false;
    apSearchDotMap = false;
    apSearchValidationMap = false;
    map.drawActive = false;
    map.AtlasActive = false;
    map.mapOption.ShowPrivateBirdSites = false;
    map.mapOption.searchMap = true;

    map.coordinateSystem = 0;
    map.speciesGroupId = 0;

    map.selectedSite = -2;

    map.showOnlyProjects = false;

    if (sessionStorage.showCluster == 0) {
        map.showCluster = false;
    } else {
        map.showCluster = true;
    }
    map.breakYear = 2000;
    map.showValidated = true;

    var strokeColor = 'black';

    var delimitLayer = new ol.layer.Vector({
        title: 'theDelimitLayer',
        type: 'vector',
        visible: true,
        source: new ol.source.Vector({
            format: new ol.format.GeoJSON()
        }),
        style: SetDelimitStyle
    });
    map.addLayer(delimitLayer);

    function clusterFunction(feature) {
        if (feature.getGeometry().getType() == 'Point') {
            return feature.getGeometry();
        } else {
            return feature.getGeometry().getInteriorPoint();
        }
    }

    var siteLayer = new ol.layer.Vector({
        title: 'theSiteLayer',
        type: 'vector',
        visible: true,
        source: new ol.source.Vector({ format: new ol.format.GeoJSON() }),
        style: SetSiteStyle,
        zIndex: 4
    });
    map.addLayer(siteLayer);

    var siteArrowLayer = new ol.layer.Vector({
        title: 'theSiteArrowLayer',
        type: 'vector',
        visible: true,
        source: new ol.source.Vector({ format: new ol.format.GeoJSON() }),
        style: SetSiteStyle
    });
    map.addLayer(siteArrowLayer);

    var siteConnectionLayer = new ol.layer.Vector({
        title: 'theSiteConnectionLayer',
        type: 'vector',
        visible: true,
        source: new ol.source.Vector({ format: new ol.format.GeoJSON() }),
        style: SetSiteStyle
    });
    map.addLayer(siteConnectionLayer);

    var editableSiteLayer = new ol.layer.Vector({
        title: 'theEditableSiteLayer',
        type: 'vector',
        visible: true,
        source: new ol.source.Vector({ format: new ol.format.GeoJSON() }),
        style: SetSiteStyle,
        zIndex: 5
    });
    map.addLayer(editableSiteLayer);

    /*var precisionLayer = new ol.layer.Vector({
        title: 'thePrecisionLayer',
        type: 'vector',
        visible: true,
        /*source: new ol.source.Vector({
            format: new ol.format.GeoJSON()
        }),*/
    /*source: new ol.source.Cluster({ distance: 20, source: new ol.source.Vector({}) }),
    style: SetPrecisionLayerStyle
});
map.addLayer(precisionLayer);*/

    var precisionLayer = new ol.layer.Vector({
        title: 'thePrecisionLayer',
        type: 'vector',
        visible: true,
        source: new ol.source.Vector({
        }),
        style: SetAccuracyStyle,
        zIndex: 2
    });
    map.addLayer(precisionLayer);

    var priavteSiteLayer = new ol.layer.Vector({
        title: 'thePrivateSiteLayer',
        type: 'vector',
        visible: true,
        source: new ol.source.Vector({
        }),
        style: SetPrivateSiteStyle,
        zIndex: 5
    });
    map.addLayer(priavteSiteLayer);

    if (map.mapOption.AtlasMap == true || map.mapOption.AtlasSurveyMap == true) {
        var atlasLayer = new ol.layer.Vector({
            title: 'Atlas',
            type: 'vector',
            visible: true,
            source: new ol.source.Vector({
            }),
            style: SetAtlasStyle
        });
        map.layerAtlas = atlasLayer;
        map.addLayer(atlasLayer);
    }

    var hooverLayer = new ol.layer.Vector({
        title: 'theHooverLayer',
        type: 'vector',
        visible: true,
        source: new ol.source.Vector(),
        style: SetHooverHighlightStyle,
        zIndex: 7
    });
    map.addLayer(hooverLayer);

    var selectLayer = new ol.layer.Vector({
        title: 'theSelectLayer',
        type: 'vector',
        visible: true,
        source: new ol.source.Vector(),
        style: SetHighlightStyle,
        zIndex: 7
    });
    map.addLayer(selectLayer);

    var areasLayer = new ol.layer.Vector({
        title: 'theAreasLayer',
        type: 'vector',
        visible: true,
        source: new ol.source.Vector({ format: new ol.format.GeoJSON() }),
        style: SetAreaStyle,
        zIndex: 4
    });
    map.addLayer(areasLayer);

    if (map.mapOption.SosGeoServer != '' && map.mapOption.NornaRasterLayerName != '') {
        var nornaLayer = new ol.layer.Tile({
            title: 'theNornaLayer',
            visible: false,
            source: new ol.source.TileWMS({
                url: map.mapOption.SosGeoServer,
                params: { 'LAYERS': map.mapOption.NornaRasterLayerName }, //'NornaMean0216' },
                serverType: 'geoserver',
            })
        })
        map.addLayer(nornaLayer);
    }

    var getAtlasSurveyBaseRequest = function (request, url, data) {

        if (request != null) {
            request.abort();
        }
        ShowBussyLoader(map);
        request = $.ajax(
            {
                type: "GET",
                async: true,
                cache: true,
                url: url,
                data: data,
                success: function (results) {
                    if ((map.layerAtlas.features != null) && (map.layerAtlas.features != 'undefined')) {
                        if (!isEmpty(map.layerAtlas.features)) {
                            map.layerAtlas.destroyFeatures();
                        }
                    }

                    var foundCells = false;
                    var layer = getLayerByName(map, 'Atlas');
                    if ((layer.getSource().getFeatures() != null) && (layer.getSource().getFeatures() != 'undefined')) {
                        if (!isEmpty(layer.getSource().getFeatures())) {
                            layer.getSource().clear();
                        }
                    }
                    if ((results != null) && (results != "nothing" && results != '')) {
                        $(document).trigger("atlassquarescount", { count: results.AtlasCells.features.length, legends: results.Legend, datacount: results.Count, mapMode: results.MapMode, speciesGroupId: results.SpeciesGroupId });
                        var myObject = eval(results);
                        //var polfeatures = new OpenLayers.Format.GeoJSON().read(myObject.AtlasCells);
                        var polfeatures = new ol.format.GeoJSON().readFeatures(myObject.AtlasCells);
                        SetAtlasLevels(myObject.Legend.labels);
                        map.atlasLegend = myObject.Legend;
                        map.speciesGroupId = results.SpeciesGroupId;

                        if (polfeatures != null) {
                            foundCells = polfeatures.length > 0;
                            layer.getSource().addFeatures(polfeatures, { silent: true });
                        }
                    }

                    if (foundCells) {
                        map.getView().fit(layer.getSource().getExtent(), {});
                    }
                    HideBussyLoader();
                    request = null;
                },
                error: function (req, status, error) {
                    WriteDebugMessage("ERROR: /api/atlas/area not found or not responding...");
                    HideBussyLoader();
                    $(document).trigger("atlassquaresloadfail", error);
                }
            }
        );
    };

    map.asyncGetAtlasSurveyRequest = null;
    var getAtlasSurvey = function (projectId, taxonId, atlasStatusIds) {

        var url = window.Artportalen_ApplicationPath + "/AtlasSurvey/GetAtlasSurvey";
        var data = "project=" + projectId + "&taxon=" + taxonId + "&atlasStatusIds=" + atlasStatusIds + "&cache=" + new Date().getTime();
        getAtlasSurveyBaseRequest(map.asyncGetAtlasSurveyRequest, url, data);
    };

    map.asyncGetMyAtlasSurveyCellsRequest = null;
    var getMyAtlasSurveyCells = function (projectId, taxonId, atlasStatusIds) {
        var url = window.Artportalen_ApplicationPath + "/AtlasSurvey/GetMyAtlasSurveyCellsByProject";
        var data = "project=" + projectId + "&taxon=" + taxonId + "&atlasStatusIds=" + atlasStatusIds + "&cache=" + new Date().getTime();
        getAtlasSurveyBaseRequest(map.asyncGetMyAtlasSurveyCellsRequest, url, data);
    };

    map.asyncGetAdministratorsAtlasSurveyCellsRequest = null;
    var getAdministratorsAtlasSurveyCells = function (projectId, speciesGroupId) {

        map.speciesGroupId = speciesGroupId;
        var url = window.Artportalen_ApplicationPath + "/AtlasSurvey/GetAdministratorsAtlasSurveyCellsByProject";
        var data = "project=" + projectId + "&cache=" + new Date().getTime();
        getAtlasSurveyBaseRequest(map.asyncGetAdministratorsAtlasSurveyCellsRequest, url, data);
    };

    map.asyncGetSitesInAtlasRequest = null;

    map.asyncGetAtlasRequest = null;
    var getAtlas = function (areaId, atlasLayerId, taxonId, fromYear, toYear, includeSpeciesOnly, baseUri) {

        if (map.asyncGetAtlasRequest != null) {
            map.asyncGetAtlasRequest.abort();
        }
        ShowBussyLoader(map);
        map.asyncGetAtlasRequest = $.ajax(
            {
                type: "GET",
                async: true,
                cache: true,
                contentType: 'application/json; charset=UTF-8',
                url: baseUri + "/atlas/geojsonatlascells?areaId=" + areaId + "&atlasLayerId=" + atlasLayerId + "&taxonId=" + taxonId + "&fromYear=" + fromYear + "&toYear=" + toYear + "&includeSpeciesOnly=" + includeSpeciesOnly,
                success: function (results) {
                    var layer = getLayerByName(map, 'Atlas');
                    if ((layer.getSource().getFeatures() != null) && (layer.getSource().getFeatures() != 'undefined')) {
                        if (!isEmpty(layer.getSource().getFeatures())) {
                            layer.getSource().clear();
                        }
                    }

                    if ((results != null) && (results != "nothing" && results != '')) {
                        $(document).trigger("atlassquarescount", { count: results.atlasCells.features.length, legends: results.legend, datacount: results.count });
                        var myObject = eval(results);
                        var polfeatures = new ol.format.GeoJSON().readFeatures(myObject.atlasCells);
                        map.atlasLegend = myObject.legend;
                        SetAtlasLevels(myObject.legend.labels);
                        if (polfeatures != null) {
                            layer.getSource().addFeatures(polfeatures, { silent: true });
                        }
                    }
                    map.getView().fit(layer.getSource().getExtent(), {});
                    HideBussyLoader();
                    map.asyncGetAtlasRequest = null;
                },
                error: function (req, status, error) {
                    WriteDebugMessage("ERROR: /atlas/geojsonatlascells not found or not responding...");
                    HideBussyLoader();
                    $(document).trigger("atlassquaresloadfail", error);
                }
            }
        );
    };

    if (map.mapOption.AtlasMap == true) {
        map.getAtlas = getAtlas;
    }

    if (map.mapOption.AtlasSurveyMap == true) {
        map.getAtlasSurvey = getAtlasSurvey;
        map.getMyAtlasSurveyCells = getMyAtlasSurveyCells;
        map.getAdministratorsAtlasSurveyCells = getAdministratorsAtlasSurveyCells;
    }

    //trigger is commented out so no need to trigger it (I think)
    $('#' + divId).triggerHandler('onMapInitialized', map);
    map.divId = divId;

    apTheMap = map;

    map.on('moveend', OnMapPanOrZoom);

    if (mapOption.ShowSpecificSites == true) {
        if (mapOption.ShowSpecificSites == true || mapOption.ShowSpecificSitesIds != null) {
            var ids = mapOption.ShowSpecificSitesIds;
            GetSpecificGeoJSONSites(map, ids, false);
        }
    }

    var displayFeatureInfo = function (pixel, layer, coordinates, resolution, features) {
        if (features) {
            if (features != hooverHighlight) {
                var hooverLayer = getLayerByName(map, 'theHooverLayer');
                if (hooverHighlight) {
                    if (hooverLayer.getSource().getFeatures().length > 0) {
                        hooverLayer.getSource().clear();
                    }
                }
                hooverLayer.getSource().addFeature(features[0]);

                hooverHighlight = features;
            }
            if (showFeaturePopup) {
                var currentId = features[0].getId();
                if (currentSelectId != currentId) {
                    closeSelectPopup = true;
                }

                if (map.popupType == 'ShowFeaturePopup') {
                    ShowFeaturePopup(map, features, coordinates, pixel);
                } else if (map.popupType == 'ShowAtlasFeaturePopup') {
                    ShowAtlasFeaturePopup(map, features, coordinates);
                } else if (map.popupType == 'ShowAtlasSurveyFeaturePopup') {
                    ShowAtlasSurveyFeaturePopup(map, features, coordinates);
                }
            }
        }

    };

    map.on('click',
        function (evt) {
            if (!map.drawActive) {

                currentClickCoordinate = evt.coordinate;
                var tmpLayer;
                var features = [];
                map.forEachFeatureAtPixel(evt.pixel,
                    function (feature, layer) {
                        tmpLayer = layer;
                        if (layer && (layer.getProperties().title != 'theSiteLayer' &&
                            layer.getProperties().title != 'theEditableSiteLayer' &&
                            layer.getProperties().title != 'thePrivateSiteLayer' &&
                            layer.getProperties().title != 'Atlas')) {
                            feature = null;
                        } else {
                            //if (IsInside(map, currentClickCoordinate, feature)) {
                            features.push(feature);
                            //} 
                        }
                    });

                var coord = evt.coordinate;
                if (!map.selectAdminSighting) {
                    selectLayer.getSource().clear();
                }

                if (features.length > 0) {
                    features.forEach(function (fe) {
                        if (fe) {
                            selectLayer.getSource().getFeatures().forEach(function (fea) {
                                if (fea.getId() == fe.getId() && fea.getId() && fea.getId() != null) {
                                    unselectFeat = true;
                                    var featureInLayer = selectLayer.getSource().getFeatureById(fea.getId());
                                    if (featureInLayer) {
                                        selectLayer.getSource().removeFeature(fea);
                                    }

                                    $('#' + map.divId).triggerHandler('onMapSitesUnSelected', [fea]);
                                }
                            });

                            //if (!map.selectAdminSighting && IsInside(map, currentClickCoordinate, fe)) {
                            if (!map.selectAdminSighting) {
                                selectLayer.getSource().addFeature(fe);
                            } else {
                                selectLayer.getSource().addFeature(fe);
                            }

                            /*if (tmpLayer && tmpLayer != null){
                                displayFeatureInfo(evt.pixel, tmpLayer, coord, map.getView().getResolution(), [fe]);
                            }
                            closeSelectPopup = false;*/
                            currentSelectId = fe.getId();

                        }
                    });
                    if (tmpLayer && tmpLayer != null) {
                        displayFeatureInfo(evt.pixel, tmpLayer, coord, map.getView().getResolution(), features);
                        selectFeaturePopup = true;
                    }
                    closeSelectPopup = false;
                    //showFeaturePopup = true;
                } else {
                    //selectSite.getFeatures().clear();
                    //feature
                    closeSelectPopup = true;
                    apMapPopup.setPosition(undefined);
                    UnselectFeatures(map);
                    $('#' + map.divId).triggerHandler('onMapAllSitesUnSelected');

                    map.forEachFeatureAtPixel(evt.pixel,
                        function (feature, layer) {
                            tmpLayer = layer;
                            if (layer && (layer.getProperties().title != 'theSiteLayer' &&
                                layer.getProperties().title != 'theEditableSiteLayer' &&
                                layer.getProperties().title != 'thePrivateSiteLayer' &&
                                layer.getProperties().title != 'Atlas')) {
                                feature = null;
                            } else {
                                //if (IsInside(map, currentClickCoordinate, feature)) {
                                features.push(feature);
                                //}
                            }
                        });

                    $('#' + map.divId).triggerHandler('onMapSitesUnSelected', [features]);
                }
                $('#' + map.divId).triggerHandler('onMapClick', [features]);
            }

        });

    map.on('pointermove', function (evt) {
        if (evt.dragging) {
            return;
        }
        if (!map.drawActive) {
            var pixel = map.getEventPixel(evt.originalEvent);
            var coord = evt.coordinate;

            var features = [];
            var lay;
            map.forEachFeatureAtPixel(evt.pixel,
                function (feature, layer) {

                    if (layer && (layer.getProperties().title != 'theSiteLayer' &&
                        layer.getProperties().title != 'theEditableSiteLayer' &&
                        layer.getProperties().title != 'thePrivateSiteLayer' &&
                        layer.getProperties().title != 'Atlas')) {
                        feature = null;

                    } else {
                        lay = layer;
                        //if (IsInside(map, evt.coordinate, feature)) {
                        features.push(feature);
                        //currentClickCoordinate = evt.coordinate;
                        currentHooverCoordinate = evt.coordinate;
                        //}
                    }
                });

            if (features.length > 0) {
                if (!selectFeaturePopup || map.AtlasActive) {

                    displayFeatureInfo(pixel, lay, coord, map.getView().getResolution(), features);
                }

            } else {
                if (!selectFeaturePopup || map.AtlasActive) {
                    ClearHooverLayer(map);
                    if (closeSelectPopup && apMapPopup) {
                        apMapPopup.setPosition(undefined);
                    }

                }

            }
            if (!$(popup).is(":visible")) {
                selectFeaturePopup = false;
            }
        }
    });

    return map;
}  //end initOlMap

function ShowNornaRaster(map, show) {
    var x = getLayerByName(map, 'theNornaLayer');
    if (x) {
        x.setVisible(show);
    }
}

function SetAtlasLevels(label) {
    if (label.length > 1) {
        apAtlasLevel1.min = label[1].min;
        apAtlasLevel1.max = label[1].max;
        apAtlasLevel1.color = label[1].color;
        apAtlasLevel1.opacity = label[1].opacity;
    }
    if (label.length > 2) {
        apAtlasLevel2.min = label[2].min;
        apAtlasLevel2.max = label[2].max;
        apAtlasLevel2.color = label[2].color;
        apAtlasLevel2.opacity = label[2].opacity;
    }
    if (label.length > 3) {
        apAtlasLevel3.min = label[3].min;
        apAtlasLevel3.max = label[3].max;
        apAtlasLevel3.color = label[3].color;
        apAtlasLevel3.opacity = label[3].opacity;
    }
    if (label.length > 4) {
        apAtlasLevel4.min = label[4].min;
        apAtlasLevel4.max = label[4].max;
        apAtlasLevel4.color = label[4].color;
        apAtlasLevel4.opacity = label[4].opacity;
    }
    if (label.length > 5) {
        apAtlasLevel5.min = label[5].min;
        apAtlasLevel5.max = label[5].max;
        apAtlasLevel5.color = label[5].color;
        apAtlasLevel5.opacity = label[5].opacity;
    }
}

function AddInteraction(interAction, interActionObj, map) {
    var selectInteractionAlreadyExist = false;
    map.getInteractions().forEach(function (interaction) {
        if (interaction instanceof interAction) {
            selectInteractionAlreadyExist = true;
        }
    });
    if (!selectInteractionAlreadyExist) {
        map.addInteraction(interActionObj);
    }
}

function ClearSelectLayer(map) {
    getLayerByName(map, 'theSelectLayer').getSource().clear();
    highlight = null;
}

function ClearHooverLayer(map) {
    getLayerByName(map, 'theHooverLayer').getSource().clear();
    hooverHighlight = null;
}

function RemoveInteraction(map) {
    var continueSearch = true;
    while (continueSearch) {
        var interactionRemoved = false;
        map.getInteractions().forEach(function (interaction) {
            if (interaction instanceof ol.interaction.Select ||
                interaction instanceof ol.interaction.Draw ||
                interaction instanceof ol.interaction.Modify ||
                interaction instanceof ol.interaction.DragZoom ||
                interaction instanceof ol.interaction.Translate ||
                interaction instanceof ol.interaction.DragBox /*||
                interaction instanceof app.Drag*/) {
                interactionRemoved = true;
                map.removeInteraction(interaction);
            }
        });
        if (interactionRemoved) {
            continueSearch = true;
        } else {
            continueSearch = false;
        }
    }
}

function SetAreaStyle(feature, resolution) {
    let opacity = 0.1;
    let fillColor = 'rgba(51,136,255,' + opacity + ')';
    let strokeColor = '#3388ff';
    let strokeWidth = 1.25

    let currentFeature;
    if (feature.getProperties().features) {
        currentFeature = feature.getProperties().features[0];
    } else {
        currentFeature = feature;
    }

    style = PolygonStyle(currentFeature, fillColor, strokeColor, strokeWidth);

    return style;
}

function SetPrivateSiteStyle(feature, resolution) {
    /*if (feature.getProperties().features && IsCluster(feature)) { // Cluster
        feat = feature;
    } else*/ if (feature.getProperties().features) {
        if (feature.getProperties().features[0].getGeometry().getType() == 'Polygon') {
            var accuracyOfPolygon = feature.getProperties().features[0].getProperties().accuracy;
            if (ShallShowPolygonAsPoint(apTheMap, accuracyOfPolygon, resolution)) {
                feat = feature;
            } else {
                feat = feature.getProperties().features[0];
            }
        } else {
            feat = feature.getProperties().features[0];
        }
    } else {
        feat = feature;
    }

    var zIndex = 2;
    var strokeColor = '#000000';
    var polygonOpacity = 0.2;
    var pointOpacity = 0.5;
    var strokeWidth = 1.25;
    //var fillColor = 'rgba(255, 255, 0,' + opacity + ')';

    if (feat.getGeometry().getType() == 'Point') {
        fillColor = 'rgba(255, 255, 0,' + pointOpacity + ')';
    } else {
        fillColor = 'rgba(255, 255, 0,' + polygonOpacity + ')';
    }

    var style;
    if (feat.getGeometry().getType() == 'Polygon') {
        style = PolygonStyle(feat, fillColor, strokeColor, 1.25);
    } else if (feat.getGeometry().getType() == 'Point') {
        if (feat.getProperties().parentId > 0) {
            style = TriangleStyle(feat, pointOpacity, strokeColor, 'rgba(255, 165, 0,' + pointOpacity + ')', zIndex); // Connected
        } else {
            style = CircleStyle(feat, strokeColor, fillColor, 5, strokeWidth, zIndex);
        }
    }

    return style;
}
/*
function IsCluster(feature) {
    var status = false;
    if (feature.getProperties().features && feature.getProperties().features.length > 1) {
        status = true;
    }
    return status;
}*/

function SetSiteStyle(feature, resolution) {
    var polygonOpacity = 0.2;
    var pointOpacity = 0.5;
    var opacity = 0.3;
    var strokeColor = '#000000';
    var style;
    var fillColor;
    var isPolygon = false;
    var strokeWidth = 1.25;
    var zIndex = 3;

    var feat;
    if (feature.getProperties().features) {
        feat = feature.getProperties().features[0];
    } else {
        feat = feature;
    }


    if (feat.getProperties().features) {
        feat = feat.getProperties().features[0];
    }
    var properties;
    properties = feat.getProperties();

    var currentFeature;
    var accuracyOfPolygon;
    if (feat.getGeometry().getType() == 'Polygon') {
        accuracyOfPolygon = feat.getProperties().accuracy;
        currentFeature = feature;
        opacity = polygonOpacity;
    } else {
        currentFeature = feat;
        opacity = pointOpacity;
    }

    var radius = 5;
    if (properties.siteType == 39) {
        zIndex = zIndex - 1;
    }


    if (properties.siteType == 4) { // cluster
        radius = 7;
        fillColor = 'rgba(0, 153, 255,' + opacity + ')';
    } else if (apSearchDotMap && properties.siteType != 5 && properties.siteType != 7 && properties.siteType != 8 &&
        properties.siteType != 17 && properties.siteType != 39) {
        fillColor = 'rgba(255, 255, 0,' + opacity + ')';
    } else if ((properties.siteType == 39 || properties.siteType == 40) && !properties.importCandidate) {
        fillColor = 'rgba(' + Artportalen.DiffusionColor + ',' + Artportalen.DiffusionOpacity + ')';
    } else if (properties.siteType == 17) {
        fillColor = 'rgba(255, 255, 0,' + opacity + ')';
    } else if (properties.dividedByYearUntil) {
        fillColor = 'rgba(255, 255, 0,' + opacity + ')';
    } else if (properties.dividedByYearAfter) {
        fillColor = 'rgba(255, 165, 0,' + opacity + ')';
    } else if (properties.dividedByYearNotRecoveredUntil) {
        fillColor = 'rgba(255, 255, 0,' + opacity + ')';
    } else if (properties.dividedByYearNotRecoveredAfter) {
        fillColor = 'rgba(255, 165, 0,' + opacity + ')';
    } else if (properties.dividedByValidReject) {
        fillColor = 'rgba(255, 0, 0,' + opacity + ')';
    } else if (properties.dividedByValidInProgress) {
        fillColor = 'rgba(39, 82, 37,' + opacity + ')';
    } else if (properties.dividedByValidApproved) {
        fillColor = 'rgba(0, 255, 0,' + opacity + ')';
    } else if (properties.dividedByUnValidInterest) {
        fillColor = 'rgba(255, 255, 0,' + opacity + ')';
    } else if (properties.dividedByUnValidWarning) {
        fillColor = 'rgba(255, 0, 0,' + opacity + ')';
    } else if (properties.dividedByFloraGuardian) {
        fillColor = 'rgba(0, 255, 0,' + opacity + ')';
    } else if (properties.dividedByFloraGuardianNotRecovered) {
        fillColor = 'rgba(0, 255, 0,' + opacity + ')';
    } else if (properties.dividedByFloraGuardianOrdinary) {
        fillColor = 'rgba(255, 255, 0,' + opacity + ')';
    } else if (properties.dividedByFloraGuardianOrdinaryNotRecovered) {
        fillColor = 'rgba(255, 255, 0,' + opacity + ')';
    } else if (properties.dividedByFloraGuardianCurrentYear) {
        fillColor = 'rgba(0, 221, 255,' + opacity + ')';
    } else if (properties.dividedByFloraGuardianCurrentYearNotRecovered) {
        fillColor = 'rgba(0, 221, 255,' + opacity + ')';
    } else if (properties.dividedByFloraGuardian1To3YearsAgo) {
        fillColor = 'rgba(255, 255, 0,' + opacity + ')';
    } else if (properties.dividedByFloraGuardian1To3YearsAgoNotRecovered) {
        fillColor = 'rgba(255, 255, 0,' + opacity + ')';
    } else if (properties.dividedByFloraGuardianOld) {
        fillColor = 'rgba(255, 165, 0,' + opacity + ')';
    } else if (properties.dividedByFloraGuardianOldNotRecovered) {
        fillColor = 'rgba(255, 165, 0,' + opacity + ')';
    } else if (properties.dividedByProportionSize) {
        fillColor = properties.proportionColour;
        radius = properties.proportionSize;
    } else if (properties.importCandidate) {
        fillColor = 'rgba(141, 7, 168,' + opacity + ')';
    } else if (properties.showAsProjectSite) { //Project 
        fillColor = 'rgba(0, 221, 255,' + opacity + ')';
    } else if (apSearchValidationMap && properties.siteType == 0) {
        fillColor = 'rgba(255, 255, 0,' + opacity + ')';
    } else if (properties.siteType == 0) { //Private 
        if (properties.parentId > 0) {
            fillColor = 'rgba(255, 165, 0,' + opacity + ')'; // Connected
        } else {
            fillColor = 'rgba(255, 255, 0,' + opacity + ')';
        }
    } else if (properties.siteType == 1) { // Child
        fillColor = 'rgba(0, 255, 0,' + opacity + ')';
    } else if (properties.siteType == 2) { // 
        fillColor = 'rgba(0, 102, 0, ' + opacity + ')';
        //style = TriangleStyle(currentFeature, opacity, strokeColor, '#FFA500');
    } else if (properties.siteType == 3) { // Childless
        fillColor = 'rgba(0, 101, 0,' + opacity + ')';
    } else if (properties.siteType == 5) { //Not recovered 
        fillColor = 'rgba(0, 0, 0,' + opacity + ')';
    } else if (properties.siteType == 6) { // Assessment 
        fillColor = 'rgba(255, 0, 212,' + opacity + ')';
    } else if (properties.siteType == 7) { //Protected 
        fillColor = 'rgba(153, 0, 0,' + opacity + ')';
    } else if (properties.siteType == 8) { // Not present 
        strokeColor = '#999999';
        fillColor = 'rgba(63, 63, 63,' + opacity + ')';
    } else if (properties.showAsProjectSite) { //Project 
        fillColor = 'rgba(0, 221, 255,' + opacity + ')';
    } else if (properties.siteType == 100) {  // Raster diffused
        fillColor = 'rgba(255, 0, 0,' + opacity + ')';
    } else {
        fillColor = 'rgba(255, 255, 0,' + opacity + ')';
    }

    var diffusionStrokeWidth = 1.25;
    if (currentFeature.getGeometry().getType() == 'Point') {
        if (properties.importCandidate && properties.siteType == 39) {
            style = SetDiffusionStyle(currentFeature, opacity, strokeColor, fillColor, zIndex, diffusionStrokeWidth, properties.diffusion, resolution, radius, strokeWidth);
        }
        else if (properties.siteType == 4 || (apSearchDotMap && properties.siteType != 5 && properties.siteType != 7 &&
                properties.siteType != 8 && properties.siteType != 17 && properties.siteType != 39) || properties.dividedByYearUntil ||
            properties.dividedByValidReject || properties.dividedByValidInProgress || properties.dividedByValidApproved ||
            properties.dividedByFloraGuardianOrdinary || properties.dividedByFloraGuardianCurrentYear || 
            properties.dividedByFloraGuardian1To3YearsAgo || properties.dividedByFloraGuardianOld || properties.importCandidate ||
            properties.dividedByProportionSize || (apSearchValidationMap && properties.siteType == 0) || properties.siteType == 1 ||
            properties.siteType == 3 || properties.siteType == 6 || properties.siteType == 40) {
            style = CircleStyle(currentFeature, strokeColor, fillColor, radius, strokeWidth, zIndex);

        } else if (properties.siteType == 39) {
            style = SetDiffusionStyle(currentFeature, opacity, strokeColor, fillColor, zIndex, diffusionStrokeWidth, properties.diffusion, resolution, radius, strokeWidth);

        } else if (properties.dividedByYearAfter || properties.dividedByUnValidInterest || properties.dividedByUnValidWarning ||
            properties.dividedByFloraGuardian || properties.siteType == 2 || properties.siteType == 7) {
            style = TriangleStyle(currentFeature, opacity, strokeColor, fillColor, zIndex);

        } else if (properties.dividedByYearNotRecoveredUntil || properties.dividedByYearNotRecoveredAfter ||
            properties.dividedByFloraGuardianNotRecovered || properties.dividedByFloraGuardianOrdinaryNotRecovered ||
            properties.dividedByFloraGuardianCurrentYearNotRecovered || 
            properties.dividedByFloraGuardian1To3YearsAgoNotRecovered || properties.dividedByFloraGuardianOldNotRecovered ||
            properties.siteType == 5 || properties.siteType == 8 || properties.siteType == 17) {
            style = XStyle(currentFeature, opacity, strokeColor, fillColor, zIndex);

        } else if (properties.showAsProjectSite) { //Project 
            style = SquareStyle(currentFeature, opacity, strokeColor, fillColor, zIndex, 7, 1.25);
        } else if (properties.siteType == 0) { //Private 
            if (properties.parentId > 0) {
                style = TriangleStyle(currentFeature, opacity, strokeColor, fillColor, zIndex); // Connected
            } else {
                style = CircleStyle(currentFeature, strokeColor, fillColor, 5, strokeWidth, zIndex);
            }
        } /*else if (properties.cellSize != 0) { //Diffusion grid
            var diffusionRadius = GetAccuracyRadius(properties.cellSize, resolution);
            style = SquareStyle(feature, opacity, strokeColor, fillColor, zIndex, diffusionRadius, diffusionStrokeWidth);
        }*/

        if ((properties.dividedByYearUntil || properties.dividedByYearAfter || properties.dividedByYearNotRecoveredUntil ||
                properties.dividedByYearNotRecoveredAfter || properties.dividedByValidReject || properties.dividedByValidInProgress ||
                properties.dividedByValidApproved || properties.dividedByUnValidInterest || properties.dividedByUnValidWarning ||
                properties.dividedByFloraGuardian || properties.dividedByFloraGuardianNotRecovered || properties.dividedByFloraGuardianOrdinary ||
                properties.dividedByFloraGuardianOrdinaryNotRecovered || properties.dividedByFloraGuardianCurrentYear ||
                properties.dividedByFloraGuardianCurrentYearNotRecovered || properties.dividedByFloraGuardian1To3YearsAgo ||
                properties.dividedByFloraGuardian1To3YearsAgoNotRecovered || properties.dividedByFloraGuardianOld ||
                properties.dividedByFloraGuardianOldNotRecovered || properties.dividedByProportionSize || properties.dividedByValid) &&
            properties.diffusion != 0) {
            var diffusionRadius = GetAccuracyRadius(properties.diffusion, resolution);

            var diffuseStyle = SquareStyle(currentFeature, opacity, strokeColor, 'rgba(' + Artportalen.DiffusionColor + ',' + Artportalen.DiffusionOpacity + ')', zIndex, diffusionRadius, diffusionStrokeWidth);
            if (style instanceof Array) {
                style.unshift(diffuseStyle);
            } else {
                style = [diffuseStyle, style];
            }
        } else if (properties.showAsProjectSite && properties.diffusion != 0 && properties.siteType == 39) {
            var projectStyle = SquareStyle(currentFeature, opacity, strokeColor, 'rgba(0, 221, 255,' + opacity + ')', zIndex, 7, 1.25);
            if (style instanceof Array) {
                style.unshift(projectStyle);
            } else {
                style = [projectStyle, style];
            }
        }

        if( properties.dividedByFloraGuardianArchivedSite) {
            fillColor = 'rgba(128, 128, 128,' + opacity + ')';
            style = SquareStyle(currentFeature, opacity, 'rgb(0,0,0)', 'rgba(255,255,255,' + opacity + ')', zIndex, 7, 1.25);
        }
    } else {
        if (properties.isPolygon || currentFeature.getGeometry().getType() == 'Polygon') {
            isPolygon = true;
            style = PolygonStyle(currentFeature, fillColor, strokeColor, strokeWidth);
        }
    }
    return style;
}

function SetDiffusionStyle(feature, opacity, strokeColor, fillColor, zIndex, diffusionStrokeWidth, diffusion, resolution, radius, strokeWidth) {
    var diffusionRadius = GetAccuracyRadius(diffusion, resolution);
    if ((diffusion == 100 && resolution > 20) || (diffusion == 500 && resolution > 152) || (diffusion == 1000 && resolution > 2400)) {
        style = CircleStyle(feature, strokeColor, fillColor, radius, strokeWidth, zIndex);
    } else {
        style = SquareStyle(feature, opacity, strokeColor, fillColor, zIndex, diffusionRadius, diffusionStrokeWidth);
    }
    return style;
}

function SetAccuracyStyle(feature, resolution) {
    var opacity = 0.3;
    var strokeColor = '#000000';
    var style; 1
    var fillColor;
    var isPolygon = false;
    var strokeWidth = 1.25;
    var zIndex = 1;

    var feat;
    if (feature.getProperties().features) {
        feat = feature.getProperties().features[0];
    } else {
        feat = feature;
    }

    var style;
    // if (apShowAccuracy && !isPolygon && feat.getProperties().features != null &&
    var siteLayer = getLayerByName(apTheMap, 'theSiteLayer');
    var siteLayerFeature = siteLayer.getSource().getFeatureById(feature.getId());
    var editableSiteLayer = getLayerByName(apTheMap, 'theEditableSiteLayer');
    var editableSiteLayerFeature = editableSiteLayer.getSource().getFeatureById(feature.getId());
    var privateSiteLayer = getLayerByName(apTheMap, 'thePrivateSiteLayer');
    var privateSiteLayerFeature = privateSiteLayer.getSource().getFeatureById(feature.getId());


    if (feat.getProperties().siteType != 39 && feat.getProperties().siteType != 40 &&
    ((siteLayerFeature && !siteLayerFeature.getProperties().clustered) ||
        (editableSiteLayerFeature && !editableSiteLayerFeature.getProperties().clustered) ||
        privateSiteLayerFeature)) {
        style = new ol.style.Style({
            image: new ol.style.Circle({
                radius: GetAccuracyRadius(feature.getProperties().accuracy, resolution),
                stroke: new ol.style.Stroke({
                    color: '#AAAAAA',
                    width: strokeWidth
                })
            }),
            zIndez: zIndex
        });
    }
    return style;
}


function SetAtlasHighlightStyle(feature) {
    var style;
    var feat;
    if (feature.getProperties().features) {
        feat = feature.getProperties().features[0];
    } else {
        feat = feature;
    }


    if (feature) {
        if (feat.getGeometry().getType() == 'Polygon') {
            style = [
                new ol.style.Style({
                    stroke: new ol.style.Stroke({
                        color: [255, 0, 0, 1],
                        width: 2
                    }),
                    geometry: feat.getGeometry()
                })
            ];
        } else if (feat.getGeometry().getType() == 'Point') {
            style = new ol.style.Style({
                image: new ol.style.Circle({
                    radius: 5,
                    stroke: new ol.style.Stroke({
                        color: [255, 0, 0, 1],
                        width: 1.25
                    })
                })
            });
        }
    }

    if (feature.getProperties().value.toString() != '0') {
        style[0].setText(new ol.style.Text({
            fill: new ol.style.Fill({ color: '#fff' }),
            stroke: new ol.style.Stroke({
                color: '#333',
                width: 3
            }),
            text: feature.getProperties().value.toString()
        }));
    }

    return style;
};


function SetDelimitStyle(feature) {
    var style;
    var feat;
    if (feature.getProperties().features) {
        feat = feature.getProperties().features[0];
    } else {
        feat = feature;
    }
    if (feature) {
        if (feat.getGeometry().getType() == 'Polygon' || feat.getGeometry().getType() == 'MultiPolygon') {
            if (feat.getProperties().limitType == 'AtlasSquareBorder') {
                style = [
                    new ol.style.Style({
                        stroke: new ol.style.Stroke({
                            color: [255, 0, 0, 1],
                            width: 2
                        }),
                        geometry: feat.getGeometry()
                    })
                ];
            } else if (feat.getProperties().limitType == 'Area') {
                style = [
                    new ol.style.Style({
                        stroke: new ol.style.Stroke({
                            color: [255, 0, 0, 1],
                            width: 2,
                            lineDash: [.1, 5]
                        }),
                        geometry: feat.getGeometry()
                    })
                ];
            } else {
                style = [
                    new ol.style.Style({
                        stroke: new ol.style.Stroke({
                            color: [255, 0, 0, 1],
                            width: 2
                        }),
                        geometry: feat.getGeometry()
                    })
                ];
                
            }

        }
    }
    return style;
};


function SetHighlightStyle(feature, resolution) {
    return PrepareHighlightStyle(feature, resolution, true);
};

function SetHooverHighlightStyle(feature, resolution) {
    return PrepareHighlightStyle(feature, resolution, false);
};

function PrepareHighlightStyle(feature, resolution, selectStyle) {
    var feat;
    var style;
    if (feature.getProperties().features) {
        if (feature.getProperties().features[0].getGeometry().getType() == 'Polygon') {
            var accuracyOfPolygon = feature.getProperties().features[0].getProperties().accuracy;
            if (ShallShowPolygonAsPoint(apTheMap, accuracyOfPolygon, resolution)) {
                feat = feature;
            } else {
                feat = feature.getProperties().features[0];
            }
        } else {
            feat = feature.getProperties().features[0];
        }
    } else {
        feat = feature;
    }

    var coordinate;
    if (selectStyle) {
        coordinate = currentClickCoordinate;
    } else {
        coordinate = currentHooverCoordinate;
    }

    var strokeColor = '#FF0000';

    if (feat) {
        // if ((coordinate && IsInside(map, coordinate, feat)) || !coordinate) {
        if (selectStyle && feat.getGeometry().getType() == 'Point') {
            currentClickCoordinate = feat.getGeometry().getCoordinates();
        }
        if (feat.getGeometry().getType() == 'Polygon') {
            var fillCol = feat.getProperties().colorString;
            if (!fillCol) {
                fillCol = 'transparent';
            }
            if (fillCol != 'transparent') {
                var tmpStr = fillCol.split(',');
                fillCol = tmpStr[0] + ", " + tmpStr[1] + ", " + tmpStr[2] + ", 0.1)";
            }
            style = PolygonStyle(feat, fillCol, strokeColor, 2);
        } else if (feat.getGeometry().getType() == 'Point') {
            var accRad = 5.0;
            var rad = 5.0;
            var col = [255, 0, 0, 1];

            if (selectStyle && feat.getProperties().dividedByProportionSize) {
                accRad = feat.getProperties().proportionSize;
            } else if (feat.getProperties().dividedByProportionSize) {
                accRad = GetAccuracyRadius(feat.getProperties().accuracy, resolution);
                var propRad = feat.getProperties().proportionSize;
                if (accRad < propRad) {
                    accRad = propRad;
                }
            } else if (feat.getProperties().accuracy) {
                accRad = GetAccuracyRadius(feat.getProperties().accuracy, resolution);
            }


            if (feat.getProperties().colorString) {
                col = 'rgba(255, 255, 0, 0.2)';
            }

            if (accRad > 5 && !selectStyle) {
                if (feat.getProperties().siteType == 39) {
                    var diffusionStrokeWidth = 1.25;
                    var strokeWidth = 1.25;
                    var opacity = 0.3;
                    var zIndex = 2;
                    var fillColor = 'rgba(' + Artportalen.DiffusionColor + ',' + Artportalen.DiffusionOpacity + ')';
                    style = SetDiffusionStyle(feat, opacity, strokeColor, fillColor, zIndex, diffusionStrokeWidth, feat.getProperties().diffusion, resolution, rad, strokeWidth);
                } else if (feat.getProperties().siteType == 40) {
                    style = new ol.style.Style({
                        image: new ol.style.Circle({
                            radius: rad,
                            stroke: new ol.style.Stroke({
                                color: [255, 0, 0, 1],
                                width: 2
                            })
                        })
                    });
                } else {
                    rad = accRad;
                    style = [
                        new ol.style.Style({
                            image: new ol.style.Circle({
                                radius: accRad,
                                fill: new ol.style.Fill({ color: col }),

                            })
                        }),
                        new ol.style.Style({
                            image: new ol.style.Circle({
                                radius: rad,
                                stroke: new ol.style.Stroke({
                                    color: [255, 0, 0, 1],
                                    width: 2
                                })
                            })
                        })
                    ];
                }
            } else {
                style = SetSiteStyle(feat, resolution);
                if (style && style != null) {
                    if (style.length > 1) {
                        var img = style[0].getImage();
                        var highlightedImage = new ol.style.RegularShape({
                            fill: img.getFill(),
                            points: img.getPoints(),
                            radius: img.getRadius(),
                            radius2: img.getRadius2(),
                            angle: img.getAngle(),
                            stroke: new ol.style.Stroke({
                                color: [255, 0, 0, 1],
                                width: 3.25
                            })
                        });
                        style[0].setImage(highlightedImage);
                        img = style[1].getImage();
                        style[1].setImage(img);
                    } else {
                        var img = style.getImage();
                        var highlightedImage = new ol.style.RegularShape({
                            fill: img.getFill(),
                            points: img.getPoints(),
                            radius: img.getRadius(),
                            angle: img.getAngle(),
                            stroke: new ol.style.Stroke({
                                color: [255, 0, 0, 1],
                                width: 2
                            })
                        });
                        style.setImage(highlightedImage);
                    }
                }

            }
            //}
        }
    }

    return style;
};

function IsInside(map, coordinate, feature) {
    var status;
    var feat;
    var resolution = map.getView().getResolution();

    /*if (feature.getProperties().features && IsCluster(feature)) { // Cluster
        feat = feature;
    } else*/ if (feature.getProperties().features) {
        if (feature.getProperties().features[0].getGeometry().getType() == 'Polygon') {
            var accuracyOfPolygon = feature.getProperties().features[0].getProperties().accuracy;
            if (ShallShowPolygonAsPoint(map, accuracyOfPolygon, resolution)) {
                feat = feature;
            } else {
                feat = feature.getProperties().features[0];
            }
        } else {
            feat = feature.getProperties().features[0];
        }
    } else {
        feat = feature;
    }

    if (feat.getGeometry().getType() == 'Polygon') {
        status = feat.getGeometry().intersectsCoordinate(coordinate);
    } else if (feat.getGeometry().getType() == 'Point') {
        var mapScale = getMapScale(resolution);
        var radius = 6.25; //5;
        if (feat.getProperties().dividedByProportionSize) {
            radius = feat.getProperties().proportionSize;
        }
        //var scaledRadius = radius * mapScale / 2834 / 2;
        //var scaledRadius = radius / mapScale  * 1000000;
        //var scaledRadius = radius * mapScale / resolution;
        var scaledRadius = radius * mapScale / 2750;
        //var scaledRadius = radius * mapScale / resolution * 2;
        var tmpCircle = new ol.geom.Circle(feat.getGeometry().getCoordinates(), scaledRadius);
        if (tmpCircle.intersectsCoordinate(coordinate)) {
            status = true;
        } else {
            status = false;
        }
    }
    return status;
}

function convertHex(hex, opacity) {
    hex = hex.replace('#', '');
    r = parseInt(hex.substring(0, 2), 16);
    g = parseInt(hex.substring(2, 4), 16);
    b = parseInt(hex.substring(4, 6), 16);

    result = 'rgba(' + r + ',' + g + ',' + b + ',' + opacity + ')';
    return result;
}

function GetAtlasColour(feature, opacity) {
    var value = feature.getProperties().value;
    var colour = '#FFFFFF';
    var dbOpacity = 0.4;
    if (value >= apAtlasLevel1.min && value <= apAtlasLevel1.max) {
        colour = apAtlasLevel1.color;
        dbOpacity = apAtlasLevel1.opacity;
    } else if (value >= apAtlasLevel2.min && value <= apAtlasLevel2.max) {
        colour = apAtlasLevel2.color;
        dbOpacity = apAtlasLevel2.opacity;
    } else if (value >= apAtlasLevel3.min && value <= apAtlasLevel3.max) {
        colour = apAtlasLevel3.color;
        dbOpacity = apAtlasLevel3.opacity;
    } else if (value >= apAtlasLevel4.min && value <= apAtlasLevel4.max) {
        colour = apAtlasLevel4.color;
        dbOpacity = apAtlasLevel4.opacity;
    } else if (value >= apAtlasLevel5.min && value <= apAtlasLevel5.max) {
        colour = apAtlasLevel5.color;
        dbOpacity = apAtlasLevel5.opacity;
    }
    if (opacity != 1) {
        opacity = dbOpacity;
    }
    return convertHex(colour, opacity);
}

function SetAtlasStyle(feature, resolution) {
    var strokeColor = '#000000';
    var style;
    var strokeWidth = 0.5;
    var lineDash = [5, 5];

    if (feature) {
        var colour = GetAtlasColour(feature, 0.4);
        if (colour != null) {
            style = new ol.style.Style({
                fill: new ol.style.Fill({
                    color: colour
                }),
                stroke: new ol.style.Stroke({
                    color: strokeColor,
                    lineDash: lineDash,
                    width: strokeWidth
                })
            });
        } else {
            style = new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color: strokeColor,
                    lineDash: lineDash,
                    width: strokeWidth
                })
            });

        }

        if (feature.getProperties().value.toString() != '0') {
            var fontSize = '10px sans-serif';
            if (resolution > 500 && resolution < 1000) {
                fontSize = '6px sans-serif';
            }
            style.setText(new ol.style.Text({
                font: fontSize,
                fill: new ol.style.Fill({ color: '#fff' }),
                stroke: new ol.style.Stroke({
                    color: '#333',
                    width: 3
                }),
                text: feature.getProperties().value.toString()
            }));
        }
    }

    return style;
}

function PolygonStyle(feature, fillColor, strokeColor, width) {
    feature.setProperties({ 'colorString': fillColor });

    return new ol.style.Style({
        fill: new ol.style.Fill({ color: fillColor }),
        stroke: new ol.style.Stroke({
            color: strokeColor,
            width: width
        }),
        geometry: feature.getGeometry(),
        zIndex: 5
    });
}

function CircleStyle(feature, strokeColor, fillColor, pointRadius, strokeWidth, zIndex) {
    feature.setProperties({ 'colorString': fillColor });
    return new ol.style.Style({
        image: new ol.style.Circle({
            radius: pointRadius,
            fill: new ol.style.Fill({ color: fillColor }),
            stroke: new ol.style.Stroke({
                color: strokeColor,
                width: strokeWidth
            })
        }),
        zIndex: zIndex
    });
}

function SquareStyle(feature, opacity, strokeColor, fillColor, zIndex, radius, width) {
    feature.setProperties({ 'colorString': fillColor });
    return new ol.style.Style({
        image: new ol.style.RegularShape({
            points: 4,
            radius: radius,
            stroke: new ol.style.Stroke({
                color: strokeColor,
                width: width
            }),
            fill: new ol.style.Fill({ color: fillColor }),
            fillOpacity: opacity,
            angle: Math.PI / 4
        }),
        zIndex: zIndex
    });
}

function TriangleStyle(feature, opacity, strokeColor, fillColor, zIndex) {
    feature.setProperties({ 'colorString': fillColor });
    return new ol.style.Style({
        image: new ol.style.RegularShape({
            points: 3,
            radius: 7,
            stroke: new ol.style.Stroke({
                color: strokeColor,
                width: 1.25
            }),
            fill: new ol.style.Fill({ color: fillColor }),
            fillOpacity: opacity
        }),
        zIndex: zIndex
    });
}

function XStyle(feature, opacity, strokeColor, fillColor, zIndex) {
    feature.setProperties({ 'colorString': fillColor });
    return [
        new ol.style.Style({
            image: new ol.style.RegularShape({
                points: 4,
                stroke: new ol.style.Stroke({
                    color: strokeColor,
                    width: 3.25
                }),
                fill: new ol.style.Fill({ color: fillColor }),
                fillOpacity: opacity,
                radius: 7,
                radius2: 0,
                angle: Math.PI / 4
            }),
            zIndex: zIndex
        }),
        new ol.style.Style({
            image: new ol.style.RegularShape({
                points: 4,
                stroke: new ol.style.Stroke({
                    color: fillColor,
                    width: 2.25
                }),
                fill: new ol.style.Fill({ color: fillColor }),
                fillOpacity: opacity,
                radius: 7,
                radius2: 0,
                angle: Math.PI / 4
            }),
            zIndex: zIndex
        })];
}

function getMapScale(resolution) {
    return 39.37 * 72 * resolution;
    //return 39.37 * 90.71 * resolution;
}

function GetAccuracyRadius(accuracy, resolution) {
    var mapScale = getMapScale(resolution);
    var rad = (accuracy * 2834 * 2 / mapScale);
    //var rad = accuracy * mapScale / 2834 / 2;
    if (rad < 5.0) {
        rad = 5.0;
    }

    return rad;
}

function SetPrecisionLayerStyle(feature, resolution) {
    var style;
    if (feature.getProperties().features != null &&
        feature.getProperties().features.length == 1) { // Not cluster       
        style = new ol.style.Style({
            image: new ol.style.Circle({
                radius: GetAccuracyRadius(feature.getProperties().features[0].getProperties().accuracy, resolution),
                stroke: new ol.style.Stroke({
                    color: '#AAAAAA',
                    width: 0.25 + 1
                })
            })
        });
    }
    return style;
}

function SetEditSiteLayerStyle(feature, resolution) {
    return new ol.style.Style({
        image: new ol.style.Circle({
            radius: GetAccuracyRadius(feature.getProperties().accuracy, resolution),
            stroke: new ol.style.Stroke({
                color: '#FF0000',
                width: 0.25 + 1
            })
        }),
        zIndex: 2
    });
}

function setBaseLayer(map, layerName) {
    map.getLayers().forEach(function (lyr) {
        if (lyr.get('type') == 'base') {
            if (lyr.get('title') == layerName) {
                lyr.setVisible(true);
            } else if (lyr.get('title') != layerName) {
                lyr.setVisible(false);
            }
        }
    });
}

function getBaseLayer(map) {
    var baseLayerName = "OpenStreetMap";
    map.getLayers().forEach(function (lyr) {
        if (lyr.get('type') == 'base' && lyr.get('visible')) {
            baseLayerName = lyr.get('title');
        }
    });
    return baseLayerName;
}

function setMapLayer(map, layerName, visible) {
    map.getLayers().forEach(function (lyr) {
        if (lyr.get('title') == layerName) {
            lyr.setVisible(visible);
            if (layerName == 'thePrecisionLayer') {
                getLayerByName(map, 'theSiteArrowLayer').setVisible(visible);
                getLayerByName(map, 'theSiteConnectionLayer').setVisible(visible);
            }
            if (layerName == 'theSiteLayer' || layerName == 'thePrivateSiteLayer' || layerName == 'theEditableSiteLayer') {
                lyr.getSource().getFeatures().forEach(function (feature) {
                    var selectedFeatures = getLayerByName(map, 'theSelectLayer').getSource().getFeatures();
                    for (var i = 0; i < selectedFeatures.length; i++) {
                        if (feature.getId() == selectedFeatures[i].getId()) {
                            getLayerByName(map, 'theSelectLayer').setVisible(visible);
                            getLayerByName(map, 'theHooverLayer').setVisible(visible);
                            if (!visible) {
                                if (typeof selectClick !== 'undefined') {
                                    selectClick.getFeatures().clear();
                                }
                                if (typeof selectSite !== 'undefined') {
                                    selectSite.getFeatures().clear();
                                }
                            }

                        }
                    }
                });
            }
        }
    });
}

function CornfirmSiteEdit() {
    var text = window.Artportalen.ResourceLabel("Shared_Map_ConfirmSiteMoveViaMap");
    return confirm(text);
}

function showTaxonProtectionEye(showEye) {
    showTaxonProtectEye = showEye;
}

function setCoordinateStringPresentation(coordPresentation) {
    coordinateStringPresentation = coordPresentation;
}

function renderFeaturePopup(feature) {
    var popupStr = "";
    if (feature.getProperties().siteCoordinateStringPresentation) {
        var outputCoordStr = "";
        if (coordinateStringPresentation != "") {
            outputCoordStr = coordinateStringPresentation;
        } else {
            var siteCoordStr = feature.getProperties().siteCoordinateStringPresentation
                .split(")");
            if (siteCoordStr.length > 1) {
                outputCoordStr = siteCoordStr[0] + ")" + "<br />";
                // Coordinates and accuracy}                    
                if (siteCoordStr.length > 2) { // Coordsystem 
                    var startPos = feature.getProperties().siteCoordinateStringPresentation
                        .indexOf(siteCoordStr[1]);
                    outputCoordStr += feature.getProperties()
                        .siteCoordinateStringPresentation
                        .substring(startPos,
                            feature.getProperties().siteCoordinateStringPresentation
                            .length) +
                        "<br />";
                }
            }
        }
        var parentSiteName = "";
        if (feature.getProperties().parentSiteName) {
            parentSiteName = window.Artportalen.ResourceLabel("Shared_Site_Parentsite") +
                ": <strong>" +
                feature.getProperties().parentSiteName +
                "</strong><br />";
        }
        var siteAreaDescription = "";

        if (feature.getProperties().siteAreaDescription) {
            siteAreaDescription = feature.getProperties().siteAreaDescription +
                ": <strong>" +
                feature.getProperties().siteAreaName +
                "</strong><br />";
        }
        var associatedProjects = "";
        if (feature.getProperties().projectAndExternalId &&
            feature.getProperties().projectAndExternalId.length > 0) {
            associatedProjects =
                feature.getProperties().projectAndExternalIdDescription +
                ": <strong>" +
                feature.getProperties().projectAndExternalId +
                "</strong>";
        }

        if (feature.getProperties().siteType == 39 || feature.getProperties().siteType == 40) {
            var siteId = GetUndiffusedSiteId(feature.getId());
            popupStr +=
                "<div class='sitenamewrapper'><a onclick = 'selectAndGetSite(" +
                siteId +
                "); " +
                "'><span class='siteindicator' style='background-color:" +
                feature.getProperties().colorString +
                ";'></span><span class='sitename'>" +
                feature.getProperties().siteName +
                "</span></a>";
        } else {
            popupStr +=
                "<div class='sitenamewrapper'><a onclick = 'selectAndGetSite(" +
                feature.getId() +
                "); " +
                "'><span class='siteindicator' style='background-color:" +
                feature.getProperties().colorString +
                ";'></span><span class='sitename'>" +
                feature.getProperties().siteName +
                "</span></a>";
        }

        if (feature.getProperties().protectedBySystem) {
            popupStr +=
                "<span class='UI-Icon-16 UI-Icon-16-NoFloat UI-Icon-16-ProtectedBySystem'></span>";
        }

        if (feature.getProperties().numberOfSightings) {
            popupStr +=
                "</div><div class='site-info'>" +
                parentSiteName +
                feature.getProperties().numberOfSightings +
                " " +
                window.Artportalen.ResourceLabel("Shared_Sightings_Quantity") +
                "<br />" +
                "</div>";
            if (feature.getProperties().date) {
                popupStr += "<div>" +
                    feature.getProperties().date +
                    "<br />" +
                    "</div>";
            }
        } else {
            popupStr +=
                "</div><div class='site-info'>" +
                parentSiteName +
                siteAreaDescription +
                outputCoordStr +
                associatedProjects +
                "</div>";
        }
    } else {
        popupStr +=
            "<div class='sitenamewrapper'>" +
            "<span class='siteindicator' style='background-color:" +
            feature.getProperties().colorString +
            ";'></span><span class='sitename'>" +
            feature.getProperties().siteName +
            "</span></a>";

    }
    return popupStr;
}

function ShowFeaturePopup(map, feature, position, pixel) {
    // TODO: Add ajax-call fetch properties for site if feature.attributes.count < 0.
    // To get better performance we cannot load all feature attributes when fetching all sites. 
    // So we need to retreive additional information about the site (feature) attributes with an ajax call.
    // if the fid is -1 then this is a cluster and there is no need to go to the server

    overlapMap = map; // Global var
    var featureIdArray = [];
    var featu = feature;
    var featureIdMissing = false;
    for (var i = 0; i < feature.length; i++) {
        featureIdArray[i] = feature[i].getId();
        if (feature[i].getProperties().siteName == "") {
            featureIdMissing = true;
        }
    }

    /*if (feature.getProperties().features == null) {
        featureIdArray[0] = feature.getId();
        featu = feature;
    } else if (feature.getProperties().features.length != null) {
        for (var i = 0; i < feature.getProperties().features.length; i++) {
            featureIdArray[i] = feature.getProperties().features[i].getId();
        }
        featu = feature.getProperties().features[0];
    } else {
        featureIdArray[0] = feature.getProperties().features[0].getId();
        featu = feature.getProperties().features[0];
    }*/

    var popupStr = "";
    var feat;
    if (featu[0].getId() == -1 && !featureIdMissing) {
        if (feature[0].getProperties().features) {
            feat = feature[0].getProperties().features[0];
        } else {
            feat = feature;
        }

        popupStr =
            "<div class = 'olPopup olPopupContent' style='background-color:white;'>";
        popupStr += "<span id='closeLegend' class='olPopupCloseBox'" + " onclick = '$(" + "popup" + ").hide();'" + "style='float: right;'></span>";
        popupStr += renderFeaturePopup(feat[0]);
        popupStr += "</div>";
        if (feat[0].getProperties().siteName && feat[0].getProperties().siteName != "" && feat[0].getProperties().siteName != "Select") {
            apMapPopupContainer.innerHTML = popupStr;
            apMapPopup.setPosition([position[0], position[1]]);
            apMapPopup.setOffset(apPopupOffset);
        }
    } else {

        var siteUrl = map.SiteFeatureUrl;
        if (featu[0].getProperties().siteName == "" || featureIdMissing) {
            if (showTaxonProtectEye) {
                siteUrl = Artportalen_ApplicationPath + '/ViewSighting/SiteFeatureAttributesWithProtected';
            }

            Artportalen.ajaxPost(siteUrl,
                {
                    SiteIdList: featureIdArray,
                    showProtectedByUser: map.mapOption.searchMap ? false : true
                },
                function (data, code, xht) {
                    if (data.results.length != 0) {

                        // ta hänsyn till array features
                        popupStr =
                            "<div class = 'olPopup olPopupContent' style='background-color:white;'>";
                        popupStr += "<span id='closeLegend' class='olPopupCloseBox'" + " onclick = '$(" + "popup" + ").hide();'" + "style='float: right;'></span>";
                        //var coordinate = coordinates;
                        /*var hdms = ol.coordinate.toStringHDMS(ol.proj.transform(coordinate,
                            'EPSG:3857',
                            'EPSG:4326'));*/
                        var length = 1;
                        /*if (feature.length != null) {
                            length = data.length;
                        }*/
                        length = data.results.length;
                        var tmpPopupStr = "";
                        for (var i = 0; i < length; i++) {
                            /*if (feature.getProperties().features) {
                                feat = feature.getProperties().features[i];
                                /*if (feat.getProperties()) {
                                    feat = feat.getProperties();
                                }*/
                            /*} else if (length == 1) {
                                feat = feature;
                            }*/
                            feat = feature[i];

                            feat.setProperties({ 'siteName': data.results[i].SiteName });
                            feat.setProperties({ 'siteAreaName': data.results[i].SiteAreaName });
                            feat.setProperties({
                                'projectAndExternalId': data.results[i].ProjectAndExternalId
                            });
                            feat.setProperties({
                                'siteCoordinateStringPresentation': data.results[i]
                                    .SiteCoordinateStringPresentation
                            });
                            feat.setProperties({ 'parentSiteName': data.results[i].ParentSiteName });
                            feat.setProperties({
                                'protectedBySystem': data.results[i].ProtectedBySystem
                            });
                            //renderFeaturePopup(feature);

                            if (feat.getProperties().siteName && feat.getProperties().siteName != "" && feat.getProperties().siteName != "Select") {
                                tmpPopupStr += renderFeaturePopup(feat);
                            }
                        }
                        popupStr += tmpPopupStr;
                        popupStr += "</div>";
                        if (tmpPopupStr != "") {
                            apMapPopupContainer.innerHTML = popupStr;
                            //popup.setPosition(coordinates);

                            apMapPopup.setPosition([position[0], position[1]]);
                            apMapPopup.setOffset(apPopupOffset);
                        }
                    }

                });
        } else {
            // ta hänsyn till array features
            $("#popup").show();
            popupStr =
                "<div class = 'olPopup olPopupContent' style='background-color:white;'>";

            popupStr += "<span id='closeLegend' class='olPopupCloseBox'" + " onclick = '$(" + "popup" + ").hide();'" + "style='float: right;'></span>";

            //var coordinate = coordinates;
            /*var hdms = ol.coordinate.toStringHDMS(ol.proj.transform(coordinate,
                'EPSG:3857',
                'EPSG:4326'));*/
            //var length = 1;
            /*if (feature.length != null) {
                length = data.length;
            }*/
            /*if (feature.getProperties().features) {
                length = feature.getProperties().features.length;
            }*/

            if (feature[0].getId() < 0) {
                //Shared_Map_ConfirmSiteMoveViaMap
                //popupStr += window.Artportalen.ResourceLabel("Map_ZoomInToChooseOneSite");
                popupStr += renderFeaturePopup(feature[0]);
                //Map_ZoomInToChooseOneSite
            } else {
                for (var i = 0; i < feature.length; i++) {
                    /*if (feature[0].getProperties().features) {
                        feat = feature[0].getProperties().features[i];
                    } else if (length == 1) {
                        feat = feature;
                    }*/
                    //renderFeaturePopup(map, feature);
                    popupStr += renderFeaturePopup(feature[i]);
                }
            }

            popupStr += "</div>";
            if (feature[0].getProperties().siteName && feature[0].getProperties().siteName != "" && feature[0].getProperties().siteName != "Select") {
                apMapPopupContainer.innerHTML = popupStr;
                //popup.setPosition(coordinates);
                //var extent = getExtent(map);
                //if ((extent[2] - 100) < position[0]) {
                /*var t = map.getSize()[0] - 10;
                var s = pixel[0];
                if (t < s)
                    apMapPopup.setPositioning('bottom-right');
                }*/

                apMapPopup.setPosition([position[0], position[1]]);
                apMapPopup.setOffset(apPopupOffset);
            }
        }
    }
}

function ShowShapeFeaturePopup(map, feature, position) {
    var popupStr =
        "<div class = 'olPopup olPopupContent' style='background-color:white;'>";
    popupStr += "<span id='closeLegend' class='olPopupCloseBox'" + " onclick = '$(" + "popup" + ").hide();'" + "style='float: right;'></span>";

    var getProp = feature.getProperties();
    if (!getProp.siteName) {
        getProp = feature.getProperties().features[0].getProperties();
    }

    popupStr +=
        "<div class='sitenamewrapper'><span class='siteindicator' style='background-color:" +
        getProp.colorString +
        ";'></span><span class='sitename'>" +
        getProp.siteName +
        "</span></a></div></div>";

    if (getProp.siteName && getProp.siteName != "") {
        apMapPopupContainer.innerHTML = popupStr;
        apMapPopup.setPosition([position[0], position[1]]);
        apMapPopup.setOffset(apPopupOffset);
    }
}

function ShowAtlasFeaturePopup(map, feature, position) {
    var colour = GetAtlasColour(feature[0], 1);
    var popupStr =
        "<div class = 'olPopup olPopupContent' style='background-color:white;'>";
    popupStr += "<h4 class='atlassquare'>" +
        " <b style='background-color: " + colour + "'>" + feature[0].getProperties().value + "</b> " +
        feature[0].getProperties().name +
        "</h4>" +
        "</div>";

    apMapPopupContainer.innerHTML = popupStr;
    apMapPopup.setPosition([position[0], position[1]]);
    apMapPopup.setOffset(apPopupOffset);
}

function ShowAtlasSurveyFeaturePopup(map, feature, position) {
    var colour = GetAtlasColour(feature[0], 1);
    var popupStr =
        "<div class = 'olPopup olPopupContent' style='background-color:white;'>";
    popupStr += "<h4 class='atlassquare'>" +
        (feature[0].getProperties().mapMode == "normal" ? (" <b style='background-color: " + colour + "'>" +
            feature[0].getProperties().value + "</b> ") : "") + ((feature[0].getProperties().mapMode == "taxon" &&
            feature[0].getProperties().value > 0) ? (" <b style='background-color: " + colour + "'>" +
            window.Artportalen.ResourceLabel("Shared_AtlasSurvey_AltasValue_" + map.speciesGroupId + "_" +
                feature[0].getProperties().value) + "</b> ") : "") + feature[0].getProperties().name +
        (feature[0].getProperties().userPresentationName != null ? "</br>" + feature[0].getProperties().userPresentationName : "") +
        "</h4>" +
        "</div>";

    apMapPopupContainer.innerHTML = popupStr;
    apMapPopup.setPosition([position[0], position[1]]);
    apMapPopup.setOffset(apPopupOffset);
}

var showTaxonProtectEye = false;

function SetMapSiteSelected(map, feature) {
    if (map.unSelectTimeout != null) {
        window.clearTimeout(map.unSelectTimeout);
        map.unSelectTimeout = null;
    }

    map = GetMapReference(map);
    if (map.skipSelectEvent) {
        map.skipSelectEvent = false;
        return;
    }

    var feat;
    if (feature.length > 0) {
        feat = feature[0];
    } else if (feature.selected) {
        if (feature.selected[0].getProperties().features.length > 0) {
            feat = feature.selected[0].getProperties().features[0];
        } else {
            feat = feature.selected[0];
        }
    } else {
        feat = feature;
    }


    if (feat) {
        SiteMarkRelationShip(map, feat);

        map.selectedSite = feat.getId();
        map.featureToSelectId = feat.getId();
        /*if (feature) {
            $('#' + map.divId).triggerHandler('onMapSiteSelected', [feature]);
        }*/

    }
    /*if (feature.deselected.length > 0) {
        $('#' + map.divId).triggerHandler('onMapSitesUnSelected', [feature]);
    }*/

    /*if (feature.selected.length > 0) {
        
        if (map.unSelectTimeout != null) {
            window.clearTimeout(map.unSelectTimeout);
            map.unSelectTimeout = null;
        }

        map = GetMapReference(map);
        if (map.skipSelectEvent) {
            map.skipSelectEvent = false;
            return;
        }

        SiteMarkRelationShip(map, feature.selected[0]);

        map.selectedSite = -1;
        feature.selected[0].setId(-1);
        if (!feature.selected[0].getId()) {
            feature.selected[0].getProperties().features[0].setId(-1);
        }
        if (feature) {
            $('#' + map.divId).triggerHandler('onMapSiteSelected', [feature]);
        }
    }*/
}

var onMapZoomTimer = null;
var timeout = 1000;


function OnMapPanOrZoom(evt) {
    map = GetMapReference(evt.map);
    if (map.mapOption.AtlasMap == true || map.mapOption.AtlasSurveyMap == true) return;

    /*if (typeof map.getZoom() === "undefined" || map.getZoom() === null || typeof map.getExtent() === "undefined" || map.getExtent() === null) {
        return;
    }*/
    /*if (typeof map.getView().calculateExtent(map.getSize()) === "undefined" || map.getView().calculateExtent(map.getSize()) === null) {
        return;
    }*/

    //fix for unselect on dblclickzoom
    /*if (map.unSelectTimeout != null) {
        map.unSelectTimeout = null;
    }*/

    if (onMapZoomTimer != null) {
        clearTimeout(onMapZoomTimer);
    }

    onMapZoomTimer = setTimeout(
        function () {
            timeout = 333;
            SendExtentToSession(map);

            //this call to GetGeoJSONSitesComplete is done so that the map for detailed sightings zooming between polygons and points works
            //it reuses the previously fetched results to reinit the layers on the map which checks if a polygon or point should be used
            if (previouslyFetchedMapData != null) {
                GetGeoJSONSitesComplete(map, previouslyFetchedMapData);
            }

            if (!map.mapOption.ShowSpecificSites) {
                if (map.firstDraw) {
                    map.zoomOrPanActive = false;
                    map.firstDraw = false;
                } else {
                    map.zoomOrPanActive = true;
                }
                //WriteDebugMessage('MoveZoom' + map.getZoom() + ' b ' + map.getExtent().toString() + ' scale ' + map.getScale());
                if (map.mapOption.ParentSitesOnly == true) {
                    GetParentGeoJSONSites(map, map.selectedSite);
                } else if (map.mapOption.ShowServerSessionSideSites == true || map.getView().getZoom() > 9) {                
                    if (map.mapOption.ShowEditableSitesOnly == true) {
                        GetEditableGeoJSONSites(map, true);
                    } else if (map.mapOption.ShowAllPrivateAndPublicSites) {
                        GetPrivateAndPublicGeoJSONSites(map);
                    } else {
                        GetAllGeoJSONSitesForSpeciesGroup(map, null);
                    }
                } else if (map.getView().getZoom() >= map.mapOption.MinScaleForPublicSites) {
                    if (map.getView().getZoom() != null && map.lastSitesZoomLevel == null) {
                        map.lastSitesZoomLevel = map.getView().getZoom();
                    }
                    if (map.getView().calculateExtent(map.getSize()) != null && map.lastSitesExtent == null) {
                        map.lastSitesExtent = map.getView().calculateExtent(map.getSize());
                        if (map.selectedSite > -2) {
                            refreshLayers(map, map.selectedSite);
                        } else {
                            refreshLayers(map, null);
                        }

                    } else {
                        //if (map.lastSitesZoomLevel <= map.mapOption.MinScaleForFullSiteRefresh || (map.lastSitesExtent.containsBounds(getExtent(map), false, true) == false)) {
                        //if (map.lastSitesZoomLevel <= map.mapOption.MinScaleForFullSiteRefresh) {
                        if (map.selectedSite > -2) {
                            refreshLayers(map, map.selectedSite);
                        } else {
                            refreshLayers(map, null);
                        }
                        //}
                    }
                } else {
                    if (map.getView().getZoom() != null) {
                        map.lastSitesZoomLevel = map.getView().getZoom();
                        map.lastSitesExtent = getExtent(map);
                    }
                    getLayerByName(map, 'theSiteLayer').getSource().clear();
                    if (!map.mapOption.SelectByPolygon) {
                        getLayerByName(map, 'theEditableSiteLayer').getSource().clear();

                    }
                    getLayerByName(map, 'thePrecisionLayer').getSource().clear();
                }
            }
        }, timeout);
}


var GetEditableSitesRequest = null;
var GetNonEditableSitesRequest = null;
var GetSitesRequest = null;
var GetParentsRequest = null;

function getExtent(map) {
    var mapSize = map.getSize();
    if (mapSize[0] == 0 || mapSize[1] == 0) {
        mapSize[0] = 348;
        mapSize[1] = 350;
    }

    var extent = map.getView().calculateExtent(mapSize);
    var xMin = extent[0];
    var yMin = extent[1];
    var xMax = extent[2];
    var yMax = extent[3];
    if (xMin < 11404 || yMin < 7372675 || xMax > 3416215 || yMax > 10797054 || xMin > xMax || yMin > yMax ||
        isNaN(xMin) || isNaN(yMin) || isNaN(xMax) || isNaN(yMax) || xMin == xMax || yMin == yMax) {
        xMin = 11404;
        yMin = 7372675;
        xMax = 3416215;
        yMax = 10797054;
    }
    return xMin + "," + yMin + "," + xMax + "," + yMax;
}

function ShowBussyLoader(map) {
    if (apMapBussyLoaderContainer) {
        apMapBussyLoaderContainer.innerHTML = "<div class = 'ap2-ui-gridloading-image'></div>";
        if (apMapBussyLoader) {
            apMapBussyLoader.setPosition([map.getView().getCenter()[0], map.getView().getCenter()[1]]);
        }
    }
}

function HideBussyLoader() {
    if (apMapBussyLoaderContainer) {
        apMapBussyLoaderContainer.innerHTML = "";
    }
}

function setStatusText(completeResult, noSites) {
    if (completeResult) {
        $("#status").text("");
    } else {
        $("#status").css({ "font-style": "italic", "font-weight": "bold", "color": "red" });
        $("#status").text(window.Artportalen.ResourceLabel("Shared_Map_ShowFirst") + " " + noSites + " " + window.Artportalen.ResourceLabel("Shared_Map_Places") + ".");
        $("#status").attr("title", window.Artportalen.ResourceLabel("Shared_Map_ShowFirstPlacesInfo"));
    }   
}

function GetAllGeoJSONSitesForSpeciesGroup(map, projectId) {
    if (map.mapOption.AtlasMap == true || map.mapOption.AtlasSurveyMap == true) return; // don't call sites if AtlasMap
    map = GetMapReference(map);
    var speciesGroupIdWhenFetching = map.speciesGroupId;
    if (GetSitesRequest != null) {
        GetSitesRequest.abort();
    }

    var getgeojsonurl = window.Artportalen_ApplicationPath + "/Map/GetSitesGeoJson";
    if (map.mapOption.GetSitesGeoJsonUrl) {
        getgeojsonurl = map.mapOption.GetSitesGeoJsonUrl;
    }

    var projectIds = "";
    if (projectId === undefined || projectId === null) {
        projectIds = $("input.ap2-ui-multiproject-value").val();
    } else {
        projectIds = projectId;
    }

    ShowBussyLoader(map);

    if (map.selectedSite > -2) {
        map.featureToSelectId = map.selectedSite;
    }

    ShowBussyLoader(map);

    GetSitesRequest = window.Artportalen.ajaxPost(getgeojsonurl,
        { zoomLevel: Math.ceil(map.getView().getZoom()), bbox: getExtent(map), userId: map.mapOption.UserId, speciesGroupId: map.speciesGroupId, projectIds: projectIds, showOnlyProjects: map.showOnlyProjects, showCluster: map.showCluster, breakYear: map.breakYear, showValidated: map.showValidated }, function (data) {
            if ($("#status").length && data.completeResult != undefined) {
                setStatusText(data.completeResult, data.noSites);
            }

            GetAllGeoJSONSitesForSpeciesGroupComplete(map, data, speciesGroupIdWhenFetching);
        });
}

//
// Get parent geojson sites
//
function GetParentGeoJSONSites(map, appendSiteId) {
    map = GetMapReference(map);
    if (GetParentsRequest != null) {
        GetParentsRequest.abort();
    }

    ShowBussyLoader(map);
    GetParentsRequest = $.ajax(
        {
            type: "POST",
            async: true,
            cache: false,
            url: window.Artportalen_ApplicationPath + "/Map/GetParentSitesGeoJson",
            data: "bbox=" + getExtent(map) + "&appendSiteId=" + appendSiteId,
            success: function (data) { map.zoomOrPanActive = false; GetGeoJSONSitesComplete(map, data); },
            error: function (req, status, error) {
                WriteDebugMessage("ERROR: /Map/GetGeoJSONSitesComplete not found or not responding...");
                HideBussyLoader();
            }
        }
    );
}

function GetGeoJSONSiteForNewSite(map, name, coordEast, coordNorth, accuracy, diffusion, coordNotationId, coordsystemId) {
    map = GetMapReference(map);
    window.Artportalen.ajaxPost(window.Artportalen_ApplicationPath + "/Map/GetGeoJsonForNewSite",
        {
            name: name,
            coordEast: coordEast,
            coordNorth: coordNorth,
            coordNotationId: coordNotationId,
            coordSystemId: coordsystemId,
            accuracy: accuracy,
            diffusion: diffusion
        },
        function (data) {
            GetGeoJSONSiteForNewSiteComplete(map, data);
        });
}

function GetPrivateAndPublicGeoJSONSites(map) {
    map = GetMapReference(map);
    if (GetSitesRequest != null) {
        GetSitesRequest.abort();
    }

    ShowBussyLoader(map);
    var bboxStr = map.getView().calculateExtent(map.getSize())[0] + "," + map.getView().calculateExtent(map.getSize())[1] + "," + map.getView().calculateExtent(map.getSize())[2] + "," + map.getView().calculateExtent(map.getSize())[3];
    GetSitesRequest = $.ajax(
        {
            type: "POST",
            async: true,
            cache: false,
            url: window.Artportalen_ApplicationPath + "/Map/GetPrivateAndPublicSitesGeoJson",
            data: "zoomLevel=" + Math.ceil(map.getView().getZoom()) + "&bbox=" + bboxStr + "&userId=" + map.mapOption.UserId + "&coordSys=" + map.coordinateSystem,
            success: function (data) { GetGeoJSONSitesComplete(map, data); },
            error: function (req, status, error) {
                WriteDebugMessage("ERROR: /Map/GetPrivateAndPublicSitesGeoJson not found or not responding...");
                HideBussyLoader();
            }
        }
    );
}

function GetGeoJSONSites(map) {
    map = GetMapReference(map);
    if (GetSitesRequest != null) {
        GetSitesRequest.abort();
    }

    ShowBussyLoader(map);
    var bboxStr = map.getView().calculateExtent(map.getSize())[0] + "," + map.getView().calculateExtent(map.getSize())[1] + "," + map.getView().calculateExtent(map.getSize())[2] + "," + map.getView().calculateExtent(map.getSize())[3];
    GetSitesRequest = $.ajax(
        {
            type: "POST",
            async: true,
            cache: false,
            url: window.Artportalen_ApplicationPath + "/ViewSighting/GetViewSightingAsMapGeoJsonSites",
            data: "zoomLevel=" + Math.ceil(map.getView().getZoom()) + "&bbox=" + bboxStr + "&showCluster=" + map.showCluster + "&coordSys=" + map.coordinateSystem,
            success: function (data) { map.zoomOrPanActive = false; GetGeoJSONSitesComplete(map, data); },
            error: function (req, status, error) {
                WriteDebugMessage("ERROR: /ViewSighting/GetViewSightingAsMapGeoJsonSites not found or not responding...");
                HideBussyLoader();
            }
        }
    );
}

function GetDividedByYearGeoJSONSites(map) {
    map = GetMapReference(map);
    if (GetSitesRequest != null) {
        GetSitesRequest.abort();
    }

    ShowBussyLoader(map);
    var bboxStr = map.getView().calculateExtent(map.getSize())[0] + "," + map.getView().calculateExtent(map.getSize())[1] + "," + map.getView().calculateExtent(map.getSize())[2] + "," + map.getView().calculateExtent(map.getSize())[3];
    GetSitesRequest = $.ajax(
        {
            type: "POST",
            async: true,
            cache: false,
            url: window.Artportalen_ApplicationPath + "/ViewSighting/GetViewSightingDividedByYearAsMapGeoJsonSites",
            data: "zoomLevel=" + Math.ceil(map.getView().getZoom()) + "&bbox=" + bboxStr + "&showCluster=" + map.showCluster + "&coordSys=" + map.coordinateSystem + "&breakYear=" + map.breakYear,
            success: function (data) { map.zoomOrPanActive = false; GetGeoJSONSitesComplete(map, data); },
            error: function (req, status, error) {
                WriteDebugMessage("ERROR: /ViewSighting/GetViewSightingDividedByYearAsMapGeoJsonSites not found or not responding...");
                HideBussyLoader();
            }
        }
    );
}

function GetDividedByProportionGeoJSONSites(map) {
    map = GetMapReference(map);
    if (GetSitesRequest != null) {
        GetSitesRequest.abort();
    }

    ShowBussyLoader(map);
    var bboxStr = map.getView().calculateExtent(map.getSize())[0] + "," + map.getView().calculateExtent(map.getSize())[1] + "," + map.getView().calculateExtent(map.getSize())[2] + "," + map.getView().calculateExtent(map.getSize())[3];
    GetSitesRequest = $.ajax(
        {
            type: "POST",
            async: true,
            cache: false,
            url: window.Artportalen_ApplicationPath + "/ViewSighting/GetViewSightingProportionAsMapGeoJsonSites",
            data: "zoomLevel=" + Math.ceil(map.getView().getZoom()) + "&bbox=" + bboxStr + "&showCluster=" + map.showCluster + "&coordSys=" + map.coordinateSystem,
            success: function (data) { map.zoomOrPanActive = false; GetGeoJSONSitesComplete(map, data); },
            error: function (req, status, error) {
                WriteDebugMessage("ERROR: /ViewSighting/GetViewSightingProportionAsMapGeoJsonSites not found or not responding...");
                HideBussyLoader();
            }
        }
    );
}

function GetDividedByValidationJSONSites(map) {
    map = GetMapReference(map);
    if (GetSitesRequest != null) {
        GetSitesRequest.abort();
    }

    ShowBussyLoader(map);
    var bboxStr = map.getView().calculateExtent(map.getSize())[0] + "," + map.getView().calculateExtent(map.getSize())[1] + "," + map.getView().calculateExtent(map.getSize())[2] + "," + map.getView().calculateExtent(map.getSize())[3];
    GetSitesRequest = $.ajax(
        {
            type: "POST",
            async: true,
            cache: false,
            url: window.Artportalen_ApplicationPath + "/ViewSighting/GetViewSightingValidationAsMapGeoJsonSites",
            data: "zoomLevel=" + Math.ceil(map.getView().getZoom()) + "&bbox=" + bboxStr + "&showCluster=" + map.showCluster + "&showValidated=" + map.showValidated + "&coordSys=" + map.coordinateSystem,
            success: function (data) { map.zoomOrPanActive = false; GetGeoJSONSitesComplete(map, data); },
            error: function (req, status, error) {
                WriteDebugMessage("ERROR: /ViewSighting/GetViewSightingValidationAsMapGeoJsonSites not found or not responding...");
                HideBussyLoader();
            }
        }
    );
}

function GetDividedByFloraGuardianGeoJSONSites(map) {
    GetDividedByGeoJSONSites(map, "GetViewSightingFloraGuardianAsMapGeoJsonSites", "zoomLevel=" + 'Math.ceil(map.getView().getZoom()) + "&bbox=" + bboxStr + "&showCluster=" + map.showCluster + "&coordSys=" + map.coordinateSystem');
}

function GetDividedByFloraGuardianByYearGeoJSONSites(map) {
    GetDividedByGeoJSONSites(map, "GetViewSightingFloraGuardianByYearAsMapGeoJsonSites", "zoomLevel=" + 'Math.ceil(map.getView().getZoom()) + "&bbox=" + bboxStr + "&showCluster=" + map.showCluster + "&coordSys=" + map.coordinateSystem');
}

/*function GetDividedByDiffusionGeoJSONSites(map) {
    GetDividedByGeoJSONSites(map, "GetViewSightingDiffusionAsMapGeoJsonSites", '"zoomLevel=" + Math.ceil(map.getView().getZoom()) + "&bbox=" + bboxStr + "&coordSys=" + map.coordinateSystem');
}*/

function GetDividedByGeoJSONSites(map, path, data) {
    map = GetMapReference(map);
    if (GetSitesRequest != null) {
        GetSitesRequest.abort();
    }

    ShowBussyLoader(map);
    var bboxStr = map.getView().calculateExtent(map.getSize())[0] + "," + map.getView().calculateExtent(map.getSize())[1] + "," + map.getView().calculateExtent(map.getSize())[2] + "," + map.getView().calculateExtent(map.getSize())[3];
    GetSitesRequest = $.ajax(
        {
            type: "POST",
            async: true,
            cache: false,
            url: window.Artportalen_ApplicationPath + "/ViewSighting/" + path,
            data: data,
            success: function (data) { map.zoomOrPanActive = false; GetGeoJSONSitesComplete(map, data); },
            error: function (req, status, error) {
                WriteDebugMessage("ERROR: /ViewSighting/" + path + " not found or not responding...");
                HideBussyLoader();
            }
        }
    );
}

/**
 * Get the all private sites within the public sites accuracy
 */
function GetPrivateBirdSitesWithinRadiusGeoJsonSites(map, publicSiteId) {
    map = GetMapReference(map);
    if (GetSitesRequest != null) {
        GetSitesRequest.abort();
    }

    ShowBussyLoader(map);
    GetSitesRequest = $.ajax(
        {
            type: "POST",
            async: true,
            cache: false,
            url: window.Artportalen_ApplicationPath + "/Map/GetPrivateBirdSitesWithinRadiusGeoJson",
            data: "publicSiteId=" + publicSiteId + "&userId=" + map.mapOption.UserId + "&coordSys=" + map.coordinateSystem,
            success: function (data) {
                GetGeoJSONSitesPrivate(map, data);

                // refresh site mark relationships
                //var publicSiteFeature = map.theEditableSiteLayer.getFeatureByFid(publicSiteId);
                var editableLayer = getLayerByName(map, 'theEditableSiteLayer');
                var publicSiteFeature = editableLayer.getSource().getFeatureById(publicSiteId);
                SiteMarkRelationShip(map, publicSiteFeature);
            },
            error: function (req, status, error) {
                WriteDebugMessage("ERROR: /Map/GetPrivateBirdSitesWit" +
                    "hinRadiusGeoJson not found or not responding...");
                HideBussyLoader();
            }
        }
    );
}

function GetNonEditableGeoJSONSites(map) {
    map = GetMapReference(map);
    if (GetNonEditableSitesRequest != null) {
        GetNonEditableSitesRequest.abort();
    }

    ShowBussyLoader(map);
    var projectIds = $("input.ap2-ui-multiproject-value").val();
    var bboxStr = map.getView().calculateExtent(map.getSize())[0] + "," + map.getView().calculateExtent(map.getSize())[1] + "," + map.getView().calculateExtent(map.getSize())[2] + "," + map.getView().calculateExtent(map.getSize())[3];
    GetNonEditableSitesRequest = $.ajax(
        {
            type: "POST",
            async: true,
            cache: false,
            url: window.Artportalen_ApplicationPath + "/Map/GetNonEditableSitesGeoJson",
            data: "zoomLevel=" + Math.ceil(map.getView().getZoom()) + "&bbox=" + bboxStr + "&userId=" + map.mapOption.UserId + "&speciesGroupId=" + map.speciesGroupId + "& projectIds=" + projectIds + "&showOnlyProjects=" + map.showOnlyProjects,
            success: function(data) {
                if ($("#status").length) {
                    if (data.completeResult != undefined) {
                        setStatusText(data.completeResult, data.noSites);
                    }
                }
                GetNonEditableGeoJSONSitesComplete(map, data);
            },
            error: function (req, status, error) {
                WriteDebugMessage("ERROR: /Map/GetNonEditableSitesGeoJson not found or not responding...");
                HideBussyLoader();
            }
        }
    );
}

function GetEditableGeoJSONSites(map, clearMap) {
    map = GetMapReference(map);
    if (GetEditableSitesRequest != null) {
        GetEditableSitesRequest.abort();
    }
    ShowBussyLoader(map);
    var projectIds = $("input.ap2-ui-multiproject-value").val();
    var bboxStr = map.getView().calculateExtent(map.getSize())[0] + "," + map.getView().calculateExtent(map.getSize())[1] + "," + map.getView().calculateExtent(map.getSize())[2] + "," + map.getView().calculateExtent(map.getSize())[3];
    var zoomLevel = Math.ceil(map.getView().getZoom());

    if (zoomLevel && zoomLevel != null) {
        GetEditableSitesRequest = $.ajax(
            {
                type: "POST",
                async: true,
                cache: false,
                url: window.Artportalen_ApplicationPath + "/Map/GetEditableSitesGeoJson",
                data: "zoomLevel=" + Math.ceil(zoomLevel) + "&bbox=" + bboxStr + "&userId=" + map.mapOption.UserId + "&projectIds=" + projectIds + "&showOnlyProjects=" + map.showOnlyProjects,
                success: function (data) { GetEditableGeoJSONSitesComplete(map, data, clearMap); },
                error: function (req, status, error) {
                    WriteDebugMessage("ERROR: /Map/GetEditableSitesGeoJson not found or not responding...");
                    HideBussyLoader();
                }
            }
        );
    }
}

function GetSpecificGeoJSONSites(map, ids) {
    map = GetMapReference(map);
    if (GetSitesRequest != null) {
        GetSitesRequest.abort();
    }

    var uniqueIds = window.Artportalen.Helpers.arrayToUnique(ids);

    ShowBussyLoader(map);
    GetSitesRequest = $.ajax(
        {
            type: "POST",
            async: true,
            cache: false,
            traditional: true,
            url: window.Artportalen_ApplicationPath + "/Map/GetSpecificSitesGeoJson",
            data: { siteIds: uniqueIds, coordSys: map.coordinateSystem },
            success: function (data) { map.zoomOrPanActive = false; GetGeoJSONSitesComplete(map, data); },
            error: function (req, status, error) {
                WriteDebugMessage("ERROR: /Map/GetSpecificSitesGeoJson not found or not responding...");
                HideBussyLoader();
            }
        }
    );
}

function GetSpecificGeoJSONSitesConstrainedByMap(map, ids) {
    map = GetMapReference(map);
    if (GetSitesRequest != null) {
        GetSitesRequest.abort();
    }

    ShowBussyLoader(map);
    GetSitesRequest = $.ajax(
        {
            type: "POST",
            async: true,
            cache: false,
            traditional: true,
            url: window.Artportalen_ApplicationPath + "/Map/GetSpecificSitesGeoJsonConstrainedByMap",
            data: { siteIds: ids, bbox: getExtent(map) },
            success: function (data) { map.zoomOrPanActive = false; GetGeoJSONSitesComplete(map, data); },
            error: function (req, status, error) {
                WriteDebugMessage("ERROR: /Map/GetSpecificSitesGeoJsonConstrainedByMap not found or not responding...");
                HideBussyLoader();
            }
        }
    );
}

function LoadGeoJSONSitesConstrainedByMap(map) {
    map = GetMapReference(map);
    if (GetSitesRequest != null) {
        GetSitesRequest.abort();
    }

    ShowBussyLoader(map);
    GetSitesRequest = $.ajax(
        {
            type: "POST",
            async: true,
            cache: false,
            traditional: true,
            url: map.mapOption.GetSitesGeoJsonUrl,
            data: "zoomLevel=" + Math.ceil(map.getView().getZoom()) + "&bbox=" + getExtent(map) + "&showCluster=" + map.showCluster + "&coordSys=" + map.coordinateSystem,
            success: function (data) { map.zoomOrPanActive = false; GetGeoJSONSitesComplete(map, data); },
            error: function (req, status, error) {
                WriteDebugMessage("ERROR: URL " + url + " not found or not responding...");
                HideBussyLoader();
            }
        }
    );
}

function AddFeaturesToMap(map, results, layer) {
    var arrowLayer = getLayerByName(map, 'theSiteArrowLayer');
    arrowLayer.getSource().clear();

    map = GetMapReference(map);
    var myObject = eval(results);
    var features;
    if (myObject.points != null && myObject.points != 'undefined') {
        features = new ol.format.GeoJSON().readFeatures(myObject.points);
    }

    if (results.borderLimit && results.borderLimit.length > 0) {
        var delimitLayer = getLayerByName(map, 'theDelimitLayer');
        var borderFeatures = new Array();
        for (var i = 0; i < results.borderLimit.length; i++)
        {
            var tmpBorderFeatures = new ol.format.WKT().readFeatures(results.borderLimit[i]);
            tmpBorderFeatures[0].setProperties({ 'limitType': 'AtlasSquareBorder' });
            borderFeatures[i] = tmpBorderFeatures[0];
        } 

        delimitLayer.getSource().addFeatures(borderFeatures, { silent: true });
        //map.getView().fit(delimitLayer.getSource().getExtent(), {});        
    }

    var polfeatures;
    if (myObject.polygons != null && myObject.polygons != 'undefined' && myObject.polygons.features != null) {
        polfeatures = new ol.format.GeoJSON().readFeatures(myObject.polygons);
    }

    var polFeaturesAdjusted = new Array();
    var zoom = map.getView().getZoom();
    var j = 0;
    if (polfeatures != null) {
        for (var i = 0; i < polfeatures.length; i++) {
            var accuracyOfPolygon = polfeatures[i].getProperties().accuracy;
            if (accuracyOfPolygon != null && ShallShowPolygonAsPoint(map, accuracyOfPolygon, zoom)) {
                var centroid = getCentroid(polfeatures[i]);
                var point = new ol.Feature({
                });
                point.setProperties({
                    'siteName': polfeatures[i].getProperties().siteName,
                    'siteType': polfeatures[i].getProperties().siteType,
                    'importCandidate': polfeatures[i].getProperties().importCandidate,
                    'parentId': polfeatures[i].getProperties().parentId,
                    'projectAndExternalId': polfeatures[i].getProperties().projectAndExternalId,
                    'siteId': polfeatures[i].getProperties().siteId,
                    'dividedByFloraGuardian': polfeatures[i].getProperties().dividedByFloraGuardian, 
                    'dividedByFloraGuardian1To3YearsAgo': polfeatures[i].getProperties().dividedByFloraGuardian1To3YearsAgo,
                    'dividedByFloraGuardian1To3YearsAgoNotRecovered': polfeatures[i].getProperties().dividedByFloraGuardian1To3YearsAgoNotRecovered,
                    'dividedByFloraGuardianCurrentYear': polfeatures[i].getProperties().dividedByFloraGuardianCurrentYear,
                    'dividedByFloraGuardianCurrentYearNotRecovered': polfeatures[i].getProperties().dividedByFloraGuardianCurrentYearNotRecovered,
                    'dividedByFloraGuardianNotRecovered': polfeatures[i].getProperties().dividedByFloraGuardianNotRecovered,
                    'dividedByFloraGuardianOld': polfeatures[i].getProperties().dividedByFloraGuardianOld,
                    'dividedByFloraGuardianOldNotRecovered': polfeatures[i].getProperties().dividedByFloraGuardianOldNotRecovered,
                    'dividedByFloraGuardianOrdinary': polfeatures[i].getProperties().dividedByFloraGuardianOrdinary,
                    'dividedByFloraGuardianOrdinaryNotRecovered': polfeatures[i].getProperties().dividedByFloraGuardianOrdinaryNotRecovered,
                    'dividedByProportionSize': polfeatures[i].getProperties().dividedByProportionSize,
                    'dividedByUnValidInterest': polfeatures[i].getProperties().dividedByUnValidInterest,
                    'dividedByUnValidWarning': polfeatures[i].getProperties().dividedByUnValidWarning,
                    'dividedByValidApproved': polfeatures[i].getProperties().dividedByValidApproved,
                    'dividedByValidInProgress': polfeatures[i].getProperties().dividedByValidInProgress,
                    'dividedByValidReject': polfeatures[i].getProperties().dividedByValidReject,
                    'dividedByYearAfter': polfeatures[i].getProperties().dividedByYearAfter,
                    'dividedByYearNotRecoveredAfter': polfeatures[i].getProperties().dividedByYearNotRecoveredAfter,
                    'dividedByYearNotRecoveredUntil': polfeatures[i].getProperties().dividedByYearNotRecoveredUntil,
                    'dividedByYearUntil': polfeatures[i].getProperties().dividedByYearUntil,
                    'numberOfSightings': polfeatures[i].getProperties().numberOfSightings,
                    'proportionColour': polfeatures[i].getProperties().proportionColour,
                    'proportionHeight': polfeatures[i].getProperties().proportionHeight,
                    'proportionRotation': polfeatures[i].getProperties().proportionRotation,
                    'proportionSize': polfeatures[i].getProperties().proportionSize
                });
                point.setId(polfeatures[i].getId());
                point.setGeometry(new ol.geom.Point([centroid[0], centroid[1]]));
                features.push(point);
            } else {
                polFeaturesAdjusted[j++] = polfeatures[i];
            }
        }
    }
    length = polFeaturesAdjusted.length;

    var precisionfeatures;
    if (myObject.points != null && myObject.points != 'undefined') {
        precisionfeatures = new ol.format.GeoJSON().readFeatures(myObject.points);
    }
    layer.getSource().addFeatures(polFeaturesAdjusted, { silent: true });
    //}
    if (features != null) {
        length = features.length;
        for (var i = 0; i < length; i++) {
            if (features[i].getProperties().siteType == 31) {
                arrowLayer = getLayerByName(map, 'theSiteArrowLayer');
                var rotation = parseInt(features[i].getProperties().proportionRotation) * (Math.PI / 180);
                var height = parseInt(features[i].getProperties().proportionHeight);
                var mapScale = getMapScale(map.getView().getResolution());
                var scaleFactor = 2000;
                var x = features[i].getGeometry().getCoordinates()[0] +
                    ((height * Math.sin(rotation) * mapScale) / scaleFactor);
                var y = features[i].getGeometry().getCoordinates()[1] +
                    ((height * Math.cos(rotation) * mapScale) / scaleFactor);
                var arrowX1 = 0;
                var arrowY1 = 0;
                var arrowX2 = 0;
                var arrowY2 = 0;
                var leg = 4;
                var hypotenuse = 6;
                if (features[i].getProperties().proportionRotation == "0") {
                    arrowX1 = x + ((leg * mapScale) / scaleFactor);
                    arrowY1 = y - ((leg * mapScale) / scaleFactor);
                    arrowX2 = x - ((leg * mapScale) / scaleFactor);
                    arrowY2 = y - ((leg * mapScale) / scaleFactor);
                } else if (features[i].getProperties().proportionRotation == "45") {
                    arrowX1 = x;
                    arrowY1 = y - ((hypotenuse * mapScale) / scaleFactor);
                    arrowX2 = x - ((hypotenuse * mapScale) / scaleFactor);
                    arrowY2 = y;
                } else if (features[i].getProperties().proportionRotation == "90") {
                    arrowX1 = x - ((leg * mapScale) / scaleFactor);
                    arrowY1 = y - ((leg * mapScale) / scaleFactor);
                    arrowX2 = x - ((leg * mapScale) / scaleFactor);
                    arrowY2 = y + ((leg * mapScale) / scaleFactor);
                } else if (features[i].getProperties().proportionRotation == "135") {
                    arrowX1 = x - ((hypotenuse * mapScale) / scaleFactor);
                    arrowY1 = y;
                    arrowX2 = x;
                    arrowY2 = y + ((hypotenuse * mapScale) / scaleFactor);
                } else if (features[i].getProperties().proportionRotation == "180") {
                    arrowX1 = x + ((leg * mapScale) / scaleFactor);
                    arrowY1 = y + ((leg * mapScale) / scaleFactor);
                    arrowX2 = x - ((leg * mapScale) / scaleFactor);
                    arrowY2 = y + ((leg * mapScale) / scaleFactor);
                } else if (features[i].getProperties().proportionRotation == "225") {
                    arrowX1 = x;
                    arrowY1 = y + ((hypotenuse * mapScale) / scaleFactor);
                    arrowX2 = x + ((hypotenuse * mapScale) / scaleFactor);
                    arrowY2 = y;
                } else if (features[i].getProperties().proportionRotation == "270") {
                    arrowX1 = x + ((leg * mapScale) / scaleFactor);
                    arrowY1 = y - ((leg * mapScale) / scaleFactor);
                    arrowX2 = x + ((leg * mapScale) / scaleFactor);
                    arrowY2 = y + ((leg * mapScale) / scaleFactor);
                } else if (features[i].getProperties().proportionRotation == "315") {
                    arrowX1 = x + ((hypotenuse * mapScale) / scaleFactor);
                    arrowY1 = y;
                    arrowX2 = x;
                    arrowY2 = y - ((hypotenuse * mapScale) / scaleFactor);
                }

                var style = new ol.style.Style({
                    fill: new ol.style.Fill({ color: 'rgba(0, 0, 0, 1)' }),
                    stroke: new ol.style.Stroke({
                        color: '#000000',
                        width: 4
                    })
                });

                var feature = new ol.Feature({
                    geometry: new ol.geom.LineString([
                        [
                            features[i].getGeometry().getCoordinates()[0],
                            features[i].getGeometry().getCoordinates()[1]
                        ],
                        [x, y]
                    ])
                });
                feature.setStyle(style);
                arrowLayer.getSource().addFeature(feature, { silent: true });

                feature = new ol.Feature({
                    geometry: new ol.geom.LineString([
                        [x, y],
                        [arrowX1, arrowY1]
                    ])
                });
                feature.setStyle(style);
                arrowLayer.getSource().addFeature(feature, { silent: true });

                feature = new ol.Feature({
                    geometry: new ol.geom.LineString([
                        [x, y],
                        [arrowX2, arrowY2]
                    ])
                });
                feature.setStyle(style);
                arrowLayer.getSource().addFeature(feature, { silent: true });
            } else {
                //layer.getSource().addFeature(features[i], { silent: true });
                if ((features[i].getId() == -1 && features[i].getProperties().siteType == 4) ||
                    ((features[i].getId() == 0 || features[i].getId() == -1) && (features[i].getProperties().siteType == 39 || features[i].getProperties().siteType == 40))) {
                    features[i].setId(-i - 1);
                }
                layer.getSource().addFeature(features[i]);
            }
        }
    }

    if (precisionfeatures != null && map.showAccuracy && layer.get('title') != 'thePrivateSiteLayer') {

        var arrPrecisionFeatures = new Array();
        for (i in precisionfeatures) {
            //if (precisionfeatures.hasOwnProperty(i)) {  
            // if clusterlayer todo
            /*var layerFeature
            if (layer.get('title') == 'theSiteLayer' || layer.get('title') == 'theEditableSiteLayer') {
                layerFeature = layer.getSource().getSource().getFeatureById(precisionfeatures[i].getId());
            } else {
                layerFeature = layer.getSource().getFeatureById(precisionfeatures[i].getId());
            }*/
            //if (precisionfeatures[i].getProperties().accuracy > 0 && layerFeature && !IsCluster(layerFeature)) {
            if (precisionfeatures[i].getProperties().accuracy > 0) {
                arrPrecisionFeatures.push(precisionfeatures[i]);
            }
            //}
        }

        // If it's the private site layer then add precision features to thePrivateSitePrecisionLayer
        /*if (layer.isPrivateSiteLayer === true) {
            map.thePrivateSitePrecisionLayer.addFeatures(arrPrecisionFeatures);
        } else {*/
        /*var precisionLayer;
        map.getLayers().forEach(function (lay) {
            if (lay.get('title') == 'thePrecisionLayer') {
                precisionLayer = lay;
            }
        });*/
        var precisionLayer = getLayerByName(map, 'thePrecisionLayer');
        precisionLayer.getSource().addFeatures(arrPrecisionFeatures);
        //}
    }
    /*}*/
    
    if (myObject.areas != null) {
        let areaFeatures = new ol.format.GeoJSON().readFeatures(myObject.areas);

        let areasLayer = getLayerByName(map, 'theAreasLayer');
        areasLayer.getSource().addFeatures(areaFeatures)
    }
}

function showNoResultMessage(map, showNoResult, completeResult) {
    if (map.firstLoad) {
        map.emptyResult = true;
        $('#noResult').html(Artportalen.ResourceLabel('Shared_JavaScript_NoSearchResult'));
        $('#noResultMessage').show();
        console.log($('#noResultMessage'));
    } else if (map.emptyResult) {
        $('#noResult').html(Artportalen.ResourceLabel('Shared_JavaScript_NoSearchResult'));
        $('#noResultMessage').show();
    }
    if (showNoResult) {
        $('#SelectSightingMessage').hide();
    } else {
        $('#noResultMessage').hide();
        $('#SelectSightingMessage').show();
    }
    if (completeResult) {
        $('#UncompleteResultsMessage').hide();
    } else {
        $('#UncompleteResultsMessage').show();
    }
}

function ShallShowPolygonAsPoint(map, accuraccyOfPolygon, zoom) {
    var showAsPoint = false;
    var resolution = map.getView().getResolution();
    var mapScale = getMapScale(resolution);
    var scaledRadius = accuraccyOfPolygon * 2750 / mapScale;
    if (scaledRadius < 4.5) {
        showAsPoint = true;
    }

    return showAsPoint;
}

function getLayerByName(map, layerName) {
    var layer;
    map.getLayers().forEach(function (lay) {
        if (lay.get('title') == layerName) {
            layer = lay;
        }
    });

    return layer;
}

function AddFeaturesToMapAndSelect(map, results) {
    map = GetMapReference(map);
    var myObject = eval(results);

    var features;
    var polfeatures;
    var editeableLayer = getLayerByName(map, 'theEditableSiteLayer');
    if (myObject.points.features.length != 0) {
        features = new ol.format.GeoJSON().readFeatures(myObject.points);
        //var precisionfeatures = new ol.format.GeoJSON().readFeatures(myObject.points);
        if (features) {
            var i = 0;
            features.forEach(function (item) {
                if ((item.getId() == -1 && item.getProperties().siteType == 4) ||
                    ((item.getId() == 0 || item.getId() == -1) && (item.getProperties().siteType == 39 || item.getProperties().siteType == 40))) {
                    item.setId(-i - 1);
                    i++;
                }
            });
            $('#' + map.divId).triggerHandler('onMapSiteCreated', [features]);
            editeableLayer.getSource().addFeatures(features, { silent: true });
        }
        /*if (precisionfeatures) {
            for (var i in precisionfeatures) {
                if (precisionfeatures[i].getProperties().accuracy > 0) {
                    var precisionLayer = getLayerByName(map, 'thePrecisionLayer');
                    precisionLayer.getSource().addFeatures([precisionfeatures[i]]);
                }
            }
        }*/
    } else {
        polfeatures = new ol.format.GeoJSON().readFeatures(myObject.polygons);
        if (polfeatures) {
            $('#' + map.divId).triggerHandler('onMapSiteCreated', [polfeatures]);
            editeableLayer.getSource().addFeatures(polfeatures, { silent: true });
        }
    }

    //map.skipSelectEvent = true;
    /*if (polfeatures && polfeatures[0] != null) {
        var feature = map.theEditableSiteLayer.getFeatureById(polfeatures[0].id);
    }
    else if (features) {
        feature = map.theEditableSiteLayer.getFeatureById(features[0].id);
    }*/
    UnselectFeatures(map);
    if (features) {
        features.forEach(function (item) {
            SelectFeature(map, item);
        });
        $('#' + map.divId).triggerHandler('onMapSiteSelected', [features]);

    } else if (polfeatures) {
        polfeatures.forEach(function (item) {
            SelectFeature(map, item);
        });
        $('#' + map.divId).triggerHandler('onMapSiteSelected', [polfeatures]);
    }
}

function isEmpty(ob) {
    for (var i in ob) { if (ob.hasOwnProperty(i)) { return false; } }
    return true;
}

function GetAllGeoJSONSitesForSpeciesGroupComplete(map, results, speciesGroupIdWhenFetching) {
    map = GetMapReference(map);
    if (map.speciesGroupId && speciesGroupIdWhenFetching != map.speciesGroupId) {
        // The species group id has changed, so we need to reload the sites according to the new id
        GetAllGeoJSONSitesForSpeciesGroup(map, null);
    }
    //map.zoomOrPanActive = false; 
    GetGeoJSONSitesComplete(map, results);
}

function GetGeoJSONSiteForNewSiteComplete(map, data) {
    console.log('map', map, 'data', data);
    map = GetMapReference(map);
    if ((data != null) && (data != "nothing" && data != '')) {
        var myObject = eval(data);
        var features;
        if (myObject.points.features.length > 0) {
            features = new ol.format.GeoJSON().readFeatures(myObject.points);
        } else {
            features = new ol.format.GeoJSON().readFeatures(myObject.polygons);
        }
        var centroid = getCentroid(features[0]);
        DestroyTemporarySite(map);
        map.temporarySite = data;
        map.featureToSelectId = -1;
        map.selectedSite = -2;
        var currentCenterOfMap = map.getView().getCenter();
        if (currentCenterOfMap[0] == centroid[0] && currentCenterOfMap[1] == centroid[1]) {
            zoomToSiteByCoordinate(map, centroid[0] + 1, centroid[1] + 1);
            //need to force a change for mappanzoomevent to trigger
        } else {
            var zoomLevel = map.getView().getZoom();
            if (features[0].getProperties().diffusion == 100) {
                zoomLevel = 16;
            } else if (features[0].getProperties().diffusion == 500) {
                zoomLevel = 14;
            } else if (features[0].getProperties().diffusion == 1000) {
                zoomLevel = 13;
            }
            zoomToSiteByCoordinate(map, centroid[0], centroid[1], zoomLevel);
        }
    }
}

// Destroy all existing features in (not the "private" layers) all layers
function DestroyTemporarySite(map) {
    map = GetMapReference(map);
    var editableLayer = getLayerByName(map, 'theEditableSiteLayer');
    //var precisionLayer = getLayerByName(map, 'thePrecisionLayer');
    var feature = editableLayer.getSource().getFeatureById(-1);
    if (feature) {
        editableLayer.getSource().removeFeature(feature);
    }
    /*feature = precisionLayer.getSource().getFeatureById(-1);
    if (feature) {
        precisionLayer.getSource().removeFeature(feature);
    }*/
}

// Add private sites to the private layer
function GetGeoJSONSitesPrivate(map, results) {
    map = GetMapReference(map);
    var privateLayer = getLayerByName(map, 'thePrivateSiteLayer');

    // Clear private layer
    //if (!isEmpty(map.thePrivateSiteLayer.features)) {
    if (!isEmpty(privateLayer.getSource().getFeatures())) {
        privateLayer.getSource().clear();
    }

    // Add features to map
    if (results != '') {
        AddFeaturesToMap(map, results, privateLayer);
    }

    HideBussyLoader();
}

function SelectFeature(map, feature) {
    var overlayLayer = getLayerByName(map, 'theSelectLayer');
    overlayLayer.getSource().addFeature(feature);
    if (!map.zoomOrPanActive) {
        if (feature.getGeometry().getType == "Point") {
            map.getView().setCenter([feature.getGeometry().getCoordinates()[0], feature.getGeometry().getCoordinates()[1]]);
        } else {
            var centroid = getCentroid(feature);
            map.getView().setCenter([centroid[0], centroid[1]]);
        }

    }

}

function UnselectFeatures(map) {
    var overlayLayer = getLayerByName(map, 'theSelectLayer');
    if (overlayLayer.getSource().getFeatures().length > 0) {
        overlayLayer.getSource().clear();
    }
    map.featureToSelectId = null;
    map.selectedSite = null;
}

function selectAndGetSite(id) {
    var layer = getLayerByName(overlapMap, 'theSiteLayer');
    var feature = layer.getSource().getFeatureById(id);
    if (!feature) {
        layer = getLayerByName(overlapMap, 'theEditableSiteLayer');
        feature = layer.getSource().getFeatureById(id);
    }

    selectById(overlapMap, id, true);
    SetMapSiteSelected(overlapMap, feature);
    $('#' + map.divId).triggerHandler('onMapSiteSelected', [feature]);
}

function GetCenterOfExtent(extent) {
    var x = extent[0] + (extent[2] - extent[0]) / 2;
    var y = extent[1] + (extent[3] - extent[1]) / 2;
    return [x, y];
}

function ZoomToExtent(map, siteLayer) {
    if (!map.zoomOrPanActive) {
        if (map.selectAdminSighting) {
            var layer = getLayerByName(map, 'theDelimitLayer');
            map.getView().fit(layer.getSource().getExtent());
        } else if (siteLayer.getSource().getFeatures().length > 0) {
            var coordDiff = 100;
            if (Math.abs(siteLayer.getSource().getExtent()[0] -
                    siteLayer.getSource().getExtent()[2]) <
                coordDiff ||
                Math.abs(siteLayer.getSource().getExtent()[1] -
                    siteLayer.getSource().getExtent()[3]) <
                coordDiff) {
                if (map.getView().getZoom() < 15) {
                    map.getView().setZoom(15);
                }
                //map.getView().setCenter([siteLayer.getSource().getSource().getExtent()[0], siteLayer.getSource().getSource().getExtent()[1]]);
                map.getView().setCenter(GetCenterOfExtent(siteLayer.getSource().getExtent()));
            } else {
                map.getView().fit(siteLayer.getSource().getExtent());
            }
        }
    }
}
function GetGeoJSONSitesComplete(map, results) {
    //showNoResultMessage(map, false);
    previouslyFetchedMapData = results;
    map = GetMapReference(map);
    var siteLayer = getLayerByName(map, 'theSiteLayer');
    var precisionLayer = getLayerByName(map, 'thePrecisionLayer');
    var privateLayer = getLayerByName(map, 'thePrivateSiteLayer');
    //var privatePrecisionLayer = getLayerByName(map, 'thePrivateSitePrecisionLayer');
    var editableLayer = getLayerByName(map, 'theEditableSiteLayer');
    var areasLayer = getLayerByName(map, 'theAreasLayer');

    if ((siteLayer.getSource().getFeatures() != null) && (siteLayer.getSource().getFeatures() != 'undefined')) {
        if (!isEmpty(siteLayer.getSource().getFeatures())) {
            siteLayer.getSource().clear();
        }
    }
    if ((precisionLayer.getSource().getFeatures() != null) && (precisionLayer.getSource().getFeatures() != 'undefined')) {
        if (!isEmpty(precisionLayer.getSource().getFeatures())) {
            precisionLayer.getSource().clear();
        }
    }
    if ((privateLayer.getSource().getFeatures() != null) && (privateLayer.getSource().getFeatures() != 'undefined')) {
        if (!isEmpty(privateLayer.getSource().getFeatures())) {
            privateLayer.getSource().clear();
        }
    }
    if ((areasLayer.getSource().getFeatures() != null) && (areasLayer.getSource().getFeatures() != 'undefined')) {
        if (!isEmpty(areasLayer.getSource().getFeatures())) {
            areasLayer.getSource().clear();
        }
    }

    // When calls comes from view sighting views results == "" on Report resluts == undefined :/
    if (typeof results == 'undefined' || results == "") {
        map.firstLoad = !map.hasOwnProperty('firstLoad');
        showNoResultMessage(map, false, false);
    } else {
        var feature = editableLayer.getSource().getFeatureById("-1");
        var featureUndiffused = editableLayer.getSource().getFeatureById("-2");
        if ((editableLayer.getSource().getFeatures() != null) && (editableLayer.getSource().getFeatures() != 'undefined')) {
            if (editableLayer.getSource().getFeatures().length > 0 && !isEmpty(editableLayer.getSource().getFeatures())) {
                editableLayer.getSource().clear();
                if (feature != null) {
                    editableLayer.getSource().addFeatures([feature], { silent: true });
                }
                if (featureUndiffused != null) {
                    editableLayer.getSource().addFeatures([featureUndiffused], { silent: true });
                }
            }
        }

        showNoResultMessage(map, false, results.completeResult);
        //setClusterDistance(map, siteLayer);

        /*if ($("#status").length) {
            if (results.messages == 'No results') {
                $("#status").css({ "font-style": "italic", "font-weight": "bold", "color": "red" });
                $("#status").text(window.Artportalen.ResourceLabel("Shared_Map_Diffused_Square_MissingArea"));
                $("#status").attr("title", window.Artportalen.ResourceLabel("Shared_Map_Diffused_Square_MissingArea"));
            } else {
                $("#status").text("");
            }
        }*/

        AddFeaturesToMap(map, results, siteLayer);

        //ZoomToExtent(map, siteLayer);

        //var extent = siteLayer.getSource().getExtent();

        //map.getView().fit(siteLayer.getSource().getExtent(), {});
    }

    map.lastSitesZoomLevel = map.getView().getZoom();
    map.lastSitesExtent = getExtent(map);
    var thefeature;

    if (results != null && map.featureToSelectId != null && !map.mapOption.MultiSiteSelect) {
        thefeature = siteLayer.getSource().getFeatureById(map.featureToSelectId);
        if (thefeature == null && map.featureToSelectId != -1) {
            thefeature = editableLayer.getSource().getFeatureById(map.featureToSelectId);
        }
        if (thefeature != null) {
            map.skipSelectEvent = true;
            //ShowFeaturePopup(map, thefeature);
            SelectFeature(map, thefeature);
            map.featureToSelectId = null;
            SiteMarkRelationShip(map, thefeature);
        }
    }
    if (map.temporarySite) {
        DestroyTemporarySite(map);
        if (map.featureToSelectId == null) {
            AddFeaturesToMap(map, map.temporarySite, editableLayer);
            ZoomToExtent(map, editableLayer);
            //map.getView().fit(editableLayer.getSource().getSource().getExtent());

        }
        else {
            AddFeaturesToMapAndSelect(map, map.temporarySite);
            //map.featureToSelectId = null;
        }
        if (map.featureToSelectId) {
            thefeature = editableLayer.getSource().getFeatureById(map.featureToSelectId);
            if (thefeature != null) {
                map.skipSelectEvent = true;
                SelectFeature(map, thefeature);
                //ShowFeaturePopup(map, thefeature);
                SiteMarkRelationShip(map, thefeature);
            }
        }
    }
    GetSitesRequest = null;
    HideBussyLoader();
}

function GetNonEditableGeoJSONSitesComplete(map, results) {
    map = GetMapReference(map);
    var siteLayer = getLayerByName(map, 'theSiteLayer');
    var precisionLayer = getLayerByName(map, 'thePrecisionLayer');
    var privateLayer = getLayerByName(map, 'thePrivateSiteLayer');
    //var privatePrecisionLayer = getLayerByName(map, 'thePrivateSitePrecisionLayer');

    if ((siteLayer.getSource().getFeatures() != null) && (siteLayer.getSource().getFeatures() != 'undefined')) {
        if (!isEmpty(siteLayer.getSource().getFeatures())) {
            siteLayer.getSource().clear();
        }
    }
    if ((precisionLayer.getSource().getFeatures() != null) && (precisionLayer.getSource().getFeatures() != 'undefined')) {
        if (!isEmpty(precisionLayer.getSource().getFeatures())) {
            precisionLayer.getSource().clear();
        }
    }
    if ((privateLayer.getSource().getFeatures() != null) && (privateLayer.getSource().getFeatures() != 'undefined')) {
        if (!isEmpty(privateLayer.getSource().getFeatures())) {
            privateLayer.getSource().clear();
        }
    }
    /*if ((privatePrecisionLayer.getSource().getFeatures() != null) && (privatePrecisionLayer.getSource().getFeatures() != 'undefined')) {
        if (!isEmpty(privatePrecisionLayer.getSource().getFeatures())) {
            privatePrecisionLayer.getSource().clear();
        }
    }*/


    if ((results != null) && (results != "nothing" && results != '')) {
        AddFeaturesToMap(map, results, siteLayer);
    }

    map.lastSitesZoomLevel = map.getView().getZoom();
    map.lastSitesExtent = getExtent(map);

    if (results != null && map.featureToSelectId != null) {
        var thefeature = siteLayer.getSource().getFeatureById(map.featureToSelectId);
        if (thefeature != null) {
            map.skipSelectEvent = true;
            //map.selectControl.activate();
            //map.selectControl.select(thefeature);
            //ShowFeaturePopup(map, thefeature);
            SelectFeature(map, thefeature);
            map.featureToSelectId = null;
        }
    }

    GetNonEditableSitesRequest = null;
    if (!map.mapOption.SelectByPolygon) { GetEditableGeoJSONSites(map, false); }
    HideBussyLoader();
}

// Destroy all features in the private site layer and private site precision layer
function DestroyPrivateSites(map) {
    // destroy the private features
    DestroySites(getLayerByName(map, 'thePrivateSiteLayer'));

    // destroy private site precision features
    //DestroySites(getLayerByName(map, 'thePrivateSitePrecisionLayer'));
}

// Destroy all features in specified layer
function DestroyClusterSites(layer) {
    if ((layer.getSource().getFeatures() != null) && (layer.getSource().getFeatures() != 'undefined')) {
        if (!isEmpty(layer.getSource().getFeatures())) {
            layer.getSource().clear();
        }
    }
}

function DestroySites(layer) {
    if ((layer.getSource().getFeatures() != null) && (layer.getSource().getFeatures() != 'undefined')) {
        if (!isEmpty(layer.getSource().getFeatures())) {
            layer.getSource().clear();
        }
    }
}

/*function setClusterDistance(map, layer) {
    if (map.showCluster) {
        if (map.getView().getZoom() > 16) {
            layer.getSource().setDistance(5);
        } else {
            layer.getSource().setDistance(20);
        }
    } else {
        layer.getSource().setDistance(0);
    }
}*/

function GetEditableGeoJSONSitesComplete(map, results, clearMap) {
    map = GetMapReference(map);

    var siteLayer = getLayerByName(map, 'theSiteLayer');

    var editableLayer = getLayerByName(map, 'theEditableSiteLayer');
    var precisionLayer = getLayerByName(map, 'thePrecisionLayer');
    var privateLayer = getLayerByName(map, 'thePrivateSiteLayer');
    //var privatePrecisionLayer = getLayerByName(map, 'thePrivateSitePrecisionLayer');
    var hooverLayer = getLayerByName(map, 'theHooverLayer');
    var connectionLayer = getLayerByName(map, 'theSiteConnectionLayer');


    if ((siteLayer.getSource().getFeatures() != null) && (siteLayer.getSource().getFeatures() != 'undefined') && clearMap) {
        if (!isEmpty(siteLayer.getSource().getFeatures())) {
            siteLayer.getSource().clear();
            /*hooverLayer.getSource().clear();
            UnselectFeatures(map);
            highlight = null;*/

        }
    }

    if ((editableLayer.getSource().getFeatures() != null) && (editableLayer.getSource().getFeatures() != 'undefined') && clearMap) {
        if (!isEmpty(editableLayer.getSource().getFeatures())) {
            editableLayer.getSource().clear();
            /*hooverLayer.getSource().clear();
            UnselectFeatures(map);
            highlight = null;*/

        }
    }

    if ((precisionLayer.getSource().getFeatures() != null) && (precisionLayer.getSource().getFeatures() != 'undefined') && clearMap) {
        if (!isEmpty(precisionLayer.getSource().getFeatures())) {
            precisionLayer.getSource().clear();
        }
    }
    if ((privateLayer.getSource().getFeatures() != null) && (privateLayer.getSource().getFeatures() != 'undefined') && clearMap) {
        if (!isEmpty(privateLayer.getSource().getFeatures())) {
            privateLayer.getSource().clear();
            /*hooverLayer.getSource().clear();
            UnselectFeatures(map);
            highlight = null;*/
        }
    }
    if ((connectionLayer.getSource().getFeatures() != null) && (connectionLayer.getSource().getFeatures() != 'undefined')) {
        if (!isEmpty(connectionLayer.getSource().getFeatures())) {
            connectionLayer.getSource().clear();
        }
    }






    /*if ((privatePrecisionLayer.getSource().getFeatures() != null) && (privatePrecisionLayer.getSource().getFeatures() != 'undefined')) {
        if (!isEmpty(privatePrecisionLayer.getSource().getFeatures())) {
            privatePrecisionLayer.getSource().clear();
        }
    }*/

    //setClusterDistance(map, editableLayer);

    if ((results != null) && (results != "nothing" && results != '')) {
        AddFeaturesToMap(map, results, editableLayer);
        //ZoomToExtent(map, editableLayer);
    }
    if (map.temporarySite != null)
        AddFeaturesToMapAndSelect(map, map.temporarySite);
    // AddFeaturesToMap(map, map.temporarySite, editableLayer);

    map.lastSitesZoomLevel = map.getView().getZoom();
    map.lastSitesExtent = getExtent(map);

    if (results != null && map.featureToSelectId != null) {
        var thefeature = editableLayer.getSource().getFeatureById(map.featureToSelectId);

        if (thefeature != null) {
            map.skipSelectEvent = true;
            //ShowFeaturePopup(map, thefeature);
            SelectFeature(map, thefeature);
            map.featureToSelectId = null;
            SiteMarkRelationShip(map, thefeature);
        }
    }

    GetEditableSitesRequest = null;
    if (map.mapOption.ShowPrivateBirdSites) {
        GetPrivateBirdSitesWithinRadiusGeoJsonSites(map, map.selectedSite);
    } else {
        HideBussyLoader();
    }
}

function TryToAddSiteToMap(map, e) {
    var feature;
    var centroid;
    var wktexp;
    if (map.mapOption.SelectByPolygon) {
        // simply say - new site - remove previous
        var editableLayer = getLayerByName(map, 'theEditableSiteLayer');
        feature = editableLayer.getSource().getFeatureById(-1)
        if (feature) {
            editableLayer.getSource().removeFeature(feature);
        }
        //previous removed - now add
        feature = e.feature;
        feature.setId(-1);
        feature.setProperties({ accuracy: "0", siteType: "37", siteName: "Select" });
        centroid = getCentroid(feature);
        wktexp = new ol.format.WKT();
        var geometry = wktexp.writeGeometry(feature.getGeometry());
        editableLayer.getSource().addFeature(feature, { silent: true });
        if (map.mapSiteCreatedHandler != null) {
            map.mapSiteCreatedHandler(map, feature, -1, centroid, geometry);
        }

        return;
    }

    if (map.mapSiteCreatedHandler != null) {
        feature = e.feature;
        feature.setId(-1);
        centroid = getCentroid(feature);
        wktexp = new ol.format.WKT();
        var geom = wktexp.writeGeometry(feature.getGeometry());
        map.mapSiteCreatedHandler(map, feature, -1, centroid, geom);
        return;
    }
    NewSiteAdded(map, e);
}

function getCentroid(feature) {
    if (feature) {
        var centroid = [];
        var isPoint = true;
        if (feature.coordinate == null) {
            if (feature[0]) {
                if (feature[0].getGeometry().getType() === 'Polygon') {
                    isPoint = false;
                }
            } else {
                if (feature.getGeometry().getType() === 'Polygon') {
                    isPoint = false;
                }
            }
        } else {
            if (feature.coordinate.length > 2) {
                isPoint = false;
            }
        }
        if (isPoint) {
            if (feature.coordinate == null) {
                if (feature[0]) {
                    centroid = feature[0].getGeometry().getCoordinates();
                } else {
                    centroid = feature.getGeometry().getCoordinates();
                }
            } else {
                centroid = feature.coordinate;
            }
        } else {
            var coordinates = [];
            var feat;
            if (feature.coordinate == null) {
                if (feature[0]) {
                    feat = feature[0];
                } else {
                    feat = feature;
                }
            } else {
                feat = feature;
            }

            for (var i = 0; i < feat.getGeometry().getCoordinates()[0].length; i++) {
                coordinates.push([
                    feat.getGeometry().getCoordinates()[0][i][0], feat.getGeometry().getCoordinates()[0][i][1]
                ]);
            }
            var pol = new ol.geom.Polygon([coordinates]);
            centroid = pol.getInteriorPoint().getCoordinates();
        }
        return centroid;
    } else {
        return null;
    }
}

function NewSiteAdded(map, e) {
    map = GetMapReference(map);
    var wktexp = new ol.format.WKT();
    var feature = e.feature;
    var centroid = getCentroid(feature);
    var geometry = wktexp.writeGeometry(feature.getGeometry());
    if (map.mapSiteCreatedHandler != null) {
        map.mapSiteCreatedHandler(map, feature, centroid, geometry);
    }
    else {
        $.ajax(
            {
                type: "POST",
                url: window.Artportalen_ApplicationPath + "/Map/SaveSite",
                data: "Id=" + id + "&Name=" + "Test" + "&XCoord=" + Math.round(centroid[0]) + "&YCoord=" + Math.round(centroid[1]) + "&Geometry=" + geometry + "&comment=test",
                success: function (data) { onSiteAddedSuccess(map, data); },
                error: function (req, status, error) {
                    WriteDebugMessage("ERROR: /Map/SaveSite not found or not responding...");
                }
            }
        );
    }
}

function SiteMoved(map, feature) {
    map = GetMapReference(map);
    var centroid;
    var wktexp;
    var geometry;
    /*if (map.mapOption.SelectByPolygon) {
        centroid = feature.geometry.getCentroid();
        wktexp = new OpenLayers.Format.WKT();
        geometry = wktexp.write(feature);
        if (map.mapSiteCreatedHandler != null) {
            map.mapSiteCreatedHandler(map, feature, -1, centroid, geometry);
        }

        return;
    }*/
    if (!CornfirmSiteEdit()) {
        refreshLayers(map, null);
        return;
    }
    wktexp = new ol.format.WKT();
    var id = feature.getId();
    if (!id && feature.getProperties().features[0]) {
        id = feature.getProperties().features[0].getId();
    }
    centroid = getCentroid(feature);
    geometry = wktexp.writeGeometry(feature.getGeometry());
    var precisionLayer = getLayerByName(map, 'thePrecisionLayer');
    var precisionFeature = precisionLayer.getSource().getFeatureById(id);
    var editableLayer = getLayerByName(map, 'theEditableSiteLayer');
    //var editableFeature = editableLayer.getSource().getSource().getFeatureById(id);

    var siteLayer = getLayerByName(map, 'theSiteLayer');
    //var siteFeature = siteLayer.getSource().getFeatureById(id);

    if ((id > 0 && feature.getProperties().siteType != 39) || feature.getProperties().siteType == 40) {
        if (id < 0 && feature.getProperties().siteType == 40) {
            id = id * -1;
        }
        window.Artportalen.ajaxPost(window.Artportalen_ApplicationPath + "/Map/MoveSite", { siteId: id, coordX: Math.round(centroid[0]), coordY: Math.round(centroid[1]), geometry: geometry }, function (data) {
            if (data.success == false) {
                window.Artportalen.AjaxNotificationMessage($('#Site_NotificationMessage_EditSite_Failure').text(), true, "success");

                var featureInLayer = editableLayer.getSource().getFeatureById(feature.getId());
                if (featureInLayer) {
                    editableLayer.getSource().removeFeature(feature);
                }
                feature.geometry = oldGeometry.clone();
                oldGeometry = null;
                editableLayer.getSource().addFeatures([feature], { silent: true });
                window.Artportalen.AjaxNotificationMessage(data.message, true, 'error');
                return;
            }
            var dataFeatures;
            if (data.points.features.length != 0) {
                dataFeatures = data.points.features;
            } else {
                dataFeatures = data.polygons.features;
            }
            $('#' + map.divId).triggerHandler('onMapSiteChanged', [dataFeatures]);

            window.Artportalen.AjaxNotificationMessage($('#Site_NotificationMessage_EditSite_Success').text(), true, "success");
            if (precisionFeature) {
                precisionLayer.getSource().removeFeature(precisionFeature);
            }
            //if (editableFeature) {
            //    editableLayer.getSource().getSource().removeFeature(editableFeature);
            //}
            ClearHooverLayer(map);
            ClearSelectLayer(map);

            onSiteMovedSuccess(map, data, id);
        });

    }
}

function SiteEdited(map, feature) {
    map = GetMapReference(map);
    var centroid;
    var wktexp;
    var geometry;
    /*if (map.mapOption.SelectByPolygon) {
        var feature = e.feature;
        feature.fid = -1;
        centroid = feature.geometry.getCentroid();
        wktexp = new OpenLayers.Format.WKT();
        geometry = wktexp.write(feature);
        if (map.mapSiteCreatedHandler != null) {
            map.mapSiteCreatedHandler(map, feature, -1, centroid, geometry);
        }

        return;
    }*/

    if (!CornfirmSiteEdit()) {
        refreshLayers(map, null);
        return;
    }
    wktexp = new ol.format.WKT();

    var id = feature.getId();
    centroid = getCentroid(feature);
    geometry = wktexp.writeGeometry(feature.getGeometry());
    if (id > 0) {
        window.Artportalen.ajaxPost(window.Artportalen_ApplicationPath + "/Map/MoveSite", { siteId: id, coordX: Math.round(centroid[0]), coordY: Math.round(centroid[1]), geometry: geometry }, function (data) {
            if (data.success == false) {
                window.Artportalen.AjaxNotificationMessage($('#Site_NotificationMessage_EditSite_Failure').text(), true, "success");
                var layer = getLayerByName(map, 'theEditableSiteLayer');
                //layer.getSource().removeFeature(feature);
                var featureInLayer = layer.getSource().getFeatureById(feature.getId());
                if (featureInLayer) {
                    layer.getSource().removeFeature(feature);
                }
                //feature.geometry = oldGeometry.clone();
                //oldGeometry = null;
                layer.getSource().addFeature(feature, { silent: true });
                window.Artportalen.AjaxNotificationMessage(data.message, true, 'error');
                return;
            }
            window.Artportalen.AjaxNotificationMessage($('#Site_NotificationMessage_EditSite_Success').text(), true, "success");
            $('#' + map.divId).triggerHandler('onMapSiteChanged', [feature]);
            onSiteMovedSuccess(map, data, id);
        });
    }
}

function onSiteAddedSuccess(map, result) {
    map = GetMapReference(map);
    if (!result.success) {
        window.Artportalen.AjaxNotificationMessage(result.message, true, 'error');
    } else {
        window.Artportalen.AjaxNotificationMessage($('#Site_NotificationMessage_NewSite_Success').text(), true, "success");
        if (result.points) {
            AddFeaturesToMapAndSelect(map, result);
            if (typeof window.rebindUserSitesGrid == 'function') {
                window.rebindUserSitesGrid();
            }

        } else {
            WriteDebugMessage('ERROR' + result);
        }
    }
    refreshLayers(map, null);
}

function onSiteMovedSuccess(map, result, id) {
    map = GetMapReference(map);
    if (result.points) {
        var myObject = eval(result);
        /*var precisionfeatures = new ol.format.GeoJSON().readFeatures(myObject.points);
        for (i in precisionfeatures) {
            if (precisionfeatures[i].getProperties().accuracy > 0) {
                var lay = getLayerByName(map, 'thePrecisionLayer');
                lay.getSource().getSource().addFeatures([precisionfeatures[i]]);
            }
        }*/
        refreshLayers(map, id);

        var layer = getLayerByName(map, 'theEditableSiteLayer');

        var feature = layer.getSource().getFeatureById(id);

        if (feature) {
            $('#' + map.div).triggerHandler('onMapSiteSelected', [feature]);
        }

        if (typeof window.rebindUserSitesGrid == 'function') {
            window.rebindUserSitesGrid();
        }

    } else {
        WriteDebugMessage('ERROR' + result);
    }
}

function WriteDebugMessage(message) {
    $("#infoTextDiv").append(message + '<br />');
}

function SiteMarkRelationShip(map, feature) {

    if (feature) {
        var child = true;
        //var precisionLayer = getLayerByName(map, 'thePrecisionLayer');
        //var precisionFeatures = precisionLayer.getSource().getFeatures();

        /*for (var i = precisionFeatures.length; i >= 1; i = i - 1) {
            if (precisionFeatures[i - 1].getGeometry().getType() == 'LINE') {
                precisionLayer.removeFeature([precisionFeatures[i - 1]]);
            }
        }*/
        var feat;
        if (feature.length > 0) {
            feat = feature[0];
        } else if (feature.getProperties() && feature.getProperties().features) {
            feat = feature.getProperties().features[0];
        } else {
            feat = feature;
        }


        /*if (feature.getProperties() && feature.getProperties().features) {
            feat = feature.getProperties().features[0];
        } else {
            feat = feature;
        }*/
        if (feat.getGeometry().getType() != 'LineString') {

            if (feat.getProperties().siteType == 2) {
                child = false;
            }
            if (feat.getProperties().siteType == 3) {
                child = false;
            }
            var pStart = [feat.getGeometry().getCoordinates()[0], feat.getGeometry().getCoordinates()[1]];
            var pEnd;
            var connectionLayer = getLayerByName(map, 'theSiteConnectionLayer');
            connectionLayer.getSource().clear();
            var style = new ol.style.Style({
                fill: new ol.style.Fill({ color: 'rgba(0, 0, 0, 1)' }),
                stroke: new ol.style.Stroke({
                    color: '#000000',
                    width: 1
                })
            });
            var siteLayer = getLayerByName(map, 'theSiteLayer');
            var lineFeature;
            for (i in siteLayer.getSource().getFeatures()) {
                if ((child == true &&
                        siteLayer.getSource().getFeatures()[i].getId() == feat.getProperties().parentId) ||
                    (child == false &&
                        siteLayer.getSource().getFeatures()[i].getProperties().parentId == feat.getId())) {
                    pEnd = [
                        siteLayer.getSource().getFeatures()[i].getGeometry().getCoordinates()[0],
                        siteLayer.getSource().getFeatures()[i].getGeometry().getCoordinates()[1]
                    ];
                    lineFeature = new ol.Feature({
                        geometry: new ol.geom.LineString([pEnd, pStart])
                    });
                    lineFeature.setStyle(style);
                    connectionLayer.getSource().addFeature(lineFeature);
                }
            }
            var editableLayer = getLayerByName(map, 'theEditableSiteLayer');
            for (i in editableLayer.getSource().getFeatures()) {
                if ((child == true &&
                        editableLayer.getSource().getFeatures()[i].getId() ==
                        feat.getProperties().parentId) ||
                    (child == false &&
                        editableLayer.getSource().getFeatures()[i].getProperties().parentId == feat.getId())) {
                    pEnd = [
                        editableLayer.getSource().getFeatures()[i].getGeometry().getCoordinates()[0],
                        editableLayer.getSource().getFeatures()[i].getGeometry().getCoordinates()[1]
                    ];
                    lineFeature = new ol.Feature({
                        geometry: new ol.geom.LineString([pEnd, pStart])
                    });
                    lineFeature.setStyle(style);
                    connectionLayer.getSource().addFeature(lineFeature);
                }
            }
            var privateSiteLayer = getLayerByName(map, 'thePrivateSiteLayer');
            for (i in privateSiteLayer.getSource().getFeatures()) {
                if ((child == true &&
                        privateSiteLayer.getSource().getFeatures()[i].getId() ==
                        feat.getProperties().parentId) ||
                    (child == false &&
                        privateSiteLayer.getSource().getFeatures()[i].getProperties().parentId == feat.getId())) {
                    pEnd = [
                        privateSiteLayer.getSource().getFeatures()[i].getGeometry().getCoordinates()[0],
                        privateSiteLayer.getSource().getFeatures()[i].getGeometry().getCoordinates()[1]
                    ];
                    lineFeature = new ol.Feature({
                        geometry: new ol.geom.LineString([pEnd, pStart])
                    });
                    lineFeature.setStyle(style);
                    connectionLayer.getSource().addFeature(lineFeature);
                }
            }
            //var privateSitePresisionLayer = getLayerByName(map, 'thePrivateSitePrecisionLayer');
            /*for (i in privateSiteLayer.getSource().getFeatures()) {
                if (((child == true && privateSiteLayer.getSource().getFeatures()[i].getId()) ==
                        privateSiteLayer.getSource().getFeatures()[i].getProperties().parentId) ||
                    (child == false &&
                        privateSiteLayer.getSource().getFeatures()[i].getProperties().parentId == feat.getId())) {
                    pEnd = new ol.geom.Point(privateSiteLayer.getSource().getFeatures()[i].getGeometry()
                        .getCoordinates()[0],
                        privateSiteLayer.getSource().getFeatures()[i].getGeometry().getCoordinates()[1]);
                    /*privateSitePresisionLayer.addFeatures(
                        new ol.feature.Vector(new ol.geom.LineString([pStart.clone(), pEnd.clone()])));*/
            /*    }
            }*/
        }
    }
}

function SendExtentToSession(map) {
    map = GetMapReference(map);
    //$.post(window.Artportalen_ApplicationPath + "/HttpSession/SetMapExtent?bbox=" + map.getExtent().toBBOX());
    var bBoxArr = map.getView().calculateExtent(map.getSize());
    var coordDiff = 10000;
    if (Math.abs(bBoxArr[0] - bBoxArr[2]) > coordDiff &&
        Math.abs(bBoxArr[1] - bBoxArr[3]) > coordDiff) {

        var bboxStr = bBoxArr[0] + "," + bBoxArr[1] + "," + bBoxArr[2] + "," + bBoxArr[3];

        $.post(window.Artportalen_ApplicationPath + "/HttpSession/SetMapExtent?bbox=" + bboxStr);
    }
}

function GetMapExtent(map) {
    map = GetMapReference(map);
    return map.getProjection() + ';' + getExtent(map);
}

function SetMapExtent(map, value) {
    map = GetMapReference(map);
    var element = value.split(';');
    var extent = element[1].split(',');

    map.getView().fit([Number(extent[0]), Number(extent[1]), Number(extent[2]), Number(extent[3])]);
    return true;
}

// This method sets the extent to the closest zoomlevel.
// It may not show all the extent. We use this for saved map extents because we want to show it with
// same zoom level as the extent was saved with.
function SetMapExtentToClosestLevel(map, value) {
    map = GetMapReference(map);
    var element = value.split(';');
    var extent = element[1].split(',');
    map.getView().fit([Number(extent[0]), Number(extent[1]), Number(extent[2]), Number(extent[3])]);
    return true;
}

function SetMapExtentByCoords(map, xcoord, ycoord) {
    map = GetMapReference(map);
    var xoffset = 5000;
    var minX = parseInt(xcoord) - xoffset;
    var maxX = parseInt(xcoord) + xoffset;
    var yoffset = 6000;
    var minY = parseInt(ycoord) - yoffset;
    var maxY = parseInt(ycoord) + yoffset;
    SetMapExtent(map, 'dummy;' + minX + ',' + minY + ',' + maxX + ',' + maxY);
}

function zoomToSiteById(map, id, select) {
    map = GetMapReference(map);
    map.featureToSelectId = id;
    map.selectedSite = id;

    var layer = getLayerByName(map, 'theSiteLayer');

    var feature = layer.getSource().getFeatureById(id);
    /*if (!feature) {
        feature = layer.getSource().getSource().getFeatureById(id);
    }*/

    if (!feature) {
        layer = getLayerByName(map, 'theEditableSiteLayer');
        feature = layer.getSource().getFeatureById(id);
    }
    if (feature) {
        //var centroid = feature.geometry.getCentroid();
        var centroid = getCentroid(feature);
        if (map.getView().getZoom() < 15) {
            map.getView().setZoom(15);
        }
        map.getView().setCenter([centroid[0], centroid[1]]);

        if (select) {
            // deselect all selected
            //map.selectControl.unselectAll();
            UnselectFeatures(map);
            map.skipSelectEvent = true;
            SelectFeature(map, feature);
            //map.selectControl.select(feature);
            // Fix by JSZ
            // SiteMarkRelationShip krashade då objektet e med proprtyn feature skickades in istället för en feature som function förväntade sig
            //ShowFeaturePopup(map, feature);
            SiteMarkRelationShip(map, feature);
        }
    }
}

function selectById(map, id, select) {
    map = GetMapReference(map);
    map.featureToSelectId = id;
    map.selectedSite = id;
    var layer = getLayerByName(map, 'theSiteLayer');
    var feature = layer.getSource().getFeatureById(id);

    if (!feature) {
        layer = getLayerByName(map, 'theEditableSiteLayer');
        feature = layer.getSource().getFeatureById(id);

    }
    if (select) {
        // deselect all selected
        //map.selectControl.unselectAll();
        UnselectFeatures(map);
        map.skipSelectEvent = true;
        //map.selectControl.select(feature);
        SelectFeature(map, feature);
        // Fix by JSZ
        // SiteMarkRelationShip krashade då objektet e med proprtyn feature skickades in istället för en feature som function förväntade sig
        SiteMarkRelationShip(map, feature);

        if (feature) {
            $('#' + map.divId).triggerHandler('onMapSiteSelected', [feature]);
        }
    }
}


function refreshLayers(map, selectedId) {

    map = GetMapReference(map);
    if (map.mapPopup) {
        map.removePopup(map.mapPopup);
        map.mapPopup = null;
    }
    if (selectedId != null) {
        map.featureToSelectId = selectedId;
    }
    if (map.mapOption.GetSitesGeoJsonUrl) {
        GetAllGeoJSONSitesForSpeciesGroup(map, null);
    } else if (map.mapOption.ShowEditableSitesOnly) {
        GetEditableGeoJSONSites(map, true);
    } else if (map.mapOption.ShowAllPrivateAndPublicSites) {
        GetPrivateAndPublicGeoJSONSites(map);
    } else {
        GetNonEditableGeoJSONSites(map);
    }
}

function zoomToSiteByIdOrCoordinate(map, id, xcoord, ycoord, speciesGroupId) {
    map = GetMapReference(map);
    if (speciesGroupId) {
        map.speciesGroupId = speciesGroupId;
    }
    if (map.getView().getZoom() < 15) {
        map.getView().setZoom(15);
    }
    map.selectedSite = id;
    var layer = getLayerByName(map, 'theSiteLayer');
    var feature = layer.getSource().getFeatureById(id);

    if (feature != null) {
        zoomToSiteById(map, id, true);
    } else {
        map.featureToSelectId = id;
        map.getView().setCenter([xcoord, ycoord]);

    }
}

function zoomToSiteByCoordinate(map, xcoord, ycoord, zoomlevel) {
    map = GetMapReference(map);
    if (zoomlevel) {
        map.getView().setZoom(zoomlevel);
    }
    map.getView().setCenter([xcoord, ycoord]);
}


function CreateMap(x, y, diffusion,baseap2url) {
    var coordinates = [x, y];
    var point = new ol.Feature();
    point.setGeometry(new ol.geom.Point(ol.proj.fromLonLat(coordinates)));
    var vectorLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
            features: [point]
        })
    });
    let options = ol.source.WMTS.optionsFromCapabilities(new ol.format.WMTSCapabilities().read($.ajax({ url: baseap2url + '/LantmaterietCache/LantmaterietWmsProxyCapabilities?request=getcapabilities&service=wmts', async: false }).responseText), { layer: 'topowebb', matrixSet: '3857' });
    options.attributions = [new ol.Attribution({html: "© <a href=''https://www.lantmateriet.se/''>Lantmäteriet</a>"})]
    var simpleMap = new ol.Map({
        target: 'simpleMap',
        layers: [
            new ol.layer.Tile({ title: 'Sverige', type: 'base', source: new ol.source.WMTS(options) }),
            vectorLayer
        ],
        view: new ol.View({
            center: ol.proj.fromLonLat(coordinates),
            zoom: 12
        }),
    });

    var siteColor = 'rgba(0, 255, 0, 0.3)';
    var style = new ol.style.Style({
        image: new ol.style.Circle({
            stroke: new ol.style.Stroke({
                color: 'rgba(0, 0, 0, 1)',
                width: 1.25
            }),
            fill: new ol.style.Fill({
                color: siteColor
            }),
            radius: 7
        }),
    });

    if (diffusion > 0) {
        var radius = GetAccuracyRadius(diffusion, simpleMap.getView().getResolution());
        var fillColor = 'rgba(' + Artportalen.DiffusionColor + ',' + Artportalen.DiffusionOpacity + ')';
        style = new ol.style.Style({
            image: new ol.style.RegularShape({
                points: 4,
                radius: radius,
                stroke: new ol.style.Stroke({
                    color: 'rgba(0, 0, 0, 1)',
                    width: 1.25
                }),
                fill: new ol.style.Fill({ color: fillColor }),
                fillOpacity: Artportalen.DiffusionOpacity,
                angle: Math.PI / 4
            })
        });
    }
    point.setStyle(style);
    point.setId(1);
}

function CreateSimpleMap(x, y, diffusion, file, baseap2url) {
    $.getScript(file,
        function () {
            CreateMap(x, y, diffusion, baseap2url);
        });

}

function GetUndiffusedSiteId(siteId) {
    if (siteId < -10000) {
        siteId *= -1;
    }
    return siteId;
}

function GetMapReference(map) {
    if (typeof (map) != 'object') {
        return $("#" + map).get(0);
    } else {
        return map;
    }
}

function SetPresentationMenu(project, taxon) {
    if (taxon != 0) {
        Artportalen.ajaxPost(Artportalen_ApplicationPath + '/ViewSighting/GetProjectAndTaxonCategoryId',
            { projectId: project, taxonId: taxon },
            function(data, code, xht) {
                if (data.speciesGroupId == 1 &&
                    data.projectCategoryId === 4 &&
                    (data.taxonCategoryId === 17 || data.taxonCategoryId === 18 || data.taxonCategoryId === 19 ||
                        data.taxonCategoryId === 20 || data.taxonCategoryId === 21)) {
                    $("#rightSubMenuLu #floraMenu").show();
                    $("#rightSubMenuLu #floraMenuByYear").show();
                } else {
                    $("#rightSubMenuLu #floraMenu").hide();
                    $("#rightSubMenuLu #floraMenuByYear").hide();
                }
                if (data.taxonCategoryId === 17 || data.taxonCategoryId === 18 || data.taxonCategoryId === 19 || data.taxonCategoryId === 20 ||
                    data.taxonCategoryId === 21 || data.taxonCategoryId === 32) {
                    $("#rightSubMenuLu #diffusionMenu").css({ opacity: 1, 'pointer-events': 'auto' })
                        .removeProp('disabled').prop("title", "");                    
                } else {
                    $("#rightSubMenuLu #diffusionMenu").css({ opacity: 0.5, 'pointer-events': 'none' })
                        .prop('disabled', 'disabled');                    
                    $("#diffusionMenuTitle").prop('title', window.Artportalen.ResourceLabel("Shared_Navigation_MapDiffusionGrid_NotActive"));
                }
            });
    } else {
        $("#rightSubMenuLu #floraMenu").hide();
        $("#rightSubMenuLu #floraMenuByYear").hide();
        $("#rightSubMenuLu #diffusionMenu").css({ opacity: 0.5, 'pointer-events': 'none' })
            .prop('disabled', 'disabled');
    }
}

var onAtlasCellSelect = function (feature, map) {
    $(document).trigger("atlassquareselected", { name: feature.getProperties().name, value: feature.getProperties().value });
    map.getView().fit(feature.getGeometry().getExtent(), { padding: [180, 450, 180, 180] });
};

var $Artportalen_WireCoordinateSystemControl = function (fieldid, csg) {
    /// <summary>
    ///     Wire the group and zone selectors to the hidden coordinatesystem control
    /// </summary>
    ///	<param name="fieldid" type="String">
    ///		The id of the hidden coordinatesystem control (wich are used for persistence and syncronization with other ui)
    ///	</param>
    ///	<param name="csg" type="JSON object">
    ///		JSON data for client side functionality
    ///     Normaly generated by SubmitSightingController.GetCoordinateSystemsAndGroups
    ///	</param>
    /// <returns>
    ///     Returns a service object to serve related controls (mgrs, coordinate input e.g.)
    /// </returns>
    csg = csg || { "coordinatesystems": {}, "groups": {} };
    fieldid = fieldid || 'coordsys';

    var fields;
    var that = {};

    var getcoordfieldids = function (fieldidn) {
        return {
            'group': '#' + fieldidn + '_csgroup',
            'zone': '#' + fieldidn + '_cszone',
            'coordinatesystem': '#' + fieldidn,
            'notation': '#' + fieldidn + '_csnotation',
            'selectednotation': '#' + fieldidn + '_selectedNotation'
        };
    };
    var getCoordSysId = function () {
        return $(fields.coordinatesystem).val();
    };
    var updateInput = function () {
        var csid = getCoordSysId();
        var cs;
        if (csg.coordinatesystems) {
            cs = csg.coordinatesystems[csid];
        }
        if (cs === undefined) {
            //alert('No coordinate system with id: "' + csid + '"');
            return;
        }
        var groupid = cs.groupid;
        var group = csg.groups[groupid];
        if (groupid !== $(fields.group).val()) {
            $(fields.group).val(groupid);
        }
        var id = group.notations[0].Id;
        $(fields.selectednotation).val(id);
        $(fields.zone).toggle(group.haszones);
        $(fields.zone).html("");
        var options = "";
        for (var zi in group.zones) {
            if (group.zones.hasOwnProperty(zi)) {
                var zn = group.zones[zi];
                options += '<option value="' + zn.csid + '"';
                if (csid === zn.csid) {
                    options += ' selected="selected"';
                }
                options += '>' + zn.name + '</option>';
            }
        }
        $(fields.zone).html(options);
        var notationid = $(fields.notation).val();
        if (notationid == 3) {
            $(fields.zone).toggle(false);
        }
        else {
            $(fields.zone).toggle(true);
        }
        if (!group.haszones) {
            $(fields.zone).toggle(false);
        }
        $(fields.notation).html("");
        options = "";
        var selectednotation = $(fields.selectednotation).val();
        var notationCount = 0;
        for (var not in group.notations) {

            var item = group.notations[not];
            options += '<option value="' + item.Id + '"';
            if (item.Id === selectednotation) {
                options += ' selected="selected"';
            }
            options += '>' + item.name + '</option>';
            notationCount++;
        }
        $(fields.notation).html(options);
        $(fields.notation).toggle(notationCount > 1);
        $(fields.notation).trigger('change');
    };

    var selectGroup = function () {
        var groupid = $(fields.group).val();
        if (groupid === undefined || groupid === "-1" || groupid == null) {
            return undefined;
        }
        var group = csg.groups[groupid];
        var csid;
        if (group.haszones) {
            csid = group.zones[0].csid;
        } else {
            csid = group.csid;
        }
        $(fields.coordinatesystem).val(csid);
        $(fields.coordinatesystem).trigger('change');

        updateInput(fieldid);
    };

    var selectZone = function () {
        $(fields.coordinatesystem).val($(fields.zone).val());
        $(fields.coordinatesystem).trigger('change');
    };
    var setCoordSysId = function (coordsysid, coordnotationid) {
        if ($(fields.coordinatesystem).val() != coordsysid) {
            $(fields.coordinatesystem).val(coordsysid);
            $(fields.coordinatesystem).trigger('change');
        }
        if ($(fields.selectednotation).val() != coordnotationid) {
            $(fields.selectednotation).val(coordnotationid);
            $(fields.notation).val(coordnotationid);
            $(fields.notation).trigger('change');
        }
    };

    var selectNotation = function () {
        var notationid = $(fields.notation).val();
        if (notationid == 3) {
            $(fields.zone).toggle(false);
        }
        else {
            $(fields.zone).toggle(true);
        }
        var groupid = $(fields.group).val();
        if (groupid === undefined || groupid === "-1" || groupid == null) {
            return undefined;
        }
        var group = csg.groups[groupid];
        if (!group.haszones) {
            $(fields.zone).toggle(false);
        }
        var val = $(fields.notation).val();
        $(fields.selectednotation).val(val);
    };

    var getNorthLabel = function () {
        var notationid = $(fields.notation).val();
        var groupid = $(fields.group).val();
        if (groupid === undefined || groupid === "-1" || groupid == null) {
            return undefined;
        }
        if (notationid == 3)
            return "";
        if (notationid == 4)
            return window.Artportalen.ResourceLabel("Shared_CultureInfo_Coordinate_Latitude") + "<span class=\"field-required\">*</span>:";
        return window.Artportalen.ResourceLabel("Shared_CultureInfo_Coordinate_NorthCoord") + "<span class=\"field-required\">*</span>:";
    };
    var getEastLabel = function () {
        var notationid = $(fields.notation).val();
        var groupid = $(fields.group).val();
        if (groupid === undefined || groupid === "-1" || groupid == null) {
            return undefined;
        }
        if (notationid == 3)
            return window.Artportalen.ResourceLabel("Shared_CultureInfo_Coordinate_Mgrs") + "<span class=\"field-required\">*</span>:";
        if (notationid == 4)
            return window.Artportalen.ResourceLabel("Shared_CultureInfo_Coordinate_Longitude") + "<span class=\"field-required\">*</span>:";
        return window.Artportalen.ResourceLabel("Shared_CultureInfo_Coordinate_EastCoord") + "<span class=\"field-required\">*</span>:";
    };
    var getNorthLabelInstruction = function () {
        var notationid = $(fields.notation).val();
        var groupid = $(fields.group).val();
        if (groupid === undefined || groupid === "-1" || groupid == null) {
            return undefined;
        }
        if (notationid == 3)
            return "";
        if (notationid == 4)
            return window.Artportalen.ResourceLabel("Shared_CultureInfo_Coordinate_Latitude_FieldInstruction");
        return window.Artportalen.ResourceLabel("Shared_CultureInfo_Coordinate_NorthCoord_FieldInstruction");
    };
    var getEastLabelInstruction = function () {
        var notationid = $(fields.notation).val();
        var groupid = $(fields.group).val();
        if (groupid === undefined || groupid === "-1" || groupid == null) {
            return undefined;
        }
        if (notationid == 3)
            return window.Artportalen.ResourceLabel("Shared_CultureInfo_Coordinate_Mgrs_FieldInstruction");
        if (notationid == 4)
            return window.Artportalen.ResourceLabel("Shared_CultureInfo_Coordinate_Longitude_FieldInstruction");
        return window.Artportalen.ResourceLabel("Shared_CultureInfo_Coordinate_EastCoord_FieldInstruction");
    };
    var getCoordSysType = function () {
        var groupid = $(fields.group).val();
        if (groupid === undefined || groupid === "-1" || groupid == null) {
            return undefined;
        }
        var group = csg.groups[groupid];
        return group.coordtype;
    };
    var getCoordNotation = function () {
        return $(fields.selectednotation).val();
    };

    fields = getcoordfieldids(fieldid);

    $(fields.coordinatesystem).change(function () { updateInput(); });
    $(fields.group).change(function () { selectGroup(); });
    $(fields.zone).change(function () { selectZone(); });
    $(fields.notation).change(function () { selectNotation(); });

    that.$group = fields.group;
    that.$zone = fields.zone;
    that.$notation = fields.notation;
    that.$coordinatesystem = fields.coordinatesystem;
    that.setcoordinatesystem = setCoordSysId;
    that.getcoordinatesystem = getCoordSysId;
    that.getcoordinatesystemtype = getCoordSysType;
    that.getnorthlabel = getNorthLabel;
    that.geteastlabel = getEastLabel;
    that.getnorthlabelinstruction = getNorthLabelInstruction;
    that.geteastlabelinstruction = getEastLabelInstruction;
    that.getCoordNotation = getCoordNotation;
    return that;
};
;
/*

-----------------------------------------------------------------------------------------------
DOCUMENTATION popupInfoTooltip()
This widget is used to display information about user, taxon, sites etc. in a tooltip.
Both AJAX-generated content and static content can be displayed.
-----------------------------------------------------------------------------------------------

### To display information in a tooltip, with User as an example
    - use the data attribute; <a href="UserProfile/UserAlias123" data-useralias="UserAlias123">User 123</a> on the element that will display the tooltip
    - init the popupInfoTooltip() by selecting the element with the data attribute and attach the widget; $("a[data-useralias]").popupInfoTooltip();
    - the _showTooltip() method inside popupInfoTooltip() automatically calls different AJAX-methods based on which data-attribute the calling element has
    - in this case, an AJAX function is called inside Artportalen.UI.js to fetch a User by its alias; Artportalen.GetUserInformationByAlias(userAlias);
    - an event named "AP2UserFetched" is binded to the $(document)
    - Artportalen.GetUserInformationByAlias(userAlias) fetch information about the user via AJAX. The tooltip is shown with a loading indicator.
    - when the AJAX call is complete GetUserInformationByAlias() triggers the event "AP2UserFetched" with the HTML result as an agrument; $(document).trigger("AP2UserFetched", [result]);
    - the previously attached event "AP2UserFetched" catches the result, hides the loading indicator and displays the result inside the tooltip.
    - the "AP2UserFetched" event on $(document) gets undbind

*/
(function ($) {
    $.fn.popupInfoTooltip = function (optionsIn) {

        var defaults = {
            tooltip: "",
            width: "281px",
            height: "",
            position: "right", //top, right, bottom, left
            offsetX: "0",
            offsetY: "-11",
            attr: "",
            cssclass: "user-profile",
            loadingmessage: "<span class='ap2-ui-loadingmessage-inline'>" + Artportalen.ResourceLabel("Shared_JavaScript_Loading") + "</span>",
            parentID: "",
            mouseInDelay: 600,
            mouseOutDelay: 600,
            onClick: false,
            onFocus: false,
            mouseIsOverPopup: false
        };

        var options = $.extend({}, defaults, optionsIn);

        // Kill all existing tooltips that is not pinned
        // $("div.tt-popup").not(".pinned").remove();

        var _toolTip = "";
        var toolTipDebounceTimer; // Use this to reduce AJAX-calls, look at "data-userAlias" below 

        function _initTooltip() {
            if ($(document.body).data("popupInfoTooltip")) {
                _toolTip = options.tooltip = $(document.body).data("popupInfoTooltip");
            } else {
                _toolTip = options.tooltip = $(['<div class="tt-wrapper tt-popup clearfix">',
		            '<div class="arrow"></div>',
                    '<div class="arrow-bar"></div>',
		            '<div class="tt-top"></div>',
		            '<div class="tt-content clearfix"></div>',
		            '<div class="tt-bottom"></div>',
                    '<a href="#" class="tt-closebutton"></a>',
                    '<a href="#" class="tt-pinbutton"><span class="UI-Icon-16 UI-Icon-16-Pinned-Off"></span></a>',
		            '</div>'].join("")).appendTo(document.body).hide();

                _toolTip.find(".tt-closebutton").click(function (e) {
                    e.preventDefault();
                    _toolTip.hide();
                });

                _toolTip.find(".tt-pinbutton").click(function (e) {
                    e.preventDefault();
                    _toolTip.clone(false, false).addClass("pinned").appendTo(document.body).draggable({
                        stack: ".tt-popup"
                    }).find(".tt-closebutton, .tt-pinbutton").click(function (e) {
                        e.preventDefault();
                        $(this).closest(".tt-popup").remove();
                    }).end().find(".iconbar a").tipsy({ gravity: 'sw', opacity: 1 });
                    _hideTooltip();
                });

                _toolTip.bind("mouseover", function () {
                    _toolTip.data("mouseIsOverPopup", true);
                }).bind("mouseleave", function (e) {
                    _toolTip.data("mouseIsOverPopup", false);
                    if (!_toolTip.hasClass("pinned")) _hideTooltip();
                });

                $(document.body).data("popupInfoTooltip", _toolTip);
            }
        }

        function _attachTooltip(elem) {
            var box = $(elem);
            box.addClass("has_tooltip");
            if (options.onClick) {
                box.click(function (e) {
                    _showTooltip(e, box);
                });
            } else if (options.onFocus) {
                box.bind("focusin mouseover", function (e) {
                    _showTooltip(e, box);
                });
            } else {
                box.hoverIntent({
                    interval: options.mouseInDelay,
                    timeout: options.mouseOutDelay,
                    over: function (e) { _showTooltip(e, box); },
                    out: function (e) { _mouseleaveTooltip(e, box); }
                });
            }
        };

        function _mouseleaveTooltip(e, box) {
            /*
            console.log(e.relatedTarget);
            console.log(box);
            console.log("_mouseleaveTooltip - $(e.currentTarget).hasClass('tt-wrapper'): " + $(e.currentTarget).hasClass("tt-wrapper"));
            */
            if ($(e.currentTarget).hasClass("tt-wrapper") || $(e.currentTarget).parents(".tt-wrapper").length) {
                var boxParent = $(e.relatedTarget);
                if (boxParent.hasClass("has_tooltip") || boxParent.parents(".has_tooltip").length) {
                    //box.mouseleave(function (e) { $(this).unbind("mouseleave"); _mouseleaveTooltip(e, box); });
                    return;
                    //} else if ($(e.relatedTarget).is(".arrowtooltip") || $(e.relatedTarget).parents(".arrowtooltip").length || $(e.relatedTarget).is(".dropout_share") || $(e.relatedTarget).parents(".dropout_share").length) {
                    //    return;
                } else {
                    _hideTooltip();
                }
            } else {
                var tooltipParent = $(e.relatedTarget).parents(".tt-wrapper");
                if (tooltipParent.length || _toolTip.data("mouseIsOverPopup")) {
                    _toolTip.data("mouseIsOverPopup", true);
                    return false;
                } else {
                    _hideTooltip();
                }
            }
        }

        function _loadTooltipContent(box) {
        }

        function _showTooltip(e, box) {

            if (!$(box).is(":visible")) return false;

            _initTooltip();

            var loadingMessage, contentHtml, tempDelay = 200;
            _toolTip.data("box", box).removeClass("css-enabled");

            if (box.is("[data-taxonid]")) {

                options.position = "right";
                options.offsetX = "0";
                options.offsetY = "-11";

                loadingMessage = "<span class='ap2-ui-loadingmessage-inline'>Loading taxon info...</span>";
                contentHtml = "<h4>Valideringsmeddelanden</h4>" + box.find("span.validation-messages").html();
                _toolTip.find(".tt-content").html(loadingMessage).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

                // Listen for the event when the taxon info is fecthed
                $(document).bind("AP2TaxonFetched", function (event, data) {
                    _toolTip.find(".tt-content").html(data).find(".iconbar a").tipsy({ gravity: 'sw', opacity: 1 });
                    $(document).unbind("AP2TaxonFetched");
                    _positionTooltip(box);
                });

                // Fetch taxon information
                Artportalen.TaxonInfo(box.attr("data-taxonid"));

            } else if (box.is("[data-organisationdetails]")) {

                var organisationData = box.data("organisationdetails");
                var size = { width: organisationData.Image.split("_")[2], height: organisationData.Image.split("_")[3] };
                var imagePath = [Artportalen_ApplicationPath, "Content/Images/Logos", organisationData.Image].join('/');

                var outPut = ["<h3><a href='", box.attr("href"), "' target='_blank'>", box.text(), "</a></h3>",
                    "<table><tr><td class='logo'>", "<a href='", box.attr("href"), "' target='_blank'><img src='", imagePath, "' width='", size.width, "' height='", size.height, "'/></a></td>",
                    "<td><p class='last'>", organisationData.Description, "</p>",
                    "<a href='", box.attr("href"), "' target='_blank' class='link'>", box.attr("href"), "</a></td></tr></table>"
                ];

                options.width = "500px";
                _toolTip.addClass("css-enabled").find(".tt-content").html(outPut.join(''));
                _positionTooltip(box);

            } else if (box.is(".hascollection")) {

                options.position = "right"; options.offsetX = "0"; options.offsetY = "-11";
                loadingMessage = "<span class='ap2-ui-loadingmessage-inline'>Loading...</span>";
                contentHtml = "<h4>Valideringsmeddelanden</h4>" + box.find("span.validation-messages").html();
                _toolTip.find(".tt-content").html(loadingMessage).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

                // Listen for the event when the taxon info is fecthed
                $(document).bind("AP2SightingCollectionSummaryFetched", function (event, data) {
                    _toolTip.find(".tt-content").html(data);
                    $(document).unbind("AP2SightingCollectionSummaryFetched");
                    _positionTooltip(box);
                });

                // Fetch taxon information
                setTimeout(function () {
                    Artportalen.SightingCollectionSummary(box.attr("data-sightingid"));
                }, 500);

            } else if (box.is(".hasecology")) {

                options.position = "right"; options.offsetX = "0"; options.offsetY = "-11";
                _toolTip.find(".tt-content").html(options.loadingmessage).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

                // Listen for the event when the info is fecthed
                $(document).bind("AP2SightingEcologySummaryFetched", function (event, data) {
                    _toolTip.find(".tt-content").html(data);
                    $(document).unbind("AP2SightingEcologySummaryFetched");
                    _positionTooltip(box);
                });

                // Fetch ecology information
                if (isNaN(box.attr("data-sightingid"))) {
                    setTimeout(function () {
                        Artportalen.DiaryEntryEcologySummary(box.attr("data-diaryentryid"));
                    }, 500);
                }
                else {
                    setTimeout(function () {
                        Artportalen.SightingEcologySummary(box.attr("data-sightingid"));
                    }, 500);
                }
            } else if (box.is(".hasbarcode")) {

                options.position = "right"; options.offsetX = "0"; options.offsetY = "-11";
                _toolTip.find(".tt-content").html(options.loadingmessage).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

                // Listen for the event when the info is fecthed
                $(document).bind("AP2SightingBarCodeSummaryFetched", function (event, data) {
                    _toolTip.find(".tt-content").html(data);
                    $(document).unbind("AP2SightingBarCodeSummaryFetched");
                    _positionTooltip(box);
                });

                // Fetch barcode information               
                setTimeout(function () {                        
                    Artportalen.SightingBarCodeSummary(box.attr("data-sightingid"));
                }, 500);               
            } else if (box.is(".hasprojectinfo")) {

                options.position = "right"; options.offsetX = "0"; options.offsetY = "-11";
                _toolTip.find(".tt-content").html(options.loadingmessage).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

                // Listen for the event when the info is fecthed
                $(document).bind("AP2DiaryEntryProjectSummaryFetched", function (event, data) {
                    _toolTip.find(".tt-content").html(data);
                    $(document).unbind("AP2DiaryEntryProjectSummaryFetched");
                    _positionTooltip(box);
                });

                // Fetch project information
                setTimeout(function () {
                    Artportalen.DiaryEntryProjectSummary(box.attr("data-diaryentryid"));
                }, 500);

            } else if (box.is(".hasweatherinfo")) {

                options.position = "right"; options.offsetX = "0"; options.offsetY = "-11";
                _toolTip.find(".tt-content").html(options.loadingmessage).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

                // Listen for the event when the info is fecthed
                $(document).bind("AP2SDiaryEntryWeatherSummaryFetched", function (event, data) {
                    _toolTip.find(".tt-content").html(data);
                    $(document).unbind("AP2SDiaryEntryWeatherSummaryFetched");
                    _positionTooltip(box);
                });

                // Fetch weather information
                setTimeout(function () {
                    Artportalen.DiaryEntryWeatherSummary(box.attr("data-diaryentryid"));
                }, 500);

            } else if (box.is(".medialink")) {
                sightingId = box.attr("data-sightingid");
                if (sightingId == "") return false;

                options.position = "right"; options.offsetX = "0"; options.offsetY = "-11";
                _toolTip.find(".tt-content").html(options.loadingmessage).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

                // Listen for the event when the user info is fecthed
                $(document).bind("AP2ImagesForSightingFetched", function (event, data) {
                    _toolTip.find(".tt-content").html(data).find("a[data-imageid]").click(function (e) {
                        e.preventDefault();
                        Artportalen.OpenImageInFloatingDiv($(this).attr("data-imageid"));
                    });
                    $(document).unbind("AP2ImagesForSightingFetched");
                    _positionTooltip(box);
                });

                // Fetch user information
                Artportalen.GetImagesForSighting(sightingId);

            } else if (box.is(".validationstatusicon")) {
                sightingId = box.attr("data-sightingid");
                if (sightingId == "") return false;

                options.position = 'bottom'; options.offsetX = '-13'; options.offsetY = '-1';
                _toolTip.find(".tt-content").html(options.loadingmessage).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

                // Listen for the event when the taxon info is fecthed
                $(document).bind("AP2SightingValidationSummaryFetched", function (event, data) {
                    $(".tipsy").hide(); // Hide tipsy bubble above the validation icon
                    _toolTip.find(".tt-content").html(data);
                    $(document).unbind("AP2SightingValidationSummaryFetched");
                    _positionTooltip(box);
                });

                // Fetch validation information
                Artportalen.GetSightingValidationSummary(sightingId);

            } else if (box.is(".triggeredvalidationruleicon")) {
                sightingId = box.attr("data-sightingid");
                if (sightingId == "" || box.hasClass("UI-Icon-16-valStatUnvalidated")) return false;

                options.position = 'bottom'; options.offsetX = '-13'; options.offsetY = '-1';
                _toolTip.find(".tt-content").html(options.loadingmessage).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

                // Listen for the event when the triggered validation rule info is fecthed
                $(document).bind("AP2TriggeredValidationRuleSummaryFetched", function (event, data) {
                    $(".tipsy").hide(); // Hide tipsy bubble above the validation icon
                    _toolTip.find(".tt-content").html(data);
                    $(document).unbind("AP2TriggeredValidationRuleSummaryFetched");
                    _positionTooltip(box);
                });

                // Fetch validation rule information
                Artportalen.GetTriggeredValidationRuleSummary(sightingId);

            } else if (box.is("[data-useralias]")) {

                var userAlias = box.attr("data-useralias");
                if (userAlias == "") return false;

                options.position = "right"; options.offsetX = "0"; options.offsetY = "-11";
                _toolTip.find(".tt-content").html(options.loadingmessage).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

                // Listen for the event when the user info is fecthed
                $(document).bind("AP2UserFetched", function (event, data) {
                    _toolTip.find(".tt-content").html(data);
                    $(document).unbind("AP2UserFetched");
                    _positionTooltip(box);
                });

                clearTimeout(toolTipDebounceTimer);
                // Fetch user information
                toolTipDebounceTimer = setTimeout(function () {
                    Artportalen.GetUserInformationByAlias(userAlias);
                }, 300);

            } else if (box.is("[data-siteid]")) {

                sightingId = box.attr("data-sightingid");
                var siteId = box.attr("data-siteid");
                if (siteId == "" || sightingId == "" || !$(box).is(":visible")) return false;

                options.position = "right"; options.offsetX = "0"; options.offsetY = "-11";
                _toolTip.find(".tt-content").html(options.loadingmessage).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

                // Listen for the event when the user info is fecthed
                $(document).bind("AP2SightingSiteSummaryFetched", function (event, data) {
                    _toolTip.find(".tt-content").html(data);
                    $(document).unbind("AP2SightingSiteSummaryFetched");
                    _positionTooltip(box);
                });

                // Fetch user information
                Artportalen.SightingSiteSummary(siteId, sightingId);

            } else if (box.is("[data-publicsiteid]")) {

                siteId = box.attr("data-publicsiteid");
                if (siteId == "" || !$(box).is(":visible")) return false;

                options.position = "right"; options.offsetX = "0"; options.offsetY = "-11";
                _toolTip.find(".tt-content").html(options.loadingmessage).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

                // Listen for the event when the public site info is fecthed
                $(document).bind("AP2PublicSiteSummaryFetched", function (event, data) {
                    _toolTip.find(".tt-content").html(data);
                    $(document).unbind("AP2PublicSiteSummaryFetched");
                    _positionTooltip(box);
                });

                // Fetch public site information
                Artportalen.PublicSiteSummary(siteId);

            } else if (box.is("[data-projectid]")) {

                var projectId = box.attr("data-projectid");
                if (projectId == "") return false;

                options.position = "right"; options.offsetX = "0"; options.offsetY = "-11";
                _toolTip.find(".tt-content").html(options.loadingmessage).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

                // Listen for the event when the project info is fecthed
                $(document).bind("AP2ProjectSummaryFetched", function (event, data) {
                    _toolTip.find(".tt-content").html(data);
                    $(document).unbind("AP2ProjectSummaryFetched");
                    _positionTooltip(box);
                });

                // Fetch user information
                Artportalen.ProjectSummary(projectId);

            } else if (box.hasClass("validation-wrapper")) {
                options.offsetX = '-5';
                options.position = 'right';
                options.offsetY = '-10';
                loadingMessage = "<span class='ap2-ui-loadingmessage-inline'>Loading user profile...</span>";
                contentHtml = "<h4>Valideringsmeddelanden</h4>" + box.find("span.validation-messages").html();
                _toolTip.find(".tt-content").html(contentHtml).removeClass(":not(.tt-content clearfix)").addClass(options.cssclass);

            } else if (box.hasClass("messagelink")) {
                options.offsetX = '-2';
                options.position = 'left';
                options.offsetY = '-10';
                loadingMessage = "<span class='ap2-ui-loadingmessage-inline'>Loading message information...</span>";
            }
            //_toolTip.find(".tt-content").html(box.attr(options.attr)).addClass(options.cssclass);
            _positionTooltip(box);
            _loadTooltipContent(box);
            _toolTip.stop(true, true).fadeIn("fast").addClass("is_active");
            if (tempDelay == 400) {
                tempTimer = setTimeout(function () {
                    _toolTip.data("caller", box).find(".tt-content").html(contentHtml).find("a, input, select").first(":not(.tt-closebutton)").focus();
                }, tempDelay);
            }
        }

        function _hideTooltip() {
            //options.mouseIsOverPopup = false;
            //$(options.tooltip).unbind("mouseout mouseleave");
            $(options.tooltip).fadeOut("fast").removeClass("is_active");
        }

        function _positionTooltip(box) {
            boxHeight = box.outerHeight();
            boxWidth = box.outerWidth();
            var css, pos, arrowPosStr, offset = box.offset();
            var posTop, posLeft;

            var rightPossible = offset.left + boxWidth - parseInt(options.offsetX) + parseInt(options.width) < $(window).width() + $(window).scrollLeft();
            var leftPossible = offset.left - parseInt(options.offsetX) - parseInt(options.width) > 0;
            var winBottomPos = $(window).height() + $(window).scrollTop();
            var bottomPossible = offset.top + boxHeight - parseInt(options.offsetY) + Math.max(options.height, _toolTip.height()) < winBottomPos;

            if (options.position == "right" && !rightPossible) options.position = "left";
            if (options.position == "left" && !leftPossible) options.position = "right";
            if (!bottomPossible) {
                options.offsetX = "0";
                options.offsetY = "0";
                options.position = "top";
            }

            switch (options.position) {
                case "top":
                    posTop = (offset.top - _toolTip.height()) - parseInt(options.offsetY);
                    posLeft = offset.left + parseInt(options.offsetX);
                    break;
                case "left":
                    posLeft = (offset.left - _toolTip.width()) - parseInt(options.offsetX);
                    posTop = offset.top + parseInt(options.offsetY);
                    break;
                case "right":
                    posLeft = (offset.left + boxWidth) + parseInt(options.offsetX);
                    posTop = offset.top + parseInt(options.offsetY);
                    break;
                case "bottom":
                    posTop = (offset.top + boxHeight) + parseInt(options.offsetY);
                    posLeft = offset.left + parseInt(options.offsetX);
                    break;
                default:
                    posTop = (offset.top + boxHeight) + parseInt(options.offsetY);
                    posLeft = offset.left + parseInt(options.offsetX);
                    break;
            }
            _toolTip.css({
                'top': posTop,
                'left': posLeft,
                'width': options.width,
                'height': options.height
            }).removeClass("top right left bottom").addClass(options.position);
        }


        this.each(function () {
            obj = $(this);
            _attachTooltip(obj);
        });

        return this;
    };
})(jQuery);
;
$.widget("ui.ap2ImageUpload", {
  options: {
    uploadRestriction: 3, /* Number of images per sighting */
    deleteActionURL: "/Media/DeleteImage/",
    addActionURL: "/Media/ImagesForSightingOrDiaryEntry/",
    hideCallBack: null
  },
  _create: function () {
    var self = this;
    var $self = this.element;

    self.debug = false; // debug true turns on console.log(function name) so that all function calls can be traced
    if (self.debug) {
      $("#ap2ImageUpload h3").html(function () {
        return $(this).html() + " - <span style='color:#c00;'>DEBUG MODE</span>";
      });
      console.log("ap2ImageUpload: _create");
    }

    self.selectedImageId = 0;
    self.numberOfImages = 0;
    self.options.uploadRestriction = $("#MediaFilePerSightingRestriction").val(); /* Number of images per sighting */
    self.imageUploadDiv = $self;
    self.imageTable = self.imageUploadDiv.find("#imageTable");
    self.imageTableHeader = self.imageUploadDiv.find("#imageTableHeader").hide();

    self.imageUploadDiv.find(".popupdiv_close").click(function (e) {
      e.preventDefault();
      self._hideImageUpload();
    });

    // Actionbuttons
    $("a.ap2-ui-actionbutton", self.imageTable).live("click", function (e) {
      e.preventDefault();
      var action = $(this).attr("href").replace("#", "").toLowerCase();
      var id = $(this).attr("data-imageid");
      if (action == "deleteimage") {
          self._deleteImage(id);
      } else if (action == "saveimagecomment") {
          self._saveImageComment(id);
      } else if (action == "rotate-left") {
          self._rotateImage(id, 'left')
      } else if (action == "rotate-right") {
          self._rotateImage(id, 'right')
      }
    });

    // Validate url
    $("#UploadMediaButton").click(function (e) {
      $("#url").parent("div").removeClass("ap2-ui-form-error");
      var regex = new RegExp($("#MediaUrlValidationRegEx").val());
      if (regex.test($("#url").val())) {
        return;
      }
      e.preventDefault();
      $("#url").parent("div").addClass("ap2-ui-form-error");
    });

    // Media type tabs
    $("#MediaFileUploadTabImage").click(function (e) {
      e.preventDefault();
      $("#MediaFileUploadTabImage").addClass("active");
      $("#MediaFileUploadTabVideoSound").removeClass("active");

      // Hide the file upload and display the upload button
      $("#ImageInstructions").show();
      $("#MediaInstructions").hide();
      $("#ImageInput").show();
      $("#MediaInput").hide();
    });

    $("#MediaFileUploadTabVideoSound").click(function (e) {
      e.preventDefault();
      self._changeToVideoSound();
    });

    self.imageUploadDiv.bind("ap2UploadImage", function (event, data) {
      if (self.debug) {
        console.log("ap2ImageUpload: fired event 'ap2UploadImage' with parameters:");
        console.log(data);
      }
      Artportalen.ToggleGridLoadingMessage($("#uploadformwrapper"), false);
      self._addImage(data.selectedid, data.position, data.selectedtype);
    });

    console.log(self.options.uploadRestriction);
    // Full dropzone mode.
    Dropzone.options.uploadForm = {
      acceptedFiles: "image/jpeg, image/jpg, image/png, image/gif",
      timeout: 120000,
      createImageThumbnails: false,
      dictDefaultMessage: "Släpp dina bildfiler här (klicka för att öppna en fildialog). De bildformat som stöds är <b>.jpg</b>, <b>.gif</b> och <b>.png</b>.  Är det stora bildfiler (~32 MB) är det bättre att ladda upp dem en och en. Ju mindre filer (~1 MB), ju fler kan laddas upp samtidigt.",
      paramName: "UploadImageViewModel.Image",
      previewsContainer: false,
      maxFiles: self.options.uploadRestriction,
      accept: function (file, done) {
        console.log(self.numberOfImages);
        var dz = this;

        if (self._isMaxDropzoneFilesLimitReached()) {
          done("Number of uploaded files reached.");

          dz.removeFile(file);
        } else {
          done();

          self.numberOfImages++;
        }
      },
      init: function () { 
        var dz = this;

        this.on("complete",
          function (file) {               
            if (file.accepted) {
              var jsonData = $(file.xhr.responseText).text();

              if (jsonData == null || jsonData == '') {
                Artportalen.AjaxNotificationMessage(Artportalen.ResourceLabel("Shared_JavaScript_ImageUploadedFailure"), true, "error");        

                self.numberOfImages = self.imageTable.find(".imageTableRow").length;
              } else {
                var data = JSON.parse(jsonData);

                var newImage = [
                  {
                    thumbnail: data.thumbnail,
                    fileurl: data.fileurl,
                    id: data.id,
                    comment: data.Description,
                    sightingid: data.SightingId,
                    diaryentryid: data.DiaryEntryId,
                    imageposition: self.imageTable.find(".imageTableRow").length,
                    isImage: true
                  }
                ]; 

                $.tmpl("imageTemplate", newImage).prependTo(self.imageTable);

                self.numberOfImages = self.imageTable.find(".imageTableRow").length;

                self._checkUploadRestriction();
                  Artportalen.AjaxNotificationMessage(Artportalen.ResourceLabel("Shared_JavaScript_ImageUploadedSuccess"), true, "success", {
                      delayTime: 2000,
                      offsetBottom: 10
                  });
              }     
            }

            dz.removeFile(file);

            Artportalen.ToggleGridLoadingMessage($("#uploadformwrapper"), false);
          });
        this.on("sending",
          function () {
            Artportalen.ToggleGridLoadingMessage($("#uploadformwrapper"), true);
          });
      }
    }
  },
  _init: function () {
    var self = this;
    if (self.debug) { console.log("ap2ImageUpload: _init"); }

    $("#MediaInstructions").hide();
    $("#MediaInput").hide();

    $("#uploadForm").find("input:file").change(function (e) {

      // Split string by slashes, pop() removes last element from the array and returns that value.
      var fileName = $(this).val().split(/(\\|\/)/g).pop();

      // Hide the file upload and display the upload button
      $("#uploadForm")
        .find(".fileuploadwrapper").hide().end();
      $("#UploadButton").show();

      // Create a label with the uploaded filename
      var fileNameHtml = $([
        "<span class='UI-Icon-16 UI-Icon-16-AddImage'></span>",
        fileName,
        "<span class='UI-Icon-16 UI-Icon-16-Close'></span>",
        "</a>"
      ].join(''));

      // Click the filename label to remove the file and reset the form
      $("#uploadfilename").html(fileNameHtml).show().click(function () {
        $(this).unbind().hide();
        $("#uploadForm")
          .find(".fileuploadwrapper").show().end()
          .resetForm();
        $("#UploadButton").hide();
      });
    });


    $(".uploadForm").ajaxForm({
      iframe: true,
      dataType: "json",
      beforeSubmit: function () {
        Artportalen.ToggleGridLoadingMessage($("#uploadformwrapper"), true);
      },
      success: function (data) {
        if (data == null) {
          $("#uploadfilename").click(); // Click to reset the file
          Artportalen.ToggleGridLoadingMessageError($("#uploadformwrapper"));
          Artportalen.AjaxNotificationMessage(Artportalen.ResourceLabel("Shared_JavaScript_ImageUploadedFailure"), true, "error");
          return false;
        }
        $("#uploadfilename").click(); // Reset the filename
        var newImage = [{
          thumbnail: data.thumbnail,
          fileurl: data.fileurl,
          id: data.id,
          comment: data.Description,
          sightingid: data.SightingId,
          diaryentryid: data.DiaryEntryId,
          imageposition: data.ImagePosition
        }];
        $.tmpl("imageTemplate", newImage).prependTo(self.imageTable.find("tbody"));
        self.imageTableHeader.show();
        self.numberOfImages = self.imageTable.find(".imageTableRow").length;

        self._checkUploadRestriction();

        Artportalen.ToggleGridLoadingMessage($("#uploadformwrapper"), false);
        Artportalen.ToggleGridLoadingMessage(self.imageUploadDiv.find("div.uploaded-imagelist-wrapper"), false);
        Artportalen.RebindFormFieldInstructions(self.imageUploadDiv);
        Artportalen.AjaxNotificationMessage(Artportalen.ResourceLabel("Shared_JavaScript_ImageUploadedSuccess"), true, "success", {
            delayTime: 2000,
            offsetBottom: 10
        });
        $("#uploadForm").resetForm();
        if (self.debug) { console.log("ap2ImageUpload: UPLOAD completed!"); }
      },
      error: function (xhr, textStatus, errorThrown) {
        if (self.debug) { console.log("ap2ImageUpload: ERROR in upload!"); }
      }
    });

    var validator = $("#existingImagesForm").validate({
      submitHandler: function (form) {
        var options = {
          success: function (json) {
                Artportalen.AjaxNotificationMessage(Artportalen.ResourceLabel("Shared_JavaScript_ImageCommentSaved"), true, "success", {
                    delayTime: 2000,
                    offsetBottom: 10
                });
          }
        };
        $("#existingImagesForm").ajaxSubmit(options);
        return false;
      }
    });


  },
  _checkUploadRestriction: function () {
    var self = this;
    if (self.debug) {
      console.log("Restriction: " + self.options.uploadRestriction);
      console.log("Number of images: " + self.numberOfImages);
    }
    var bRestricted = (self.numberOfImages >= self.options.uploadRestriction);
    $("#uploadformwrapper").toggle(!bRestricted);
    $("#uploadrestrictionmessage").toggle(bRestricted);
  },
  // Change to the video/sound tab
  _changeToVideoSound: function () {
    $("#MediaFileUploadTabImage").removeClass("active");
    $("#MediaFileUploadTabVideoSound").addClass("active");

    // Hide the file upload and display the upload button
    $("#ImageInstructions").hide();
    $("#MediaInstructions").show();
    $("#ImageInput").hide();
    $("#MediaInput").show();
  },
  // Hide the image upload div
  _hideImageUpload: function () {
    var self = this;
    if (self.debug) { console.log("ap2ImageUpload: _hideImageUpload"); }
    self.imageUploadDivVisible = false;
    self.imageUploadDiv.hide();
    if (jQuery.isFunction(self.options.hideCallBack)) { self.options.hideCallBack.call(); }
    return false;
  },
  // Save comments
  _saveImageComment: function (id) {
    var self = this;
    if (self.debug) { console.log("ap2ImageUpload: _saveImageComment"); }
    self.imageUploadDiv.find("input.image-savedmediafileid").val(id);
    $("#existingImagesForm").submit();
  },
  _addImage: function (selectedId, dialogOffset, selectedType) {
    var self = this;
    if (self.debug) { console.log("ap2ImageUpload: _addImage (selectedId: " + selectedId + "  dialogOffset: " + dialogOffset + ", parenttype: " + selectedType + ")"); }

    var _selectedId = selectedId;
    var _position = dialogOffset;
    var _selectedType = selectedType;
    self.imageTableHeader.hide();

    // Display an ajax loading message
    Artportalen.ToggleGridLoadingMessage(self.imageUploadDiv.find("div.uploaded-imagelist-wrapper"), true);

    Artportalen.ajaxPost(Artportalen_ApplicationPath + self.options.addActionURL, { selectedId: _selectedId, selectedtype: _selectedType },
      function (data, code, xht) {

        // Reset the table
        self.imageTable.find("tr.imageTableRow").remove();
        if (data.length) {
          $.tmpl("imageTemplate", data).appendTo(self.imageTable.find("tbody"));
          self.imageTableHeader.show();
        }

        self.numberOfImages = data.length;

        self._checkUploadRestriction();

        // Delay this a short while
        setTimeout(function () {
          Artportalen.RebindFormFieldInstructions(self.imageUploadDiv);
        }, 200);
        Artportalen.ToggleGridLoadingMessage(self.imageUploadDiv.find("div.uploaded-imagelist-wrapper"), false);

      });
    self.imageUploadDiv.css({
      left: _position.left - 460,
      top: _position.top - 10
    }).show();
    if (_selectedType === "sighting") {
      self.imageUploadDiv.find("input.image-sightingid").val(_selectedId);
      self.imageUploadDiv.find("input.newimage-sightingid").val(_selectedId);
      self.imageUploadDiv.find("input.image-diaryentryid").val(0);
      self.imageUploadDiv.find("input.newimage-diaryentryid").val(0);
    } else {
      self.imageUploadDiv.find("input.image-sightingid").val(0);
      self.imageUploadDiv.find("input.newimage-sightingid").val(0);
      self.imageUploadDiv.find("input.image-diaryentryid").val(_selectedId);
      self.imageUploadDiv.find("input.newimage-diaryentryid").val(_selectedId);
    }
    //jQuery.scrollTo({ top: _position.top - 460, left: _position.left - 10 }, 1000);
  },
  _deleteImage: function (id) {
    var self = this;
    if (self.debug) { console.log("ap2ImageUpload: _deleteImage(" + id + ")"); }
    Artportalen.ModalConfirm({
      questionText: Artportalen.ResourceLabel("Shared_JavaScript_DeleteImageQuestion"),
      yesButtonText: Artportalen.ResourceLabel("Shared_JavaScript_Yes"),
      yesButtonFunction: function () {
        Artportalen.ToggleGridLoadingMessage(self.imageTable.find("tr.row" + id).find("div.comment"), true);
        self.imageTable.find("tr.row" + id).find("img:first").fadeOut("slow");
        Artportalen.ajaxPost(
          Artportalen_ApplicationPath + self.options.deleteActionURL,
          { id: id },
          function () {
            self.imageTable.find("input[value='" + id + "']").closest("tr").remove();

            // Delay this a short while
            setTimeout(function () {
              self.numberOfImages = self.imageTable.find(".imageTableRow").length;
              
              self._checkUploadRestriction();
            }, 50);

            if (!self.imageTable.find(".imageTableRow").length) {
              self.imageTableHeader.hide();
            }

            // Uppdatera alla index eftersom rad tagits bort
            self.imageTable.find("tr").each(function (index) {
              $(this).find(":input").each(function (index2) {
                var inputName = $(this).attr("name");
                inputName = inputName.replace(/\[\d+\]/, "[" + (index - 1) + "]"); // -1 one is to ignore the header tr
                $(this).attr("name", inputName);
              });
            });

            $('#ap2-ui-gridloading-message').remove();
            Artportalen.AjaxNotificationMessage(Artportalen.ResourceLabel("Shared_JavaScript_DeleteImageSuccess"), true, "success");
          }
        );
        /*
        $.getJSON(Artportalen_ApplicationPath + self.options.deleteActionURL + id, function (data) {
        self.imageTable.find("input[value='" + id + "']").closest("tr").remove();

        if (!self.imageTable.find(".imageTableRow").length) {
        self.imageTableHeader.hide();
        }

        // Uppdatera alla index eftersom rad tagits bort
        self.imageTable.find("tr").each(function (index) {
        $(this).find(":input").each(function (index2) {
        var input_name = $(this).attr("name");
        input_name = input_name.replace(/\[\d+\]/, "[" + (index - 1) + "]"); // -1 one is to ignore the header tr
        $(this).attr("name", input_name);
        });
        });
        });
        */
      },
      noButtonText: Artportalen.ResourceLabel("Shared_JavaScript_No"),
      noButtonFunction: null
    });
  },
  _isMaxDropzoneFilesLimitReached: function () {
    var self = this;

    return !(self._maxDropzoneFilesLeft() > 0);
  },
  _maxDropzoneFilesLeft: function () {
    var self = this;

    return self.options.uploadRestriction - self.numberOfImages;
  },

  _rotateImage: function(imageId, direction){
    Artportalen.ToggleGridLoadingMessage($(`.row${imageId}`), true);
    Artportalen.ajaxPost(
      Artportalen_ApplicationPath + '/media/rotateimage/' + imageId + '/' + direction,
      {},
      function(data, code, xht){
          var imageElement = $(`.row${imageId} img`)

          var newSource = `data:image/jpeg;base64,  ${data.thumbnail}`;
          imageElement.attr("src", newSource);
  
          var height = imageElement.attr('height');
          var width = imageElement.attr('width');
          imageElement.attr('height',width);
          imageElement.attr('width',height);

          $('#ap2-ui-gridloading-message').remove();
          $('.ap2-ui-gridloading').remove();
      }
    );
  }
});;
$.widget("ui.ap2ContextMenu", {
    options: {
        elementSelector: "a.contextmenu",
        contextMenuToLoad: null, // determines which context menu to load. Check ContextMenuController for menues.
        mouseInDelay: 50,
        mouseOutDelay: 500,
        onClick: false,
        destroy: false,
        showDetails: null,      // A function that will override the default implementation for the "show sighting details" action.
        addCoobserver: null,    // A function that will override the default implementation for the "become coobserver" action.
        edit: null,             // A function that will override the default implementation for the "edit sighting" action. 
        deleteSighting: null,   // A function that will override the default implementation for the "delete sighting" action. 
        addImage: null,         // A function that will override the default implementation for the "load image" action. 
        orderObservers: null,   // A function that will override the default implementation for the "order observers" action. 
        administrateSightings: null,   // A function that will override the default implementation for the "administrate sightings" action. 
        contactReporter: null,  // A function that will override the default implementation for the "contact reporter" action. 
        viewTaxonByReporter: null,  // A function that will override the default implementation for the "view taxon by reporter" action. 
        contactValidator: null, // A function that will override the default implementation for the "contact validator" action. 
        notifyValidator: null,  // A function that will override the default implementation for the "notifyValidator" action. 
        viewInFieldDiary: null, // A function that will override the default implementation for the "view in field diary" action. 
        sightingsByTaxon: null, // A function that will override the default implementation for the "my sightings by taxon" action. 
        sightingsByDate: null,  // A function that will override the default implementation for the "my sightings by date" action. 
        refresh: null,          // Will be called during action execution in order to e.g. refresh a grid
        success: null,          // Will be called after an action is executed
        writeReport: null,      // A function that will override the default implementation for the "write rarity report" action.
        showReport: null        // A function that will override the default implementation for the "show rarity report" action.
    },
    _create: function () {
        var self = this;
        var $self = this.element;

        self.debug = true; // debug true turns on console.log(function name) so that all function calls can be traced
        if (self.debug) {
            console.log("Debugging of ap2ContextMenu");
            console.log("ap2ContextMenu: _create");
        }

        self.selectedId = 0;
        self.action = "";
        self.posY = 0;
        self.posX = 0;
        self.contextMenuVisible = false;
        self.contextMenu = $self;
        self.contextMenuTrigger = ""; // Which element was clicked to trigger the context menu?
        if (!self.contextMenu.length) { alert("Error in contextmenu implementation. Could not find the menu!"); return false; }
        self.contextMenu.addClass("ap2ContextMenu-active");
        self.contextMenu.detach().appendTo(document.body);

    },
    _init: function () {
        var self = this;
        if (self.debug) { console.log("ap2ContextMenu: _init"); }
        $(self.options.elementSelector).unbind(".ap2ContextMenu").addClass("has_ap2contextmenu").bind("click.ap2ContextMenu", function (event) {
            event.preventDefault();
            if (self.contextMenuTrigger.length) {
                self.contextMenuTrigger.removeClass("ap2ContextMenuTriggerActive"); }
            self.contextMenuTrigger = $(this);
            $(this).addClass("ap2ContextMenuTriggerActive");
            self._showContextMenu();
        }).bind('keypress.ap2ContextMenu', function (event) {
            var code = event.charCode || event.keyCode;
            if (code && code == 13) {
                event.preventDefault();
                self.contextMenuTrigger = $(this);
                $(this).addClass("ap2ContextMenuTriggerActive");
                self._showContextMenu();
                self.contextMenu.find("a.enabled:first").focus();
            };
        });
    },
    _showContextMenu: function () {
        var self = this;
        if (self.debug) { console.log("ap2ContextMenu: _showContextMenu"); }
        self.selectedId = self.contextMenuTrigger.attr("data-id");

        self.contextMenu.load(Artportalen_ApplicationPath + '/ContextMenu/' + self.options.contextMenuToLoad, { SightingId: self.selectedId }, function (response, status, xhr) {
            // If the window is resized - reposition the popup
            self._repositionContextMenu();

            self.contextMenu.find(".ap2ContextMenu-closebutton").unbind(".ap2ContextMenu").bind("click.ap2ContextMenu", function (event) {
                self._hideContextMenu();
            });

            self.contextMenu.unbind().hoverIntent({
                interval: self.options.mouseInDelay,
                timeout: self.options.mouseOutDelay,
                over: function (event) { return; },
                out: function (event) { self._mouseLeaveContextMenu(event); }
            }).find("a").unbind().click(function (event) {
                event.preventDefault();
                if ($(this).is(".disabled")) {
                    return false;
                } else {
                    self.action = $(this).attr("id");
                    self._executeAction();
                }
            });
            
            self._calculatePosition();
            self.contextMenu.css({
                top: self.posY,
                left: self.posX
            }).show();
            self.contextMenuVisible = true;
        });
    },
    _hideContextMenu: function () {
        var self = this;
        if (self.debug) { console.log("ap2ContextMenu: _hideContextMenu"); }
        if (self.contextMenuTrigger.length) { self.contextMenuTrigger.removeClass("ap2ContextMenuTriggerActive"); }
        self.contextMenuVisible = false;
        self.contextMenu.hide();
        return false;
    },
    // calculate position of the context menu - is there enough room to the right?
    _calculatePosition: function () {
        var self = this;
        if (self.debug) { console.log("ap2ContextMenu: _calculatePosition"); }
        var position = self.contextMenuTrigger.offset();
        var rightPossible = position.left + self.contextMenu.outerWidth() + self.contextMenuTrigger.outerWidth() < $(window).width() + $(window).scrollLeft();
        self.posY = position.top + self.contextMenuTrigger.outerHeight() - 1;
        self.posX = ((rightPossible) ? (position.left - 3) : (position.left - self.contextMenu.outerWidth() + self.contextMenuTrigger.outerWidth()));
    },
    // When window is resized and the context menu is visible - recalculate the position
    _repositionContextMenu: function () {
        var self = this;
        if (self.debug) { console.log("ap2ContextMenu: _repositionContextMenu"); }
        var adjustTimer;
        $(window).smartresize(function (event) {
            clearTimeout(adjustTimer);
            if (self.contextMenuVisible) {
                adjustTimer = setTimeout(function () {
                    self._calculatePosition();
                    self.contextMenu.stop().animate({
                        top: self.posY,
                        left: self.posX
                    }, 200, 'swing');
                }, 100);
            }
        });
    },
    _mouseLeaveContextMenu: function (event) {
        var self = this;
        if (self.debug) { console.log("ap2ContextMenu: _mouseLeaveContextMenu"); }
        var $currentTarget = $(event.currentTarget);
        if ($currentTarget.is("#" + self.element.attr("id")) || $currentTarget.parents("#" + self.element.attr("id")).length) {
            if ($currentTarget.hasClass("has_ap2contextmenu") || $currentTarget.parents(".has_ap2contextmenu").length) {
                return;
            } else {
                self._hideContextMenu();
            }
        } else {
            if ($currentTarget.hasClass("has_ap2contextmenu") || $currentTarget.parents(".has_ap2contextmenu").length) {
                return;
            } else {
                self._hideContextMenu();
            }
        }
    },
    _executeAction: function () {
        var self = this;
        if (self.debug) { console.log("ap2ContextMenu: _executeAction"); }
        if (!self.action || self.action == "") {
            alert("Something went wrong, no action was executed!");
        } else {
            var _position = self.contextMenuTrigger.offset();
            if (self.action == "contextmenu-sighting-details") {
                var showDetailsCallback = self.options.showDetails;
                if ($.isFunction(showDetailsCallback)) {
                    showDetailsCallback(self.action, self.selectedId, _position);
                } else {
                    self._showDetails();
                }
            }

            if (self.action == "contextmenu-coobserver-add") {
                self._addCoobserver(false);
                /*
                var addCoobserverCallback = self.options.addCoobserver;
                if ($.isFunction(addCoobserverCallback)) {
                addCoobserverCallback(self.action, self.selectedId, _position);
                } else {
                self._addCoobserver(false);
                }
                */
            }

            if (self.action == "contextmenu-coobserver-delete") {
                self._deleteCoobserver(true);
            }

            if (self.action == "contextmenu-sighting-edit") {
                var editCallback = self.options.edit;
                if ($.isFunction(editCallback)) {
                    editCallback(self.action, self.selectedId, _position);
                } else {
                    self._edit();
                }
            }

            if (self.action == "contextmenu-sighting-delete") {
                var deleteCallback = self.options.deleteSighting;
                if ($.isFunction(deleteCallback)) {
                    deleteCallback(self.action, self.selectedId, _position);
                } else {
                    self._deleteSighting();
                }
            }

            if (self.action == "contextmenu-image-add") {
                var addImageCallback = self.options.addImage;
                if ($.isFunction(addImageCallback)) {
                    addImageCallback(self.action, self.selectedId, _position);
                } else {
                    self._addImage();
                }
            }

            if (self.action == "contextmenu-sighting-history") {
                var historyCallback = self.options.showHistory;
                if ($.isFunction(historyCallback)) {
                    historyCallback(self.action, self.selectedId, _position);
                } else {
                    self._showHistory();
                }
            }

            if (self.action == "contextmenu-order-observers") {
                var orderCallback = self.options.orderObservers;
                if ($.isFunction(orderCallback)) {
                    orderCallback(self.action, self.selectedId, _position);
                } else {
                    self._orderObservers();
                }
            }

            if (self.action == "contextmenu-administrate_sightings") {
                var administrateSightingsCallback = self.options.administrateSightings;
                if ($.isFunction(administrateSightingsCallback)) {
                    administrateSightingsCallback(self.action, self.selectedId, _position, self.contextMenuTrigger.attr("data-taxonid"), self.contextMenuTrigger.attr("data-year"));
                } else {
                    self._administrateSightings();
                }
            }

            if (self.action == "contextmenu-notify-validator") {
                var notifyValidatorCallback = self.options.notifyValidator;
                if ($.isFunction(notifyValidatorCallback)) {
                    notifyValidatorCallback(self.action, self.selectedId, _position);
                } else {
                    self._notifyValidator();
                }
            }

            if (self.action == "contextmenu-contact-reporter") {
                var contactCallback = self.options.contactReporter;
                if ($.isFunction(contactCallback)) {
                    contactCallback(self.action, self.selectedId, _position);
                } else {
                    self._contactReporter();
                }
            }

            if (self.action == "contextmenu-view-taxon-by-reporter") {
                var viewTaxonByReporterCallback = self.options.viewTaxonByReporter;
                if ($.isFunction(viewTaxonByReporterCallback)) {
                    viewTaxonByReporterCallback(self.action, self.selectedId, _position, self.contextMenuTrigger.attr("data-useralias"), self.contextMenuTrigger.attr("data-taxonid"));
                } else {
                    self._viewTaxonByReporter();
                }
            }

            if (self.action == "contextmenu-contact-validator") {
                var contactCallback = self.options.contactValidator;
                if ($.isFunction(contactCallback)) {
                    contactCallback(self.action, self.selectedId, _position);
                } else {
                    self._contactValidator();
                }
            }

            if (self.action == "contextmenu-report-write") {
                var writeReportCallback = self.options.writeReport;
                if ($.isFunction(writeReportCallback)) {
                    writeReportCallback(self.action, self.selectedId, _position);
                } else {
                    self._writeReport();
                }
            }

            if (self.action == "contextmenu-viewinfielddiary") {
                var viewInFieldDiaryCallback = self.options.viewInFieldDiary;
                if ($.isFunction(viewInFieldDiaryCallback)) {
                    viewInFieldDiaryCallback(self.contextMenuTrigger.attr("data-date"));
                } else {
                    self._viewInFieldDiary();
                }
            }

            if (self.action == "contextmenu-mysightingsbydate") {
                var mySightingsByDateCallback = self.options.sightingsByDate;
                if ($.isFunction(mySightingsByDateCallback)) {
                    mySightingsByDateCallback(self.contextMenuTrigger.attr("data-date"));
                } else {
                    self._mySightingsByDate();
                }
            }

            if (self.action == "contextmenu-mysightingsbytaxon") {
                var mySightingsByTaxonCallback = self.options.sightingsByTaxon;
                if ($.isFunction(mySightingsByTaxonCallback)) {
                    mySightingsByTaxonCallback(self.contextMenuTrigger.attr("data-taxonid"));
                } else {
                    self._mySightingsByTaxon();
                }
            }

            if (self.action == "contextmenu-report-show") {
                var showReportCallback = self.options.showReport;
                if ($.isFunction(showReportCallback)) {
                    showReportCallback(self.action, self.selectedId, _position);
                } else {
                    self._showReport();
                }
            }

            if (self.action == "contextmenu-verification-showsighting") {
                var showSightingInVerificationCallback = self.options.showSightingInVerification;
                if ($.isFunction(showSightingInVerificationCallback)) {
                    showSightingInVerificationCallback(self.action, self.selectedId, _position);
                } else {
                    self._showSightingInVerification();
                }
            }

            var callback = self.options.success;
            if ($.isFunction(callback)) callback(self.action, self.selectedId, _position);
        }
    },
    _showDetails: function () {
        var self = this;
        //window.location = Artportalen_ApplicationPath + '/Sighting/' + self.selectedId;
        window.open(Artportalen_ApplicationPath + '/Sighting/' + self.selectedId, '_blank');
    },
    _addCoobserver: function () {
        var self = this;
        Artportalen.ajaxPost(Artportalen_ApplicationPath + '/ViewSighting/ToggleObserver/' + self.selectedId, { sightingid: self.selectedId }, function (data) {
            self._hideContextMenu();
            Artportalen.AjaxNotificationMessage(data.Message, true, data.MessageType);
            var menuActions = self.contextMenuTrigger.attr("href");
            self.contextMenuTrigger.attr("href", menuActions.replace("contextmenu-coobserver-add", "contextmenu-coobserver-delete"));

            var addCoobserverCallback = self.options.addCoobserver;
            if ($.isFunction(addCoobserverCallback)) {
                addCoobserverCallback();
            }
        });
    },
    _deleteCoobserver: function () {
        var self = this;
        Artportalen.ajaxPost(Artportalen_ApplicationPath + '/ViewSighting/ToggleObserver/' + self.selectedId, { sightingId: self.selectedId }, function (data) {
            self._hideContextMenu();
            Artportalen.AjaxNotificationMessage(data.Message, true, data.MessageType);
            var menuActions = self.contextMenuTrigger.attr("href");
            self.contextMenuTrigger.attr("href", menuActions.replace("contextmenu-coobserver-delete", "contextmenu-coobserver-add"));

            var deleteCoobserverCallback = self.options.deleteCoobserver;
            if ($.isFunction(deleteCoobserverCallback)) {
                deleteCoobserverCallback(self.selectedId);
            }
        });
    },
    _edit: function () {
        var self = this;
        //window.location = Artportalen_ApplicationPath + '/Edit/' + self.selectedId;
        window.open(Artportalen_ApplicationPath + '/Edit/' + self.selectedId, '_blank');
    },
    _deleteSighting: function () {
        var self = this;
        // TODO: Översätt!!!!
        Artportalen.ModalConfirm({
            questionText: "Vill du radera detta fynd?",
            yesButtonText: "Ja",
            yesButtonFunction: function () {
                $("#content").find("div.ap2-ui-loadingblocker-message span").text("Raderar fynd");
                $("#content")
                    .find("div.ap2-ui-loadingblocker-shade, div.ap2-ui-loadingblocker-message")
                    .show()
                    .filter(".ap2-ui-loadingblocker-shade")
                    .css({ opacity: 0.7 });
                Artportalen.ajaxPost(Artportalen_ApplicationPath + '/ReviewSighting/DeleteSighting/', { sightingId: self.selectedId, isTemporary: false }, function () {
                    var refreshCallback = self.options.refresh;
                    if ($.isFunction(refreshCallback)) refreshCallback();
                    $("#content").find("div.ap2-ui-loadingblocker-shade, div.ap2-ui-loadingblocker-message").hide();
                    Artportalen.AjaxNotificationMessage(" Fyndet raderat", true, "success");
                });
            },
            noButtonText: "Nej",
            noButtonFunction: null
        });
    },
    _addImage: function () {
        alert("Not implemented!");
    },
    _showHistory: function () {
        alert("Not implemented!");
    },
    _orderObservers: function () {
        alert("Not implemented!");
    },
    _administrateSightings: function () {
        alert("Not implemented!");
    },
    _contactReporter: function () {
        alert("Not implemented!");
    },
    _viewTaxonByReporter: function () {
        alert("Not implemented!");
    },
    _contactValidator: function () {
        alert("Not implemented!");
    },
    _viewInFieldDiary: function () {
        alert("Not implemented!");
    },
    _mySightingsByTaxon: function () {
        alert("Not implemented!");
    },
    _mySightingsByDate: function () {
        alert("Not implemented!");
    },
    _writeReport: function () {
        var self = this;
        window.location = Artportalen_ApplicationPath + '/RarityReport/WriteReport/' + self.selectedId;
    },
    _showReport: function () {
        var self = this;
        window.location = Artportalen_ApplicationPath + '/RarityReport/ShowReport/' + self.selectedId;
    },
    _showSightingInVerification: function(){
        alert("Not implemented!");
    },
    destroy: function () {
        $.Widget.prototype.destroy.apply(this, arguments); // default destroy
        alert("Im destroyed!");
        // now do other stuff particular to this widget
    }
});;
/// <reference path="../jquery/jquery-1.4.2.js"/>
$.fn.simplepickerSetValues = function (itemName, itemId, bResetValues, bFocusElement, element) {
    return this.each(function () {
        if (this.tagName == 'INPUT') {

            var inputBox = this;
            if (element != null){
                inputBox = element;
            }
            
            var valueBox = $(inputBox).closest('.ap2-ui-simplepicker-wrapper').find('.ap2picker_value');
            var selectedItemLabel = $(inputBox).closest('.ap2-ui-picker-wrapper').find('.ap2-ui-simplepicker-selected-item-label');
            if (element != null) {
                inputBox = element;
                valueBox = $(inputBox).find('.ap2picker_value');
                selectedItemLabel = $(inputBox).find('.ap2-ui-simplepicker-selected-item-label');
            }

            bFocusElement = (typeof bFocusElement === 'undefined') ? true : bFocusElement;

            if (bResetValues) {
                selectedItemLabel.hide();
                $(valueBox).closest(".ap2-ui-simplepicker-wrapper").show();
                $(valueBox).val(""); // clear selected item
                jQuery.removeData($(inputBox), "pickedvalues"); // Remove stored data
                if (bFocusElement) {
                    $(inputBox).focus();
                }

            } else {
                if (selectedItemLabel.length !== 0) {
                    var storeValues = {
                        name: itemName,
                        id: itemId
                    };
                    $(inputBox).data("pickedvalues", JSON.stringify(storeValues)); // Store values in the data attribute
                    selectedItemLabel.find("h3").text(jQuery.trim(itemName));
                    selectedItemLabel.find(".close-this-div").unbind().click(function (event) {
                        event.preventDefault();
                        selectedItemLabel.hide();
                        $(valueBox).closest(".ap2-ui-simplepicker-wrapper").show();
                        $(valueBox).val(""); // clear selected item
                        $(inputBox).trigger("pickerValueEmpty");
                        jQuery.removeData($(inputBox), "pickedvalues"); // Remove stored data
                        if (bFocusElement) {
                            $(inputBox).focus();
                        }
                        $(valueBox).change();
                    });
                    $(valueBox).closest(".ap2-ui-simplepicker-wrapper").hide();
                    $(inputBox).val("");
                    selectedItemLabel.show();
                    selectedItemLabel.find(".close-this-div");
                }
            }
        }
    });
};




$.fn.taxonpickerSetValues = function (settings) {
    return this.each(function () {
        if (this.tagName == 'INPUT') {

            var inputBox = this;

            /*
            var settings = {
                taxonName: "",
                taxonId: "",
                speciesGroupId: "",
                protectionLevelId: "",
                protectionLevelLabel: "",
                resetValues: false
            };
            */

            var valueBox = $(inputBox).closest('.ap2-ui-taxonpicker-wrapper').find('.ap2picker_value');
            var speciesGroupValue = $(inputBox).closest('.ap2-ui-taxonpicker-wrapper').find('.ap2-ui_input_taxonpicker_speciesgroupid');
            var applyAuthorizationFilterValue = $(inputBox).closest('.ap2-ui-taxonpicker-wrapper').find('.ap2-ui_input_taxonpicker_applyAuthorizationFilter');
            var securedEntityTypeIdentifierValue = $(inputBox).closest('.ap2-ui-taxonpicker-wrapper').find('.ap2-ui_input_taxonpicker_securedEntityTypeIdentifier');

            var selectedTaxonLabel = $(inputBox).closest('.ap2-ui-picker-wrapper').find('.ap2-ui-taxonpicker-selected-taxon-label');
            //var selectedTaxonLabel = $("#ap2-ui-taxonpicker-selected-taxon-label");
            
            if (settings.resetValues) {
                selectedTaxonLabel.hide();
                $(valueBox).closest(".ap2-ui-taxonpicker-wrapper").show();
                $(valueBox).val(""); // clear selected taxon
                //$(inputBox).focus();
            } else {
                if (selectedTaxonLabel.length !== 0) {

                    var protectionHtml = (settings.protectionLevelId > 1) ? "<span class='UI-Icon-16 UI-Icon-16-NoFloat UI-Icon-16-ProtectedBySystem'></span>" : "";

                    selectedTaxonLabel.find("h3").html(jQuery.trim(settings.taxonName) + protectionHtml).attr("data-taxonid", settings.taxonId).popupInfoTooltip();
                    selectedTaxonLabel.find(".close-this-div").unbind().click(function (event) {
                        event.preventDefault();

                        // If speciesgroup is set to antoher group than the selected species, change the group to the current taxon being reset
                        if (settings.speciesGroupId && settings.speciesGroupId != $(inputBox).closest('.ap2-ui-taxonpicker-wrapper').find(".ap2-ui_input_taxonpicker_scope").val()) {
                            $(inputBox).closest('.ap2-ui-taxonpicker-wrapper').find(".ap2-ui_input_taxonpicker_scope").val(settings.speciesGroupId).change();
                        }

                        $(inputBox).trigger("pickerValueEmpty");
                        selectedTaxonLabel.hide();
                        $(valueBox).closest(".ap2-ui-taxonpicker-wrapper").show();
                        $(valueBox).val(""); // clear selected taxon
                        $(inputBox).focus();
                        $(valueBox).change();
                    });
                    $(valueBox).closest(".ap2-ui-taxonpicker-wrapper").hide();
                    $(inputBox).val("");
                    selectedTaxonLabel.show();
                    selectedTaxonLabel.find(".close-this-div").focus();
                }
            }
        }
    });
};

// ----------------------------------------------------------------------------------
// JSZ PICKER
// ----------------------------------------------------------------------------------
$.widget("ui.ap2Picker", {

    options: {
        ajaxSearchUrl: null,
        ajaxChildrenUrl: null,
        ajaxRenderTopLevelUrl: null,
        ajaxReturnFormat: 'html',
        afterRenderCallback: null,
        filterSection: false,
        renderTopLevel: false,
        noCacheUrl: false,
        minimumCharacters: 2,
        keyUpTimeOut: 300,
        on: "#f00",
        off: "#0f0"
    },
    _create: function () {
        var self = this;
        var $self = this.element;

        self.debug = false; // debug true turns on console.log(function name) in self.debugMessage(msg); so that all function calls can be traced
        if (self.debug) {
            if (typeof console == 'undefined') {
                alert('ERROR in picker implementation! Set self.debug to false in SimplePicker.');
                return false;
            }
            console.log("_create");
        }
        
        self.debugMessage = function (msg) {
            if (self.debug) {
                console.log('%cui.ap2Picker: %c' + msg, 'color: blue; background-color:#F2F7F9; font-weight:bold;', 'color: darkgreen; background-color:#F2F7F9;');
            }
        };

        $self.attr("autocomplete", "off"); // Turn off autocomplete in browser
        self.firstLoad = true;
        self.mouseOverPicker = false;
        self.keyDown = false;
        self.keyUpTimer = self.options.keyUpTimeOut;
        self.pickerPopupDisabled = false;
        self.pickerPopupVisible = false;
        self.pickerWrapper = $self.closest('.ap2picker');
        self.pickerValue = self.pickerWrapper.find('.ap2picker_value');

        if (!self.pickerWrapper.length) { alert("ERROR in picker implementation! The picker must be wrapped in a div with css-class-name 'ap2picker'") }
        if (!self.pickerValue.length) { alert("ERROR in picker implementation! The css-classname of the hidden input for picked value must equal 'ap2picker_value'") }

        // Css classes
        self.css_itemClass = ".listitem"; //.ap2-ui_input_simplepicker_item
        self.css_nodeOpenClass = ".node-open", // .ap2-ui_node_children_link_open
        self.css_nodeClosedClass = ".node-closed"; // .ap2-ui_node_children_link_closed
        self.css_nodeNeverOpendedClass = ".node-neveropened"; // .ap2-ui_node_children_link_never_opened
        self.css_childSubMenu = ".nodemenu"; //.ap2-ui_node_children_submenu

        // Create the popup div 
        self.pickerPopupDiv = $([
            '<div class="ap2picker-dropdown-wrapper ap2picker">',
                '<div class="ap2picker-dropdown-wrapper-inner clearfix">',
                    '<ul class="ap2picker-dropdown"></ul>',
                    '<div class="ap2picker-dropdown-closebutton"></div>',
                    self.options.filterSection ? self.options.filterSection : '',
                '</div>',
            '</div>'].join(''))
        .find(".ap2picker-dropdown-closebutton").click(function () {
            self._hidePickerPopup();
            self.pickerPopupDisabled = true; // Disables picker popup ones so that the popup dosent show up when calling $self.focus();
            $self.focus();
        }).end().appendTo(document.body);

        // If the window is resized - reposition the popup
        self._repositionPopup();

        // Cache the dropdown selector and store state on mouse-over/out
        self.pickerDropDown = self.pickerPopupDiv.find("ul.ap2picker-dropdown");
        self.pickerPopupDiv.hover(function () {
            self.mouseOverPicker = true;
        }, function () {
            self.mouseOverPicker = false;
            //console.log(document.activeElement);
            //console.log(self.mouseOverPicker);
            setTimeout(function () {
                if ($self.attr("id") !== $(document.activeElement).attr("id") && !self.mouseOverPicker) {
                    self._hidePickerPopup();
                }
            }, 50);
        });

        // Render top levels on focus or click?
        $self.bind("focusin click", function () {
            self.debugMessage("focusin event triggered");
            if (!self.pickerPopupVisible) {
                if (self.firstLoad) {
                    if (self.options.renderTopLevel) {
                        self._renderTopLevel();
                    } else {
                        self._displayResultMessage("Shared_JavaScript_TooShortSearchString");
                        self._showPickerPopup();
                    }
                } else {
                    self._showPickerPopup();
                }
            }
        }).focusout(function (event) {
            self.debugMessage("focusout event triggered");
            // In some browsers the input loses focus and triggers the hide function. Here is a workaround for that.
            if ((jQuery.browser.msie || jQuery.browser.webkit) && self.mouseOverPicker) {
                // When you try too click the dropdown scrollbar the input looses focus and trigger the _hidePickerPopup() function.
                // To prevent this behaviour this code sets focus to the input again
                setTimeout(function () {
                    $self.focus();
                }, 1);
            } else {
                // When the focusout event on the input is triggered, wait for 500 ms and check if the focus is still there
                setTimeout(function () {
                    if ($self.attr("id") !== $(document.activeElement).attr("id") && !self.mouseOverPicker) {
                        self._hidePickerPopup();
                    }
                }, 500);
            }
        }).keydown(function (event) {
            self.debugMessage("keydown event triggered"); 
            self.keyDown = true;
            if (self.pickerPopupVisible) { // Apply keyboard navigation
                self._initKeyboardNavigation(event);
            } else if (event.keyCode == 13) { // If enter key, search for value
                event.preventDefault();
                self._checkLengthBeforeAjaxCall();
            }
        }).bind("keyup paste", function (event) {
            self.debugMessage(event.type + " event triggered"); 
            self.keyDown = false;
            var arrKeyCodes = [9, 13, 40, 39, 38, 37, 27];
            if (jQuery.inArray(event.keyCode, arrKeyCodes) !== -1) { // If the key is not TAB, ESC, ENTER, UP/DOWN/LEFT/RIGHT KEY
                return false;
            } else {
                if ($self.val() === "") { // If empty string and not tab key - render top levels or display to short search string message
                    if (self.options.renderTopLevel) {
                        self._renderTopLevel();
                    } else {
                        self._checkLengthBeforeAjaxCall();
                    }
                } else { // If searchstring is OK, wait for "keyUpTimeOut" milliseconds after keyup before AJAX search is done
                    self._displayResultMessage("Shared_JavaScript_Searching");
                    var timerCallback = function () {
                        self._checkLengthBeforeAjaxCall();
                    };
                    clearTimeout(self.keyUpTimer);
                    self.keyUpTimer = setTimeout(timerCallback, self.options.keyUpTimeOut);
                }
            }
        });

        if (self.pickerWrapper.find(".ap2-ui_input_taxonpicker_language").length) {
            self._setTaxonLanguage();
        }
        if (self.pickerWrapper.find(".ap2-ui_input_taxonpicker_scope").length) { 

            self.pickerDropDownSearchScope = $('<div class="ap2picker-dropdown-searchscope clear clearfix"></div>').hide().insertAfter(self.pickerPopupDiv.find("ul.ap2picker-dropdown"));

            // Bind settings scope event
            $(self).data("SimplePicker.Settings.SearchScope", { Item: [] });
            $(self).bind("SimplePicker.Settings.SearchScope.Added", self._setSearchScope);

            self._setTaxonScope();
            if (Artportalen.IsUserLoggedIn()) {
                 self._setScopeCurrentRole();
            }
        }
    },
    // Optional, the picker renders the three on focus/firstload
    _renderTopLevel: function () {
        var self = this;
        self.debugMessage("_renderTopLevel"); 
        self._displayResultMessage("Shared_JavaScript_Loading");
        self._showPickerPopup();
        self.pickerDropDown.load(self.options.ajaxRenderTopLevelUrl, function (html) {
            if (html !== "") {
                $(this).html(html);
                self._initializeChildrenLinks();                
                self._applyNavigation();
                if (jQuery.isFunction(self.options.afterRenderCallback)) {
                    self.options.afterRenderCallback();
                }
            } else {
                self._displayResultMessage("Shared_JavaScript_NoSearchResult");
            }
        });
    },

    _setSearchScope: function (e) {
        ///	<summary>
        ///		1: Event handler for SimplePicker.Settings.SearchScope.Added event.
        ///     2: Bound object is $(self) done in _create().
        ///	</summary>
        ///	<param name="e" type="event object">
        ///		1: JSON object : { type: "SimplePicker.Settings.SearchScope.Added", dataObject: <simplePickerObjectReference>, scopeSetting: { id: <unique id for setting>, text: <text of setting, displayed in popup>, type: <setting type>} }
        ///     2: if the id in scopeSetting is -1 the setting type will be removed. User have choosen to search on all scopes.
        ///     3: only one scopeSetting per type can exist.
        ///     4: To display what type of scope setting we're seeing, scopeSetting.type is used and combined with Shared_JavaScript_SimplePickerSearchScope' + scopeSettings.Item[i].type.
        ///     5: Shared_JavaScript_SimplePickerSearchScopeSpeciesGroup is the label for SpeciesGroup, you need to create one for each scopeSetting.type.
        ///	</param>
        var self = this;
        self.debugMessage("_setSearchScope");

        var scopeSettings = $(e.dataObject).data("SimplePicker.Settings.SearchScope");
        if ($.inJSON(scopeSettings.Item, "type") != e.scopeSetting.type) {
            scopeSettings.Item[scopeSettings.Item.length] = e.scopeSetting;
        }

        var scopeSettingsHtml = [];
        if (scopeSettings) {
            if (scopeSettings.Item.length != 0) {
                scopeSettingsHtml[scopeSettingsHtml.length] = '<span class="UI-Icon-16 UI-Icon-16-SearchScope"></span>'
                scopeSettingsHtml[scopeSettingsHtml.length] = Artportalen.ResourceLabel("Shared_JavaScript_SimplePickerSearchScopeConstraint");
                scopeSettingsHtml[scopeSettingsHtml.length] = '';
                for (var i = 0; i < scopeSettings.Item.length; i++) {
                    if (scopeSettings.Item[i].type == e.scopeSetting.type) {
                        if (e.scopeSetting.id == -1) {
                            scopeSettings.Item.splice(i, 1);
                            continue;
                        }
                        else {
                            scopeSettings.Item[i] = e.scopeSetting;
                        }
                    }
                    scopeSettingsHtml[scopeSettingsHtml.length] = [' ', Artportalen.ResourceLabel('Shared_JavaScript_SimplePickerSearchScope' + scopeSettings.Item[i].type).toLowerCase(), ': <strong>', scopeSettings.Item[i].text, '</strong>'].join('');
                    if (i == scopeSettings.Item.length) { scopeSettingsHtml[scopeSettingsHtml.length] = ","; }
                }
                scopeSettingsHtml[scopeSettingsHtml.length] = ['<a href="#changescope" class="changescope">', Artportalen.ResourceLabel('Shared_JavaScript_SimplePickerSettings'), '</a>'].join('');
            }
        }

        if (scopeSettings.Item.length == 0) {
            scopeSettingsHtml = [];
        }
        self.pickerDropDownSearchScope.html(scopeSettingsHtml.join('')).toggle(!(scopeSettings.Item.length == 0));
        self.pickerDropDownSearchScope.find("a.changescope").unbind(".changescope").bind("click.changescope", function (event) {
            event.preventDefault();
            self._hidePickerPopup();
            self.pickerWrapper.find("a.show-settings-scope").click();
        });
        $(e.dataObject).data("SimplePicker.Settings.SearchScope", scopeSettings);
    },
    // Save values from taxon settings
    _setTaxonLanguage: function () {
        var self = this;
        self.debugMessage("_setTaxonLanguage"); 
        // Show language settings
        self.pickerWrapper.find("a.show-settings-language").click(function (e) {
            e.preventDefault();
            self.pickerWrapper.find(".ap2-ui-form-taxonpicker-settings-language").toggle().find("select").focus();
            self.pickerWrapper.find("div.ap2-ui-form-taxonpicker-settings-language-close").unbind().click(function (e) {
                $(this).unbind().closest(".ap2-ui-form-taxonpicker-settings-language").hide();
            });
        });
        // Implement saving of language settings
        var pickerWrapperTaxonLanguage = self.pickerWrapper.find(".ap2-ui_input_taxonpicker_language");
        pickerWrapperTaxonLanguage.bind("change blur", function (event) {
            self.debugMessage("_setTaxonLanguage event change/blur"); 
            var _me = $(this);
            if (_me.find(":selected").text() === "") {
                return false;
            } else {
                _me.closest(".ap2-ui-form-taxonpicker-settingsrow").find("a.show-settings-language").text(_me.find(":selected").text()).focus();
                _me.closest(".ap2-ui-form-taxonpicker-settings-language").hide();
                var SpeciesNamesLanguageId = _me.val();
                // Save changes
                if (event.type === 'change') {
                    Artportalen.ajaxPost(Artportalen_ApplicationPath + '/User/SetSpeciesNamesLanguage/', { speciesNamesLanguageId: SpeciesNamesLanguageId, 'uniq_param': (new Date()).getTime() }, function (items, code, xht) { });
                }
            }
        });
    },
    _setTaxonScope: function () {
        ///	<summary>
        ///		1: Enables the "select taxon scope" dropdown below the picker.
        ///     2: Depends on HTML: <a class="show-settings-scope"/> below this.pickerWrapper and .ap2-ui-form-taxonpicker-* classes.
        ///     3: Triggers the "SimplePicker.Settings.SearchScope.Added" event with type "SpeciesGroup" to tell wich taxon scope that has been choosen.
        ///	</summary>
        var self = this;
        self.debugMessage("_setTaxonScope"); 
        self.pickerWrapper.find("a.show-settings-scope").click(function (e) {
            e.preventDefault();
            self.pickerWrapper.find(".ap2-ui-form-taxonpicker-settings-scope").toggle().find("select").focus();
            self.pickerWrapper.find("div.ap2-ui-form-taxonpicker-settings-scope-close").unbind().click(function (e) {
                $(this).unbind().closest(".ap2-ui-form-taxonpicker-settings-scope").hide();
            });
        });

        var pickerWrapperTaxonScope = self.pickerWrapper.find(".ap2-ui_input_taxonpicker_scope");
        pickerWrapperTaxonScope.bind("change blur", function (event) {
            self.debugMessage("_setTaxonScope event change/blur"); 
            var _me = $(this);
            _me.closest(".ap2-ui-form-taxonpicker-settingsrow").find("a.show-settings-scope").text(_me.find(":selected").text()).focus();
            _me.closest(".ap2-ui-form-taxonpicker-settings-scope").hide();
            var speciesGroupId = _me.val();
            // Save changes
            if (event.type === 'change') {
                Artportalen.ajaxPost(Artportalen_ApplicationPath + '/User/SetSpeciesGroup/', { speciesGroupId: speciesGroupId }, function (items, code, xht) {
                    $(self).trigger({ type: "SimplePicker.Settings.SearchScope.Added", dataObject: self, scopeSetting: { id: speciesGroupId, text: _me.find(":selected").text(), type: "SpeciesGroup"} });
                    if (self.element.val() !== "") { self._checkLengthBeforeAjaxCall(); }
                });
            }

        });

        if (!self.pickerWrapper.hasClass("ap2picker-searchAllSpecies")) {
            // If user isn't authenticated, we need to read the speciesgroup from a cookie instead.
            var anonymousSpeciesGroup = $.cookie("SpeciesGroup");
            if (anonymousSpeciesGroup != null && anonymousSpeciesGroup != "") {
                self.debugMessage("_setTaxonScope, Species group read from cookie.");
                pickerWrapperTaxonScope.find("option[value='" + anonymousSpeciesGroup + "']").prop("selected", true);
            }
            pickerWrapperTaxonScope.change();
        }
    },
    _setScopeCurrentRole: function () {
        ///	<summary>
        ///		1: Fetches the current role of the current user.
        ///     2: Triggers "SimplePicker.Settings.SearchScope.Added" event with type "CurrentRole" to set current role to searchScope settings.
        ///     3: Assumes that Role id 2 is the role id for "private person", a role that doesn't affect the search. TODO: Make this not-hardcoded.
        ///	</summary>
        var self = this;
        self.debugMessage("_setScopeCurrentRole");
        Artportalen.ajaxPost(Artportalen_ApplicationPath + '/User/CurrentRoleWithTaxonAuthority', null, function (data, code, xht) {
            if (data.Id == 2) data.Id = -1;
            $(self).trigger({ type: "SimplePicker.Settings.SearchScope.Added", dataObject: self, scopeSetting: { id: data.Id, text: data.Name, type: "CurrentRole"} });
        });
    },

    // Check the length of user input before calling the ajax function
    _checkLengthBeforeAjaxCall: function (event) {
        var self = this;
        self.debugMessage("_checkLengthBeforeAjaxCall");
        if (self.element.val() === "") { // Check for empty string again. It can have become empty again after timeout
            return;
        } else if (self.element.val().length < self.options.minimumCharacters) {
            self._displayResultMessage("Shared_JavaScript_TooShortSearchString");
            self._showPickerPopup();
        } else {
            self._performAjaxCall();
        }
    },

    _displayResultMessage: function (resourceLabelName) {
        var self = this;
        self.debugMessage("_displayResultMessage"); 
        var spanClass = (resourceLabelName.match(/[Ll]oading/) || resourceLabelName.match(/[Ss]earching/)) ? "UI-Icon-16-Loading" : "UI-Icon-16-NoInfo";
        if (self.pickerDropDown.find(".UI-Icon-16-Loading").length && spanClass == "UI-Icon-16-Loading") {
        } else {
            self.pickerDropDown.html(['<li><span class="UI-Icon-16 ', spanClass, '"></span><strong>', Artportalen.ResourceLabel(resourceLabelName), '</strong></li>'].join(''));
        }
    },
    // Do the AJAX call
    _performAjaxCall: function () {
        var self = this;
        var $self = this.element;
        self.debugMessage("_performAjaxCall"); 
        self._displayResultMessage("Shared_JavaScript_Loading");
        self._showPickerPopup();
        var searchAllSpecies = (self.pickerWrapper.hasClass("ap2picker-searchAllSpecies")) ? "&searchAllSpecies=true" : "";        
        var searchSpeciesGroup = (self.pickerWrapper.find('.ap2-ui-taxon-picker-speciesgroupid')) ? "&speciesGroup=" + self.pickerWrapper.find('.ap2-ui-taxon-picker-speciesgroupid').val() : "";
        var nocache = self.options.noCacheUrl ? '&cache=' + new Date().getTime() : '';
        self.pickerDropDown.load(this.options.ajaxSearchUrl + '?search=' + encodeURIComponent($self.val()) + '&returnformat=' + self.options.ajaxReturnFormat + searchAllSpecies + searchSpeciesGroup + nocache, function (html) {
            if (html !== "") {
                $(this).html(html);
                self._initializeChildrenLinks();
                self._applyNavigation();
                if (jQuery.isFunction(self.options.afterRenderCallback)) {
                    self.options.afterRenderCallback();
                }
            } else {
                self._displayResultMessage("Shared_JavaScript_NoSearchResult");
            }
        });
        return true;
    },
    // Show popup div and calculate it's position under the input
    _showPickerPopup: function () {
        var self = this;
        self.debugMessage("_showPickerPopup");
        if (self.pickerPopupDisabled || !self.element.is(":visible")) { // The picker popup can be temporary disabled (when the users hides/closes the pickerPopup)
            self.pickerPopupDisabled = false;
            return false;
        }
        var $selfParent = self.element.parent();
        self.pickerPopupDiv.css({
            left: $selfParent.offset().left - 5,
            top: $selfParent.offset().top + $selfParent.outerHeight(),
            width: $selfParent.outerWidth() + 10
        }).show();
        // If there is no selected item the keyboard navigation fails - set the first item to selected
        if (self.pickerDropDown.find(self.css_itemClass).length) {
            if (!self.pickerDropDown.find(".item_selected").length) {
                self.pickerDropDown.find(self.css_itemClass + ":first").find("a:first").addClass("item_selected");
            }
        }
        self.firstLoad = false;
        self.pickerPopupVisible = true;
    },
    // When window is resized and the popup is visible - recalculate the position
    _repositionPopup: function () {
        var self = this;
        var $self = this.element;
        var $selfParent = self.element.parent();
        var adjustTimer;
        $(window).smartresize(function (event) {
            clearTimeout(adjustTimer);
            if (self.pickerPopupVisible) {
                adjustTimer = setTimeout(function () {
                    self.pickerPopupDiv.stop().animate({
                        left: $selfParent.offset().left - 5,
                        top: $selfParent.offset().top + $selfParent.outerHeight()
                    }, 200, 'swing');
                }, 100);
            }
        });
    },
    // Hide the popup div
    _hidePickerPopup: function () {
        this.debugMessage("_hidePickerPopup");
        if (this.pickerPopupVisible) {
            this.pickerPopupDiv.hide();
            this.pickerPopupVisible = false;
            this.mouseOverPicker = false;
            this.element.blur();
        }
    },
    // Keyboard navigation - handles different behaviour
    _initKeyboardNavigation: function (event) {
        var self = this;
        var $self = this.element;
        self.debugMessage("_initKeyboardNavigation"); 

        var $selectedItem, $nextItem, $previousItem, $link;

        // Store scroll and height of the dropdown
        // offsetHeight and scrollTop is core JavaScript, objectName[0] makes a core JS-element out of a jQeury-object
        var topScroll = self.pickerDropDown[0].scrollTop;
        var offsetHeight = self.pickerDropDown[0].offsetHeight;

        // Array with all keyCodes used for navigation in the picker
        var arrKeyCodes = [13, 40, 39, 38, 37];

        // Selected item used for navigation
        if (jQuery.inArray(event.keyCode, arrKeyCodes) != -1) {
            $selectedItem = self.pickerDropDown.find('.item_selected:first');
        }

        // Navigation with keyboard
        switch (event.keyCode) {
            // Enter key                                                                                                  
            case 13:
                event.preventDefault();
                self.pickerDropDown.find('.item_selected:first').click();
                return false;
                break;
            // Esc key                                                                                                  
            case 27:
                self._hidePickerPopup();
                self.pickerPopupDisabled = true; // Disables picker popup one time so that the popup dosen't show up when calling $self.focus();
                $self.focus();
                return false;
                break;
            // Arrow down key                                                                                                  
            case 40:
                $nextItem = $selectedItem.closest("li").nextAll(self.css_itemClass + ':first').find("a:first");
                // if a list of subitems exists and it is opened - step into the first item in the subtree
                if ($selectedItem.closest("li").find(self.css_childSubMenu).length !== 0 && $selectedItem.closest("li").find("a:first").find(self.css_nodeOpenClass + ":first").length !== 0) {
                    $nextItem = $selectedItem.closest("li").find(self.css_childSubMenu + ":first").find(self.css_itemClass + ':first').find('a:first');
                }
                // reached the end of items - step up to next node if it exists 
                if ($nextItem.length === 0 && $selectedItem.closest(self.css_childSubMenu).length !== 0) {
                    $nextItem = $selectedItem.closest(self.css_childSubMenu).closest("li").nextAll(self.css_itemClass + ':first').find("a:first");
                }
                if ($nextItem.length !== 0) {
                    $selectedItem.removeClass('item_selected');
                    $nextItem.addClass('item_selected');
                    if (($nextItem[0].offsetTop + ($nextItem[0].offsetHeight * 2)) > (topScroll + self.pickerDropDown[0].offsetHeight)) {
                        self.pickerDropDown[0].scrollTop = topScroll + ($nextItem[0].offsetHeight * 2); //topScroll + $nextItem[0].offsetHeight;
                    } else if ($nextItem[0].offsetTop < topScroll) {
                        self.pickerDropDown[0].scrollTop = $nextItem[0].offsetTop - $nextItem[0].offsetHeight;
                    }
                }
                return false;
                break;
            // Arrow up key                                                                                                  
            case 38:
                $previousItem = $selectedItem.closest("li").prev(self.css_itemClass).find("a:first");
                // reached the end of previous item - step up to next node if it exists 
                if ($previousItem.length === 0 && $selectedItem.closest(self.css_childSubMenu).length !== 0) {
                    $previousItem = $selectedItem.closest(self.css_childSubMenu).closest(self.css_itemClass).find('a:first');
                }
                if ($previousItem.length !== 0) {
                    $selectedItem.removeClass('item_selected');
                    $previousItem.addClass('item_selected');
                    if ($previousItem[0].offsetTop < topScroll) {
                        self.pickerDropDown[0].scrollTop = $previousItem[0].offsetTop - $previousItem[0].offsetHeight;
                    }
                }
                return false;
                break;
            // Arrow left key                                                                                                  
            case 37:
                $link = $selectedItem.find(self.css_nodeOpenClass + ':first');
                // This selected item is an opened folder - close it and jump up the three
                if ($link.length !== 0) {
                    $selectedItem.removeClass("item_selected");
                    $link.click();
                    $link = $link.closest(self.css_itemClass).find('a:first').addClass('item_selected');
                    // step up one node if it is a sub item
                } else if ($selectedItem.closest(self.css_childSubMenu).length !== 0) {
                    $selectedItem.removeClass('item_selected');
                    $link = $selectedItem.closest(self.css_childSubMenu).closest("li").find(self.css_nodeOpenClass + ':first');
                    $selectedItem = $link.closest(self.css_itemClass).find('a:first').addClass('item_selected');
                    $link.click();
                } else {
                    return false;
                }
                if ($selectedItem[0].offsetTop < topScroll) {
                    self.pickerDropDown[0].scrollTop = $selectedItem[0].offsetTop - $selectedItem[0].offsetHeight;
                }
                return false;
                break;
            // Arrow right key                                                                                                  
            case 39:
                $link = $selectedItem.find(self.css_nodeClosedClass);
                // if an open subthree exists - step to first item in that three
                if ($selectedItem.closest("li").find(self.css_childSubMenu).length !== 0 && $selectedItem.closest("li").find(self.css_nodeOpenClass).length !== 0) {
                    $nextItem = $selectedItem.closest("li").find(self.css_childSubMenu + ":first").find(self.css_itemClass + ':first').find('a:first');
                    if ($nextItem.length) {
                        $selectedItem.removeClass('item_selected');
                        $nextItem.addClass('item_selected');
                    }
                }
                if ($link.hasClass(self.css_nodeClosedClass.replace(".", ""))) {
                    $link.click();
                    $nextItem = $link.closest(self.css_itemClass).find(self.css_childSubMenu + ':first').find('a:first');
                    if ($nextItem.length) {
                        $selectedItem.removeClass('item_selected');
                        $nextItem.addClass('item_selected');
                    }
                    if (($link[0].offsetTop + ($link[0].offsetHeight * 2)) > (self.pickerDropDown[0].scrollTop + self.pickerDropDown[0].offsetHeight)) {
                        self.pickerDropDown[0].scrollTop = self.pickerDropDown[0].scrollTop + ($link[0].offsetHeight * 2); //topScroll + $nextItem[0].offsetHeight;
                    }
                }
                return false;
                break;
        }
        return true;
    },
    _applyNavigation: function () {
        var self = this;
        var $self = this.element;
        self.debugMessage("_applyNavigation");

        // Set focus to first item
        self.pickerPopupDiv.find(self.css_itemClass + ":first").find("a:first").addClass('item_selected');

        // Destroy previously bound events and add one click event to the entire dropdown
        self.pickerDropDown.unbind().click(function (e) {

            // Stop the event from bubbling up the DOM, important if it is an item in the submenu that triggers the event
            e.stopPropagation();
            e.preventDefault();

            // Check which element that triggered the click - stop all click outside known nodes
            var itemId, itemName, itemJSON, $listItem, _target = $(e.target);
            if (_target.is(".item") || _target.is(".itemname") || _target.is(".node-leaf") || _target.is("em") || e.target.nodeName == "A") {
                $listItem = _target.closest('.listitem');
            } else if (_target.is(".listitem")) {
                $listItem = _target;
            } else {
                $self.focus();
                return false;
            }

            if ($listItem.find('a:first').hasClass("disabled")) {
                $listItem.find('a:first').effect("highlight", { color: "#FF7000" }, 500, function() {
                });
                $listItem.find(".node-neveropened, .node-closed, .node-open").click();
                return false;
            }

            self.pickerDropDown.find(".item_selected").removeClass('item_selected');

            itemId = $listItem.find('a:first').addClass('item_selected').attr('data-id');
            itemName = $listItem.find(".itemname:first").text();
            itemJSON = $listItem.find(".itemjson:first").text();

            // Set value and trigger a change event
            self.pickerValue.val(itemId).change();
            self.mouseOverPicker = false;
            self._hidePickerPopup();
            var arrSelectedValues = [itemId, itemName, itemJSON];
            $self.triggerHandler("pickerItemSelected", [arrSelectedValues]);
            return false;
        });

        var items = self.pickerPopupDiv.find(self.css_itemClass);
        $self.triggerHandler("SimplePicker_Navigation_Applied", [{ items: items}]);
    },

    // Initalize children links
    _initializeChildrenLinks: function () {
        var self = this;
        var $self = this.element;
        self.debugMessage("_initializeChildrenLinks"); 
        self.pickerPopupDiv.find(self.css_nodeNeverOpendedClass).unbind().click(function (event) {
            event.preventDefault();
            var link = this;
            var nocache = self.options.noCacheUrl ? '&cache=' + new Date().getTime() : '';
            var itemId = link.id.split('_')[1];
            $childrenContainer = $(this).closest("li").find(".nodemenu:first");
            if ($childrenContainer.length !== 0) {
                $childrenContainer.html(['<span id="ap2-ui-loadingmessage-inline">',
                    Artportalen.ResourceLabel("Shared_JavaScript_Loading"),
                '</span>'].join(''))
                .show()
                .load(self.options.ajaxChildrenUrl + '?parentId=' + itemId + nocache, function (html) {
                    $childrenContainer.html(html);
                    self._setMinimizeLink(link, $childrenContainer);
                    self._initializeChildrenLinks();
                    if (jQuery.isFunction(self.options.afterRenderCallback)) {
                        self.options.afterRenderCallback();
                    }
                    var $focusItem = $childrenContainer.find("a:first");
                    if ($focusItem.length) {
                        self.pickerPopupDiv.find('.item_selected').removeClass('item_selected');
                        $focusItem.addClass("item_selected");
                        self.pickerPopupDiv[0].scrollTop = $focusItem[0].offsetTop + $focusItem[0].offsetHeight;
                    }
                    $self.focus();
                });
            }
            return false;
        });
    },
    _setMinimizeLink: function (link, $childrenContainer) {
        var self = this;
        self.debugMessage("_setMinimizeLink"); 
        $(link).html("-").removeClass().addClass(self.css_nodeOpenClass.replace(".", "")).unbind().click(function (event) {
            event.preventDefault();
            $childrenContainer.hide();
            self._setMaximizeLink(this, $childrenContainer);
            self.element.focus();
            return false;
        });
    },
    _setMaximizeLink: function (link, $childrenContainer) {
        var self = this;
        self.debugMessage("_setMaximizeLink");
        $(link).html("+").removeClass().addClass(self.css_nodeClosedClass.replace(".", "")).unbind().click(function (event) {
            event.preventDefault();
            $childrenContainer.show();
            self._setMinimizeLink(this, $childrenContainer);
            self.element.focus();
            return false;
        });
    }
});

/*

$.fn.simplepicker = function (actionPath) {
    return this.each(function () {
        if (this.tagName == 'INPUT') {
            var inputBox = this; inputBox.setAttribute("autocomplete", "off");
            var newValue = this.value;
            var firstLoad = true;
            var popupOpen = false;
            var settingsPopupOpen = false;

            var simplePickerWrapper = $(inputBox).closest('.ap2-ui-simplepicker-wrapper');
            var valueBox = $(inputBox).closest('.ap2-ui-simplepicker-wrapper').find('.ap2-ui_input_simplepicker_value');
            var searchButton = $(inputBox).closest('.ap2-ui-simplepicker-wrapper').find('a.ap2-ui_input_simplepicker_search_button');

            var selectedItemLabel = $(inputBox).closest('.ap2-ui-picker-wrapper').find('.ap2-ui-simplepicker-selected-item-label');

            var inputPosition = $(inputBox).parent().offset();
            var popupList = $('<div id="' + $(inputBox).attr("id") + '_dropdown" class="ap2-ui_input_simplepicker_dropdown_wrapper"><div class="ap2-ui_input_simplepicker_dropdown_wrapper_inner clearfix"><ul class="ap2-ui_input_simplepicker_dropdown"></ul><div class="ap2-ui_input_simplepicker_dropdown_close"></div></div></div>')
                .css('left', inputPosition.left - 5)
                .css('top', inputPosition.top + $(inputBox).parent().outerHeight())
                .css('width', $(inputBox).parent().outerWidth() + 10)
                .find(".ap2-ui_input_simplepicker_dropdown_close").click(function () {
                    $HidePopup();
                    $(".ap2-ui-simplepicker-wrapper").show();
                    $(valueBox).val(""); // clear selected item
                    $(inputBox).focus();
                }).end();

            // Append both popup containers to the document.body - prevent some positioning problem when the parent is set to "position:relative"
            popupList.appendTo(document.body);
            //settingsPopup.detach().appendTo(document.body); // move the popup outside
        }

        $ShowPopup = function () {
            $(popupList)
                .css('left', $(inputBox).parent().offset().left - 5)
                .css('top', $(inputBox).parent().offset().top + $(inputBox).parent().outerHeight())
                .css('width', $(inputBox).parent().parent().outerWidth() + 10) // added 2010-08-05 -test
                .show();
        }

        $HidePopup = function () {
            $(popupList).hide();
            popupOpen = false;
            firstLoad = true;
        }

        $ApplyNavigation = function () {
            // Set focus to the first item
            $(popupList).find(".ap2-ui_input_simplepicker_item:first").find("a").addClass('item_selected').focus();
            // Destroy previously bound events and add a click listener
            $(popupList).unbind().click(function (e) {
                e.stopPropagation();
                e.preventDefault();
                // Stop the event from bubbling up the DOM-three, important if it is an item in the submenu that triggers the event
                var itemId, _target = $(e.target);
                if (_target.is(".itemname")) {
                    itemId = _target.closest("a").attr("rel");
                    itemName = _target.closest('.ap2-ui_node_item').find(".itemname:first").text();
                    //alert("itemName: " + itemId + "/" + itemName + "/" + speciesGroupID + "   |   target-node:" + e.target.nodeName + "/class" + $(e.target).attr("class"));
                } else if (_target.is(".ap2-ui_node_item")) {
                    itemId = _target.find("a").attr("rel");
                    itemName = _target.find(".itemname:first").text();
                    //alert("ap2-ui_taxon_item: " + itemId + "/" + itemName + "/" + speciesGroupID + "   |   target-node:" + e.target.nodeName + "/class" + $(e.target).attr("class"));
                } else if (e.target.nodeName == "A") {
                    itemId = _target.attr("rel");
                    itemName = _target.find(".itemname:first").text();
                } else {
                    // Stop all click outside node
                    return false;
                }

                $(valueBox).val(itemId);
                $(valueBox).change();
                $(inputBox).val(itemName);
                if (selectedItemLabel.length !== 0) {
                    selectedItemLabel.find("h3").text(jQuery.trim(itemName));
                    selectedItemLabel.find(".close-this-div").unbind().click(function (event) {
                        event.preventDefault();
                        selectedItemLabel.hide();
                        $(valueBox).closest(".ap2-ui-simplepicker-wrapper").show();
                        $(valueBox).val(""); // clear selected item
                        $(inputBox).focus();
                    });
                    $(valueBox).closest(".ap2-ui-simplepicker-wrapper").hide();
                    $(inputBox).val("");
                    selectedItemLabel.show();
                    selectedItemLabel.find(".close-this-div").focus();
                }
                $HidePopup();
            });
            popupOpen = true;
            $(inputBox).focus();
        };

        $InitializeChildrenLink = function () {
            $(popupList).find('.ap2-ui_node_children_link_never_opened').unbind().click(function (event) {
                var link = this;
                var itemId = this.id.split('_')[1];
                var subMenuGuid = this.id.split('_')[2];
                var childrenContainer = $('#node_' + itemId + '_' + subMenuGuid + '_ChildrenContainer');

                $(childrenContainer).html('<span id="ap2-ui-loadingmessage-inline">' + Artportalen.ResourceLabel("Shared_JavaScript_Loading") + '</span>');
                $(childrenContainer).show();

                var url = Artportalen_ApplicationPath + '/SimplePicker/RenderBiotopeChildren?parentId=' + itemId;
                $(childrenContainer).load(url, function (html) {
                    $(childrenContainer).html(html);
                    $Artportalen_SimplePicker_SetMinimizeLink(link, childrenContainer);
                    $InitializeChildrenLink();
                    $ApplyNavigation();

                    $(popupList).find('.item_selected').removeClass('item_selected');
                    $(childrenContainer).find("a:first").addClass("item_selected").focus();
                    $(inputBox).focus();
                });

                event.preventDefault();
                return false;
            });
        };

        $(inputBox).keydown(function (event) {
            if (popupOpen) {

                // Declare jQuery elements used for navigation
                var $selectedItem, $nextItem, $previousItem, $link;

                // Array with all used keyCodes for the picker
                var arrKeyCodes = [13, 40, 39, 38, 37];

                // Hide the popup if it is an unused keyCode
                // The user must hit the enter key to populate the popupList again
                if (jQuery.inArray(event.keyCode, arrKeyCodes) == -1) {
                    $HidePopup();
                    $(inputBox).focus();
                }

                // Tab or Enter key (no tab - event.keyCode == 9 || )
                if (event.keyCode == 13) {
                    event.preventDefault();
                    $selectedItem = $(popupList).find('.item_selected:first');
                    $selectedItem.click();
                }

                // Arrow down key
                if (event.keyCode == 40) {
                    $selectedItem = $(popupList).find('.item_selected');
                    $nextItem = $selectedItem.closest("li").nextAll('.ap2-ui_input_simplepicker_item:first').find("a:first");
                    // if a list of subitems exists and it is opened - step into the first item in the subtree
                    if ($selectedItem.closest("li").find(".ap2-ui_node_children_submenu").length !== 0 && $selectedItem.closest("li").find(".ap2-ui_node_children_link_open:first").length !== 0) {
                        $nextItem = $selectedItem.closest("li").find(".ap2-ui_node_children_submenu:first").find('.ap2-ui_input_simplepicker_item:first').find('a:first');
                    }
                    // reached the end of items - step up to next node if it exists 
                    if ($nextItem.length === 0 && $selectedItem.closest(".ap2-ui_node_children_submenu").length !== 0) {
                        $nextItem = $selectedItem.closest(".ap2-ui_node_children_submenu").closest("li").nextAll('.ap2-ui_input_simplepicker_item:first').find("a:first");
                    }
                    if ($nextItem.length !== 0) {
                        $selectedItem.removeClass('item_selected');
                        $nextItem.focus().addClass('item_selected');
                        $(inputBox).focus();
                    }
                }

                // Arrow up key
                if (event.keyCode == 38) {
                    $selectedItem = $(popupList).find('.item_selected');
                    $previousItem = $selectedItem.closest("li").prev('.ap2-ui_input_simplepicker_item').find("a:first");
                    // reached the end of previous item - step up to next node if it exists 
                    if ($previousItem.length === 0 && $selectedItem.closest(".ap2-ui_node_children_submenu").length !== 0) {
                        $previousItem = $selectedItem.closest(".ap2-ui_node_children_submenu").closest('.ap2-ui_input_simplepicker_item').find('a:first');
                    }
                    if ($previousItem.length !== 0) {
                        $selectedItem.removeClass('item_selected');
                        $previousItem.focus().addClass('item_selected');
                        $(inputBox).focus();
                    }
                }

                // Arrow left key
                if (event.keyCode == 37) {
                    $selectedItem = $(popupList).find('.item_selected');
                    $link = $selectedItem.find('.ap2-ui_node_children_link_open:first');
                    // step up one node if it is a sub item
                    if ($selectedItem.closest(".ap2-ui_node_children_submenu").length !== 0) {
                        $selectedItem.removeClass('item_selected');
                        $link = $selectedItem.closest('.ap2-ui_node_children_submenu').closest("li").find('.ap2-ui_node_children_link_open:first');
                    }
                    if ($link.hasClass('ap2-ui_node_children_link_open')) {
                        $link.click();
                        $link.closest('.ap2-ui_input_simplepicker_item').find('a:first').focus().addClass('item_selected');
                        $(inputBox).focus();
                    }
                }

                // Arrow right key
                if (event.keyCode == 39) {
                    $selectedItem = $(popupList).find('.item_selected');
                    $link = $selectedItem.find('.ap2-ui_node_children_link_closed');
                    // if an open subthree exists - step to first item in that three
                    if ($selectedItem.closest("li").find(".ap2-ui_node_children_submenu").length !== 0 && $selectedItem.closest("li").find(".ap2-ui_node_children_link_open").length !== 0) {
                        $selectedItem.removeClass('item_selected');
                        $selectedItem.closest("li").find(".ap2-ui_node_children_submenu:first").find('.ap2-ui_input_simplepicker_item:first').find('a:first').addClass('item_selected').focus();
                        $(inputBox).focus();
                    }
                    if ($link.hasClass('ap2-ui_node_children_link_closed')) {
                        $link.click();
                        $selectedItem.removeClass('item_selected');
                        $link.closest('.ap2-ui_input_simplepicker_item').find('.ap2-ui_node_children_submenu:first').find('a:first').focus().addClass('item_selected');
                        $(inputBox).focus();
                    }
                }

            }
            else {
                // Enter key
                if (event.keyCode == 13) {
                    event.preventDefault();
                    if ($(inputBox).val().length < 3) {
                        $(popupList).find(".ap2-ui_input_simplepicker_dropdown").html('<li><span class="ap2-ui-noresult-inline">' + Artportalen.ResourceLabel("Shared_JavaScript_TooShortSearchString") + '</span></li>');
                        $ShowPopup();
                    } else {
                        $(searchButton).click();
                    }
                }
            }
        });

        $(searchButton).click(function (event) {
            event.preventDefault();
            newValue = $(inputBox).val();
            //alert(escape(newValue));
            if (newValue === '') {
                $(inputBox).parent().find('.ap2-ui_input_autocomplete-value').val('-1');
                return true;
            }
            $(popupList).find(".ap2-ui_input_simplepicker_dropdown").html('<li><span id="ap2-ui-loadingmessage-inline">' + Artportalen.ResourceLabel("Shared_JavaScript_Loading") + '</span></li>');

            //$(settingsPopup).hide();
            $ShowPopup();
            $(popupList).find(".ap2-ui_input_simplepicker_dropdown").load(actionPath + '?searchText=' + encodeURIComponent(newValue), function (html) {
                if (html !== "") {
                    $(popupList).find(".ap2-ui_input_simplepicker_dropdown").html(html);
                    $InitializeChildrenLink();
                    $ApplyNavigation();
                } else {
                    $(popupList).find(".ap2-ui_input_simplepicker_dropdown").html('<li><span class="ap2-ui-noresult-inline">' + Artportalen.ResourceLabel("Shared_JavaScript_NoSearchResult") + '</span></li>');
                }
            });


            return true;
        });
    });
};


$Artportalen_SimplePicker_SetMinimizeLink = function (link, childrenContainer) {
    $(link)
        .html("-")
        .removeClass()
        .addClass("ap2-ui_node_children_link_open")
        .unbind()
        .click(function (event) {
            childrenContainer.hide();
            $Artportalen_SimplePicker_SetMaximizeLink(this, childrenContainer);
            event.preventDefault();
            return false;
        });
};

$Artportalen_SimplePicker_SetMaximizeLink = function (link, childrenContainer) {
    $(link)
        .html("+")
        .removeClass()
        .addClass("ap2-ui_node_children_link_closed")
        .unbind()
        .click(function (event) {
            childrenContainer.show();
            $Artportalen_SimplePicker_SetMinimizeLink(this, childrenContainer);
            event.preventDefault();
            return false;
        });
};

$Artportalen_SimplePicker_InitializeChildrenLink = function () {
    $('.ap2-ui_node_children_link_never_opened').unbind().click(function (event) {
        var link = this;
        var itemId = this.id.split('_')[1];
        var subMenuGuid = this.id.split('_')[2];
        var childrenContainer = $('#node_' + itemId + '_' + subMenuGuid + '_ChildrenContainer');

        $(childrenContainer).html('<span id="ap2-ui-loadingmessage-inline">' + Artportalen.ResourceLabel("Shared_JavaScript_Loading") + '</span>');
        $(childrenContainer).show();

        var url = Artportalen_ApplicationPath + '/SimplePicker/RenderBiotopeChildren?parentId=' + itemId;
        $(childrenContainer).load(url, function (html) {
            $(childrenContainer).html(html);
            $Artportalen_SimplePicker_SetMinimizeLink(link, childrenContainer);
            $Artportalen_SimplePicker_InitializeChildrenLink();
        });
        event.preventDefault();
        return false;
    });
};


*/
;
(function ($) {
    $.fn.AP2YearPicker = function (options) {
        // Build main options before element iteration
        var settings = $.extend({}, $.fn.AP2YearPicker.defaults, options);

        return this.each(function () {
            $.AP2YearPicker(this, settings);
        });
    };

    $.AP2YearPicker = function (elm, settings) {
        var e = $(elm)[0];
        if (settings.resetPicker) {
            settings.resetPicker = false;
            return (e.AP2YearPicker = new jQuery._AP2YearPicker(e, settings));
        } else {
            return e.AP2YearPicker || (e.AP2YearPicker = new jQuery._AP2YearPicker(e, settings));
        }
    };

    $._AP2YearPicker = function (elm, settings) {

        var ypOver = false;
        var keyDown = false;

        $(elm).attr('autocomplete', 'OFF'); // Disable browser autocomplete

        /* dropdown container and list */
        var $ypDropDown = $('<div class="ap2-ui-yearpicker"></div>');
        var $ypYearList = $('<ul></ul>');

        // Remove existing yearpicker
        if ($(elm).attr("id") !== undefined) {
            if ($("." + $(elm).attr("id").replace("#", "")).length) {
                $("." + $(elm).attr("id").replace("#", "")).remove();
            }
            $ypDropDown.addClass($(elm).attr("id").replace("#", ""));
        }


        /* create list of years from startYear to todays year */
        var startYear = (typeof (settings.startYear) === 'undefined') ? 1900 : parseInt(settings.startYear);
        var endYear = (typeof (settings.endYear) === 'undefined') ? new Date().getFullYear() : parseInt(settings.endYear);
        var yearList = [];

        for (var i = endYear; i >= startYear; i--) {
            yearList.push("<li>");
            yearList.push(i);
            yearList.push("</li>");
        }
        $ypYearList.append(yearList.join(''));

        /* append and position the drop down */
        if (typeof settings.startValue !== 'undefined') {
            $('<li class="startvalue">' + settings.startValue + '</li>').prependTo($ypYearList);
        }
        $ypDropDown.append($ypYearList);
        var elmOffset = $(elm).offset();
        $ypDropDown.appendTo('body').css({ 'top': elmOffset.top + $(elm).outerHeight(), 'left': elmOffset.left }).hide();

        $ypDropDown.mouseover(function () {
            ypOver = true;
        }).mouseout(function () {
            ypOver = false;
        });

        $("li", $ypYearList).mouseover(function () {
            if (!keyDown) {
                $("li.selected", $ypDropDown).removeClass("selected");
                $(this).addClass("selected");
            }
        }).mousedown(function () {
            ypOver = true;
        }).click(function () {
            setYearVal(elm, this, $ypDropDown, settings);
            ypOver = false;
        });

        var showPicker = function () {
            if ($ypDropDown.is(":visible")) {
                return false;
            }
            $("li", $ypDropDown).removeClass("selected");

            // Calculate position
            var elmOffset = $(elm).offset();
            $ypDropDown.css({ 'top': elmOffset.top + $(elm).outerHeight() + 2, 'left': elmOffset.left });

            // Show picker. This has to be done before scrollTop is set since that
            // can't be done on hidden elements.
            $ypDropDown.show();

            // Try to find a year in the list that matches the entered year.
            if ($(elm).val()) {
                var $matchedYear = $("li:contains(" + $(elm).val() + ")", $ypDropDown);
                if ($matchedYear.length) {
                    $matchedYear.addClass("selected");
                    // Scroll to matched time.
                    $ypDropDown[0].scrollTop = $matchedYear[0].offsetTop;
                }
            }
            return true;
        };
        // Attach to click as well as focus so yearPicker can be shown again when
        // clicking on the input when it already has focus.
        $(elm).focus(showPicker).click(showPicker);
        // Hide yearpicker on blur
        $(elm).blur(function () {
            if (!ypOver) {
                $ypDropDown.hide();
            }
        });

        // Keypress doesn't repeat on Safari for non-text keys.
        // Keydown doesn't repeat on Firefox and Opera on Mac.
        // Using kepress for Opera and Firefox and keydown for the rest seems to
        // work with up/down/enter/esc.
        //var event = ($.browser.opera || $.browser.mozilla) ? 'keypress' : 'keydown';
        //$(elm).bind(event, function (e) {
        $(elm).keydown(function (e) {
            var $selected;
            keyDown = true;
            var top = $ypDropDown[0].scrollTop;
            switch (e.keyCode) {
                case 38: // Up arrow.
                    // Just show picker if it's hidden.
                    if (showPicker()) {
                        return false;
                    };
                    $selected = $("li.selected", $ypYearList);
                    var prev = $selected.prev().addClass("selected")[0];
                    if (prev) {
                        $selected.removeClass("selected");
                        // Scroll item into view.
                        if (prev.offsetTop < top) {
                            $tpDiv[0].scrollTop = top - prev.offsetHeight;
                        }
                    }
                    else {
                        // Loop to next item.
                        $selected.removeClass("selected");
                        prev = $("li:last", $ypYearList).addClass("selected")[0];
                        $ypDropDown[0].scrollTop = prev.offsetTop - prev.offsetHeight;
                    }
                    return false;
                    break;
                case 40: // Down arrow, similar in behaviour to up arrow.
                    if (showPicker()) {
                        return false;
                    };
                    $selected = $("li.selected", $ypYearList);
                    var next = $selected.next().addClass("selected")[0];
                    if (next) {
                        $selected.removeClass("selected");
                        if (next.offsetTop + next.offsetHeight > top + $ypDropDown[0].offsetHeight) {
                            $ypDropDown[0].scrollTop = top + next.offsetHeight;
                        }
                    }
                    else {
                        $selected.removeClass("selected");
                        next = $("li:first", $ypYearList).addClass("selected")[0];
                        $ypDropDown[0].scrollTop = 0;
                    }
                    return false;
                    break;
                case 13: // Enter
                    if ($ypDropDown.is(":visible")) {
                        var sel = $("li.selected", $ypYearList)[0];
                        setYearVal(elm, sel, $ypDropDown, settings);
                    }
                    return false;
                    break;
                case 27: // Esc
                    $ypDropDown.hide();
                    return false;
                    break;
            }
            return true;
        });
        $(elm).keyup(function (e) {
            keyDown = false;
        });

        function setYearVal(elm, sel, $ypDropDown, settings) {
            // Update input field
            elm.value = $(sel).text();
            // Trigger element's change events.
            $(elm).change();
            // Keep focus for all but IE (which doesn't like it)
            if (!$.browser.msie && parseFloat($.browser.version) < 8) {
                elm.focus();
            }
            keyDown = false;
            // Hide picker
            $ypDropDown.hide();
            // Trigger selected event
            $(elm).trigger("AP2YearPickerSelected", [$(sel).text()]);
        }


    }; // End fn;

    // Plugin defaults.
    $.fn.AP2YearPickerdefaults = {
        step: 1,
        startYear: 1950,
        endYear: new Date().getFullYear()
    };
})(jQuery);;
(function(a){try{if(document.execCommand){document.execCommand("BackgroundImageCache",false,true)}}catch(w){}var q=/\d/;var aB=/\s+/;var aA=parseInt(a.browser.version.substring(0,5).replace(".",""));var G=a.browser.mozilla&&aA>=180&&aA<=191;var r=/d{1,4}|M{1,4}|yy(?:yy)?|([Hhmstf])\1*|"[^"]*"|'[^']*'/g;var V=(navigator.userAgent.search(/like\sMac\sOS\sX;.*Mobile\/\S+/)!=-1);var W=(navigator.userAgent.search(/4_1\slike\sMac\sOS\sX;.*Mobile\/\S+/)!=-1);var az=(function(){var e=new a.Event("triggerHandlerTest");a("<div />").triggerHandler(e);return !e.isDefaultPrevented()})();var b=a.telerik={create:function(aE,aF){var e=aF.name;var aD=a.extend({},a.fn[e].defaults,aF.options);return aE.each(function(){var aG=a(this);aD=a.meta?a.extend({},aD,aG.data()):aD;if(!aG.data(e)){var aH=aF.init(this,aD);aG.data(e,aH);b.trigger(this,"load");if(aF.success){aF.success(aH)}}})},toJson:function(e){function aE(aF){return"["+a.map(aF,aD).join(",")+"]"}function aD(aG){var aH=[];for(var aF in aG){var aI=aG[aF];if(a.isArray(aI)){aH.push('"'+aF+'":'+aE(aI))}else{if(typeof aI!="object"){aH.push('"'+aF+'":"'+(aI==null?"":aI)+'"')}else{aH.push('"'+aF+'":'+aD(aI))}}}return"{"+aH.join(",")+"}"}if(a.isArray(e)){return aE(e)}else{return aD(e)}},delegate:function(e,aD){return function(aE){aD.apply(e,[aE,this])}},stop:function(aD,e){return function(aE){aE.stopPropagation();aD.apply(e||this,arguments)}},stopAll:function(aD,e){return function(aE){aE.preventDefault();aE.stopPropagation();aD.apply(e||this,arguments)}},bind:function(aD,aE){var e=a(aD.element?aD.element:aD);a.each(aE,function(aF){if(a.isFunction(this)){e.bind(aF,this)}})},preventDefault:function(aD){aD.preventDefault()},hover:function(){a(this).addClass("t-state-hover")},leave:function(){a(this).removeClass("t-state-hover")},buttonHover:function(){a(this).addClass("t-button-hover")},buttonLeave:function(){a(this).removeClass("t-button-hover")},stringBuilder:function(){this.buffer=[]},ajaxError:function(e,aD,aG,aF){var aE=this.trigger(e,aD,{XMLHttpRequest:aG,textStatus:aF});if(!aE){if(aF=="error"&&aG.status!="0"){alert("Error! The requested URL returned "+aG.status+" - "+aG.statusText)}if(aF=="timeout"){alert("Error! Server timeout.")}}return aE},trigger:function(aE,aF,aD){aD=a.extend(aD||{},new a.Event(aF));if(az){a(aE).triggerHandler(aD)}else{aD.stopPropagation();a(aE).trigger(aD)}return aD.isDefaultPrevented()},getType:function(e){if(e instanceof Date){return"date"}if(typeof e==="number"){return"number"}return"object"},formatString:function(){var aI=arguments[0];for(var aE=0,aF=arguments.length-1;aE<aF;aE++){var aH=new RegExp("\\{"+aE+"(:([^\\}]+))?\\}","gm");var e=arguments[aE+1];var aD=this.formatters[this.getType(e)];if(aD){var aG=aH.exec(aI);if(aG){e=aD(e,aG[2])}}aI=aI.replace(aH,function(){return e})}return aI},splitClassesFromAttr:function(e){var aE=/class="([^"]*)"/i,aF={classes:"",attributes:""},aD;if(e){aD=aE.exec(e);aF.attributes=a.trim(e.replace(aE,""));if(aD){aF.classes=aD[1]}}return aF},getElementZIndex:function(e){var aD;a(e).parents().andSelf().each(function(){aD=a(this).css("zIndex");if(Number(aD)){aD=Number(aD)+1;return false}});return aD=="auto"?1:aD},scrollbarWidth:function(){var e=document.createElement("div"),aD;e.style.cssText="overflow:scroll;overflow-x:hidden;zoom:1";e.innerHTML="&nbsp;";document.body.appendChild(e);aD=e.offsetWidth-e.scrollWidth;document.body.removeChild(e);return aD},lastIndexOf:function(aF,e){var aD=e.length;for(var aE=aF.length-1;aE>-1;aE--){if(aF.substr(aE,aD)==e){return aE}}return -1},caretPos:function(e){var aD=-1;if(document.selection){aD=Math.abs(document.selection.createRange().moveStart("character",-e.value.length))}else{if(e.selectionStart!==undefined){aD=e.selectionStart}}return aD},encode:function(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\u00a0/g,"&nbsp;").replace(/'/g,"&#39;")},formatters:{},fx:{},cultureInfo:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbrDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],shortestDays:["Su","Mo","Tu","We","Th","Fr","Sa"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],abbrMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],longTime:"h:mm:ss tt",longDate:"dddd, MMMM dd, yyyy",shortDate:"M/d/yyyy",shortTime:"h:mm tt",fullDateTime:"dddd, MMMM dd, yyyy h:mm:ss tt",generalDateShortTime:"M/d/yyyy h:mm tt",generalDateTime:"M/d/yyyy h:mm:ss tt",sortableDateTime:"yyyy'-'MM'-'ddTHH':'mm':'ss",universalSortableDateTime:"yyyy'-'MM'-'dd HH':'mm':'ss'Z'",monthYear:"MMMM, yyyy",monthDay:"MMMM dd",today:"today",tomorrow:"tomorrow",yesterday:"yesterday",next:"next",last:"last",year:"year",month:"month",week:"week",day:"day",am:"AM",pm:"PM",dateSeparator:"/",timeSeparator:":",firstDayOfWeek:0,currencydecimaldigits:2,currencydecimalseparator:".",currencygroupseparator:",",currencygroupsize:3,currencynegative:0,currencypositive:0,currencysymbol:"$",numericdecimaldigits:2,numericdecimalseparator:".",numericgroupseparator:",",numericgroupsize:3,numericnegative:1,percentdecimaldigits:2,percentdecimalseparator:".",percentgroupseparator:",",percentgroupsize:3,percentnegative:0,percentpositive:0,percentsymbol:"%"},patterns:{numeric:{negative:["(n)","-n","- n","n-","n -"]},currency:{positive:["*n","n*","* n","n *"],negative:["(*n)","-*n","*-n","*n-","(n*)","-n*","n-*","n*-","-n *","-* n","n *-","* n-","* -n","n- *","(* n)","(n *)"]},percent:{positive:["n *","n*","*n"],negative:["-n *","-n*","-*n"]}}};var E,U;if(Array.prototype.filter!==undefined){E=function(e,aD){return e.filter(aD)}}else{E=function(e,aF){var aG=[],aE=e.length;for(var aD=0;aD<aE;aD++){var aH=e[aD];if(aF(aH,aD,e)){aG[aG.length]=aH}}return aG}}if(Array.prototype.map!==undefined){U=function(e,aD){return e.map(aD)}}else{U=function(e,aD){var aF=e.length,aG=new Array(aF);for(var aE=0;aE<aF;aE++){aG[aE]=aD(e[aE],aE,e)}return aG}}b.dropDown=function(e){a.extend(this,e);this.$element=a(new b.stringBuilder().cat("<div ").catIf(e.attr,e.attr).cat('><ul class="t-reset"></ul></div>').string()).addClass("t-popup t-group").hide();this.$element.delegate(".t-reset > .t-item","mouseenter",b.hover).delegate(".t-reset > .t-item","mouseleave",b.leave).delegate(".t-reset > .t-item","click",a.proxy(function(aD){if(this.onClick){this.onClick(a.extend(aD,{item:a(aD.target).closest(".t-item")[0]}))}},this));this.$element.tScrollable()};b.dropDown.prototype={_html:function(aD,aI){var aG=new b.stringBuilder();if(aD){for(var aH=0,aJ=aD.length;aH<aJ;aH++){var aK="&nbsp;",aE=aD[aH];if(aE){if(aE.Text!==undefined){aK=aE.Text}else{aK=aE}if(aI){aK=b.encode(aK)}if(!aK||!aK.replace(aB,"")){aK="&nbsp;"}}var aF={html:aK,dataItem:aE};if(this.onItemCreate){this.onItemCreate(aF)}aG.cat('<li unselectable="on" class="t-item">').cat(aF.html).cat("</li>")}}return aG.string()},open:function(aE){if(this.onOpen){this.onOpen()}if(this.isOpened()||!this.$items){return}var e=this.$element,aF;if(!e.parent()[0]){e.hide().appendTo(document.body)}if(e[0].style.width==""){aF=aE.outerWidth?aE.outerWidth-2:0}else{aF=parseInt(this.attr?a("<div"+this.attr+"></div>")[0].style.width:(a.browser.msie&&a.browser.version>8?e.outerWidth():e[0].style.width))}e.css("overflowY","auto").css("width",aF);var aD=aE.offset;aD.top+=aE.outerHeight;if(V){if(!document.body.scrollLeft&&!W){aD.left-=window.pageXOffset}if(!document.body.scrollTop&&!W){aD.top-=window.pageYOffset}}b.fx._wrap(e).css(a.extend({position:"absolute",zIndex:aE.zIndex},aD));if(G){e.css("overflow","hidden")}e.parent().show();b.fx.play(this.effects,e,{direction:"bottom"},a.proxy(function(){e.css("overflow","auto");if(a.browser.msie&&a.browser.version>8){var aH=e.css("height");if(aH=="auto"||aH!="100%"){e.css({height:"100%",boxSizing:"border-box"})}}var aG=this.$items.filter(".t-state-selected");if(aG.length){this.scrollTo(aG[0])}},this))},close:function(aF){if(!this.isOpened()){return}var aD=this.$element;var aE=this.$items;if(G){aD.css("overflow","hidden")}b.fx.rewind(this.effects,aD,{direction:"bottom"},function(){if(G){aD.css("overflow","auto")}if(aE){aE.removeClass("t-state-hover")}if(aD.parent(".t-animation-container")[0]){aD.parent().hide()}})},dataBind:function(aF,aI){aF=aF||[];var e=this.$element;if(e[0].style.height=="100%"){e.css("height","auto")}var aG=e[0].style.height,aH=aG&&aG!="auto"?aG:"200px",aE=e.find("> ul");aE[0].innerHTML=this._html(aF,aI);var aD=this.$items=aE.children();e.css("height",aD.length>10?aH:"auto")},highlight:function(e){return a(e).addClass("t-state-selected").siblings().removeClass("t-state-selected").end().index()},isOpened:function(){return this.$element.is(":visible")},scrollTo:function(aG){if(!aG){return}var aI=aG.offsetTop;var aH=aG.offsetHeight;var aD=this.$element[0];var aF=aD.scrollTop;var aE=aD.clientHeight;var e=aI+aH;aD.scrollTop=aF>aI?aI:e>(aF+aE)?e-aE:aF}};b.datetime=function(){if(arguments.length==0){this.value=new Date()}else{if(arguments.length==1){this.value=new Date(arguments[0])}else{if(arguments.length==3){this.value=new Date(arguments[0],arguments[1],arguments[2])}else{if(arguments.length==6){this.value=new Date(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5])}else{this.value=new Date(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6])}}}}return this};a.extend(b.datetime,{msPerMinute:60000,msPerDay:86400000,add:function(e,aH,aD){var aF=e.timeOffset();var aE=new b.datetime(e.time()+aH);var aG=aE.timeOffset()-aF;if(aD){return aE}return new b.datetime(aE.time()+aG*b.datetime.msPerMinute)},subtract:function(e,aD){aD=new b.datetime(aD).toDate();var aE=e.time()-aD;var aF=e.timeOffset()-aD.timeOffset();return aE-(aF*b.datetime.msPerMinute)},firstDayOfMonth:function(e){return new b.datetime(0).hours(e.hours()).minutes(e.minutes()).seconds(e.seconds()).milliseconds(e.milliseconds()).year(e.year(),e.month(),1)},dst:function(){var aE=new b.datetime(),e=new b.datetime(aE.year(),aE.month(),aE.date(),0,0,0),aD=new b.datetime(aE.year(),aE.month(),aE.date(),12,0,0);return -1*(e.timeOffset()-aD.timeOffset())},firstVisibleDay:function(e){var aD=b.cultureInfo.firstDayOfWeek;var aE=new b.datetime(e.year(),e.month(),0,e.hours(),e.minutes(),e.seconds(),e.milliseconds());while(aE.day()!=aD){b.datetime.modify(aE,-1*b.datetime.msPerDay)}return aE},modify:function(e,aG){var aE=e.timeOffset();var aD=new b.datetime(e.time()+aG);var aF=aD.timeOffset()-aE;e.time(aD.time()+aF*b.datetime.msPerMinute)},pad:function(e){if(e<10){return"0"+e}return e},standardFormat:function(e){var aD=b.cultureInfo;var aE={d:aD.shortDate,D:aD.longDate,F:aD.fullDateTime,g:aD.generalDateShortTime,G:aD.generalDateTime,m:aD.monthDay,M:aD.monthDay,s:aD.sortableDateTime,t:aD.shortTime,T:aD.longTime,u:aD.universalSortableDateTime,y:aD.monthYear,Y:aD.monthYear};return aE[e]},format:function(aD,aH){var aJ=b.cultureInfo;var e=aD.getDate();var aF=aD.getDay();var aL=aD.getMonth();var aO=aD.getFullYear();var aI=aD.getHours();var aK=aD.getMinutes();var aN=aD.getSeconds();var aG=aD.getMilliseconds();var aM=b.datetime.pad;var aE={d:e,dd:aM(e),ddd:aJ.abbrDays[aF],dddd:aJ.days[aF],M:aL+1,MM:aM(aL+1),MMM:aJ.abbrMonths[aL],MMMM:aJ.months[aL],yy:aM(aO%100),yyyy:aO,h:aI%12||12,hh:aM(aI%12||12),H:aI,HH:aM(aI),m:aK,mm:aM(aK),s:aN,ss:aM(aN),f:Math.floor(aG/100),ff:Math.floor(aG/10),fff:aG,tt:aI<12?aJ.am:aJ.pm};aH=aH||"G";aH=b.datetime.standardFormat(aH)?b.datetime.standardFormat(aH):aH;return aH.replace(r,function(aP){return aP in aE?aE[aP]:aP.slice(1,aP.length-1)})},parse:function(aD){var aE=aD.value;var e=aD.format;if(aE&&aE.value){return aE}e=b.datetime.standardFormat(e)?b.datetime.standardFormat(e):e;if(q.test(aE)){return b.datetime.parseMachineDate({value:aE,format:e,shortYearCutOff:aD.shortYearCutOff,baseDate:aD.baseDate,AM:b.cultureInfo.am,PM:b.cultureInfo.pm})}return b.datetime.parseByToken?b.datetime.parseByToken(aE,aD.today):null},parseMachineDate:function(aY){var e=aY.AM,aZ=aY.PM,a3=aY.value,aK=aY.format,aD=aY.baseDate,a1=aY.shortYearCutOff||30,a5=null,aW=null,aI=null,aO=0,aV=0,a0=0,aU=0,aP,aQ,aR=false,aT=function(a6){return(aL+1<aK.length&&aK.charAt(aL+1)==a6)},aS=function(a7){var a6=0;while(aT(a7)){a6++;aL++}return a6},aN=function(a8){var a6=new RegExp("^\\d{1,"+a8+"}");var a7=a3.substr(aG).match(a6);if(a7){aG+=a7[0].length;return parseInt(a7[0],10)}else{return -1}},aM=function(a7){for(var a6=0;a6<a7.length;a6++){if(a3.substr(aG,a7[a6].length)==a7[a6]){aG+=a7[a6].length;return a6+1}}return -1},aE=function(){if(a3.charAt(aG)==aK.charAt(aL)){aG++;return true}else{return false}},aX=function(a6){return a6===-1?0:a6},aF=0,aG=0,a4=a3.length;for(var aL=0,aJ=aK.length;aL<aJ;aL++){if(aG==a4){break}if(aR){aE();if(aK.charAt(aL)=="'"){aR=false}}else{switch(aK.charAt(aL)){case"d":aF=aS("d");aI=aF<=1?aN(2):aM(b.cultureInfo[aF==3?"days":"abbrDays"]);if(aI===null||(aI<1||aI>31)){return null}break;case"M":aF=aS("M");aW=aF<=1?aN(2):aM(b.cultureInfo[aF==3?"months":"abbrMonths"]);if(aW===null||(aW<1||aW>12)){return null}aW-=1;break;case"y":aF=aS("y");a5=aN(aF<=1?2:4);if(a5<0||a5.toString().length<=aF){return null}break;case"H":aF=aS("H");aO=aX(aN(2));if(aO===null||(aO<0||aO>23)){return null}break;case"h":aS("h");aO=aX(aN(2));if(aO==12){aO=0}if(aO===null||(aO<0||aO>11)){return null}break;case"m":aS("m");aV=aX(aN(2));if(aV===null||(aV<0||aV>59)){return null}break;case"s":aS("s");a0=aX(aN(2));if(a0===null||(a0<0||a0>59)){return null}break;case"f":aF=aS("f");aU=aX(aN(aF<=0?1:aF+1));if(aU===null||(aU<0||aU>999)){return null}break;case"t":aF=aS("t");e=aF>0?e:"a";aZ=aF>0?aZ:"p";var a2=a3.substr(aG).toLowerCase();aP=a2.indexOf(e.toLowerCase())!=-1;aQ=a2.indexOf(aZ.toLowerCase())!=-1;aG+=aQ?aZ.length:aP?e.length:0;break;case"'":aE();aR=true;break;default:if(!aE()){return null}}}}var aH=new b.datetime();if(a5!==null&&a5<100){a5+=aH.year()-aH.year()%100+(a5<=a1?0:-100)}aO=(aQ&&aO<12)?aO+12:aO==12&&aP?0:aO;if(aD==undefined){if(a5===null){a5=aH.year()}if(aI===null){aI=1}aH=new b.datetime(a5,aW,aI,aO,aV,a0,aU)}else{aH=new b.datetime(a5!==null?a5:aD.year(),aW!==null?aW:aD.month(),aI!==null?aI:aD.date(),aO,aV,a0,aU)}return aH}});b.datetime.prototype={year:function(){if(arguments.length==0){return this.value.getFullYear()}else{if(arguments.length==1){this.value.setFullYear(arguments[0])}else{this.value.setFullYear(arguments[0],arguments[1],arguments[2])}}return this},timeOffset:function(){return this.value.getTimezoneOffset()},day:function(){return this.value.getDay()},toDate:function(){return this.value},addMonth:function(e){this.month(this.month()+e)},addYear:function(e){this.year(this.year()+e)}};a.each(["Month","Date","Hours","Minutes","Seconds","Milliseconds","Time"],function(e,aD){b.datetime.prototype[aD.toLowerCase()]=function(){if(arguments.length==1){this.value["set"+aD](arguments[0])}else{return this.value["get"+aD]()}return this}});var o=/[0#?]/;var at=/n|p|c/i;function ap(aE,aD){var e=Math.pow(10,aD||0);return Math.round(aE*e)/e}function ao(e){return e.split("").reverse().join("")}function N(aL,aG,e){var aH=0,aI=0,aF=aG.length,aM=aL.length,aD=new b.stringBuilder();while(aH<aF&&aI<aM&&aG.substring(aH).search(o)>=0){if(aG.charAt(aH).match(o)){aD.cat(aL.charAt(aI++))}else{aD.cat(aG.charAt(aH))}aH++}aD.catIf(aL.substring(aI),aI<aM&&e).catIf(aG.substring(aH),aH<aF);var aJ=ao(aD.string()),aN;if(aJ.indexOf("#")>-1){aN=aJ.indexOf("0")}if(aN>-1){var aE=aJ.slice(0,aN),aK=aJ.slice(aN,aJ.length);aJ=aE.replace(/#/g,"")+aK.replace(/#/g,"0")}else{aJ=aJ.replace(/#/g,"")}if(aJ.indexOf(",")==0){aJ=aJ.replace(/,/g,"")}return e?aJ:ao(aJ)}b.formatNumber=function(aT,aH,aF,a3,aI,aJ,aX,aR,a7,aL){if(!aH){return aT}var a8,aE,aS,ba,a4=aT<0;aH=aH.split(":");aH=aH.length>1?aH[1].replace("}",""):aH[0];var aK=o.test(aH)&&!at.test(aH);if(aK){aH=aH.split(";");aE=aH[0];aS=aH[1];ba=aH[2];aH=(a4&&aS?aS:aE).indexOf("%")!=-1?"p":"n"}switch(aH.toLowerCase().charAt(0)){case"d":return Math.round(aT).toString();case"c":a8="currency";break;case"n":a8="numeric";break;case"p":a8="percent";if(!aL){aT=Math.abs(aT)*100}break;default:return aT.toString()}var aQ=aH.match(q);if(aQ){aF=parseInt(aQ[0],10)}var bb=function(bf,bc,be){for(var bd=bf.length;bd<bc;bd++){bf=be?("0"+bf):(bf+"0")}return bf};var e=function(be,bc,bd){if(aI&&bd!=0){var bf=new RegExp("(-?[0-9]+)([0-9]{"+bd+"})");while(bf.test(be)){be=be.replace(bf,"$1"+bc+"$2")}}return be};var aD=aD||b.cultureInfo,aW=b.patterns,a9;aF=aF||aF===0?aF:aD[a8+"decimaldigits"];a3=a3!==a9?a3:aD[a8+"decimalseparator"];aI=aI!==a9?aI:aD[a8+"groupseparator"];aJ=aJ||aJ==0?aJ:aD[a8+"groupsize"];aR=aR||aR===0?aR:aD[a8+"negative"];aX=aX||aX===0?aX:aD[a8+"positive"];a7=a7||aD[a8+"symbol"];var aG,aO,aZ;if(aK){var a6=(a4&&aS?aS:aE).split("."),aP=a6[0],a0=a6.length>1?a6[1]:"",aN=b.lastIndexOf(a0,"0"),aM=b.lastIndexOf(a0,"#");aF=(aM>aN?aM:aN)+1}var a2=ap(aT,aF);aT=isFinite(a2)?a2:aT;if(aT.toString().toLowerCase().indexOf("e")>-1){aT=aT.toFixed(aF)}var a5=aT.toString().split(".");aO=a5[0];aO=a4?aO.replace("-",""):aO;aZ=a5.length>1?a5[1]:"";if(aG){if(!a4){aZ=bb(aZ,aG,false);aO+=aZ.slice(0,aG);aZ=aZ.substr(aG)}else{aO=bb(aO,aG+1,true);aZ=aO.slice(aG,aO.length)+aZ;aO=aO.slice(0,aG)}}var a1=aZ.length;if(aF<1||(aK&&aN==-1&&a1===0)){aZ=""}else{aZ=a1>aF?aZ.slice(0,aF):bb(aZ,aF,false)}var aY;if(aK){if(aO==0){aO=""}aO=N(ao(aO),ao(aP),true).replace(/,/g,"");aO=aP.indexOf(",")!=-1?e(aO,aI,aJ):aO;aZ=aZ&&a0?N(aZ,a0):"";aY=aT===0&&ba?ba:(a4&&!aS?"-":"")+aO+(aZ.length>0?a3+aZ:"")}else{aO=e(aO,aI,aJ);aW=aW[a8];var aV=a4?aW.negative[aR]:a7?aW.positive[aX]:null;var aU=aO+(aZ.length>0?a3+aZ:"");aY=aV?aV.replace("n",aU).replace("*",a7):aU}return aY};a.extend(b.formatters,{date:b.datetime.format,number:b.formatNumber});b.scripts=[];var R=[];function an(aD,e){var aF=b.scripts;aD=a.grep(aD,function(aG){aG=aG.toLowerCase().replace(".min","");if(aG.indexOf("jquery-")>-1||(aG.indexOf("jquery.validate")>-1&&a.fn.validate)||aG.indexOf("telerik.common")>-1){return false}var aI=false;for(var aH=0;aH<aF.length;aH++){var aJ=aF[aH];if(aG.indexOf(aJ)>-1){aI=true;break}}return !aI});var aE=function(aG){if(aG){a.ajax({url:aG,dataType:"script",cache:!a.browser.msie,success:function(){aE(aD.shift())}})}else{e();R.shift();if(R.length){R[0]()}}};aE(aD.shift())}b.load=function(aD,e){R.push(function(){an(aD,e)});if(R.length==1){an(aD,e)}};b.stringBuilder.prototype={cat:function(e){this.buffer.push(e);return this},rep:function(aE,e){for(var aD=0;aD<e;aD++){this.cat(aE)}return this},catIf:function(){var e=arguments;if(e[e.length-1]){for(var aD=0,aE=e.length-1;aD<aE;aD++){this.cat(e[aD])}}return this},string:function(){return this.buffer.join("")}};b.isTouch="ontouchstart" in window;var Y="mousemove",au="mousedown",y="mouseup";if(b.isTouch){Y="touchmove";au="touchstart";y="touchend"}a.extend(a.fn,{tScrollable:function(e){a(this).each(function(){if(b.isTouch||(e&&e.force)){new aq(this)}})}});function aq(e){this.element=e;this.wrapper=a(e);this._horizontalScrollbar=a('<div class="t-touch-scrollbar" />');this._verticalScrollbar=this._horizontalScrollbar.clone();this._scrollbars=this._horizontalScrollbar.add(this._verticalScrollbar);this._startProxy=a.proxy(this._start,this);this._stopProxy=a.proxy(this._stop,this);this._dragProxy=a.proxy(this._drag,this);this._create()}b.touchLocation=function(aD){return{idx:0,x:aD.pageX,y:aD.pageY}};b.eventTarget=function(aD){return aD.target};b.eventCurrentTarget=function(aD){return aD.currentTarget};if(b.isTouch){b.touchLocation=function(aE,aF){var aD=aE.changedTouches||aE.originalEvent.changedTouches;if(aF){var aG=null;x(aD,function(e,aH){if(aF==aH.identifier){aG={idx:aH.identifier,x:aH.pageX,y:aH.pageY}}});return aG}else{if(aE.type in {touchstart:{},touchmove:{},touchend:{},touchcancel:{}}){return{idx:aD[0].identifier,x:aD[0].pageX,y:aD[0].pageY}}else{return{idx:0,x:aE.pageX,y:aE.pageY}}}};b.eventTarget=function(aD){var aE="originalEvent" in aD?aD.originalEvent.changedTouches:"changedTouches" in aD?aD.changedTouches:null;return aE?document.elementFromPoint(aE[0].clientX,aE[0].clientY):null};b.eventCurrentTarget=b.eventTarget}b.zoomLevel=function(){return b.isTouch?(document.documentElement.clientWidth/window.innerWidth):1};aq.prototype={_create:function(){this.wrapper.css("overflow","hidden").bind(au,a.proxy(this._wait,this))},_wait:function(aD){var aE=b.touchLocation(aD);this.start={x:aE.x+this.wrapper.scrollLeft(),y:aE.y+this.wrapper.scrollTop()};a(document).bind(Y,this._startProxy).bind(y,this._stopProxy)},_start:function(aE){var aD=b.touchLocation(aE);this._dragged=false;if(this.start.x-aD.x>10||this.start.y-aD.y>10){aE.preventDefault();this._dragged=true;a(document).unbind(Y,this._startProxy).bind(Y,this._dragProxy);var aJ=this.wrapper.innerWidth(),aF=this.wrapper.innerHeight(),aG=this.wrapper.offset(),aI=this.wrapper.attr("scrollWidth"),aH=this.wrapper.attr("scrollHeight");if(aI>aJ){this._horizontalScrollbar.appendTo(document.body).css({width:Math.floor((aJ/aI)*aJ),left:this.wrapper.scrollLeft()+aG.left+parseInt(this.wrapper.css("borderLeftWidth")),top:aG.top+this.wrapper.innerHeight()+parseInt(this.wrapper.css("borderTopWidth"))-this._horizontalScrollbar.outerHeight()})}if(aH>aF){this._verticalScrollbar.appendTo(document.body).css({height:Math.floor((aF/aH)*aF),top:this.wrapper.scrollTop()+aG.top+parseInt(this.wrapper.css("borderTopWidth")),left:aG.left+this.wrapper.innerWidth()+parseInt(this.wrapper.css("borderLeftWidth"))-this._verticalScrollbar.outerWidth()})}this._scrollbars.stop().fadeTo(200,0.5)}},_drag:function(aE){if(!this._dragged){aE.preventDefault()}var aD=b.touchLocation(aE),aH=this.wrapper.offset(),aI=aH.left+parseInt(this.wrapper.css("borderLeftWidth")),aJ=aH.top+parseInt(this.wrapper.css("borderTopWidth")),aF=this.start.x-aD.x,aL=this.start.y-aD.y,aG=Math.max(aI,aI+aF),aK=Math.max(aJ,aJ+aL);aG=Math.min(aI+this.wrapper.innerWidth()-this._horizontalScrollbar.outerWidth()-this._horizontalScrollbar.outerHeight(),aG);aK=Math.min(aJ+this.wrapper.innerHeight()-this._verticalScrollbar.outerHeight()-this._verticalScrollbar.outerWidth(),aK);this._horizontalScrollbar.css("left",aG);this._verticalScrollbar.css("top",aK);this.wrapper.scrollLeft(aF).scrollTop(aL)},_stop:function(){a(document).unbind(Y,this._startProxy).unbind(Y,this._dragProxy).unbind(y,this._stopProxy);this._scrollbars.stop().fadeTo(400,0)}};var af=function(aD,aF,aE){if(aF.length==0&&aE){aE();return null}var e=aD.list.length;return function(){if(--e==0&&aE){aE()}}};a.extend(b.fx,{_wrap:function(e){if(!e.parent().hasClass("t-animation-container")){e.wrap(a("<div/>").addClass("t-animation-container").css({width:e.outerWidth(),height:e.outerHeight()}))}return e.parent()},play:function(aE,aJ,aI,aF){var e=af(aE,aJ,aF);if(e===null){return}aJ.stop(false,true);for(var aG=0,aH=aE.list.length;aG<aH;aG++){var aD=new b.fx[aE.list[aG].name](aJ);if(!aJ.data("effect-"+aG)){aD.play(a.extend(aE.list[aG],{openDuration:aE.openDuration,closeDuration:aE.closeDuration},aI),e);aJ.data("effect-"+aG,aD)}}},rewind:function(aE,aI,aH,aF){var e=af(aE,aI,aF);if(e===null){return}for(var aG=aE.list.length-1;aG>=0;aG--){var aD=aI.data("effect-"+aG)||new b.fx[aE.list[aG].name](aI);aD.rewind(a.extend(aE.list[aG],{openDuration:aE.openDuration,closeDuration:aE.closeDuration},aH),e);aI.data("effect-"+aG,null)}}});b.fx.toggle=function(e){this.element=e.stop(false,true)};b.fx.toggle.prototype={play:function(aD,e){this.element.show();if(e){e()}},rewind:function(aD,e){this.element.hide();if(e){e()}}};b.fx.toggle.defaults=function(){return{list:[{name:"toggle"}]}};b.fx.slide=function(e){this.element=e;this.animationContainer=b.fx._wrap(e)};b.fx.slide.prototype={play:function(aI,aG){var aE=this.animationContainer;this.element.css("display","block").stop();aE.css({display:"block",overflow:"hidden"});var aJ=this.element.outerWidth();var aH=this.element.outerHeight();var e=aI.direction=="bottom"?"marginTop":"marginLeft";var aD=aI.direction=="bottom"?-aH:-aJ;aE.css({width:aJ,height:aH});var aF={};aF[e]=0;this.element.css("width",this.element.width()).each(function(){this.style.cssText=this.style.cssText}).css(e,aD).animate(aF,{queue:false,duration:aI.openDuration,easing:"linear",complete:function(){aE.css("overflow","");if(aG){aG()}}})},rewind:function(aF,aE){var aD=this.animationContainer;this.element.stop(false,true);aD.css({overflow:"hidden"});var e;switch(aF.direction){case"bottom":e={marginTop:-this.element.outerHeight()};break;case"right":e={marginLeft:-this.element.outerWidth()};break}this.element.animate(e,{queue:false,duration:aF.closeDuration,easing:"linear",complete:function(){aD.css({display:"none",overflow:""});if(aE){aE()}}})}};b.fx.slide.defaults=function(){return{list:[{name:"slide"}],openDuration:"fast",closeDuration:"fast"}};b.fx.property=function(e){this.element=e};b.fx.property.prototype={_animate:function(aG,aD,aH,aE){var aI={overflow:"hidden"},aF={},e=this.element;a.each(aG,function(aJ,aK){var aL;switch(aK){case"height":case"width":aL=e[aK]();break;case"opacity":aL=1;break;default:aL=e.css(aK);break}aI[aK]=aH?aL:0;aF[aK]=aH?0:aL});e.css(aI).show().animate(aF,{queue:false,duration:aD,easing:"linear",complete:function(){if(aH){e.hide()}a.each(aF,function(aJ){aF[aJ]=""});e.css(a.extend({overflow:""},aF));if(aE){aE()}}})},play:function(aD,e){this._animate(aD.properties,aD.openDuration,false,e)},rewind:function(aD,e){this._animate(aD.properties,aD.closeDuration,true,e)}};b.fx.property.defaults=function(){return{list:[{name:"property",properties:arguments}],openDuration:"fast",closeDuration:"fast"}};a(document).ready(function(){if(a.browser.msie&&typeof(Sys)!="undefined"&&typeof(Sys.Mvc)!="undefined"&&typeof(Sys.Mvc.FormContext)!="undefined"){var e=function(aD,aE){return a.grep(aD.getElementsByTagName("*"),function(aF){return aF.name==aE})};if(Sys.Mvc.FormContext){Sys.Mvc.FormContext.$F=Sys.Mvc.FormContext._getFormElementsWithName=e}}});var D=a.extend,ai=a.proxy,aw=a.type,P=a.isFunction,Q=a.isPlainObject,O=a.isEmptyObject,x=a.each,Z=a.noop;function B(){this._isPrevented=false}B.prototype={preventDefault:function(){this._isPrevented=true},isDefaultPrevented:function(){return this._isPrevented}};function i(){}i.extend=function(aD){var e=function(){},aG=this,aE=aD&&aD.init?aD.init:function(){aG.apply(this,arguments)},aF;e.prototype=aG.prototype;aF=aE.fn=aE.prototype=new e();for(member in aD){if(typeof aD[member]==="object"&&!(aD[member] instanceof Array)&&aD[member]!==null){aF[member]=D(true,{},e.prototype[member],aD[member])}else{aF[member]=aD[member]}}aF.constructor=aE;aE.extend=aG.extend;return aE};a.telerik.Class=i;var ac=i.extend({init:function(){this._events={}},bind:function(e,aF){var aI=this,aG,aD=a.isArray(e)?e:[e],aH,aE;for(aG=0,aH=aD.length;aG<aH;aG++){e=aD[aG];handler=a.isFunction(aF)?aF:aF[e];if(handler){aE=aI._events[e]||[];aE.push(handler);aI._events[e]=aE}}return aI},trigger:function(aD,aH){var aI=this,aE=aI._events[aD],e=D(aH,new B()),aF,aG;if(aE){for(aF=0,aG=aE.length;aF<aG;aF++){aE[aF].call(aI,e)}}return e.isDefaultPrevented()},unbind:function(e,aE){var aH=this,aD=aH._events[e],aF,aG;if(aD){if(aE){for(aF=0,aG=aD.length;aF<aG;aF++){if(aD[aF]===aE){aD.splice(aF,1)}}}else{aH._events[e]=[]}}return aH}});var j={selector:function(aD){if(a.isFunction(aD)){return aD}else{var e=H(aD);return function(aF){var aG=e(aF);if(typeof aG==="string"){var aE=/^\/Date\((.*?)\)\/$/.exec(aG);if(aE){aG=new Date(parseInt(aE[1]));return aG}}return aG}}},asc:function(e){var aD=this.selector(e);return function(aE,aF){aE=aD(aE);aF=aD(aF);return aE>aF?1:(aE<aF?-1:0)}},desc:function(e){var aD=this.selector(e);return function(aE,aF){aE=aD(aE);aF=aD(aF);return aE<aF?1:(aE>aF?-1:0)}},create:function(e){return j[e.dir.toLowerCase()](e.field)},combine:function(e){return function(aD,aE){var aH=e[0](aD,aE),aF,aG;for(aF=1,aG=e.length;aF<aG;aF++){aH=aH||e[aF](aD,aE)}return aH}}};var ae=(function(){var aF=/(?=['\\])/g;var e=/^\/Date\((.*?)\)\/$/;function aE(aG){return aG.replace(aF,"\\")}function aD(aK,aG,aH,aJ){var aI;if(aH!=null){if(typeof aH==="string"){aH=aE(aH);aI=e.exec(aH);if(aI){aH=new Date(+aI[1])}else{if(aJ){aH="'"+aH.toLowerCase()+"'";aG="("+aG+" || '').toLowerCase()"}else{aH="'"+aH+"'"}}}if(aH.getTime){aG="("+aG+"?("+aG+".getTime ? "+aG+".getTime(): new Date(+(/^\\/Date\\((.*?)\\)\\/$/.exec("+aG+"))[1]).getTime()):"+aG+")";aH=aH.getTime()}}return aG+" "+aK+" "+aH}return{eq:function(aG,aH,aI){return aD("==",aG,aH,aI)},neq:function(aG,aH,aI){return aD("!=",aG,aH,aI)},gt:function(aG,aH,aI){return aD(">",aG,aH,aI)},gte:function(aG,aH,aI){return aD(">=",aG,aH,aI)},lt:function(aG,aH,aI){return aD("<",aG,aH,aI)},lte:function(aG,aH,aI){return aD("<=",aG,aH,aI)},startswith:function(aG,aH,aI){if(aI){aG="("+aG+" || '').toLowerCase()";if(aH){aH=aH.toLowerCase()}}if(aH){aH=aE(aH)}return aG+".lastIndexOf('"+aH+"', 0) == 0"},endswith:function(aG,aH,aI){if(aI){aG="("+aG+" || '').toLowerCase()";if(aH){aH=aH.toLowerCase()}}if(aH){aH=aE(aH)}return aG+".lastIndexOf('"+aH+"') == "+aG+".length - "+(aH||"").length},contains:function(aG,aH,aI){if(aI){aG="("+aG+" || '').toLowerCase()";if(aH){aH=aH.toLowerCase()}}if(aH){aH=aE(aH)}return aG+".indexOf('"+aH+"') >= 0"},doesnotcontain:function(aG,aH,aI){if(aI){aG="("+aG+" || '').toLowerCase()";if(aH){aH=aH.toLowerCase()}}if(aH){aH=aE(aH)}return aG+".indexOf('"+aH+"') == -1"}}})();var aj=function(e){return new aj.fn.init(e)};var ad={"==":"eq",equals:"eq",isequalto:"eq",equalto:"eq",equal:"eq","!=":"neq",ne:"neq",notequals:"neq",isnotequalto:"neq",notequalto:"neq",notequal:"neq","<":"lt",islessthan:"lt",lessthan:"lt",less:"lt","<=":"lte",le:"lte",islessthanorequalto:"lte",lessthanequal:"lte",">":"gt",isgreaterthan:"gt",greaterthan:"gt",greater:"gt",">=":"gte",isgreaterthanorequalto:"gte",greaterthanequal:"gte",ge:"gte",substringof:"contains",notsubstringof:"doesnotcontain"};function ab(e){var aF,aG,aD,aH,aE=e.filters;if(aE){for(aF=0,aG=aE.length;aF<aG;aF++){aD=aE[aF];aH=aD.operator;if(aH&&typeof aH==="string"){aD.operator=ad[aH.toLowerCase()]||aH}ab(aD)}}}function aa(e){if(e&&!O(e)){if(a.isArray(e)||!e.filters){e={logic:"and",filters:a.isArray(e)?e:[e]}}ab(e);return e}}aj.normalizeFilter=aa;aj.filterExpr=function(aD){var aE=[],aL={and:" && ",or:" || "},aJ,aK,aH,e,aG=[],aN=[],aF,aM,aI=aD.filters;for(aJ=0,aK=aI.length;aJ<aK;aJ++){aH=aI[aJ];aF=aH.field;aM=aH.operator;if(aH.filters){e=aj.filterExpr(aH);aH=e.expression.replace(/__o\[(\d+)\]/g,function(aP,aO){aO=+aO;return"__o["+(aN.length+aO)+"]"}).replace(/__f\[(\d+)\]/g,function(aP,aO){aO=+aO;return"__f["+(aG.length+aO)+"]"});aN.push.apply(aN,e.operators);aG.push.apply(aG,e.fields)}else{if(typeof aF==="function"){e="__f["+aG.length+"](d)";aG.push(aF)}else{e=b.expr(aF,true)}if(typeof aM==="function"){aH="__o["+aN.length+"]("+e+", "+aH.value+")";aN.push(aM)}else{aH=ae[(aM||"eq").toLowerCase()](e,aH.value,aH.ignoreCase!==undefined?aH.ignoreCase:true)}}aE.push(aH)}return{expression:"("+aE.join(aL[aD.logic])+")",fields:aG,operators:aN}};b.query=aj;aj.expandSort=function(aF,aE){var e=typeof aF==="string"?{field:aF,dir:aE}:aF,aD=a.isArray(e)?e:(e!==undefined?[e]:[]);return a.grep(aD,function(aG){return !!aG.dir})};aj.expandAggregates=function(e){return e=a.isArray(e)?e:[e]};aj.expandGroup=function(aF,aE){var e=typeof aF==="string"?{field:aF,dir:aE}:aF,aD=a.isArray(e)?e:(e!==undefined?[e]:[]);return a.map(aD,function(aG){return{field:aG.field,dir:aG.dir||"asc",aggregates:aG.aggregates}})};aj.fn=aj.prototype={init:function(e){this.data=e||[];return this},toArray:function(){return this.data},skip:function(e){return new aj(this.data.slice(e))},take:function(e){return new aj(this.data.slice(0,e))},orderBy:function(aE){var aD=this.data.slice(0),e=a.isFunction(aE)||!aE?j.asc(aE):aE.compare;return new aj(aD.sort(e))},orderByDescending:function(e){return new aj(this.data.slice(0).sort(j.desc(e)))},sort:function(aF,aE){var aG,aH,aD=aj.expandSort(aF,aE),e=[];if(aD.length){for(aG=0,aH=aD.length;aG<aH;aG++){e.push(j.create(aD[aG]))}return this.orderBy({compare:j.combine(e)})}return this},filter:function(aF){var aI,aD,aJ,e,aL,aE=this.data,aG,aK,aM=[],aH;aF=aa(aF);if(!aF||aF.filters.length===0){return this}e=aj.filterExpr(aF);aG=e.fields;aK=e.operators;aL=aH=new Function("d, __f, __o","return "+e.expression);if(aG.length||aK.length){aH=function(aN){return aL(aN,aG,aK)}}for(aI=0,aJ=aE.length;aI<aJ;aI++){aD=aE[aI];if(aH(aD)){aM.push(aD)}}return new aj(aM)},where:function(e){return aj(E(this.data,e))},select:function(e){return aj(U(this.data,e))},concat:function(e){return aj(this.data.concat(e.data))},count:function(){return this.data.length},any:function(aE){if(a.isFunction(aE)){for(var e=0,aD=this.data.length;e<aD;e++){if(aE(this.data[e],e)){return true}}return false}return !!this.data.length},group:function(aE,e){aE=aj.expandGroup(aE||[]);e=e||this.data;var aG=this,aF=new aj(aG.data),aD;if(aE.length>0){aD=aE[0];aF=aF.groupBy(aD).select(function(aI){var aH=new aj(e).filter([{field:aI.field,operator:"eq",value:aI.value}]);return{field:aI.field,value:aI.value,items:aE.length>1?new aj(aI.items).group(aE.slice(1),aH.toArray()).toArray():aI.items,hasSubgroups:aE.length>1,aggregates:aH.aggregate(aD.aggregates)}})}return aF},groupBy:function(aF){if(O(aF)||!this.data.length){return new aj([])}var aG=aF.field,aN=this.sort(aG,aF.dir||"asc").toArray(),e=c(aG),aK,aI=e.get(aN[0],aG),aD={},aH={field:aG,value:aI,items:[]},aE,aJ,aL,aM=[aH];for(aJ=0,aL=aN.length;aJ<aL;aJ++){aK=aN[aJ];aE=e.get(aK,aG);if(!I(aI,aE)){aI=aE;aH={field:aG,value:aI,items:[]};aM.push(aH)}aH.items.push(aK)}return new aj(aM)},aggregate:function(e){var aD,aE,aF={};for(aD=0,aE=this.data.length;aD<aE;aD++){f(aF,e,this.data[aD],aD,aE)}return aF}};function I(e,aD){if(e&&e.getTime&&aD&&aD.getTime){return e.getTime()===aD.getTime()}return e===aD}function f(e,aE,aK,aJ,aM){aE=aE||[];var aI,aD,aH,aG,aL=aE.length;for(aI=0;aI<aL;aI++){aD=aE[aI];aH=aD.aggregate;var aF=aD.field;e[aF]=e[aF]||{};e[aF][aH]=F[aH.toLowerCase()](e[aF][aH],aK,c(aF),aJ,aM)}}var F={sum:function(aD,aE,e){return aD=(aD||0)+e.get(aE)},count:function(aD,aE,e){return(aD||0)+1},average:function(aD,aF,e,aE,aG){aD=(aD||0)+e.get(aF);if(aE==aG-1){aD=aD/aG}return aD},max:function(aD,aE,e){var aD=(aD||0),aF=e.get(aE);if(aD<aF){aD=aF}return aD},min:function(aD,aE,e){var aF=e.get(aE),aD=(aD||aF);if(aD>aF){aD=aF}return aD}};aj.fn.init.prototype=aj.fn;var aw=a.type,ay="UPDATED",ag="PRISTINE",m="CREATED",v="DESTROYED";function z(aD,aF){if(aD===aF){return true}var aE=aw(aD),aG=aw(aF),e;if(aE!==aG){return false}if(aE==="date"){return aD.getTime()===aF.getTime()}if(aE!=="object"&&aE!=="array"){return false}for(e in aD){if(!z(aD[e],aF[e])){return false}}return true}var C=function(e,aD){e=e||"";if(e&&e.charAt(0)!=="["){e="."+e}if(aD){e=aC(e.split("."))}else{e="d"+e}return e},H=function(e,aD){return new Function("d","return "+C(e,aD))},ar=function(e){return new Function("d,value","d."+e+"=value")},c=function(e){return{get:H(e),set:ar(e)}};var aC=function(aH){var aI="d",aE,aD,aF,aG,e=1;for(aD=0,aF=aH.length;aD<aF;aD++){aG=aH[aD];if(aG!==""){aE=aG.indexOf("[");if(aE!=0){if(aE==-1){aG="."+aG}else{e++;aG="."+aG.substring(0,aE)+" || {})"+aG.substring(aE)}}e++;aI+=aG+((aD<aF-1)?" || {})":")")}}return new Array(e).join("(")+aI};var X=ac.extend({init:function(e){var aD=this;ac.fn.init.call(aD);aD.state=ag;aD._accessors={};aD._modified=false;aD.data=D(true,{},e);aD.pristine=D(true,{},e);if(aD.id()===undefined){aD.state=m;aD.data.__id=aD.guid()}},guid:function(){var aD="",e,aE;for(e=0;e<32;e++){aE=Math.random()*16|0;if(e==8||e==12||e==16||e==20){aD+="-"}aD+=(e==12?4:(e==16?(aE&3|8):aE)).toString(16)}return aD},accessor:function(aD){var e=this._accessors;return e[aD]=e[aD]||c(aD)},get:function(aD){var aE=this,e=aE.accessor(aD);return e.get(aE.data)},set:function(aE,aG){var aF=this,aD,aH={},e;if(typeof aE==="string"){aH[aE]=aG}else{aH=aE}aF._modified=false;for(aD in aH){e=aF.accessor(aD);aG=aH[aD];if(!z(aG,e.get(aF.data))){e.set(aF.data,aG);aF._modified=true}}if(aF._modified){aF.state=aF.isNew()?m:ay;aF.trigger("change")}},isNew:function(){return this.state===m},destroy:function(){this.state=v},changes:function(){var aE=null,aD,aG=this,e=aG.data,aF=aG.pristine;for(aD in e){if(aD!=="__id"&&!z(aF[aD],e[aD])){aE=aE||{};aE[aD]=e[aD]}}return aE}});X.define=function(aF){var aE,aG=aF||{},aD=aG.id||"id",aH,e;if(a.isFunction(aD)){e=aD;aH=aD}else{e=H(aD);aH=ar(aD)}aD=function(aI,aJ){if(aJ===undefined){return aI.__id||e(aI)}else{aH(aI,aJ)}};aG.id=function(aI){return aD(this.data,aI)};aE=X.extend(aG);aE.id=aD;return aE};X.UPDATED=ay;X.PRISTINE=ag;X.CREATED=m;X.DESTROYED=v;var l="create",ak="read",ax="update",u="destroy",h="change",A="error",n=[l,ak,ax,u],K=function(e){return e};function ah(e,aF){var aI=new aj(e),aF=aF||{},aG=aF.page,aH=aF.pageSize,aE=aF.group,aJ=aj.expandSort(aF.sort).concat(aj.expandGroup(aE||[])),aK,aD=aF.filter;if(aD){aI=aI.filter(aD);aK=aI.toArray().length}if(aJ){aI=aI.sort(aJ)}if(aG!==undefined&&aH!==undefined){aI=aI.skip((aG-1)*aH).take(aH)}if(aE){aI=aI.group(aE,e)}return{total:aK,data:aI.toArray()}}function g(aD,aF){var aG=new aj(aD),aF=aF||{},e=aF.aggregates,aE=aF.filter;if(aE){aG=aG.filter(aE)}return aG.aggregate(e)}var T=i.extend({init:function(e){this.data=e.data},read:function(e){e.success(this.data)},update:Z});var am=i.extend({init:function(e){var aD=this;e=aD.options=D({},aD.options,e);x(n,function(aE,aF){if(typeof e[aF]==="string"){e[aF]={url:e[aF]}}});aD.cache=e.cache?d.create(e.cache):{find:Z,add:Z};aD.dialect=e.dialect},options:{dialect:{read:K,update:K,destroy:K,create:K}},create:function(e){a.ajax(this.setup(e,l))},read:function(aE){var aH=this,aG,aD,aF,e=aH.cache;aE=aH.setup(aE,ak);aG=aE.success||Z;aD=aE.error||Z;aF=e.find(aE.data);if(aF!==undefined){aG(aF)}else{aE.success=function(aI){e.add(aE.data,aI);aG(aI)};a.ajax(aE)}},update:function(e){a.ajax(this.setup(e,ax))},destroy:function(e){a.ajax(this.setup(e,u))},setup:function(aE,aG){aE=aE||{};var aF=this,aD=aF.options[aG],e=P(aD.data)?aD.data():aD.data;aE=D(true,{},aD,aE);aE.data=aF.dialect[aG](D(e,aE.data));return aE}});d.create=function(e){var aD={inmemory:function(){return new d()},localstorage:function(){return new S()}};if(Q(e)&&P(e.find)){return e}if(e===true){return new d()}return aD[e]()};function d(){this._store={}}d.prototype={add:function(aD,e){if(aD!==undefined){this._store[stringify(aD)]=e}},find:function(e){return this._store[stringify(e)]},clear:function(){this._store={}},remove:function(e){delete this._store[stringify(e)]}};function S(){this._store=window.localStorage}S.prototype={add:function(aD,e){if(aD!=undefined){this._store.setItem(stringify(aD),stringify(e))}},find:function(e){return a.parseJSON(this._store.getItem(stringify(e)))},clear:function(){this._store.clear()},remove:function(e){this._store.removeItem(stringify(e))}};var p=ac.extend({init:function(aE){var aF=this,e,aD,aG;aE=aF.options=D({},aF.options,aE);D(aF,{_map:{},_models:{},_data:[],_view:[],_pageSize:aE.pageSize,_page:aE.page||(aE.pageSize?1:undefined),_sort:aE.sort,_filter:aE.filter,_group:aE.group,_aggregates:aE.aggregates});ac.fn.init.call(aF);aD=aE.model;aG=aE.transport;if(aD===undefined){aD={}}else{if(Q(aD)){aE.model=aD=X.define(aD)}}e=aD.id;aF._deserializer=D({data:K,total:function(aH){return aH.length},status:function(aH){return aH.status},groups:function(aH){return aH},aggregates:function(aH){return{}}},aE.deserializer);if(aG){aF.transport=P(aG.read)?aG:new am(aG)}else{aF.transport=new T({data:aE.data})}if(e){aF.find=function(aH){return aF._data[aF._map[aH]]};aF.id=function(aH){return e(aH)}}else{aF.find=aF.at}aF.bind([A,h,l,u,ax],aE)},options:{data:[],serverSorting:false,serverPaging:false,serverFiltering:false,serverGrouping:false,serverAggregates:false,autoSync:false,sendAllFields:true,batch:{mode:"multiple"}},model:function(e){var aE=this,aD=e&&aE._models[e];if(!aD){aD=new aE.options.model(aE.find(e));aE._models[aD.id()]=aD;aD.bind(h,function(){aE.trigger(ax,{model:aD})})}return aD},_idMap:function(e){var aH=this,aD=aH.id,aE,aF,aG={};if(aD){for(aE=0,aF=e.length;aE<aF;aE++){aG[aD(e[aE])]=aE}}aH._map=aG},_byState:function(aH,aG){var aE=this._models,aF=[],aD,aG=aG||K,e;for(e in aE){aD=aE[e];if(aD.state===aH){aF.push(aG(aD))}}return aF},_createdModels:function(){return this._byState(X.CREATED,function(e){return e.data})},_updatedModels:function(){var aD=this,e=aD.options.sendAllFields;return aD._byState(X.UPDATED,function(aE){if(e){return aE.data}return aE.changes()})},_destroyedModels:function(){var aD=this,e=aD.options;return aD._byState(X.DESTROYED,function(aF){var aE={};if(e.sendAllFields){return aF.data}e.model.id(aE,aF.id());return aE})},sync:function(){var aH=this,aJ,aD,aE,e=aH.options.batch,aF,aI=aH.transport,aG=aH._promises=[];aJ=aH._updatedModels();aD=aH._createdModels();aE=aH._destroyedModels();if(e===false){aF="multiple"}else{if((e.mode||"multiple")==="multiple"){aF="single"}}if(aF){aH._send(aD,ai(aI.create,aI),aF);aH._send(aJ,ai(aI.update,aI),aF);aH._send(aE,ai(aI.destroy,aI),aF)}else{aH._send({created:aD,updated:aJ,destroyed:aE},ai(aI.update,aI),"single")}a.when.apply(null,aG).then(function(){aH.trigger(h)})},_syncSuccess:function(aG,e){var aJ=this,aI,aH,aF=aJ._models,aE=aJ._map,aD=aJ._deserializer;if(!aD.status(e)){return aJ.error({data:aG})}a.each(aG,function(aK,aL){delete aF[aJ.id(aL)]});e=aD.data(e);a.each(e,function(aK,aL){aI=aG[aK];if(aI){aH=aJ.id(aI);aK=aE[aH];if(aK>=0){aJ._data[aK]=aL}}});aJ._idMap(aJ._data)},_syncError:function(aD,e){this.error({data:aD})},_send:function(e,aF,aG){var aJ=this,aE,aH=aJ._promises,aI=ai(aJ._syncSuccess,aJ,e),aD=ai(aJ._syncError,aJ,e);if(e.length==0){return}if(aG==="multiple"){for(aE=0,length=e.length;aE<length;aE++){aH.push(aF({data:e[aE],success:aI,error:aD}))}}else{aH.push(aF({data:e,success:aI,error:aD}))}return aH},create:function(aD,aG){var aF=this,e=aF._data,aE=aF.model();if(typeof aD!=="number"){aG=aD;aD=undefined}aE.set(aG);aD=aD!==undefined?aD:e.length;e.splice(aD,0,aE.data);aF._idMap(e);aF.trigger(l,{model:aE});return aE},read:function(e){var aE=this,aD=D(e,{page:aE._page,pageSize:aE._pageSize,sort:aE._sort,filter:aE._filter,group:aE._group,aggregates:aE._aggregates});aE.transport.read({data:aD,success:ai(aE.success,aE),error:ai(aE.error,aE)})},update:function(e,aF){var aE=this,aD=aE.model(e);if(aD){aD.set(aF)}},destroy:function(e){var aE=this,aD=aE.model(e);if(aD){aE._data.splice(aE._map[e],1);aE._idMap(aE._data);aD.destroy();aE.trigger(u,{model:aD})}},error:function(){this.trigger(A,arguments)},success:function(e){var aH=this,aF={},aG,aI=X?aH._updatedModels():[],aD=aH.options.serverGrouping===true&&aH._group&&aH._group.length>0,aE=aH._models;aH._total=aH._deserializer.total(e);if(aH._aggregates&&aH.options.serverAggregates){aH._aggregateResult=aH._deserializer.aggregates(e)}if(aD){e=aH._deserializer.groups(e)}else{e=aH._deserializer.data(e)}aH._data=e;a.each(aI,function(){var aJ=aH.id(this);a.each(e,function(){if(aJ===aH.id(this)){delete aE[aJ]}})});if(aH.options.serverPaging!==true){aF.page=aH._page;aF.pageSize=aH._pageSize}if(aH.options.serverSorting!==true){aF.sort=aH._sort}if(aH.options.serverFiltering!==true){aF.filter=aH._filter}if(aH.options.serverGrouping!==true){aF.group=aH._group}if(aH.options.serverAggregates!==true){aF.aggregates=aH._aggregates;aH._aggregateResult=g(e,aF)}aG=ah(e,aF);aH._view=aG.data;if(aG.total!==undefined&&!aH.options.serverFiltering){aH._total=aG.total}aH._idMap(e);aH.trigger(h)},changes:function(e){var aE=this,aD=aE._models[e];if(aD&&aD.state===X.UPDATED){return aD.changes()}},hasChanges:function(e){var aF=this,aD,aE=aF._models,e;if(e===undefined){for(e in aE){if(aE[e].state!==X.PRISTINE){return true}}return false}aD=aE[e];return !!aD&&aD.state===X.UPDATED},at:function(e){return this._data[e]},data:function(e){if(e!==undefined){this._data=e}else{return this._data}},view:function(){return this._view},query:function(e){var aF=this,e=e,aE,aD=aF.options.serverSorting||aF.options.serverPaging||aF.options.serverFiltering||aF.options.serverGrouping||aF.options.serverAggregates;if(e!==undefined){aF._pageSize=e.pageSize;aF._page=e.page;aF._sort=e.sort;aF._filter=e.filter;aF._group=e.group;aF._aggregates=e.aggregates;if(e.sort){aF._sort=e.sort=aj.expandSort(e.sort)}if(e.filter){aF._filter=e.filter=aa(e.filter)}if(e.group){aF._group=e.group=aj.expandGroup(e.group)}if(e.aggregates){aF._aggregates=e.aggregates=aj.expandAggregates(e.aggregates)}}if(aD||(aF._data===undefined||aF._data.length==0)){aF.read(e)}else{aE=ah(aF._data,e);if(!aF.options.serverFiltering){if(aE.total!==undefined){aF._total=aE.total}else{aF._total=aF._data.length}}aF._view=aE.data;aF._aggregateResult=g(aF._data,e);aF.trigger(h)}},fetch:function(){var e=this;e.query({page:e.page(),pageSize:e.pageSize(),sort:e.sort(),filter:e.filter(),group:e.group(),aggregate:e.aggregate()})},page:function(aD){var e=this;if(aD!==undefined){aD=Math.max(Math.min(Math.max(aD,1),e._totalPages()),1);e.query({page:aD,pageSize:e.pageSize(),sort:e.sort(),filter:e.filter(),group:e.group(),aggregates:e.aggregate()});return}return e._page},pageSize:function(aD){var e=this;if(aD!==undefined){e.query({page:e.page(),pageSize:aD,sort:e.sort(),filter:e.filter(),group:e.group(),aggregates:e.aggregate()});return}return e._pageSize},sort:function(aD){var e=this;if(aD!==undefined){e.query({page:e.page(),pageSize:e.pageSize(),sort:aD,filter:e.filter(),group:e.group(),aggregates:e.aggregate()});return}return this._sort},filter:function(aD){var e=this;if(aD!==undefined){e.query({page:e.page(),pageSize:e.pageSize(),sort:e.sort(),filter:aD,group:e.group(),aggregates:e.aggregate()});return}return e._filter},group:function(aD){var e=this;if(aD!==undefined){e.query({page:e.page(),pageSize:e.pageSize(),sort:e.sort(),filter:e.filter(),group:aD,aggregates:e.aggregate()});return}return e._group},total:function(){return this._total},aggregate:function(aD){var e=this;if(aD!==undefined){e.query({page:e.page(),pageSize:e.pageSize(),sort:e.sort(),filter:aD,group:e.group(),aggregates:aD});return}return e._aggregates},aggregates:function(){return this._aggregateResult},_totalPages:function(){var aD=this,e=aD.pageSize()||aD.total();return Math.ceil((aD.total()||0)/e)}});p.create=function(aF){aF=a.isArray(aF)?{data:aF}:aF;var aD=aF||{},e=aD.data,aE=aD.fields,aH=aD.table,aG=aD.select;if(aE){if(!e){if(aH){e=M(aH,aE)}else{if(aG){e=L(aG,aE)}}}else{if(aG){al(e,aG,aE)}}}aD.data=e;return aD instanceof p?aD:new p(aD)};function L(aJ,aD){var aH=a(aJ)[0].children,aG,aF,e=[],aI,aE;for(aG=0,aF=aH.length;aG<aF;aG++){aI={};aE=aH[aG];aI[aD[0].field]=aE.text;aI[aD[1].field]=aE.value;e.push(aI)}return e}function al(e,aL,aE){var aF=H(aE[0].field),aG=H(aE[1].field),aI=e.length,aK=[],aH=0;for(;aH<aI;aH++){var aJ="<option",aD=e[aH],aM=aF(aD),aN=aG(aD);if(aN||aN===0){aJ+=" value="+aN}aJ+=">";if(aM||aM===0){aJ+=aM}aJ+="</option>";aK.push(aJ)}aL.html(aK.join(""))}function M(aN,aI){var aO=a(aN)[0].tBodies[0],aM=aO?aO.rows:[],aL,aK,aH,aG=aI.length,aE=[],aD,aJ,e,aF;for(aL=0,aK=aM.length;aL<aK;aL++){aJ={};aF=true;aD=aM[aL].cells;for(aH=0;aH<aG;aH++){e=aD[aH];if(e.nodeName.toLowerCase()!=="th"){aF=false;aJ[aI[aH].field]=e.innerHTML}}if(!aF){aE.push(aJ)}}return aE}b.DataSource=p;b.Model=X;b.getter=H;b.setter=ar;b.expr=C;var av={paramName:"data",useWithBlock:true,begin:"<#",end:"#>",render:function(aG,e){var aE,aF,aD="";for(aE=0,aF=e.length;aE<aF;aE++){aD+=aG(e[aE])}return aD},compile:function(aL,aH){var aK=D({},this,aH),aI=aK.paramName,e=aK.begin,aE=aK.end,aM=aK.useWithBlock,aG="var o='',e = $.telerik.htmlEncode;",aD=/\${([^}]*)}/g,aF=new RegExp(e+"=(.+?)"+aE,"g"),aJ=new RegExp("'(?=[^"+aE[0]+"]*"+aE+")","g");aG+=aM?"with("+aI+"){":"";aG+="o+='";aG+=aL.replace(/[\r\t\n]/g," ").replace(aJ,"\t").split("'").join("\\'").split("\t").join("'").replace(aD,"';o+=e($1);o+='").replace(aF,"';o+=$1;o+='").split(e).join("';").split(aE).join("o+='");aG+=aM?"'}":"';";aG+="return o;";return new Function(aI,aG)}};function J(e){return(""+e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}a.telerik.template=a.proxy(av.compile,av);a.telerik.htmlEncode=J;var k=ac.extend({init:function(e,aD){var aE=this;ac.fn.init.call(aE);aE.element=a(e);aE.options=D(true,{},aE.options,aD)}});a.telerik.Component=k;function s(e){var aD=1,aE=arguments.length;for(aD=1;aD<aE;aD++){t(e,arguments[aD])}return e}function t(e,aH){var aE,aG,aF,aD;for(aE in aH){aG=aH[aE];aF=typeof aG;if(aF==="object"&&aG!==null&&aG.constructor!==Array){aD=e[aE];if(typeof(aD)==="object"){e[aE]=aD||{}}else{e[aE]={}}t(e[aE],aG)}else{if(aF!=="undefined"){e[aE]=aG}}}return e}a.telerik.deepExtend=s})(jQuery);;
(function(a){var b=a.telerik,f=[8,9,37,38,39,40,46,35,36,44],g=["font-family","font-size","font-stretch","font-style","font-weight","line-height","color","text-align","text-decoration","text-transform"];b.scripts.push("telerik.textbox.js");function e(j){var l={};for(var h=0,k=g.length;h<k;h++){var m=g[h],n=j.css(m);if(n){if(g[h]!="font-style"&&n!="normal"){l[m]=n}}}return l}b.textbox=function(k,n){if(k.nodeName.toLowerCase()!=="input"&&k.type.toLowerCase()!=="text"){throw"Target element is not a INPUT"}var p=this;a.extend(p,n);p.element=k;var h=p.$element=a(k).bind({keydown:a.proxy(p._keydown,p),keypress:a.proxy(p._keypress,p)}).bind("paste",a.proxy(p._paste,p));h.closest("form").bind("reset",a.proxy(p._onParentFormReset,p));var i=new b.stringBuilder();if(k.parentNode.nodeName.toLowerCase()!=="div"){h.addClass("t-input").wrap(a('<div class="t-widget t-numerictextbox"></div>'));if(p.showIncreaseButton){i.cat('<a class="t-link t-icon t-arrow-up" href="#" tabindex="-1" title="').cat(p.increaseButtonTitle).cat('">Increment</a>')}if(p.showDecreaseButton){i.cat('<a class="t-link t-icon t-arrow-down" href="#" tabindex="-1" title="').cat(p.decreaseButtonTitle).cat('">Decrement</a>')}if(i.buffer.length>0){a(i.string()).insertAfter(h)}}p.$wrapper=h.closest(".t-numerictextbox").find(".t-arrow-up, .t-arrow-down").bind({click:b.preventDefault,dragstart:b.preventDefault}).end().bind({focusin:a.proxy(p._focus,p),focusout:a.proxy(p._blur,p)});p.enabled=!h.is("[disabled]");i.buffer=[];var l=p.groupSeparator,o=p.symbol;if(l){l="\\"+l}if(o){o="\\"+o}i.cat("( |").cat(l).catIf("|"+o,o).cat(")");p.replaceRegExp=new RegExp(i.string(),"g");var m=h.attr("value"),j=h.attr("class").replace("t-input","").replace("input-validation-error","");i.buffer=[];i.cat('<div class="t-formatted-value').catIf(" t-state-empty",m==""&&p.enabled).catIf(j,j).cat('">').cat(m||(p.enabled?p.text:"")).cat("</div>");p.$text=a(i.string()).insertBefore(h).css(e(h)).click(function(q){if(p.enabled){k.focus()}});p._blur();p[p.enabled?"enable":"disable"]();p.numFormat=p.numFormat===undefined?p.type.charAt(0):p.numFormat;p.step=p.parse(p.step);p.val=p.parse(p.val);p.minValue=p.parse(p.minValue);p.maxValue=p.parse(p.maxValue);p.decimals={"190":".","188":","};p.specialDecimals={"110":p.separator};p.value(m||p.val);b.bind(p,{load:p.onLoad,valueChange:p.onChange})};b.textbox.prototype={_paste:function(h){setTimeout(a.proxy(function(){var j=h.target.value;if(j=="-"){return true}var i=this.parse(j);if(i||i==0){this._update(i)}},this))},_keydown:function(m){setTimeout(a.proxy(function(){h.toggleClass("t-state-error",!this.inRange(this.parse(h.val()),this.minValue,this.maxValue))},this));var q=m.keyCode,h=this.$element,n=h[0],y=h.val(),u=this.separator,t=d(n),x=t.start,o=t.end,v=y?y.indexOf(u):-1,i=v===-1;if(!i&&x!==-1){if(v>=x&&v<o){i=true}}var w=this.specialDecimals[q];if(w){if(i&&this.digits>0){var p,s;if(x!=-1){p=x;s=o}else{var j=b.caretPos(n);p=j;s=j}h.val(y.slice(0,p)+w+y.slice(s,y.length));if(a.browser.msie){if(n.createTextRange){var r=n.createTextRange();r.moveStart("textedit",1);r.select()}}}return false}var k=this.decimals[q];if(k){if(k===u&&this.digits>0&&i){return true}else{m.preventDefault()}}if(q==13||q==9){this._update(this.parse(h.val()));return true}if(q==38||q==40){var l=q==38?1:-1;this._modify(l*this.step);return true}if(q==222){m.preventDefault()}},_keypress:function(h){var i=h.target,k=h.keyCode||h.which;if(k==0||a.inArray(k,f)!=-1||h.ctrlKey||(h.shiftKey&&k==45)){return true}var j;if(this.minValue===null||this.minValue<0){if(d(i).start===0||(b.caretPos(i)===0&&i.value.indexOf("-")===-1)){j=true}}if((j&&String.fromCharCode(k)=="-")||this.inRange(k,48,57)){return true}h.preventDefault()},_focus:function(){if(this.enabled){this._showTextBoxValue();this.$text.hide();var h=this.$element[0];this._focusing=setTimeout(function(){h.focus();if(a.browser.msie){h.select()}else{h.selectionStart=0;h.selectionEnd=h.value.length}},0)}},_blur:function(){clearTimeout(this._focusing);if(this.$element.attr("disabled")){return}this.$element.removeClass("t-state-error");if(this.enabled){this.$text.show();this._hideTextBoxValue()}var i=this.minValue,h=this.maxValue,j=this.parse(this.$element.val());if(j!=null){if(i!=null&&j<i){j=i}else{if(h!=null&&j>h){j=h}}j=parseFloat(j.toFixed(this.digits))}this._update(j)},_clearTimer:function(h){clearTimeout(this.timeout);clearInterval(this.timer);clearInterval(this.acceleration)},_stepper:function(h,j){if(h.which==1){var i=this.step;this._modify(j*i);this.timeout=setTimeout(a.proxy(function(){this.timer=setInterval(a.proxy(function(){this._modify(j*i)},this),80);this.acceleration=setInterval(function(){i+=1},1000)},this),200)}},_modify:function(j){var k=this.parse(this.element.value),i=this.minValue,h=this.maxValue;k=k?k+j:j;if(i!==null&&k<i){k=i}else{if(h!==null&&k>h){k=h}}this._update(parseFloat(k.toFixed(this.digits)))},_update:function(i){var h=this.val;this._value(i);if(h!=i){if(b.trigger(this.element,"valueChange",{oldValue:h,newValue:i})){this._value(h)}}},_value:function(k){var i=(typeof k==="number")?k:this.parse(k),j=this.enabled?this.text:"",h=i===null;if(i!=null){i=parseFloat(i.toFixed(this.digits))}this.val=i;this.$element.val(h?"":this.formatEdit(i));this.$text.html(h?j:this.format(i));this.$text.toggleClass("t-state-empty",h)},_hideTextBoxValue:function(){var h=this.$element;if(this.enabled){setTimeout(function(){h.css("color",h.css("background-color"))});if(a.browser.opera){h.css({color:h.css("background-color"),"text-indent":"-4444px"})}}else{if(!a.browser.msie){h.css({color:h.css("background-color"),"text-indent":"-4444px"})}else{h.css({color:h.css("background-color"),"letter-spacing":"1000px"})}}},_showTextBoxValue:function(){var h=this.$element,i=this.$text;if(this.enabled){setTimeout(function(){h.css({color:i.css("color"),"text-indent":"","letter-spacing":""})})}else{if(!a.browser.msie){h.css({color:i.css("background-color"),"text-indent":"0px"})}else{h.css({color:i.css("background-color"),"letter-spacing":"0px"})}}},_onParentFormReset:function(){var h=this;window.setTimeout(function(){h._value(h.$element.val())},1)},enable:function(){var h=this.$wrapper.find(".t-arrow-up, .t-arrow-down"),i=a.proxy(this._clearTimer,this);this.enabled=true;this.$element.removeAttr("disabled");if(!this.val&&this.val!=0){this.$text.addClass("t-state-empty").html(this.text)}else{this._hideTextBoxValue()}this.$wrapper.removeClass("t-state-disabled");h.unbind("mouseup").unbind("mouseout").unbind("dblclick").bind({mouseup:i,mouseout:i,dblclick:i});var j="mousedown";h.eq(0).unbind(j).bind(j,a.proxy(function(k){this._stepper(k,1)},this));h.eq(1).unbind(j).bind(j,a.proxy(function(k){this._stepper(k,-1)},this))},disable:function(){var h=this;h.enabled=false;h.$wrapper.addClass("t-state-disabled").find(".t-icon").unbind("mousedown").bind("mousedown",b.preventDefault);h.$element.attr("disabled","disabled");h.$text.css("color","");if(!h.val&&h.val!=0){h.$text.html("")}else{h._hideTextBoxValue()}},value:function(i){if(i===undefined){return this.parse(this.element.value)}var h=(typeof i==="number")?i:this.parse(i);if(!this.inRange(h,this.minValue,this.maxValue)){h=null}this._value(h)},formatEdit:function(i){var h=this.separator;if(i.toString().toLowerCase().indexOf("e")>-1){i=i.toFixed(this.digits)}if(i&&h!="."){i=i.toString().replace(".",h)}return i},format:function(h){return b.formatNumber(h,this.numFormat,this.digits,this.separator,this.groupSeparator,this.groupSize,this.positive,this.negative,this.symbol,true)},inRange:function(h,j,i){return h===null||((j!==null?h>=j:true)&&(i!==null?h<=i:true))},parse:function(l){var j=null,k=this.separator;if(l||l=="0"){if(typeof l==typeof 1){return l}if(l.toLowerCase().indexOf("e")>-1&&!isNaN(Number(l))){l=Number(l);l=l.toFixed(this.digits).replace(".",k)}l=l.replace(this.replaceRegExp,"");if(k&&k!="."){l=l.replace(k,".")}var h=b.patterns[this.type].negative[this.negative].replace(/(\(|\))/g,"\\$1").replace("*","").replace("n","([\\d|\\.]*)"),i=new RegExp(h);if(i.test(l)){j=-parseFloat(i.exec(l)[1])}else{j=parseFloat(l)}}return isNaN(j)?null:j}};a.fn.tTextBox=function(i){var j="numeric";if(i&&i.type){j=i.type}var h=a.fn.tTextBox.defaults[j];h.digits=b.cultureInfo[j+"decimaldigits"];h.separator=b.cultureInfo[j+"decimalseparator"];h.groupSeparator=b.cultureInfo[j+"groupseparator"];h.groupSize=b.cultureInfo[j+"groupsize"];h.positive=b.cultureInfo[j+"positive"];h.negative=b.cultureInfo[j+"negative"];h.symbol=b.cultureInfo[j+"symbol"];i=a.extend({},h,i);i.type=j;return this.each(function(){var k=a(this);i=a.meta?a.extend({},i,k.data()):i;if(!k.data("tTextBox")){k.data("tTextBox",new b.textbox(this,i));b.trigger(this,"load")}})};var c={val:null,text:"",step:1,inputAttributes:"",increaseButtonTitle:"Increase value",decreaseButtonTitle:"Decrease value",showIncreaseButton:true,showDecreaseButton:true};a.fn.tTextBox.defaults={numeric:a.extend(c,{minValue:-100,maxValue:100}),currency:a.extend(c,{minValue:0,maxValue:1000}),percent:a.extend(c,{minValue:0,maxValue:100})};function d(h){var l=-1,k=-1;if(document.selection){var j=document.selection.createRange().text,i=j.length;if(i>0){l=h.value.indexOf(j);k=i}}else{if(h.selectionStart!==undefined){var n=h.selectionStart,m=h.selectionEnd;if(n!=m){l=n;k=m}}}return{start:l,end:k}}})(jQuery);;
(function(a,n){var h={TAB:9,ENTER:13,ESC:27,LEFT:37,UP:38,RIGHT:39,DOWN:40,SPACEBAR:32,PAGEUP:33,PAGEDOWN:34,F2:113};var b=a.telerik;var j=/"+\\\/Date\((.*?)\)\\\/"+/g;var k="tr:not(.t-grouping-row,.t-group-footer,.t-detail-row,.t-no-data,.t-footer-template):visible",d=">td:not(.t-group-cell,.t-hierarchy-cell):visible",f=k+d+":first",g="t-state-focused";b.scripts.push("telerik.grid.js");function m(o){return new Function("data",("var p=[];with(data){p.push('"+unescape(o).replace(/[\r\t\n]/g," ").replace(/'(?=[^#]*#>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<#=(.+?)#>/g,"',$1,'").split("<#").join("');").split("#>").join("p.push('")+"');}return p.join('');"))}function e(o){return(o!=null?o+"":"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function i(q,s,r){var o=a("<col />").css("width",s[r].width),t,u,p=0;for(t=0,u=s.length;t<u;t++){if(t>=r&&p){break}if(!s[t].hidden){p++}}if(t>r){q.eq(p-1).before(o)}else{q.eq(p-1).after(o)}}b.grid=function(p,w){var q=this;this.element=p;this.groups=[];this.editing={};this.filterBy="";this.groupBy="";this.orderBy="";a.extend(this,w);this.sorted=a.grep(this.columns,function(C){return C.order});this.$tbody=a("> .t-grid-content > table > tbody",p);this.scrollable=this.$tbody.length>0;this.$headerWrap=a("> .t-grid-header > .t-grid-header-wrap",p);this.$footerWrap=a("> .t-grid-footer > .t-grid-footer-wrap",p);if(!this.scrollable){this.$tbody=a("> table > tbody",p);this.$header=a("> table > thead > tr",p);this.$footer=a("> table > tfoot",p)}else{a("> .t-grid-content",p).tScrollable();this.$header=a("> .t-grid-header > .t-grid-header-wrap > table > tbody > tr",p);this.$footer=a("> .t-grid-footer",p);var t=a(p).closest(".t-rtl").length,s=this._isRightScrollBar();if(t){if(s){a(p).addClass("t-grid-rightscroll")}}var x=this.$headerWrap.add(this.$footerWrap),y=b.scrollbarWidth(),z=x.parent();var u=b.isTouch;if(u){z.css("padding","0");x.css({width:"auto","border-width":0});a("> .t-grid-content",p).css("width","auto");var A=a("> .t-grid-content > table",p);A.css("table-layout","auto");window.setTimeout(function(){A.css("table-layout","fixed")},1)}else{if(!t||s){z.css("padding-right",y)}else{z.css("padding-left",y)}if(y==0){x.css("border-width",0)}}a("> .t-grid-content",p).bind("scroll",function(){if(q.pageOnScroll){var C=this.scrollTop+this.clientHeight;if(C===this.scrollHeight&&q.currentPage<q.totalPages()&&!q._pagingInProgress){q._pagingInProgress=true;q.pageTo(q.currentPage+1)}}x.scrollLeft(this.scrollLeft)})}if(this.rowTemplate){this.rowTemplate=m(this.rowTemplate)}this.$tbody.delegate(".t-hierarchy-cell .t-plus, .t-hierarchy-cell .t-minus","click",b.stopAll(function(F){var C=a(F.target);var G=C.hasClass("t-plus");C.toggleClass("t-minus",G).toggleClass("t-plus",!G);var D=C.closest("tr.t-master-row");if(this.detail&&!D.next().hasClass("t-detail-row")){var E=0;a.each(this.columns,function(){if(!this.hidden){E++}});a(new b.stringBuilder().cat('<tr class="t-detail-row').catIf(" t-alt",D.hasClass("t-alt")).cat('">').rep('<td class="t-group-cell"></td>',D.find(".t-group-cell").length).cat('<td class="t-hierarchy-cell"></td>').cat('<td class="t-detail-cell" colspan="').cat(E).cat('">').cat(this.displayDetails(this.dataItem(D))).cat("</td></tr>").string()).insertAfter(D)}b.trigger(this.element,G?"detailViewExpand":"detailViewCollapse",{masterRow:D[0],detailRow:D.next(".t-detail-row")[0]});D.next().toggle(G)},this));this.$pager=a("> .t-grid-pager .t-pager",p);var o=new b.dropDown({effects:b.fx.slide.defaults(),onClick:a.proxy(function(C){this.changePageSize(a(C.item).text());o.close()},this)});a(p).delegate(".t-button","click",a.proxy(function(C){this._command(C)},this));o.dataBind(w.pageSizesInDropDown||[]);a(document.documentElement).bind("mousedown",function(C){var D=o.$element[0];if(!a.contains(D,C.target)){o.close()}});this.$pager.delegate(".t-state-disabled","click",b.preventDefault).delegate(".t-link:not(.t-state-disabled)","mouseenter",b.hover).delegate(".t-link:not(.t-state-disabled)","mouseleave",b.leave).delegate("input[type=text]","keydown",a.proxy(this.pagerKeyDown,this)).delegate(".t-page-size .t-dropdown-wrap","click",function(){var C=a(this);o.open({offset:C.offset(),outerHeight:C.outerHeight(),outerWidth:C.outerWidth(),zIndex:b.getElementZIndex(this)})});a("> .t-grid-pager",p).delegate(".t-refresh","click",a.proxy(this.refreshClick,this));a(p).delegate(".t-button","hover",b.preventDefault);if(this.sort){this.$header.delegate("a.t-link","hover",function(){a(this).toggleClass("t-state-hover")})}var v="tr:not(.t-grouping-row,.t-detail-row,.t-no-data,.t-group-footer,:has(>.t-edit-container))";if(this.selectable){var B=this.$tbody[0];this.$tbody.delegate(v,"click",function(C){if(this.parentNode==B){q.rowClick(C)}}).delegate(v,"hover",function(C){if(this.parentNode==B){if(C.type=="mouseenter"){a(this).addClass("t-state-hover")}else{a(this).removeClass("t-state-hover")}}})}if(this.isAjax()||this.operationMode==="client"){this.$pager.delegate(".t-link:not(.t-state-disabled)","click",b.stop(this.pagerClick,this));if(this.sort){this.$header.delegate("a.t-link","click",b.stop(this.headerClick,this))}}for(var r=0;r<this.plugins.length;r++){b[this.plugins[r]].initialize(this)}b.bind(this,{columnResize:this.onColumnResize,columnReorder:this.onColumnReorder,command:this.onCommand,complete:this.onComplete,"delete":this.onDelete,detailViewExpand:this.onDetailViewExpand,detailViewCollapse:this.onDetailViewCollapse,dataBinding:this.onDataBinding,dataBound:this.onDataBound,edit:this.onEdit,error:this.onError,load:this.onLoad,rowSelect:this.onRowSelect,rowDataBound:this.onRowDataBound,save:this.onSave,submitChanges:this.onSubmitChanges,columnHide:this.onColumnHide,columnShow:this.onColumnShow});this.initializeColumns();if(this.keyboardNavigation){this.initializeNavigation()}if(this.isAjax()||this.operationMode==="client"){this._dataSource()}if(this.columnContextMenu){this.initializeContextMenu()}};b.grid.prototype={initializeNavigation:function(){var r=this,o=a(r.element).attr("tabIndex",0),p="keydown",q=a.proxy(r._keyDown,r);r._initNavigationMouseEvents();o.bind({focus:function(t){var s=r.current();if(s){s.addClass(g)}else{if(s=r.$tbody.find("td."+g).eq(0),s.length){r._current=s}else{r.current(o.find(f))}}},focusin:function(s){var t=a(s.target).closest("td");if(t.parent().hasClass("t-grid-new-row")){r.current(t)}},focusout:function(){if(r._current){r._current.removeClass(g)}},keydown:q});if(r.editing&&r.editing.mode=="PopUp"){o.bind("edit",function(s){a(s.form).bind(p,q)});a("#"+r.formId()+":visible").bind(p,q)}if(r.pageOnScroll){o.bind("dataBinding",function(){var t=r.current(),u=t?t.parent().index(k)-1:0,s=t?t.index():0;o.one("dataBound",function(){var v=r.$tbody.find(k);r._focusGridElement();if(r._current){r._current.removeClass(g)}r._current=v.eq(u).children().eq(s).addClass(g)})})}},_onCommand:function(o){if(o.row){o.dataItem=this.dataItem(o.row)}return b.trigger(this.element,"command",o)},_onComplete:function(o){return b.trigger(this.element,"complete",o)},_command:function(q){var p=a(q.currentTarget);var r=p.closest(".t-grid")[0];if(p.is(".t-ajax")&&r==this.element){var s=/t-grid-([^\s]*)/.exec(p.attr("class"));if(s){s=s[1]}var o={name:s,row:p.closest("tr")[0]};q.preventDefault();if(this._onCommand(o)){return}a.ajax(this.ajaxOptions({url:p.attr("href"),data:o.data||{},success:a.proxy(function(t){try{t=eval("("+t+")")}catch(u){if(!b.ajaxError(this.element,"error",xhr,"parsererror")){alert("Error! The requested URL did not return JSON.")}return}this._onComplete({name:s,response:t})},this)}))}},_keyDown:function(u){var F=this,w=a(F.element),E=F.$tbody,z=w.closest(".t-rtl").length,A=u.keyCode,t="dataBound",s=a.proxy(F.current,F),r=s(),B=F.$pager.length>0,q=F.selectable,C=E.has("tr>td>.t-grid-select").length>0,D=a(u.target),o=!D.is(":button,a,:input,a>.t-icon"),v=F.editRow,y=false,p;if(!r){if(F.editing&&F.editing.mode=="PopUp"){r=F._current=w.find(f)}else{return}}p=r.index();if(!a.browser.msie){o=o&&D[0]===w[0]}if(o){if(B&&h.PAGEDOWN==A){if(!F.pageOnScroll){w.one(t,function(){s(w.find(f));F._focusGridElement()})}if(F.currentPage<F.totalPages()){F.pageTo(F.currentPage+1)}y=true}else{if(B&&h.PAGEUP==A){if(!F.pageOnScroll){w.one(t,function(){s(w.find(f));F._focusGridElement()});if(F.currentPage>1){F.pageTo(Math.max(F.currentPage-1,1))}}y=true}else{if(h.UP===A){s(r?r.parent().prevAll(k).last().children(":eq("+p+"),:eq(0)").last():w.find(f));y=true}else{if(h.DOWN===A){s(r?r.parent().nextAll(k).first().children(":eq("+p+"),:eq(0)").last():w.find(f));y=true}else{if(h.LEFT===A){if(r){if(z){r=r.nextAll(":visible:first")}else{r=r.prevAll(":not(.t-group-cell, .t-hierarchy-cell):visible:first")}}else{r=w.find(f)}s(r);y=true}else{if(h.RIGHT===A){if(r){if(z){r=r.prevAll(":not(.t-group-cell, .t-hierarchy-cell):visible:first")}else{r=r.nextAll(":visible:first")}}else{r=w.find(f)}s(r);y=true}else{if((q||C)&&h.SPACEBAR==A){y=true;var x=r.parent().find(".t-grid-select:first").andSelf();if(C&&x[1]){location.href=x[1].href}else{if(q){x.click()}}}}}}}}}}if(!y&&v&&!D.is(":button,a,a>.t-icon")){y=F._handleEditing(u)}if(y){u.preventDefault();u.stopPropagation()}},_handleEditing:function(r){var I=this,C=r.keyCode,G=r.shiftKey,D,q=a.proxy(I.current,I),o=a.proxy(I._clearInputSelection,I),v=a.proxy(I._focusGridElement,I),p=q(),t=a(I.element),H=I.$tbody,E=p.parent(),F=E.index(),J,w=false,s="td.t-grid-edit-cell",u=":input:visible:first",x=I.isAjax(),A=E.closest("tr.t-grid-new-row")[0],z=I.editing.mode==="InCell",B=I.editing.mode==="PopUp",y=E.closest("tr.t-grid-edit-row")[0]||(B&&a("#"+I.formId()+":visible").length);if(h.ENTER==C||h.F2==C){w=true;if(y){if(a(r.target).is("textarea")){w=false;return}o(p.find(u)[0]);if(z){J=I.validate();if(!J){p.find(u).focus();return}if(p.is(s)){I.saveCell(p[0])}else{E.find(s).each(function(){I.saveCell(this)});I.editCell(p[0])}if(I.valid){v()}}else{if(x){t.one("dataBound",function(){var K=a(this).data("tGrid");K._current=K.$tbody.children().eq(F).find(d).eq(0);v()});if(B){a(".t-grid-update,.t-grid-insert","#"+I.formId()).click()}else{if(A){I.insertRow(E)}else{I.updateRow(E)}}}else{if(I.validate()){if(B){E=a("#"+I.formId())}E.find(".t-grid-update,.t-grid-insert").click()}}}}else{if(z){H.find(s).each(function(){I.saveCell(this)});I.editCell(p[0])}else{if(x){I.editRow(E);q(E.children().eq(0));if(B){E=a("#"+I.formId())}E.find(u).focus()}else{location.href=E.find(".t-grid-edit:first").attr("href")}}}}else{if(h.ESC==C&&y){w=true;o(p.find(u)[0]);if(z&&p.is(s)){I.cancelCell(p);v()}else{if(x){if(B){a(".t-grid-cancel","#"+this.formId()).click()}else{I.cancelRow(E)}q(E.find(d).eq(0));v()}else{if(B){E=a("#"+I.formId())}location.href=E.find(".t-grid-cancel:first").attr("href")}}}else{if(z&&h.TAB==C){if(y){o(p.find(u)[0]);I.saveCell(p);if(I.valid){v()}else{p.find(u).focus();return true}w=true}D=G?p.prevAll(":not(.t-group-cell, .t-hierarchy-cell):visible:first"):p.nextAll(":visible:first");if(!D.length){D=p.parent()[G?"prevAll":"nextAll"](k).children(G?":not(.t-group-cell, .t-hierarchy-cell):visible:last":":not(.t-group-cell, .t-hierarchy-cell):visible:first")}q(D);if(I.keyboardNavigation.editOnTab&&D.length){I.editCell(D[0]);setTimeout(function(){if(D.hasClass("t-grid-edit-cell")){D.find(u).focus()}});w=true}}}}return w},_initNavigationMouseEvents:function(){var y=this,x=y.$tbody,v=k+d,o=a.browser,p="click",s="mousedown",q,w,r,t=".t-grid-edit-row",u=":button,a,:input,a>.t-icon";if(o.msie){x.delegate(v,p,function(z){w=a(z.target),r=a(z.currentTarget),q=y._current;if(r.closest("tbody")[0]!==x[0]){return}if(w.is(u)){if(!(q&&!r.parent().is(t))){if(q){q.removeClass(g)}y._current=r}}else{if(q&&q[0]===r[0]){y._current=null}y.current(r);z.preventDefault()}})}else{x.delegate(v,s,function(z){w=a(z.target),r=a(z.currentTarget),q=y._current;if(r.closest("tbody")[0]!==x[0]){return}if(w.is(u)){if(!(q&&!r.parent().is(t))){if(q){q.removeClass(g)}y._current=r}}else{y.current(r)}})}},_clearInputSelection:function(p){if(!p||a(p).is(":checkbox, :radio")){return}var o=a.browser,q;if(o.msie&&parseInt(o.version)==8){q=p.createTextRange();q.moveStart("textedit",1);q.select()}},_focusGridElement:function(){var o=a.browser;if(o.msie&&parseInt(o.version)<9){a("body",document).focus()}this.element.focus()},current:function(p){var q=this,o=q._current;if(p!==n&&p.length){if(!o||o[0]!==p[0]){p.addClass(g);if(o){o.removeClass(g)}q._current=p;q._scrollTo(p.parent()[0])}}else{return q._current}},_scrollTo:function(s){var p=this.$tbody.closest("div.t-grid-content")[0];if(!s||!p){return}var u=s.offsetTop,t=s.offsetHeight,r=p.scrollTop,q=p.clientHeight,o=u+t;p.scrollTop=r>u?u:o>(r+q)?o-q:r},_isRightScrollBar:function(){var o=536;return(a.browser.webkit&&parseInt(a.browser.version,10)<o)||(a.browser.mozilla&&parseInt(a.browser.version,10)<2)},_transformParams:function(o){var t=this,s=t._isServerOperation(),r={},p=t.filterBy||"",q=t.orderBy||"";if(s){if(o.page){r[t.queryString.page]=o.page}if(o.pageSize){r[t.queryString.size]=o.pageSize}if(q!==""){r[t.queryString.orderBy]=q}if(p!==""){r[t.queryString.filter]=p}if(t.groupBy){r[t.queryString.groupBy]=t.groupBy}if(o.aggregates&&o.aggregates.length){r.aggregates=a.map(t.columns,function(u){if(u.aggregates){return u.member+"-"+u.aggregates.join("-")}}).join("~")}}delete o.page;delete o.pageSize;delete o.sort;delete o.filter;delete o.group;delete o.aggregates;if(t.ws){r=b.toJson(a.extend(o,{state:r}))}else{r=a.extend(r,o)}return r},_dataSourceOptions:function(){var u=this,s=this.pageSize>0,r,p=u.data||[],t=u._isServerOperation(),o=a.map(u.columns||[],function(v){return a.map(v.aggregates||[],function(w){return{field:v.member,aggregate:w}})}),q={translateGroup:function(v){return{value:v.Key,hasSubgroups:v.HasSubgroups,aggregates:v.Aggregates,items:v.HasSubgroups?a.map(v.Items,a.proxy(this.translateGroup,this)):v.Items}},flatGroups:function(v){if(v.HasSubgroups){return this.flatGroups(v.Items)}return v.Items},convert:function(v){return v.d||v},mergeChanges:function(v,D,x){var z,A,C,B=[],y,w=u.dataSource;a.each(x,function(F,E){for(A=0,C=v.length;A<C;A++){if(E===w.id(v[A])){v.splice(A,1);break}}});a.each(D,function(E,F){z=w.id(this);y=false;for(A=0,C=v.length;A<C;A++){if(z===w.id(v[A])){a.extend(true,v[A],F);y=true;break}}if(!y){B.push(F)}});return v.concat(B)},data:function(w){var x=u.dataSource,v=x.data(),z=x.page()-1,A=x.pageSize(),y=u.deletedIds||[];u.deletedIds=[];if(w){w=this.convert(w);w=!a.isArray(w)?w.data||w.Data:w;if(v&&v.length&&!t&&x.id){if(w.length&&typeof w[0].HasSubgroups!="undefined"&&!t){w=a.map(w,a.proxy(this.flatGroups,this))}return this.mergeChanges(v,w,y)}}return w},total:function(v){if(v){v=this.convert(v);return !a.isArray(v)?v.total||v.Total||0:v.length}return 0},groups:function(v){v=this.data(v);return a.map(v,a.proxy(this.translateGroup,this))},aggregates:function(v){v=this.convert(v);return v.aggregates||{}}};r={serverSorting:t,serverPaging:t,serverFiltering:t,serverGrouping:t,serverAggregates:t,page:s?u.currentPage:n,pageSize:s?u.pageSize:n,aggregates:u.aggregates||o,error:a.proxy(function(v){var x=v[0],w=v[1];if(b.ajaxError(this.element,"error",x,w)){return}},this),group:a.map(u.groups||[],function(v){return{field:v.member,dir:v.order,aggregates:o}}),sort:a.map(u.sorted,function(v){return{field:v.member,dir:v.order}}),filter:a.map(a.grep(u.columns,function(v){return v.filters}),function(v){return a.map(v.filters,function(x){var y=x.filters,A,B,C;if(y){for(A=0,B=y.length;A<B;A++){C=y[A].value;if(v.type=="Number"){C=parseFloat(C)}else{if(v.type=="Date"){if(typeof C==="string"){var w=/^\/Date\((.*?)\)\/$/.exec(C);if(w){C=new Date(parseInt(w[1]))}else{var z=v.format?/\{0(:([^\}]+))?\}/.exec(v.format)[2]:b.cultureInfo.shortDate;C=b.datetime.parse({value:C,format:z}).toDate()}}}}y[A].value=C;y[A].field=v.member}}return x})})};if(t||(u.isAjax()&&!p.length)){a.extend(r,{transport:{dialect:{read:a.proxy(u._transformParams,this)},read:{type:"POST",dataType:"text",dataFilter:function(v,w){v=eval("("+v.replace(j,"new Date($1)")+")");u._onComplete({name:"dataBinding",response:v});return v},contentType:u.ws?"application/json; charset=utf-8":n,complete:a.proxy(u.hideBusy,u)}},deserializer:q})}else{if(p.length){a.extend(r,{data:{data:u.data,total:u.total||p.length},deserializer:q})}}return r},_dataSource:function(){var q=this,p=q._dataSourceOptions(),o=p.data;q.dataSource=new b.DataSource(p);if(o&&o.data){q._convertInitialData(o.data)}q.dataSource.bind("change",a.proxy(q._dataChange,q))},_convertInitialData:function(o){var t=this;if(!t._isServerOperation()&&o&&o.length){t.dataSource.read();var u=t.dataSource.view();if(u.length&&u[0].hasSubgroups!=n){var s=[],p=function(v){if(v.hasSubgroups){return p(v.items)}return v.items};for(var q=0,r=u.length;q<r;q++){s=s.concat(p(u[q]))}t.data=s}else{t.data=u}}},_mapAggregates:function(o){var q={};for(var p in o){q[p.replace(/^\w/,function(r){return r.toUpperCase()})]=o[p]}return q},rowClick:function(q){var p=a(q.target);if(!p.is(":button,a,.t-delete,input,select,textarea,option,a>.t-icon")){q.stopPropagation();var o=p.closest("tr").addClass("t-state-selected").siblings().removeClass("t-state-selected").end();b.trigger(this.element,"rowSelect",{row:o[0]})}},$rows:function(){return this.$tbody.find("> tr:not(.t-grouping-row,.t-detail-row)")},expandRow:function(o){a(o).find("> td .t-plus, > td .t-expand").click()},collapseRow:function(o){a(o).find("> td .t-minus, > td .t-collapse").click()},headerClick:function(o){o.preventDefault();this.toggleOrder(this.$columns().index(a(o.target).closest("th")));this.sort(this.sortExpr())},refreshClick:function(o,p){if(a(p).is(".t-loading")){return}if(this.isAjax()){o.preventDefault();if(!this._isServerOperation()){this.dataSource.data([])}this.ajaxRequest()}},sort:function(o){this.orderBy=o;this.ajaxRequest()},columnFromTitle:function(p){p=a.trim(p);var o=a.grep(this.$columns(),function(q){return a.trim(a(q).text())==p})[0];if(o){return this.columns[this.$columns().index(o)]}return a.grep(this.columns,function(q){return q.title==p})[0]},columnFromMember:function(p){var o=a.grep(this.columns,function(q){return q.member==p})[0];if(!o){o=a.grep(this.columns,function(q){var r="."+q.member;return p.substr(p.length-r.length)==r})[0]}return o},toggleOrder:function(o){o=typeof o=="number"?this.columns[o]:o;var p="asc";if(o.order=="asc"){p="desc"}else{if(o.order=="desc"){if(this.allowUnsort===false){p="asc"}else{p=null}}}o.order=p;var q=a.inArray(o,this.sorted);if(this.sortMode=="single"&&q<0){a.each(this.sorted,function(){this.order=null});this.sorted=[]}if(q<0&&p){this.sorted.push(o)}if(!p){this.sorted.splice(q,1)}},sortExpr:function(){return a.map(this.sorted,function(o){return o.member+"-"+o.order}).join("~")},pagerKeyDown:function(o){if(o.keyCode==13){var p=this.sanitizePage(a(o.target).val());if(p!=this.currentPage){this.pageTo(p)}else{a(o.target).val(p)}o.preventDefault()}},isAjax:function(){return this.ajax||this.ws||this.onDataBinding},url:function(o){return(this.ajax||this.ws)[o]},pagerClick:function(p){p.preventDefault();var o=a(p.target).closest(".t-link");var s=this.currentPage;var t=o.find(".t-icon");if(t.hasClass("t-arrow-next")){s++}else{if(t.hasClass("t-arrow-last")){s=this.totalPages()}else{if(t.hasClass("t-arrow-prev")){s--}else{if(t.hasClass("t-arrow-first")){s=1}else{var r=o.text();if(r=="..."){var q=o.parent().children().index(o);if(q==0){s=parseInt(o.next().text())-1}else{s=parseInt(o.prev().text())+1}}else{s=parseInt(r)}}}}}this.pageTo(isFinite(s)?s:this.currentPage)},changePageSize:function(p){var o=parseInt(p,10);if(isNaN(o)||o<1){return this.pageSize}o=Math.max(o,1);this.currentPage=1;this.pageSize=o;if(this.isAjax()){this.ajaxRequest()}else{this.serverRequest()}},pageTo:function(o){this.currentPage=o;if(this.isAjax()){this.ajaxRequest()}else{this.serverRequest()}},_dataChange:function(){var p=this.dataSource;if(!this._clientBindingInProgress){this.total=p.total()}this.aggregates=p.aggregates();var o=p.view();if(this.pageOnScroll&&this._pagingInProgress===true){o=(this.data||[]).concat(o);this._pagingInProgress=false}this._current=null;this._populate(o)},_populate:function(o){this.data=[];this.bindTo(o);this.bindFooter();this.updatePager();this.updateSorting();b.trigger(this.element,"dataBound");b.trigger(this.element,"repaint")},ajaxOptions:function(o){var p={type:"POST",dataType:"text",dataFilter:function(r,s){return r.replace(j,"new Date($1)")},error:a.proxy(function(s,r){if(b.ajaxError(this.element,"error",s,r)){return}},this),complete:a.proxy(this.hideBusy,this),success:a.proxy(function(r,t,u){try{r=eval("("+r+")")}catch(s){if(!b.ajaxError(this.element,"error",u,"parsererror")){alert("Error! The requested URL did not return JSON.")}return}if(o.commandName){this._onComplete({name:o.commandName,response:r})}r=r.d||r;if(o.hasErrors&&o.hasErrors(r)){if(!b.trigger(this.element,"error",{XMLHttpRequest:u,textStatus:"modelstateerror",modelState:r.modelState})){o.displayErrors(r)}return}this.dataSource.success(r)},this)};a.extend(p,o);var q=this.ws?p.data.state={}:p.data;if(this._isServerOperation()){q[this.queryString.page]=this.currentPage;q[this.queryString.size]=this.pageSize;q[this.queryString.groupBy]=this.groupBy;q[this.queryString.filter]=(this.filterBy||"").replace(/\"/g,'\\"')}q[this.queryString.orderBy]=this.orderBy||"";q[this.queryString.aggregates]=a.map(this.columns,function(r){if(r.aggregates){return r.member+"-"+r.aggregates.join("-")}}).join("~");if(this.ws){p.data=b.toJson(p.data);p.contentType="application/json; charset=utf-8"}return p},showBusy:function(){this.busyTimeout=setTimeout(a.proxy(function(){a("> .t-grid-pager .t-status .t-icon",this.element).addClass("t-loading")},this),100)},hideBusy:function(){clearTimeout(this.busyTimeout);a("> .t-grid-pager .t-status .t-icon",this.element).removeClass("t-loading")},serverRequest:function(){if(this.operationMode==="client"){this.ajaxRequest()}else{location.href=b.formatString(unescape(this.urlFormat),this.currentPage,this.orderBy||"~",this.groupBy||"~",encodeURIComponent(this.filterBy)||"~",this.pageSize||"~")}},_isServerOperation:function(){return this.operationMode!=="client"},ajaxRequest:function(o){var u=this,t=u.pageSize>0,s=u.pageSize,q=u.currentPage,p=a.map(u.columns,function(v){return a.map(v.aggregates||[],function(w){return{field:v.member,aggregate:w}})});if(q>1&&u.pageOnScroll&&!u._pagingInProgress){s=q*u.pageSize;q=1}var r={page:q,sortedColumns:u.sorted,filteredColumns:a.grep(u.columns,function(v){return v.filters})};if(b.trigger(u.element,"dataBinding",r)){return}if(!u.ajax&&!u.ws&&this.operationMode!=="client"){return}if(u.dataSource.transport.options&&u.dataSource.transport.options.read){u.dataSource.transport.options.read.url=this.url("selectUrl")}if(u._isServerOperation()){u.showBusy()}u.dataSource.query(a.extend({page:q,pageSize:t?s:n,sort:a.map(u.sorted,function(v){return{field:v.member,dir:v.order}}),filter:a.map(a.grep(u.columns,function(v){return v.filters}),function(v){return u._translateFilterExpr(v,v.filters||[])}),group:a.map(u.groups,function(v){return{field:v.member,dir:v.order,aggregates:p}}),aggregates:p},a.extend({},r.data,o)))},_translateFilterExpr:function(o,p){var q=this;return a.map(p,function(s){if(s.filters){return{logic:s.logic,filters:q._translateFilterExpr(o,s.filters)}}else{var u=s.value;if(o.type=="Number"){u=parseFloat(u)}else{if(o.type=="Date"){if(typeof u==="string"){var r=/^\/Date\((.*?)\)\/$/.exec(u);if(r){u=new Date(parseInt(r[1]))}else{var t=o.format?/\{0(:([^\}]+))?\}/.exec(o.format)[2]:b.cultureInfo.shortDate;u=b.datetime.parse({value:u,format:t}).toDate()}}}}return{field:o.member,operator:s.operator,value:u}}})},valueFor:function(o){if(o.type=="Date"){return new Function("data","var value = data."+o.member+'; if (!value) return null; return value instanceof Date? value : new Date(parseInt(value.replace(/\\/Date\\((.*?)\\)\\//, "$1")));')}return new Function("data","return data"+(o.member?"."+o.member:"")+";")},displayFor:function(p){var s=this.localization,r=this;if(p.commands){var o=a.map(p.commands,function(u){return b.grid.ButtonBuilder.create(a.extend({text:s[u.name]},u))});return function(u){return a.map(o,function(v){return v.build(a.extend({},u,{__page:r.currentPage,__orderBy:r.orderBy||"",__filter:r.filterBy||"",__groupBy:r.groupBy||""}))}).join("")}}if(!p.template){var t=p.value||function(){return""};var q=t=!p.data?t:function(u){var w=p.value(u),y=p.data,z="",v,x;for(v=0,x=y.length;v<x;v++){if(w==y[v].Value){return y[v].Text}}return z};if(p.format||p.type=="Date"){t=function(u){var v=q(u);return v==null?"":b.formatString(p.format||"{0:G}",v)}}return p.encoded===false?t:function(u){return e(t(u))}}return m(p.template)},insertFor:function(o){return this.displayFor(o)},editFor:function(o){return this.displayFor(o)},initializeColumns:function(){a.each(this.columns,a.proxy(function(q,r){if(r.member!==n){r.value=this.valueFor(r)}else{r.readonly=true}r.insert=this.insertFor(r);r.edit=this.editFor(r);r.display=this.displayFor(r);if(r.footerTemplate){r.footer=m(r.footerTemplate)}if(r.groupFooterTemplate){this.showGroupFooter=true;r.groupFooter=m(r.groupFooterTemplate)}r.groupHeader=m("<#= Title #>: <#= Key #>");if(r.groupHeaderTemplate){r.groupHeader=m(r.groupHeaderTemplate)}},this));var p=this.columns.length-1;while(p>=0){var o=this.columns[p];if(o.hidden){p--;continue}if(!o.attr){o.attr=' class="t-last"';break}else{if(o.attr.indexOf("class")==-1){o.attr+=' class="t-last"';break}else{o.attr=o.attr.replace('class="','class="t-last ');break}}p--}if(this.detail){this.displayDetails=m(this.detail.template)}},bindData:function(r,u,t){Array.prototype.push.apply(this.data,r);var s=this.pageOnScroll?r.length:Math.min(this.pageSize,r.length);var p=this.columns.length;s=this.pageSize?s:r.length;if(a.browser.msie){a(this.element).find(".t-grid-content colgroup:first col").css("display","")}for(var x=0;x<s;x++){var o=a.trim((this.detail?"t-master-row":"")+(x%2==1?" t-alt":""));if(o){u.cat('<tr class="').cat(o).cat('">')}else{u.cat("<tr>")}u.rep('<td class="t-group-cell"></td>',t).catIf('<td class="t-hierarchy-cell"><a class="t-icon t-plus" href="#" /></td>',this.detail);if(this.rowTemplate){u.cat('<td colspan="').cat(p).cat('">').cat(this.rowTemplate(r[x])).cat("</td>")}else{for(var v=0,w=this.columns.length;v<w;v++){var q=this.columns[v];u.cat("<td").cat(q.attr).cat(">").cat(q.display(r[x]));u.cat("</td>")}}u.cat("</tr>")}},normalizeColumns:function(){},dataItem:function(o){return(this.data||[])[this.$tbody.find("> tr:not(.t-grouping-row,.t-detail-row,.t-grid-new-row,.t-group-footer)").index(a(o))]},_colspan:function(){return this.groups.length+a.grep(this.columns,function(o){return !o.hidden}).length+(this.detail?1:0)},bindTo:function(p){var q=new b.stringBuilder();var o=this._colspan();if(p&&p.length){this.normalizeColumns(o);if(typeof p[0].hasSubgroups!="undefined"){for(var r=0,s=p.length;r<s;r++){this.bindGroup(p[r],o,q,0)}}else{this.bindData(p,q)}}else{q.cat("<tr class='t-no-data'>").cat("<td colspan='").cat(o).cat("'>").cat(this.noRecordsTemplate?this.noRecordsTemplate:this.localization.noRecords).cat("</td></tr>")}this.$tbody.html(q.string());if(this.onRowDataBound){var t=jQuery.grep(this.$tbody[0].rows,function(u){return !a(u).is(".t-grouping-row, .t-group-footer, .t-footer-template")});for(var r=0,s=this.data.length;r<s;r++){b.trigger(this.element,"rowDataBound",{row:t[r],dataItem:this.data[r]})}}},updatePager:function(){var r=this.totalPages(this.total);var o=this.currentPage;var q=this.pageSize;this.$pager.find(".t-arrow-next").parent().add(this.$pager.find(".t-arrow-last").parent()).toggleClass("t-state-disabled",o>=r).removeClass("t-state-hover");this.$pager.find(".t-arrow-prev").parent().add(this.$pager.find(".t-arrow-first").parent()).toggleClass("t-state-disabled",o==1).removeClass("t-state-hover");var p=this.localization;this.$pager.find(".t-page-i-of-n").each(function(){this.innerHTML=new b.stringBuilder().cat(p.page).cat('<input type="text" value="').cat(o).cat('" /> ').cat(b.formatString(p.pageOf,r)).string()});this.$pager.find(".t-page-size").each(function(){var s='<div style="width: 50px;" class="t-dropdown t-header"><div class="t-dropdown-wrap t-state-default"><span class="t-input">'+q+'</span><span class="t-select"><span class="t-icon t-arrow-down">select</span></span></div></div>';this.innerHTML=s});this.$pager.find(".t-numeric").each(a.proxy(function(t,s){this.numericPager(s,o,r)},this));this.$pager.parent().find(".t-status-text").text(b.formatString(p.displayingItems,this.firstItemInPage(),this.lastItemInPage(),this.total))},numericPager:function(t,o,w){var q=10;var r=1;if(o>q){var v=(o%q);r=(v==0)?(o-q)+1:(o-v)+1}var p=(r+q)-1;p=Math.min(p,w);var u=new b.stringBuilder();if(r>1){u.cat('<a class="t-link">...</a>')}for(var s=r;s<=p;s++){if(s==o){u.cat('<span class="t-state-active">').cat(s).cat("</span>")}else{u.cat('<a class="t-link">').cat(s).cat("</a>")}}if(p<w){u.cat('<a class="t-link">...</a>')}t.innerHTML=u.string()},$columns:function(){return this.$header.find("th:not(.t-hierarchy-cell,.t-group-cell)")},updateSorting:function(){this.sorted=[];a.each(this.orderBy.split("~"),a.proxy(function(o,q){var r=q.split("-");var p=this.columnFromMember(r[0]);if(p){p.order=r[1];this.sorted.push(p)}},this));this.$columns().each(a.proxy(function(s,r){var q=this.columns[s].order;var p=a(r).children("a.t-link");var o=p.children(".t-icon");if(!q){o.hide()}else{if(o.length==0){o=a('<span class="t-icon"/>').appendTo(p)}o.toggleClass("t-arrow-up",q=="asc").toggleClass("t-arrow-down",q=="desc").html("("+(q=="asc"?this.localization.sortedAsc:this.localization.sortedDesc)+")").show()}},this))},sanitizePage:function(p){var o=parseInt(p,10);if(isNaN(o)||o<1){return this.currentPage}return Math.min(o,this.totalPages())},totalPages:function(){return Math.ceil(this.total/this.pageSize)},firstItemInPage:function(){var o=this;return o.total>0?o.pageOnScroll?1:(o.currentPage-1)*o.pageSize+1:0},lastItemInPage:function(){return Math.min(this.currentPage*this.pageSize,this.total)},dataBind:function(o){var p=this;if(!p.dataSource){p._dataSource()}else{if(o&&o.length){p.dataSource._group=a.map(p.groups,function(q){return{field:q.member,dir:q.order,aggregates:p.aggregates}})}}p._clientBindingInProgress=true;try{p.dataSource.success(o||[])}finally{p._clientBindingInProgress=false}},bindFooter:function(){var r=this,o=r.$footer.find("td:not(.t-group-cell,.t-hierarchy-cell)"),p=r.aggregates,q={Sum:0,Count:0,Average:0,Max:0,Min:0};a.each(r.columns,function(s){if(this.footer){o.eq(s).html(this.footer(r._mapAggregates(p[this.member]||q)))}})},rebind:function(o){var p=this;p.sorted=[];p.orderBy="";p.filterBy="";p.currentPage=1;p.groupBy="";p.groups=[];if(p.clearHeader){p.clearHeader()}a.each(p.columns,function(){this.order=null;this.filters=null});a(".t-filter-options",p.element).find('input[type="text"], select').val("").removeClass("t-state-error").end().find("div.t-formatted-value").html("");a(".t-grid-filter",p.element).removeClass("t-active-filter");if(this.isAjax()){p.data=[]}if(!p._isServerOperation()){p._dataSource()}p.ajaxRequest(o)},hideColumn:function(s){var E=this,u=E.columns,t,r,F,v,B=E.$tbody.children("tr"),z,A,q,x,D=0,p=a.browser,y=p.msie&&parseInt(p.version)===8,C,o,w=E.editing.mode;if(typeof s==="number"){s=u[s]}else{s=E.columnFromMember(s)}t=a.inArray(s,a.grep(u,function(G){return !G.hidden}));if(t<0||!s){return}r=a("col:not(.t-group-col,.t-hierarchy-col)",E.$header.parent().prev());if(E.scrollable){a("col:not(.t-group-col,.t-hierarchy-col)",E.$footer).eq(t).remove();r.eq(t).remove();r=a("col:not(.t-group-col,.t-hierarchy-col)",E.$tbody.prev())}F=r.eq(t).remove()[0].style.width;E.$columns().filter(":visible").eq(t).hide();E.$footer.find("td:not(.t-group-cell):visible").eq(t).hide();for(x=0,z=B.length;x<z;x++){A=B.eq(x);if(A.is(".t-grouping-row,.t-detail-row")){q=A.children(":not(.t-group-cell):first,.t-detail-cell").last();q.attr("colspan",parseInt(q.attr("colspan"),10)-1)}else{if(A.hasClass("t-grid-edit-row")){if(w==="InLine"&&!E.isAjax()){q=A.children(".t-edit-container");q.attr("colspan",parseInt(q.attr("colspan"),10)-1);q.find("col").eq(t).remove();A=q.find("tr:first")}else{if(w==="InForm"){q=A.children().first();q.attr("colspan",parseInt(q.attr("colspan"),10)-1);continue}}}A.children("td:not(.t-group-cell,.t-hierarchy-cell):visible").eq(t).hide()}}for(x=0,z=r.length;x<z;x++){if(x!=t){v=r[x].style.width;if(v&&v.indexOf("%")===-1){D+=parseInt(v)}else{D=0;break}}}C=a(">table,>.t-grid-header table,>.t-grid-content>table, >.t-grid-footer>.t-grid-footer-wrap>table",E.element);if(D){C.width(D)}if(y){C.css("display","inline-table");setTimeout(function(){C.css("display","table")},1)}s.hidden=true;s.width=F;o=s.attr;if(!o||o.indexOf("style")<0){o=(o||"")+' style="display:none" '}else{o=s.attr.replace(/(style="(.*)?display):([^;]*)/i,"$1:none");if(o===s.attr){o=o.replace(/(style=")/i,"$1display:none;")}}s.attr=o;b.trigger(E.element,"repaint")},showColumn:function(q){var z=this,r,s=z.columns,p,w=z.$tbody.children("tr"),x=a(">table,>.t-grid-header table,>.t-grid-content>table,>.t-grid-footer>.t-grid-footer-wrap>table",z.element),v,o,t,u;if(typeof q==="number"){q=s[q]}else{q=z.columnFromMember(q)}r=a.inArray(q,s);if(!q||!q.hidden){return}p=a("col:not(.t-group-col,.t-hierarchy-col)",z.$header.parent().prev());i(p,s,r);if(z.scrollable){p=a("col:not(.t-group-col,.t-hierarchy-col)",z.$tbody.prev());i(a("col:not(.t-group-col,.t-hierarchy-col)",z.$footer),s,r);i(p,s,r)}z.$columns().eq(r).show();z.$footer.find("td:not(.t-group-cell)").eq(r).show();for(t=0,u=w.length;t<u;t++){v=w.eq(t);if(v.is(".t-grouping-row,.t-detail-row")){o=v.children(":not(.t-group-cell):first,.t-detail-cell").last();o.attr("colspan",parseInt(o.attr("colspan"),10)+1)}else{if(v.hasClass("t-grid-edit-row")){if(z.editing.mode==="InLine"&&!z.isAjax()){o=v.children(".t-edit-container");o.attr("colspan",parseInt(o.attr("colspan"),10)+1);i(o.find(">form>table>colgroup>col"),s,r);v=o.find("tr:first")}else{if(z.editing.mode==="InForm"){o=v.children().first();o.attr("colspan",parseInt(o.attr("colspan"),10)+1);continue}}}v.children("td:not(.t-group-cell,.t-hierarchy-cell)").eq(r).show()}}if(!q.width){x.width("")}else{var y=parseInt(q.width,10);for(t=0,u=p.length;t<u;t++){if(p[t].style.width.indexOf("%")>-1){y=0;break}y+=parseInt(p[t].style.width,10)}if(y){x.width(y)}}q.hidden=false;delete q.width;if(q.attr){q.attr=q.attr.replace(/(style="(.*)?)(display\s*:\s*none)\s*;?/i,"$1")}b.trigger(z.element,"repaint")},initializeContextMenu:function(){var u=this,r,q=b.fx.slide.defaults(),p=a.grep(u.columns,function(v){return v.title!==""&&v.includeInContextMenu!==false}),s=u.element.id+"_contextMenu",t,o;a(document).bind("mouseup",function(v){if(t&&v.which!=3&&a(v.target).closest("#"+s).length==0){b.fx.rewind(q,t.find(".t-group"),{direction:"bottom"},function(){t.remove()})}});u.$header.closest(".t-grid-header").bind("contextmenu",function(v){if(t&&t.is(":visible")){b.fx.rewind(q,t.find(".t-group"),{direction:"bottom"});t.remove()}r=new b.stringBuilder();r.cat('<div class="t-animation-container t-menu t-menu-context" id="'+s+'" style="display:none">').cat('<ul class="t-group">');a.each(p,function(){r.cat('<li class="t-item"><label class="t-link">').cat('<input type="checkbox" data-field="'+a.inArray(this,u.columns)+'"').catIf(' checked="checked"',!this.hidden).cat("/>").cat(this.title).cat("</label></li>")});r.cat("</ul></div>");t=a(r.string()).delegate("[type=checkbox]","change",function(){var w=a(this),x,y=w.data("field");if(w.is(":checked")){u.showColumn(y);if(u.onColumnShow){b.trigger(u.element,"columnShow",{column:u.columns[y]})}}else{u.hideColumn(y);if(u.onColumnHide){b.trigger(u.element,"columnHide",{column:u.columns[y]})}}x=t.find(":checked");x.attr("disabled",x.length==1)}).appendTo(document.body);o=t.find(":checked");o.attr("disabled",o.length==1);t.css({left:v.clientX+a(document).scrollLeft(),top:v.clientY+a(document).scrollTop()});b.fx.play(q,t.find(".t-group"),{direction:"bottom"});return false})}};b.grid.ButtonBuilder=function(p){var o=b.splitClassesFromAttr(p.attr);this.classNames=["t-button"];var q=o.classes;if(q){this.classNames.push(q);p.attr=o.attributes}if(p.name){this.classNames.push("t-grid-"+p.name)}if(p.ajax){this.classNames.push("t-ajax")}this.url=p.url?m(unescape(p.url)):function(){return"#"};this.content=function(){return p.text||""};this.build=function(r){return'<a href="'+this.url(r)+'" class="'+this.classNames.join(" ")+'" '+(p.attr||"")+">"+this.content()+"</a>"}};b.grid.ButtonBuilder.create=function(o){return new (c[o.buttonType])(o)};function l(r,q){var o=b.splitClassesFromAttr(q),p=o.classes,s=o.attributes;p=p?" "+p:"";return'<span class="t-icon t-'+r+p+'"'+(s?s:"")+"></span>"}b.grid.ImageButtonBuilder=function(o){b.grid.ButtonBuilder.call(this,o);this.classNames.push("t-button-icon");this.content=function(){return l(o.name,o.imageAttr)}};b.grid.ImageTextButtonBuilder=function(o){b.grid.ButtonBuilder.call(this,o);this.classNames.push("t-button-icontext");this.content=function(){return l(o.name,o.imageAttr)+o.text}};b.grid.BareImageButtonBuilder=function(o,p){b.grid.ImageButtonBuilder.call(this,o,p);this.classNames.push("t-button-icon","t-button-bare")};var c={Text:b.grid.ButtonBuilder,ImageAndText:b.grid.ImageTextButtonBuilder,Image:b.grid.ImageButtonBuilder,BareImage:b.grid.BareImageButtonBuilder};a.fn.tGrid=function(o){return b.create(this,{name:"tGrid",init:function(p,q){return new b.grid(p,q)},options:o,success:function(p){if(p.$tbody.find("> tr.t-no-data").length){p.ajaxRequest()}}})};a.fn.tGrid.defaults={columns:[],plugins:[],currentPage:1,pageSize:10,localization:{addNew:"Add new record","delete":"Delete",cancel:"Cancel",insert:"Insert",update:"Update",select:"Select",pageOf:"of {0}",displayingItems:"Displaying items {0} - {1} of {2}",edit:"Edit",noRecords:"No records to display.",page:"Page ",filter:"Filter",filterClear:"Clear Filter",filterShowRows:"Show rows with value that",filterAnd:"And",filterOr:"Or",filterStringEq:"Is equal to",filterStringNe:"Is not equal to",filterStringStartsWith:"Starts with",filterStringSubstringOf:"Contains",filterStringNotSubstringOf:"Does not contain",filterStringEndsWith:"Ends with",filterNumberEq:"Is equal to",filterNumberNe:"Is not equal to",filterNumberLt:"Is less than",filterNumberLe:"Is less than or equal to",filterNumberGt:"Is greater than",filterNumberGe:"Is greater than or equal to",filterDateEq:"Is equal to",filterDateNe:"Is not equal to",filterDateLt:"Is before",filterDateLe:"Is before or equal to",filterDateGt:"Is after",filterDateGe:"Is after or equal to",filterEnumEq:"Is equal to",filterEnumNe:"Is not equal to",filterForeignKeyEq:"Is equal to",filterForeignKeyNe:"Is not equal to",filterBoolIsTrue:"is true",filterBoolIsFalse:"is false",filterSelectValue:"-Select value-",filterOpenPopupHint:"Open the calendar popup",groupHint:"Drag a column header and drop it here to group by that column",deleteConfirmation:"Are you sure you want to delete this record?",sortedAsc:"sorted ascending",sortedDesc:"sorted descending",ungroup:"ungroup"},queryString:{page:"page",size:"size",orderBy:"orderBy",groupBy:"groupBy",filter:"filter",aggregates:"aggregates"}}})(jQuery);;
(function(a){var b=a.telerik;var c=/'/ig;var d=b.fx.slide.defaults();b.scripts.push("telerik.grid.filtering.js");function e(g){if(!g.format){return b.cultureInfo.shortDate}return/\{0(:([^\}]+))?\}/.exec(g.format)[2]}function f(g,h){if(g.type=="Date"){if(!(h instanceof Date)){h=new Date(parseInt(h.replace(/\/Date\((.*?)\)\//,"$1")))}return b.formatString(g.format||"{0:G}",h)}return h}b.filtering={};b.filtering.initialize=function(g){a.extend(g,b.filtering.implementation);g.filterBy=g.filterExpr();a("> .t-grid-content",g.element).bind("scroll",function(){g.hideFilter()});a(document).click(function(h){if(h.which!=3){g.hideFilter()}});g.$header.find(".t-grid-filter").click(a.proxy(g.showFilter,g)).hover(function(){a(this).toggleClass("t-state-hover")})};b.filtering.implementation={createFilterCommands:function(i,g){var h=[];a.each(this.localization,function(k,m){var l="filter"+(g.data?"ForeignKey":g.type);var j=k.indexOf(l);if(j>-1){h.push({key:k.substring(j+l.length).toLowerCase(),value:m})}});if(g.type=="String"){if(h[0].key!=="eq"){h.push(h.shift())}}i.cat('<select class="t-filter-operator">');a.each(h,function(k,j){i.cat('<option value="').cat(j.key).cat('">').cat(j.value).cat("</option>")});i.cat("</select>")},createTypeSpecificInput:function(i,g,h,j){if(g.data){i.cat("<div><select><option>").cat(this.localization.filterSelectValue).cat("</option>");a.each(g.data,function(){i.cat('<option value="').cat(this.Value).cat('">').cat(this.Text).cat("</option>")});i.cat("</select></div>")}else{if(g.type=="Date"){i.cat('<div class="t-widget t-datepicker"><div class="t-picker-wrap">').cat('<input class="t-input" id="').cat(h).cat('" type="text" value="" />').cat('<span class="t-select"><label class="t-icon t-icon-calendar" for="').cat(h).cat('" title="').cat(this.localization.filterOpenPopupHint).cat('" /></span></div></div>')}else{if(g.type=="Boolean"){i.cat('<div><input type="radio" style="width:auto;display:inline" id="').cat(h+j).cat('" name="').cat(h).cat('" value="').cat(j).cat('" />').cat('<label style="display:inline" for="').cat(h+j).cat('">').cat(this.localization[j?"filterBoolIsTrue":"filterBoolIsFalse"]).cat("</label></div>")}else{if(g.type=="Enum"){i.cat("<div><select><option>").cat(this.localization.filterSelectValue).cat("</option>");a.each(g.values,function(k,l){i.cat('<option value="').cat(l).cat('">').cat(k).cat("</option>")});i.cat("</select></div>")}else{if(g.type=="Number"){i.cat('<div class="t-widget t-numerictextbox">').cat('<input class="t-input" name="').cat(h).cat('" id="').cat(h).cat('" type="text" value=""/>').cat("</div>")}else{i.cat('<input type="text" />')}}}}}},createFilterMenu:function(h){var j=new b.stringBuilder();j.cat('<div class="t-animation-container"><div class="t-filter-options t-group t-popup" style="display:none">').cat('<button class="t-button t-button-icontext t-button-expand t-clear-button"><span class="t-icon t-clear-filter"></span>').cat(this.localization.filterClear).cat('</button><div class="t-filter-help-text">').cat(this.localization.filterShowRows).cat("</div>");var i=a(this.element).attr("id")+h.member;if(h.type=="Boolean"){this.createTypeSpecificInput(j,h,i,true);this.createTypeSpecificInput(j,h,i,false)}else{this.createFilterCommands(j,h);this.createTypeSpecificInput(j,h,i+"first");if(this.showOrOption){j.cat('<select class="t-filter-logic">').cat('<option value="and">'+this.localization.filterAnd+"</option>").cat('<option value="or">'+this.localization.filterOr+"</option>").cat("</select>")}else{j.cat('<div class="t-filter-help-text">').cat(this.localization.filterAnd).cat("</div>")}this.createFilterCommands(j,h);this.createTypeSpecificInput(j,h,i+"second")}j.cat('<button class="t-button t-button-icontext t-button-expand t-filter-button"><span class="t-icon t-filter"></span>').cat(this.localization.filter).cat("</button></div></div>");var g=a(j.string());var k=h.filters||[];k=k.length&&k[0].logic?k[0].filters:k;a.each(k,function(l){g.find(".t-filter-operator:eq("+l+")").val(this.operator).end().find(":text:eq("+l+"),select:not(.t-filter-operator):eq("+l+")").val(f(h,this.value));if(h.type=="Boolean"){g.find(":radio[id$="+this.value+"]").attr("checked",true)}});return g.appendTo(this.element).find(".t-datepicker .t-input").each(function(){a(this).tDatePicker({format:e(h)})}).end().find(".t-numerictextbox .t-input").each(function(){a(this).tTextBox({type:"numeric",minValue:null,maxValue:null,numFormat:"",groupSeparator:""})}).end()},showFilter:function(k){k.stopPropagation();var g=a(k.target).closest(".t-grid-filter");this.hideFilter(function(){return this.parentNode!=g[0]});var h=g.data("filter");if(!h){var i=this.columns[this.$columns().index(g.parent())];h=this.createFilterMenu(i).data("column",i).click(function(s){s.stopPropagation();if(a(s.target).parents(".t-datepicker").length==0){a(".t-datepicker .t-input",this).each(function(){a(this).data("tDatePicker").hidePopup()})}}).find(".t-filter-button").click(a.proxy(this.filterClick,this)).end().find(".t-clear-button").click(a.proxy(this.clearClick,this)).end().find("input[type=text]").keydown(a.proxy(function(s){if(s.keyCode==13){this.filterClick(s)}},this)).end();g.data("filter",h)}var q=0;a(this.element).find("> .t-grouping-header, > .t-grid-toolbar").add(this.$header).each(function(){q+=this.offsetHeight});var p={top:q};var m=a(this.element).closest(".t-rtl").length;var l=this.$headerWrap.scrollLeft();var r=!m?-l-1:l-1;g.parent().add(g.parent().prevAll("th")).each(function(){if(a(this).css("display")!="none"){r+=this.offsetWidth}});var n=r-g.outerWidth();var o=h.outerWidth()||h.find(".t-group").outerWidth();if(n+o>this.$header.closest(".t-grid-header").innerWidth()){n=r-o+1}if(m){var j=((a.browser.mozilla&&parseInt(a.browser.version,10)<2)||a.browser.webkit)?18:0;p.right=n+j}else{p.left=n}h.css(p);b.fx[h.find(".t-filter-options").is(":visible")?"rewind":"play"](d,h.find(".t-filter-options"),{direction:"bottom"})},hideFilter:function(g){g=g||function(){return true};a(".t-grid .t-animation-container").find(".t-datepicker .t-input").each(function(){a(this).data("tDatePicker").hidePopup()}).end().find(".t-filter-options").filter(g).each(function(){b.fx.rewind(d,a(this),{direction:"bottom"})})},clearClick:function(i){i.preventDefault();var g=a(i.target);var h=g.closest(".t-animation-container").data("column");h.filters=null;g.closest(".t-filter-options").find(".t-numerictextbox .t-input").each(function(){a(this).data("tTextBox").value("")}).end().find("input").removeAttr("checked").removeClass("t-state-error").not(":radio").val("").end().end().find("select").removeClass("t-state-error").find("option:first").attr("selected","selected");this.filter(this.filterExpr());this.hideFilter()},filterClick:function(i){i.preventDefault();var g=a(i.target);var h=g.closest(".t-animation-container").data("column");h.filters=[];var k=false;var j=h.filters;if(this.showOrOption){h.filters=[{logic:g.closest(".t-filter-options").find("select.t-filter-logic").val()||"and",filters:j}]}g.closest(".t-filter-options").find("input[type=text]:visible,select:not(.t-filter-operator,.t-filter-logic)").each(a.proxy(function(m,n){var l=a(n);var r=a.trim(l.val());if(!r){l.removeClass("t-state-error");return true}var q=this.isValidFilterValue(h,r);l.toggleClass("t-state-error",!q);if(!q){k=true;return true}var o=l.data("tTextBox");if(o){r=o.value()}if(h.type==="Enum"&&r!=this.localization.filterSelectValue){r=parseInt(r,10)}var p=l.prev("select.t-filter-operator").val()||l.parent().prev("select.t-filter-operator").val()||l.parent().parent().prev("select.t-filter-operator").val();if(r!=this.localization.filterSelectValue){j.push({operator:p,value:r})}},this));g.parent().find("input:checked").each(a.proxy(function(m,n){var l=a(n);var o=a(n).attr("value");if(h.type==="Boolean"&&o&&typeof o==="string"){o=o.toLowerCase().indexOf("true")>-1?true:false}j.push({operator:"eq",value:o})},this));if(!k){if(j.length>0){this.filter(this.filterExpr())}else{h.filters=null}this.hideFilter()}},isValidFilterValue:function(g,i){if(g.type=="Date"){var h;if(i.indexOf("Date(")>-1){h=new Date(parseInt(i.replace(/^\/Date\((.*?)\)\/$/,"$1")))}else{h=b.datetime.parse({value:i,format:e(g)})}return h!=undefined}return true},encodeFilterValue:function(g,i){switch(g.type){case"String":return"'"+i.replace(c,"''")+"'";case"Date":var h;if(typeof i=="string"){if(i.indexOf("Date(")>-1){h=new Date(parseInt(i.replace(/^\/Date\((.*?)\)\/$/,"$1")))}else{h=b.datetime.parse({value:i,format:e(g)}).toDate()}}else{h=i}return"datetime'"+b.formatString("{0:yyyy-MM-ddTHH-mm-ss}",h)+"'"}return i},filterExpr:function(){var i=[];for(var h=0;h<this.columns.length;h++){var g=this.columns[h];if(g.filters){i.push(this._buildExpression(g.filters,g,"~and~"))}}return i.join("~and~")},_buildExpression:function(j,g,k){var l=[];for(var i=0;i<j.length;i++){var h=j[i];if(h.logic){l.push(new b.stringBuilder().catIf("(",h.filters.length>1).cat(this._buildExpression(h.filters,g,"~"+h.logic+"~")).catIf(")",h.filters.length>1).string())}else{l.push(new b.stringBuilder().cat(g.member).cat("~").cat(h.operator).cat("~").cat(this.encodeFilterValue(g,h.value)).string())}}return l.join(k)},filter:function(g){this.currentPage=1;this.filterBy=g;if(this.isAjax()){this.$columns().each(a.proxy(function(i,h){a(".t-grid-filter",h).toggleClass("t-active-filter",!!this.columns[i].filters)},this));this.ajaxRequest()}else{this.serverRequest()}}}})(jQuery);;
"use strict";

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/*
 *
 * More info at [www.dropzonejs.com](http://www.dropzonejs.com)
 *
 * Copyright (c) 2012, Matias Meno
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

// The Emitter class provides the ability to call `.on()` on Dropzone to listen
// to events.
// It is strongly based on component's emitter class, and I removed the
// functionality because of the dependency hell with different frameworks.
var Emitter = function () {
  function Emitter() {
    _classCallCheck(this, Emitter);
  }

  _createClass(Emitter, [{
    key: "on",

    // Add an event listener for given event
    value: function on(event, fn) {
      this._callbacks = this._callbacks || {};
      // Create namespace for this event
      if (!this._callbacks[event]) {
        this._callbacks[event] = [];
      }
      this._callbacks[event].push(fn);
      return this;
    }
  }, {
    key: "emit",
    value: function emit(event) {
      this._callbacks = this._callbacks || {};
      var callbacks = this._callbacks[event];

      if (callbacks) {
        for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
          args[_key - 1] = arguments[_key];
        }

        for (var _iterator = callbacks, _isArray = true, _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
          var _ref;

          if (_isArray) {
            if (_i >= _iterator.length) break;
            _ref = _iterator[_i++];
          } else {
            _i = _iterator.next();
            if (_i.done) break;
            _ref = _i.value;
          }

          var callback = _ref;

          callback.apply(this, args);
        }
      }

      return this;
    }

    // Remove event listener for given event. If fn is not provided, all event
    // listeners for that event will be removed. If neither is provided, all
    // event listeners will be removed.

  }, {
    key: "off",
    value: function off(event, fn) {
      if (!this._callbacks || arguments.length === 0) {
        this._callbacks = {};
        return this;
      }

      // specific event
      var callbacks = this._callbacks[event];
      if (!callbacks) {
        return this;
      }

      // remove all handlers
      if (arguments.length === 1) {
        delete this._callbacks[event];
        return this;
      }

      // remove specific handler
      for (var i = 0; i < callbacks.length; i++) {
        var callback = callbacks[i];
        if (callback === fn) {
          callbacks.splice(i, 1);
          break;
        }
      }

      return this;
    }
  }]);

  return Emitter;
}();

var Dropzone = function (_Emitter) {
  _inherits(Dropzone, _Emitter);

  _createClass(Dropzone, null, [{
    key: "initClass",
    value: function initClass() {

      // Exposing the emitter class, mainly for tests
      this.prototype.Emitter = Emitter;

      /*
       This is a list of all available events you can register on a dropzone object.
        You can register an event handler like this:
        dropzone.on("dragEnter", function() { });
        */
      this.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "addedfile", "addedfiles", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded", "maxfilesreached", "queuecomplete"];

      this.prototype.defaultOptions = {
        /**
         * Has to be specified on elements other than form (or when the form
         * doesn't have an `action` attribute). You can also
         * provide a function that will be called with `files` and
         * must return the url (since `v3.12.0`)
         */
        url: null,

        /**
         * Can be changed to `"put"` if necessary. You can also provide a function
         * that will be called with `files` and must return the method (since `v3.12.0`).
         */
        method: "post",

        /**
         * Will be set on the XHRequest.
         */
        withCredentials: false,

        /**
         * The timeout for the XHR requests in milliseconds (since `v4.4.0`).
         */
        timeout: 30000,

        /**
         * How many file uploads to process in parallel (See the
         * Enqueuing file uploads* documentation section for more info)
         */
        parallelUploads: 2,

        /**
         * Whether to send multiple files in one request. If
         * this it set to true, then the fallback file input element will
         * have the `multiple` attribute as well. This option will
         * also trigger additional events (like `processingmultiple`). See the events
         * documentation section for more information.
         */
        uploadMultiple: false,

        /**
         * Whether you want files to be uploaded in chunks to your server. This can't be
         * used in combination with `uploadMultiple`.
         *
         * See [chunksUploaded](#config-chunksUploaded) for the callback to finalise an upload.
         */
        chunking: false,

        /**
         * If `chunking` is enabled, this defines whether **every** file should be chunked,
         * even if the file size is below chunkSize. This means, that the additional chunk
         * form data will be submitted and the `chunksUploaded` callback will be invoked.
         */
        forceChunking: false,

        /**
         * If `chunking` is `true`, then this defines the chunk size in bytes.
         */
        chunkSize: 2000000,

        /**
         * If `true`, the individual chunks of a file are being uploaded simultaneously.
         */
        parallelChunkUploads: false,

        /**
         * Whether a chunk should be retried if it fails.
         */
        retryChunks: false,

        /**
         * If `retryChunks` is true, how many times should it be retried.
         */
        retryChunksLimit: 3,

        /**
         * If not `null` defines how many files this Dropzone handles. If it exceeds,
         * the event `maxfilesexceeded` will be called. The dropzone element gets the
         * class `dz-max-files-reached` accordingly so you can provide visual feedback.
         */
        maxFilesize: 256,

        /**
         * The name of the file param that gets transferred.
         * **NOTE**: If you have the option  `uploadMultiple` set to `true`, then
         * Dropzone will append `[]` to the name.
         */
        paramName: "file",

        /**
         * Whether thumbnails for images should be generated
         */
        createImageThumbnails: true,

        /**
         * In MB. When the filename exceeds this limit, the thumbnail will not be generated.
         */
        maxThumbnailFilesize: 10,

        /**
         * If `null`, the ratio of the image will be used to calculate it.
         */
        thumbnailWidth: 120,

        /**
         * The same as `thumbnailWidth`. If both are null, images will not be resized.
         */
        thumbnailHeight: 120,

        /**
         * How the images should be scaled down in case both, `thumbnailWidth` and `thumbnailHeight` are provided.
         * Can be either `contain` or `crop`.
         */
        thumbnailMethod: 'crop',

        /**
         * If set, images will be resized to these dimensions before being **uploaded**.
         * If only one, `resizeWidth` **or** `resizeHeight` is provided, the original aspect
         * ratio of the file will be preserved.
         *
         * The `options.transformFile` function uses these options, so if the `transformFile` function
         * is overridden, these options don't do anything.
         */
        resizeWidth: null,

        /**
         * See `resizeWidth`.
         */
        resizeHeight: null,

        /**
         * The mime type of the resized image (before it gets uploaded to the server).
         * If `null` the original mime type will be used. To force jpeg, for example, use `image/jpeg`.
         * See `resizeWidth` for more information.
         */
        resizeMimeType: null,

        /**
         * The quality of the resized images. See `resizeWidth`.
         */
        resizeQuality: 0.8,

        /**
         * How the images should be scaled down in case both, `resizeWidth` and `resizeHeight` are provided.
         * Can be either `contain` or `crop`.
         */
        resizeMethod: 'contain',

        /**
         * The base that is used to calculate the filesize. You can change this to
         * 1024 if you would rather display kibibytes, mebibytes, etc...
         * 1024 is technically incorrect, because `1024 bytes` are `1 kibibyte` not `1 kilobyte`.
         * You can change this to `1024` if you don't care about validity.
         */
        filesizeBase: 1000,

        /**
         * Can be used to limit the maximum number of files that will be handled by this Dropzone
         */
        maxFiles: null,

        /**
         * An optional object to send additional headers to the server. Eg:
         * `{ "My-Awesome-Header": "header value" }`
         */
        headers: null,

        /**
         * If `true`, the dropzone element itself will be clickable, if `false`
         * nothing will be clickable.
         *
         * You can also pass an HTML element, a CSS selector (for multiple elements)
         * or an array of those. In that case, all of those elements will trigger an
         * upload when clicked.
         */
        clickable: true,

        /**
         * Whether hidden files in directories should be ignored.
         */
        ignoreHiddenFiles: true,

        /**
         * The default implementation of `accept` checks the file's mime type or
         * extension against this list. This is a comma separated list of mime
         * types or file extensions.
         *
         * Eg.: `image/*,application/pdf,.psd`
         *
         * If the Dropzone is `clickable` this option will also be used as
         * [`accept`](https://developer.mozilla.org/en-US/docs/HTML/Element/input#attr-accept)
         * parameter on the hidden file input as well.
         */
        acceptedFiles: null,

        /**
         * **Deprecated!**
         * Use acceptedFiles instead.
         */
        acceptedMimeTypes: null,

        /**
         * If false, files will be added to the queue but the queue will not be
         * processed automatically.
         * This can be useful if you need some additional user input before sending
         * files (or if you want want all files sent at once).
         * If you're ready to send the file simply call `myDropzone.processQueue()`.
         *
         * See the [enqueuing file uploads](#enqueuing-file-uploads) documentation
         * section for more information.
         */
        autoProcessQueue: true,

        /**
         * If false, files added to the dropzone will not be queued by default.
         * You'll have to call `enqueueFile(file)` manually.
         */
        autoQueue: true,

        /**
         * If `true`, this will add a link to every file preview to remove or cancel (if
         * already uploading) the file. The `dictCancelUpload`, `dictCancelUploadConfirmation`
         * and `dictRemoveFile` options are used for the wording.
         */
        addRemoveLinks: false,

        /**
         * Defines where to display the file previews – if `null` the
         * Dropzone element itself is used. Can be a plain `HTMLElement` or a CSS
         * selector. The element should have the `dropzone-previews` class so
         * the previews are displayed properly.
         */
        previewsContainer: null,

        /**
         * This is the element the hidden input field (which is used when clicking on the
         * dropzone to trigger file selection) will be appended to. This might
         * be important in case you use frameworks to switch the content of your page.
         */
        hiddenInputContainer: "body",

        /**
         * If null, no capture type will be specified
         * If camera, mobile devices will skip the file selection and choose camera
         * If microphone, mobile devices will skip the file selection and choose the microphone
         * If camcorder, mobile devices will skip the file selection and choose the camera in video mode
         * On apple devices multiple must be set to false.  AcceptedFiles may need to
         * be set to an appropriate mime type (e.g. "image/*", "audio/*", or "video/*").
         */
        capture: null,

        /**
         * **Deprecated**. Use `renameFile` instead.
         */
        renameFilename: null,

        /**
         * A function that is invoked before the file is uploaded to the server and renames the file.
         * This function gets the `File` as argument and can use the `file.name`. The actual name of the
         * file that gets used during the upload can be accessed through `file.upload.filename`.
         */
        renameFile: null,

        /**
         * If `true` the fallback will be forced. This is very useful to test your server
         * implementations first and make sure that everything works as
         * expected without dropzone if you experience problems, and to test
         * how your fallbacks will look.
         */
        forceFallback: false,

        /**
         * The text used before any files are dropped.
         */
        dictDefaultMessage: "Drop files here to upload",

        /**
         * The text that replaces the default message text it the browser is not supported.
         */
        dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.",

        /**
         * The text that will be added before the fallback form.
         * If you provide a  fallback element yourself, or if this option is `null` this will
         * be ignored.
         */
        dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.",

        /**
         * If the filesize is too big.
         * `{{filesize}}` and `{{maxFilesize}}` will be replaced with the respective configuration values.
         */
        dictFileTooBig: "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.",

        /**
         * If the file doesn't match the file type.
         */
        dictInvalidFileType: "You can't upload files of this type.",

        /**
         * If the server response was invalid.
         * `{{statusCode}}` will be replaced with the servers status code.
         */
        dictResponseError: "Server responded with {{statusCode}} code.",

        /**
         * If `addRemoveLinks` is true, the text to be used for the cancel upload link.
         */
        dictCancelUpload: "Cancel upload",

        /**
         * The text that is displayed if an upload was manually canceled
         */
        dictUploadCanceled: "Upload canceled.",

        /**
         * If `addRemoveLinks` is true, the text to be used for confirmation when cancelling upload.
         */
        dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?",

        /**
         * If `addRemoveLinks` is true, the text to be used to remove a file.
         */
        dictRemoveFile: "Remove file",

        /**
         * If this is not null, then the user will be prompted before removing a file.
         */
        dictRemoveFileConfirmation: null,

        /**
         * Displayed if `maxFiles` is st and exceeded.
         * The string `{{maxFiles}}` will be replaced by the configuration value.
         */
        dictMaxFilesExceeded: "You can not upload any more files.",

        /**
         * Allows you to translate the different units. Starting with `tb` for terabytes and going down to
         * `b` for bytes.
         */
        dictFileSizeUnits: { tb: "TB", gb: "GB", mb: "MB", kb: "KB", b: "b" },
        /**
         * Called when dropzone initialized
         * You can add event listeners here
         */
        init: function init() {},


        /**
         * Can be an **object** of additional parameters to transfer to the server, **or** a `Function`
         * that gets invoked with the `files`, `xhr` and, if it's a chunked upload, `chunk` arguments. In case
         * of a function, this needs to return a map.
         *
         * The default implementation does nothing for normal uploads, but adds relevant information for
         * chunked uploads.
         *
         * This is the same as adding hidden input fields in the form element.
         */
        params: function params(files, xhr, chunk) {
          if (chunk) {
            return {
              dzuuid: chunk.file.upload.uuid,
              dzchunkindex: chunk.index,
              dztotalfilesize: chunk.file.size,
              dzchunksize: this.options.chunkSize,
              dztotalchunkcount: chunk.file.upload.totalChunkCount,
              dzchunkbyteoffset: chunk.index * this.options.chunkSize
            };
          }
        },


        /**
         * A function that gets a [file](https://developer.mozilla.org/en-US/docs/DOM/File)
         * and a `done` function as parameters.
         *
         * If the done function is invoked without arguments, the file is "accepted" and will
         * be processed. If you pass an error message, the file is rejected, and the error
         * message will be displayed.
         * This function will not be called if the file is too big or doesn't match the mime types.
         */
        accept: function accept(file, done) {
          return done();
        },


        /**
         * The callback that will be invoked when all chunks have been uploaded for a file.
         * It gets the file for which the chunks have been uploaded as the first parameter,
         * and the `done` function as second. `done()` needs to be invoked when everything
         * needed to finish the upload process is done.
         */
        chunksUploaded: function chunksUploaded(file, done) {
          done();
        },

        /**
         * Gets called when the browser is not supported.
         * The default implementation shows the fallback input field and adds
         * a text.
         */
        fallback: function fallback() {
          // This code should pass in IE7... :(
          var messageElement = void 0;
          this.element.className = this.element.className + " dz-browser-not-supported";

          for (var _iterator2 = this.element.getElementsByTagName("div"), _isArray2 = true, _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
            var _ref2;

            if (_isArray2) {
              if (_i2 >= _iterator2.length) break;
              _ref2 = _iterator2[_i2++];
            } else {
              _i2 = _iterator2.next();
              if (_i2.done) break;
              _ref2 = _i2.value;
            }

            var child = _ref2;

            if (/(^| )dz-message($| )/.test(child.className)) {
              messageElement = child;
              child.className = "dz-message"; // Removes the 'dz-default' class
              break;
            }
          }
          if (!messageElement) {
            messageElement = Dropzone.createElement("<div class=\"dz-message\"><span></span></div>");
            this.element.appendChild(messageElement);
          }

          var span = messageElement.getElementsByTagName("span")[0];
          if (span) {
            if (span.textContent != null) {
              span.textContent = this.options.dictFallbackMessage;
            } else if (span.innerText != null) {
              span.innerText = this.options.dictFallbackMessage;
            }
          }

          return this.element.appendChild(this.getFallbackForm());
        },


        /**
         * Gets called to calculate the thumbnail dimensions.
         *
         * It gets `file`, `width` and `height` (both may be `null`) as parameters and must return an object containing:
         *
         *  - `srcWidth` & `srcHeight` (required)
         *  - `trgWidth` & `trgHeight` (required)
         *  - `srcX` & `srcY` (optional, default `0`)
         *  - `trgX` & `trgY` (optional, default `0`)
         *
         * Those values are going to be used by `ctx.drawImage()`.
         */
        resize: function resize(file, width, height, resizeMethod) {
          var info = {
            srcX: 0,
            srcY: 0,
            srcWidth: file.width,
            srcHeight: file.height
          };

          var srcRatio = file.width / file.height;

          // Automatically calculate dimensions if not specified
          if (width == null && height == null) {
            width = info.srcWidth;
            height = info.srcHeight;
          } else if (width == null) {
            width = height * srcRatio;
          } else if (height == null) {
            height = width / srcRatio;
          }

          // Make sure images aren't upscaled
          width = Math.min(width, info.srcWidth);
          height = Math.min(height, info.srcHeight);

          var trgRatio = width / height;

          if (info.srcWidth > width || info.srcHeight > height) {
            // Image is bigger and needs rescaling
            if (resizeMethod === 'crop') {
              if (srcRatio > trgRatio) {
                info.srcHeight = file.height;
                info.srcWidth = info.srcHeight * trgRatio;
              } else {
                info.srcWidth = file.width;
                info.srcHeight = info.srcWidth / trgRatio;
              }
            } else if (resizeMethod === 'contain') {
              // Method 'contain'
              if (srcRatio > trgRatio) {
                height = width / srcRatio;
              } else {
                width = height * srcRatio;
              }
            } else {
              throw new Error("Unknown resizeMethod '" + resizeMethod + "'");
            }
          }

          info.srcX = (file.width - info.srcWidth) / 2;
          info.srcY = (file.height - info.srcHeight) / 2;

          info.trgWidth = width;
          info.trgHeight = height;

          return info;
        },


        /**
         * Can be used to transform the file (for example, resize an image if necessary).
         *
         * The default implementation uses `resizeWidth` and `resizeHeight` (if provided) and resizes
         * images according to those dimensions.
         *
         * Gets the `file` as the first parameter, and a `done()` function as the second, that needs
         * to be invoked with the file when the transformation is done.
         */
        transformFile: function transformFile(file, done) {
          if ((this.options.resizeWidth || this.options.resizeHeight) && file.type.match(/image.*/)) {
            return this.resizeImage(file, this.options.resizeWidth, this.options.resizeHeight, this.options.resizeMethod, done);
          } else {
            return done(file);
          }
        },


        /**
         * A string that contains the template used for each dropped
         * file. Change it to fulfill your needs but make sure to properly
         * provide all elements.
         *
         * If you want to use an actual HTML element instead of providing a String
         * as a config option, you could create a div with the id `tpl`,
         * put the template inside it and provide the element like this:
         *
         *     document
         *       .querySelector('#tpl')
         *       .innerHTML
         *
         */
        previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n  <div class=\"dz-image\"><img data-dz-thumbnail /></div>\n  <div class=\"dz-details\">\n    <div class=\"dz-size\"><span data-dz-size></span></div>\n    <div class=\"dz-filename\"><span data-dz-name></span></div>\n  </div>\n  <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress></span></div>\n  <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n  <div class=\"dz-success-mark\">\n    <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n      <title>Check</title>\n      <defs></defs>\n      <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n        <path d=\"M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835 11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915 C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022 L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" stroke-opacity=\"0.198794158\" stroke=\"#747474\" fill-opacity=\"0.816519475\" fill=\"#FFFFFF\" sketch:type=\"MSShapeGroup\"></path>\n      </g>\n    </svg>\n  </div>\n  <div class=\"dz-error-mark\">\n    <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n      <title>Error</title>\n      <defs></defs>\n      <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n        <g id=\"Check-+-Oval-2\" sketch:type=\"MSLayerGroup\" stroke=\"#747474\" stroke-opacity=\"0.198794158\" fill=\"#FFFFFF\" fill-opacity=\"0.816519475\">\n          <path d=\"M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887 38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915 C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564 L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479 14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271 38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" sketch:type=\"MSShapeGroup\"></path>\n        </g>\n      </g>\n    </svg>\n  </div>\n</div>",

        // END OPTIONS
        // (Required by the dropzone documentation parser)


        /*
         Those functions register themselves to the events on init and handle all
         the user interface specific stuff. Overwriting them won't break the upload
         but can break the way it's displayed.
         You can overwrite them if you don't like the default behavior. If you just
         want to add an additional event handler, register it on the dropzone object
         and don't overwrite those options.
         */

        // Those are self explanatory and simply concern the DragnDrop.
        drop: function drop(e) {
          return this.element.classList.remove("dz-drag-hover");
        },
        dragstart: function dragstart(e) {},
        dragend: function dragend(e) {
          return this.element.classList.remove("dz-drag-hover");
        },
        dragenter: function dragenter(e) {
          return this.element.classList.add("dz-drag-hover");
        },
        dragover: function dragover(e) {
          return this.element.classList.add("dz-drag-hover");
        },
        dragleave: function dragleave(e) {
          return this.element.classList.remove("dz-drag-hover");
        },
        paste: function paste(e) {},


        // Called whenever there are no files left in the dropzone anymore, and the
        // dropzone should be displayed as if in the initial state.
        reset: function reset() {
          return this.element.classList.remove("dz-started");
        },


        // Called when a file is added to the queue
        // Receives `file`
        addedfile: function addedfile(file) {
          var _this2 = this;

          if (this.element === this.previewsContainer) {
            this.element.classList.add("dz-started");
          }

          if (this.previewsContainer) {
            file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim());
            file.previewTemplate = file.previewElement; // Backwards compatibility

            this.previewsContainer.appendChild(file.previewElement);
            for (var _iterator3 = file.previewElement.querySelectorAll("[data-dz-name]"), _isArray3 = true, _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
              var _ref3;

              if (_isArray3) {
                if (_i3 >= _iterator3.length) break;
                _ref3 = _iterator3[_i3++];
              } else {
                _i3 = _iterator3.next();
                if (_i3.done) break;
                _ref3 = _i3.value;
              }

              var node = _ref3;

              node.textContent = file.name;
            }
            for (var _iterator4 = file.previewElement.querySelectorAll("[data-dz-size]"), _isArray4 = true, _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
              if (_isArray4) {
                if (_i4 >= _iterator4.length) break;
                node = _iterator4[_i4++];
              } else {
                _i4 = _iterator4.next();
                if (_i4.done) break;
                node = _i4.value;
              }

              node.innerHTML = this.filesize(file.size);
            }

            if (this.options.addRemoveLinks) {
              file._removeLink = Dropzone.createElement("<a class=\"dz-remove\" href=\"javascript:undefined;\" data-dz-remove>" + this.options.dictRemoveFile + "</a>");
              file.previewElement.appendChild(file._removeLink);
            }

            var removeFileEvent = function removeFileEvent(e) {
              e.preventDefault();
              e.stopPropagation();
              if (file.status === Dropzone.UPLOADING) {
                return Dropzone.confirm(_this2.options.dictCancelUploadConfirmation, function () {
                  return _this2.removeFile(file);
                });
              } else {
                if (_this2.options.dictRemoveFileConfirmation) {
                  return Dropzone.confirm(_this2.options.dictRemoveFileConfirmation, function () {
                    return _this2.removeFile(file);
                  });
                } else {
                  return _this2.removeFile(file);
                }
              }
            };

            for (var _iterator5 = file.previewElement.querySelectorAll("[data-dz-remove]"), _isArray5 = true, _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
              var _ref4;

              if (_isArray5) {
                if (_i5 >= _iterator5.length) break;
                _ref4 = _iterator5[_i5++];
              } else {
                _i5 = _iterator5.next();
                if (_i5.done) break;
                _ref4 = _i5.value;
              }

              var removeLink = _ref4;

              removeLink.addEventListener("click", removeFileEvent);
            }
          }
        },


        // Called whenever a file is removed.
        removedfile: function removedfile(file) {
          if (file.previewElement != null && file.previewElement.parentNode != null) {
            file.previewElement.parentNode.removeChild(file.previewElement);
          }
          return this._updateMaxFilesReachedClass();
        },


        // Called when a thumbnail has been generated
        // Receives `file` and `dataUrl`
        thumbnail: function thumbnail(file, dataUrl) {
          if (file.previewElement) {
            file.previewElement.classList.remove("dz-file-preview");
            for (var _iterator6 = file.previewElement.querySelectorAll("[data-dz-thumbnail]"), _isArray6 = true, _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {
              var _ref5;

              if (_isArray6) {
                if (_i6 >= _iterator6.length) break;
                _ref5 = _iterator6[_i6++];
              } else {
                _i6 = _iterator6.next();
                if (_i6.done) break;
                _ref5 = _i6.value;
              }

              var thumbnailElement = _ref5;

              thumbnailElement.alt = file.name;
              thumbnailElement.src = dataUrl;
            }

            return setTimeout(function () {
              return file.previewElement.classList.add("dz-image-preview");
            }, 1);
          }
        },


        // Called whenever an error occurs
        // Receives `file` and `message`
        error: function error(file, message) {
          if (file.previewElement) {
            file.previewElement.classList.add("dz-error");
            if (typeof message !== "String" && message.error) {
              message = message.error;
            }
            for (var _iterator7 = file.previewElement.querySelectorAll("[data-dz-errormessage]"), _isArray7 = true, _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) {
              var _ref6;

              if (_isArray7) {
                if (_i7 >= _iterator7.length) break;
                _ref6 = _iterator7[_i7++];
              } else {
                _i7 = _iterator7.next();
                if (_i7.done) break;
                _ref6 = _i7.value;
              }

              var node = _ref6;

              node.textContent = message;
            }
          }
        },
        errormultiple: function errormultiple() {},


        // Called when a file gets processed. Since there is a cue, not all added
        // files are processed immediately.
        // Receives `file`
        processing: function processing(file) {
          if (file.previewElement) {
            file.previewElement.classList.add("dz-processing");
            if (file._removeLink) {
              return file._removeLink.textContent = this.options.dictCancelUpload;
            }
          }
        },
        processingmultiple: function processingmultiple() {},


        // Called whenever the upload progress gets updated.
        // Receives `file`, `progress` (percentage 0-100) and `bytesSent`.
        // To get the total number of bytes of the file, use `file.size`
        uploadprogress: function uploadprogress(file, progress, bytesSent) {
          if (file.previewElement) {
            for (var _iterator8 = file.previewElement.querySelectorAll("[data-dz-uploadprogress]"), _isArray8 = true, _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) {
              var _ref7;

              if (_isArray8) {
                if (_i8 >= _iterator8.length) break;
                _ref7 = _iterator8[_i8++];
              } else {
                _i8 = _iterator8.next();
                if (_i8.done) break;
                _ref7 = _i8.value;
              }

              var node = _ref7;

              node.nodeName === 'PROGRESS' ? node.value = progress : node.style.width = progress + "%";
            }
          }
        },


        // Called whenever the total upload progress gets updated.
        // Called with totalUploadProgress (0-100), totalBytes and totalBytesSent
        totaluploadprogress: function totaluploadprogress() {},


        // Called just before the file is sent. Gets the `xhr` object as second
        // parameter, so you can modify it (for example to add a CSRF token) and a
        // `formData` object to add additional information.
        sending: function sending() {},
        sendingmultiple: function sendingmultiple() {},


        // When the complete upload is finished and successful
        // Receives `file`
        success: function success(file) {
          if (file.previewElement) {
            return file.previewElement.classList.add("dz-success");
          }
        },
        successmultiple: function successmultiple() {},


        // When the upload is canceled.
        canceled: function canceled(file) {
          return this.emit("error", file, this.options.dictUploadCanceled);
        },
        canceledmultiple: function canceledmultiple() {},


        // When the upload is finished, either with success or an error.
        // Receives `file`
        complete: function complete(file) {
          if (file._removeLink) {
            file._removeLink.textContent = this.options.dictRemoveFile;
          }
          if (file.previewElement) {
            return file.previewElement.classList.add("dz-complete");
          }
        },
        completemultiple: function completemultiple() {},
        maxfilesexceeded: function maxfilesexceeded() {},
        maxfilesreached: function maxfilesreached() {},
        queuecomplete: function queuecomplete() {},
        addedfiles: function addedfiles() {}
      };

      this.prototype._thumbnailQueue = [];
      this.prototype._processingThumbnail = false;
    }

    // global utility

  }, {
    key: "extend",
    value: function extend(target) {
      for (var _len2 = arguments.length, objects = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
        objects[_key2 - 1] = arguments[_key2];
      }

      for (var _iterator9 = objects, _isArray9 = true, _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) {
        var _ref8;

        if (_isArray9) {
          if (_i9 >= _iterator9.length) break;
          _ref8 = _iterator9[_i9++];
        } else {
          _i9 = _iterator9.next();
          if (_i9.done) break;
          _ref8 = _i9.value;
        }

        var object = _ref8;

        for (var key in object) {
          var val = object[key];
          target[key] = val;
        }
      }
      return target;
    }
  }]);

  function Dropzone(el, options) {
    _classCallCheck(this, Dropzone);

    var _this = _possibleConstructorReturn(this, (Dropzone.__proto__ || Object.getPrototypeOf(Dropzone)).call(this));

    var fallback = void 0,
        left = void 0;
    _this.element = el;
    // For backwards compatibility since the version was in the prototype previously
    _this.version = Dropzone.version;

    _this.defaultOptions.previewTemplate = _this.defaultOptions.previewTemplate.replace(/\n*/g, "");

    _this.clickableElements = [];
    _this.listeners = [];
    _this.files = []; // All files

    if (typeof _this.element === "string") {
      _this.element = document.querySelector(_this.element);
    }

    // Not checking if instance of HTMLElement or Element since IE9 is extremely weird.
    if (!_this.element || _this.element.nodeType == null) {
      throw new Error("Invalid dropzone element.");
    }

    if (_this.element.dropzone) {
      throw new Error("Dropzone already attached.");
    }

    // Now add this dropzone to the instances.
    Dropzone.instances.push(_this);

    // Put the dropzone inside the element itself.
    _this.element.dropzone = _this;

    var elementOptions = (left = Dropzone.optionsForElement(_this.element)) != null ? left : {};

    _this.options = Dropzone.extend({}, _this.defaultOptions, elementOptions, options != null ? options : {});

    // If the browser failed, just call the fallback and leave
    if (_this.options.forceFallback || !Dropzone.isBrowserSupported()) {
      var _ret;

      return _ret = _this.options.fallback.call(_this), _possibleConstructorReturn(_this, _ret);
    }

    // @options.url = @element.getAttribute "action" unless @options.url?
    if (_this.options.url == null) {
      _this.options.url = _this.element.getAttribute("action");
    }

    if (!_this.options.url) {
      throw new Error("No URL provided.");
    }

    if (_this.options.acceptedFiles && _this.options.acceptedMimeTypes) {
      throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated.");
    }

    if (_this.options.uploadMultiple && _this.options.chunking) {
      throw new Error('You cannot set both: uploadMultiple and chunking.');
    }

    // Backwards compatibility
    if (_this.options.acceptedMimeTypes) {
      _this.options.acceptedFiles = _this.options.acceptedMimeTypes;
      delete _this.options.acceptedMimeTypes;
    }

    // Backwards compatibility
    if (_this.options.renameFilename != null) {
      _this.options.renameFile = function (file) {
        return _this.options.renameFilename.call(_this, file.name, file);
      };
    }

    _this.options.method = _this.options.method.toUpperCase();

    if ((fallback = _this.getExistingFallback()) && fallback.parentNode) {
      // Remove the fallback
      fallback.parentNode.removeChild(fallback);
    }

    // Display previews in the previewsContainer element or the Dropzone element unless explicitly set to false
    if (_this.options.previewsContainer !== false) {
      if (_this.options.previewsContainer) {
        _this.previewsContainer = Dropzone.getElement(_this.options.previewsContainer, "previewsContainer");
      } else {
        _this.previewsContainer = _this.element;
      }
    }

    if (_this.options.clickable) {
      if (_this.options.clickable === true) {
        _this.clickableElements = [_this.element];
      } else {
        _this.clickableElements = Dropzone.getElements(_this.options.clickable, "clickable");
      }
    }

    _this.init();
    return _this;
  }

  // Returns all files that have been accepted


  _createClass(Dropzone, [{
    key: "getAcceptedFiles",
    value: function getAcceptedFiles() {
      return this.files.filter(function (file) {
        return file.accepted;
      }).map(function (file) {
        return file;
      });
    }

    // Returns all files that have been rejected
    // Not sure when that's going to be useful, but added for completeness.

  }, {
    key: "getRejectedFiles",
    value: function getRejectedFiles() {
      return this.files.filter(function (file) {
        return !file.accepted;
      }).map(function (file) {
        return file;
      });
    }
  }, {
    key: "getFilesWithStatus",
    value: function getFilesWithStatus(status) {
      return this.files.filter(function (file) {
        return file.status === status;
      }).map(function (file) {
        return file;
      });
    }

    // Returns all files that are in the queue

  }, {
    key: "getQueuedFiles",
    value: function getQueuedFiles() {
      return this.getFilesWithStatus(Dropzone.QUEUED);
    }
  }, {
    key: "getUploadingFiles",
    value: function getUploadingFiles() {
      return this.getFilesWithStatus(Dropzone.UPLOADING);
    }
  }, {
    key: "getAddedFiles",
    value: function getAddedFiles() {
      return this.getFilesWithStatus(Dropzone.ADDED);
    }

    // Files that are either queued or uploading

  }, {
    key: "getActiveFiles",
    value: function getActiveFiles() {
      return this.files.filter(function (file) {
        return file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED;
      }).map(function (file) {
        return file;
      });
    }

    // The function that gets called when Dropzone is initialized. You
    // can (and should) setup event listeners inside this function.

  }, {
    key: "init",
    value: function init() {
      var _this3 = this;

      // In case it isn't set already
      if (this.element.tagName === "form") {
        this.element.setAttribute("enctype", "multipart/form-data");
      }

      if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) {
        this.element.appendChild(Dropzone.createElement("<div class=\"dz-default dz-message\"><span>" + this.options.dictDefaultMessage + "</span></div>"));
      }

      if (this.clickableElements.length) {
        var setupHiddenFileInput = function setupHiddenFileInput() {
          if (_this3.hiddenFileInput) {
            _this3.hiddenFileInput.parentNode.removeChild(_this3.hiddenFileInput);
          }
          _this3.hiddenFileInput = document.createElement("input");
          _this3.hiddenFileInput.setAttribute("type", "file");
          if (_this3.options.maxFiles === null || _this3.options.maxFiles > 1) {
            _this3.hiddenFileInput.setAttribute("multiple", "multiple");
          }
          _this3.hiddenFileInput.className = "dz-hidden-input";

          if (_this3.options.acceptedFiles !== null) {
            _this3.hiddenFileInput.setAttribute("accept", _this3.options.acceptedFiles);
          }
          if (_this3.options.capture !== null) {
            _this3.hiddenFileInput.setAttribute("capture", _this3.options.capture);
          }

          // Not setting `display="none"` because some browsers don't accept clicks
          // on elements that aren't displayed.
          _this3.hiddenFileInput.style.visibility = "hidden";
          _this3.hiddenFileInput.style.position = "absolute";
          _this3.hiddenFileInput.style.top = "0";
          _this3.hiddenFileInput.style.left = "0";
          _this3.hiddenFileInput.style.height = "0";
          _this3.hiddenFileInput.style.width = "0";
          document.querySelector(_this3.options.hiddenInputContainer).appendChild(_this3.hiddenFileInput);
          return _this3.hiddenFileInput.addEventListener("change", function () {
            var files = _this3.hiddenFileInput.files;

            if (files.length) {
              for (var _iterator10 = files, _isArray10 = true, _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) {
                var _ref9;

                if (_isArray10) {
                  if (_i10 >= _iterator10.length) break;
                  _ref9 = _iterator10[_i10++];
                } else {
                  _i10 = _iterator10.next();
                  if (_i10.done) break;
                  _ref9 = _i10.value;
                }

                var file = _ref9;

                _this3.addFile(file);
              }
            }
            _this3.emit("addedfiles", files);
            return setupHiddenFileInput();
          });
        };
        setupHiddenFileInput();
      }

      this.URL = window.URL !== null ? window.URL : window.webkitURL;

      // Setup all event listeners on the Dropzone object itself.
      // They're not in @setupEventListeners() because they shouldn't be removed
      // again when the dropzone gets disabled.
      for (var _iterator11 = this.events, _isArray11 = true, _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : _iterator11[Symbol.iterator]();;) {
        var _ref10;

        if (_isArray11) {
          if (_i11 >= _iterator11.length) break;
          _ref10 = _iterator11[_i11++];
        } else {
          _i11 = _iterator11.next();
          if (_i11.done) break;
          _ref10 = _i11.value;
        }

        var eventName = _ref10;

        this.on(eventName, this.options[eventName]);
      }

      this.on("uploadprogress", function () {
        return _this3.updateTotalUploadProgress();
      });

      this.on("removedfile", function () {
        return _this3.updateTotalUploadProgress();
      });

      this.on("canceled", function (file) {
        return _this3.emit("complete", file);
      });

      // Emit a `queuecomplete` event if all files finished uploading.
      this.on("complete", function (file) {
        if (_this3.getAddedFiles().length === 0 && _this3.getUploadingFiles().length === 0 && _this3.getQueuedFiles().length === 0) {
          // This needs to be deferred so that `queuecomplete` really triggers after `complete`
          return setTimeout(function () {
            return _this3.emit("queuecomplete");
          }, 0);
        }
      });

      var noPropagation = function noPropagation(e) {
        e.stopPropagation();
        if (e.preventDefault) {
          return e.preventDefault();
        } else {
          return e.returnValue = false;
        }
      };

      // Create the listeners
      this.listeners = [{
        element: this.element,
        events: {
          "dragstart": function dragstart(e) {
            return _this3.emit("dragstart", e);
          },
          "dragenter": function dragenter(e) {
            noPropagation(e);
            return _this3.emit("dragenter", e);
          },
          "dragover": function dragover(e) {
            // Makes it possible to drag files from chrome's download bar
            // http://stackoverflow.com/questions/19526430/drag-and-drop-file-uploads-from-chrome-downloads-bar
            // Try is required to prevent bug in Internet Explorer 11 (SCRIPT65535 exception)
            var efct = void 0;
            try {
              efct = e.dataTransfer.effectAllowed;
            } catch (error) {}
            e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy';

            noPropagation(e);
            return _this3.emit("dragover", e);
          },
          "dragleave": function dragleave(e) {
            return _this3.emit("dragleave", e);
          },
          "drop": function drop(e) {
            noPropagation(e);
            return _this3.drop(e);
          },
          "dragend": function dragend(e) {
            return _this3.emit("dragend", e);
          }

          // This is disabled right now, because the browsers don't implement it properly.
          // "paste": (e) =>
          //   noPropagation e
          //   @paste e
        } }];

      this.clickableElements.forEach(function (clickableElement) {
        return _this3.listeners.push({
          element: clickableElement,
          events: {
            "click": function click(evt) {
              // Only the actual dropzone or the message element should trigger file selection
              if (clickableElement !== _this3.element || evt.target === _this3.element || Dropzone.elementInside(evt.target, _this3.element.querySelector(".dz-message"))) {
                _this3.hiddenFileInput.click(); // Forward the click
              }
              return true;
            }
          }
        });
      });

      this.enable();

      return this.options.init.call(this);
    }

    // Not fully tested yet

  }, {
    key: "destroy",
    value: function destroy() {
      this.disable();
      this.removeAllFiles(true);
      if (this.hiddenFileInput != null ? this.hiddenFileInput.parentNode : undefined) {
        this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput);
        this.hiddenFileInput = null;
      }
      delete this.element.dropzone;
      return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1);
    }
  }, {
    key: "updateTotalUploadProgress",
    value: function updateTotalUploadProgress() {
      var totalUploadProgress = void 0;
      var totalBytesSent = 0;
      var totalBytes = 0;

      var activeFiles = this.getActiveFiles();

      if (activeFiles.length) {
        for (var _iterator12 = this.getActiveFiles(), _isArray12 = true, _i12 = 0, _iterator12 = _isArray12 ? _iterator12 : _iterator12[Symbol.iterator]();;) {
          var _ref11;

          if (_isArray12) {
            if (_i12 >= _iterator12.length) break;
            _ref11 = _iterator12[_i12++];
          } else {
            _i12 = _iterator12.next();
            if (_i12.done) break;
            _ref11 = _i12.value;
          }

          var file = _ref11;

          totalBytesSent += file.upload.bytesSent;
          totalBytes += file.upload.total;
        }
        totalUploadProgress = 100 * totalBytesSent / totalBytes;
      } else {
        totalUploadProgress = 100;
      }

      return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent);
    }

    // @options.paramName can be a function taking one parameter rather than a string.
    // A parameter name for a file is obtained simply by calling this with an index number.

  }, {
    key: "_getParamName",
    value: function _getParamName(n) {
      if (typeof this.options.paramName === "function") {
        return this.options.paramName(n);
      } else {
        return "" + this.options.paramName + (this.options.uploadMultiple ? "[" + n + "]" : "");
      }
    }

    // If @options.renameFile is a function,
    // the function will be used to rename the file.name before appending it to the formData

  }, {
    key: "_renameFile",
    value: function _renameFile(file) {
      if (typeof this.options.renameFile !== "function") {
        return file.name;
      }
      return this.options.renameFile(file);
    }

    // Returns a form that can be used as fallback if the browser does not support DragnDrop
    //
    // If the dropzone is already a form, only the input field and button are returned. Otherwise a complete form element is provided.
    // This code has to pass in IE7 :(

  }, {
    key: "getFallbackForm",
    value: function getFallbackForm() {
      var existingFallback = void 0,
          form = void 0;
      if (existingFallback = this.getExistingFallback()) {
        return existingFallback;
      }

      var fieldsString = "<div class=\"dz-fallback\">";
      if (this.options.dictFallbackText) {
        fieldsString += "<p>" + this.options.dictFallbackText + "</p>";
      }
      fieldsString += "<input type=\"file\" name=\"" + this._getParamName(0) + "\" " + (this.options.uploadMultiple ? 'multiple="multiple"' : undefined) + " /><input type=\"submit\" value=\"Upload!\"></div>";

      var fields = Dropzone.createElement(fieldsString);
      if (this.element.tagName !== "FORM") {
        form = Dropzone.createElement("<form action=\"" + this.options.url + "\" enctype=\"multipart/form-data\" method=\"" + this.options.method + "\"></form>");
        form.appendChild(fields);
      } else {
        // Make sure that the enctype and method attributes are set properly
        this.element.setAttribute("enctype", "multipart/form-data");
        this.element.setAttribute("method", this.options.method);
      }
      return form != null ? form : fields;
    }

    // Returns the fallback elements if they exist already
    //
    // This code has to pass in IE7 :(

  }, {
    key: "getExistingFallback",
    value: function getExistingFallback() {
      var getFallback = function getFallback(elements) {
        for (var _iterator13 = elements, _isArray13 = true, _i13 = 0, _iterator13 = _isArray13 ? _iterator13 : _iterator13[Symbol.iterator]();;) {
          var _ref12;

          if (_isArray13) {
            if (_i13 >= _iterator13.length) break;
            _ref12 = _iterator13[_i13++];
          } else {
            _i13 = _iterator13.next();
            if (_i13.done) break;
            _ref12 = _i13.value;
          }

          var el = _ref12;

          if (/(^| )fallback($| )/.test(el.className)) {
            return el;
          }
        }
      };

      var _arr = ["div", "form"];
      for (var _i14 = 0; _i14 < _arr.length; _i14++) {
        var tagName = _arr[_i14];
        var fallback;
        if (fallback = getFallback(this.element.getElementsByTagName(tagName))) {
          return fallback;
        }
      }
    }

    // Activates all listeners stored in @listeners

  }, {
    key: "setupEventListeners",
    value: function setupEventListeners() {
      return this.listeners.map(function (elementListeners) {
        return function () {
          var result = [];
          for (var event in elementListeners.events) {
            var listener = elementListeners.events[event];
            result.push(elementListeners.element.addEventListener(event, listener, false));
          }
          return result;
        }();
      });
    }

    // Deactivates all listeners stored in @listeners

  }, {
    key: "removeEventListeners",
    value: function removeEventListeners() {
      return this.listeners.map(function (elementListeners) {
        return function () {
          var result = [];
          for (var event in elementListeners.events) {
            var listener = elementListeners.events[event];
            result.push(elementListeners.element.removeEventListener(event, listener, false));
          }
          return result;
        }();
      });
    }

    // Removes all event listeners and cancels all files in the queue or being processed.

  }, {
    key: "disable",
    value: function disable() {
      var _this4 = this;

      this.clickableElements.forEach(function (element) {
        return element.classList.remove("dz-clickable");
      });
      this.removeEventListeners();
      this.disabled = true;

      return this.files.map(function (file) {
        return _this4.cancelUpload(file);
      });
    }
  }, {
    key: "enable",
    value: function enable() {
      delete this.disabled;
      this.clickableElements.forEach(function (element) {
        return element.classList.add("dz-clickable");
      });
      return this.setupEventListeners();
    }

    // Returns a nicely formatted filesize

  }, {
    key: "filesize",
    value: function filesize(size) {
      var selectedSize = 0;
      var selectedUnit = "b";

      if (size > 0) {
        var units = ['tb', 'gb', 'mb', 'kb', 'b'];

        for (var i = 0; i < units.length; i++) {
          var unit = units[i];
          var cutoff = Math.pow(this.options.filesizeBase, 4 - i) / 10;

          if (size >= cutoff) {
            selectedSize = size / Math.pow(this.options.filesizeBase, 4 - i);
            selectedUnit = unit;
            break;
          }
        }

        selectedSize = Math.round(10 * selectedSize) / 10; // Cutting of digits
      }

      return "<strong>" + selectedSize + "</strong> " + this.options.dictFileSizeUnits[selectedUnit];
    }

    // Adds or removes the `dz-max-files-reached` class from the form.

  }, {
    key: "_updateMaxFilesReachedClass",
    value: function _updateMaxFilesReachedClass() {
      if (this.options.maxFiles != null && this.getAcceptedFiles().length >= this.options.maxFiles) {
        if (this.getAcceptedFiles().length === this.options.maxFiles) {
          this.emit('maxfilesreached', this.files);
        }
        return this.element.classList.add("dz-max-files-reached");
      } else {
        return this.element.classList.remove("dz-max-files-reached");
      }
    }
  }, {
    key: "drop",
    value: function drop(e) {
      if (!e.dataTransfer) {
        return;
      }
      this.emit("drop", e);

      var files = e.dataTransfer.files;

      this.emit("addedfiles", files);

      // Even if it's a folder, files.length will contain the folders.
      if (files.length) {
        var items = e.dataTransfer.items;

        if (items && items.length && items[0].webkitGetAsEntry != null) {
          // The browser supports dropping of folders, so handle items instead of files
          this._addFilesFromItems(items);
        } else {
          this.handleFiles(files);
        }
      }
    }
  }, {
    key: "paste",
    value: function paste(e) {
      if (__guard__(e != null ? e.clipboardData : undefined, function (x) {
        return x.items;
      }) == null) {
        return;
      }

      this.emit("paste", e);
      var items = e.clipboardData.items;


      if (items.length) {
        return this._addFilesFromItems(items);
      }
    }
  }, {
    key: "handleFiles",
    value: function handleFiles(files) {
      for (var _iterator14 = files, _isArray14 = true, _i15 = 0, _iterator14 = _isArray14 ? _iterator14 : _iterator14[Symbol.iterator]();;) {
        var _ref13;

        if (_isArray14) {
          if (_i15 >= _iterator14.length) break;
          _ref13 = _iterator14[_i15++];
        } else {
          _i15 = _iterator14.next();
          if (_i15.done) break;
          _ref13 = _i15.value;
        }

        var file = _ref13;

        this.addFile(file);
      }
    }

    // When a folder is dropped (or files are pasted), items must be handled
    // instead of files.

  }, {
    key: "_addFilesFromItems",
    value: function _addFilesFromItems(items) {
      var _this5 = this;

      return function () {
        var result = [];
        for (var _iterator15 = items, _isArray15 = true, _i16 = 0, _iterator15 = _isArray15 ? _iterator15 : _iterator15[Symbol.iterator]();;) {
          var _ref14;

          if (_isArray15) {
            if (_i16 >= _iterator15.length) break;
            _ref14 = _iterator15[_i16++];
          } else {
            _i16 = _iterator15.next();
            if (_i16.done) break;
            _ref14 = _i16.value;
          }

          var item = _ref14;

          var entry;
          if (item.webkitGetAsEntry != null && (entry = item.webkitGetAsEntry())) {
            if (entry.isFile) {
              result.push(_this5.addFile(item.getAsFile()));
            } else if (entry.isDirectory) {
              // Append all files from that directory to files
              result.push(_this5._addFilesFromDirectory(entry, entry.name));
            } else {
              result.push(undefined);
            }
          } else if (item.getAsFile != null) {
            if (item.kind == null || item.kind === "file") {
              result.push(_this5.addFile(item.getAsFile()));
            } else {
              result.push(undefined);
            }
          } else {
            result.push(undefined);
          }
        }
        return result;
      }();
    }

    // Goes through the directory, and adds each file it finds recursively

  }, {
    key: "_addFilesFromDirectory",
    value: function _addFilesFromDirectory(directory, path) {
      var _this6 = this;

      var dirReader = directory.createReader();

      var errorHandler = function errorHandler(error) {
        return __guardMethod__(console, 'log', function (o) {
          return o.log(error);
        });
      };

      var readEntries = function readEntries() {
        return dirReader.readEntries(function (entries) {
          if (entries.length > 0) {
            for (var _iterator16 = entries, _isArray16 = true, _i17 = 0, _iterator16 = _isArray16 ? _iterator16 : _iterator16[Symbol.iterator]();;) {
              var _ref15;

              if (_isArray16) {
                if (_i17 >= _iterator16.length) break;
                _ref15 = _iterator16[_i17++];
              } else {
                _i17 = _iterator16.next();
                if (_i17.done) break;
                _ref15 = _i17.value;
              }

              var entry = _ref15;

              if (entry.isFile) {
                entry.file(function (file) {
                  if (_this6.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') {
                    return;
                  }
                  file.fullPath = path + "/" + file.name;
                  return _this6.addFile(file);
                });
              } else if (entry.isDirectory) {
                _this6._addFilesFromDirectory(entry, path + "/" + entry.name);
              }
            }

            // Recursively call readEntries() again, since browser only handle
            // the first 100 entries.
            // See: https://developer.mozilla.org/en-US/docs/Web/API/DirectoryReader#readEntries
            readEntries();
          }
          return null;
        }, errorHandler);
      };

      return readEntries();
    }

    // If `done()` is called without argument the file is accepted
    // If you call it with an error message, the file is rejected
    // (This allows for asynchronous validation)
    //
    // This function checks the filesize, and if the file.type passes the
    // `acceptedFiles` check.

  }, {
    key: "accept",
    value: function accept(file, done) {
      if (file.size > this.options.maxFilesize * 1024 * 1024) {
        return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize));
      } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) {
        return done(this.options.dictInvalidFileType);
      } else if (this.options.maxFiles != null && this.getAcceptedFiles().length >= this.options.maxFiles) {
        done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles));
        return this.emit("maxfilesexceeded", file);
      } else {
        return this.options.accept.call(this, file, done);
      }
    }
  }, {
    key: "addFile",
    value: function addFile(file) {
      var _this7 = this;

      file.upload = {
        uuid: Dropzone.uuidv4(),
        progress: 0,
        // Setting the total upload size to file.size for the beginning
        // It's actual different than the size to be transmitted.
        total: file.size,
        bytesSent: 0,
        filename: this._renameFile(file),
        chunked: this.options.chunking && (this.options.forceChunking || file.size > this.options.chunkSize),
        totalChunkCount: Math.ceil(file.size / this.options.chunkSize)
      };
      this.files.push(file);

      file.status = Dropzone.ADDED;

      this.emit("addedfile", file);

      this._enqueueThumbnail(file);

      return this.accept(file, function (error) {
        if (error) {
          file.accepted = false;
          _this7._errorProcessing([file], error); // Will set the file.status
        } else {
          file.accepted = true;
          if (_this7.options.autoQueue) {
            _this7.enqueueFile(file);
          } // Will set .accepted = true
        }
        return _this7._updateMaxFilesReachedClass();
      });
    }

    // Wrapper for enqueueFile

  }, {
    key: "enqueueFiles",
    value: function enqueueFiles(files) {
      for (var _iterator17 = files, _isArray17 = true, _i18 = 0, _iterator17 = _isArray17 ? _iterator17 : _iterator17[Symbol.iterator]();;) {
        var _ref16;

        if (_isArray17) {
          if (_i18 >= _iterator17.length) break;
          _ref16 = _iterator17[_i18++];
        } else {
          _i18 = _iterator17.next();
          if (_i18.done) break;
          _ref16 = _i18.value;
        }

        var file = _ref16;

        this.enqueueFile(file);
      }
      return null;
    }
  }, {
    key: "enqueueFile",
    value: function enqueueFile(file) {
      var _this8 = this;

      if (file.status === Dropzone.ADDED && file.accepted === true) {
        file.status = Dropzone.QUEUED;
        if (this.options.autoProcessQueue) {
          return setTimeout(function () {
            return _this8.processQueue();
          }, 0); // Deferring the call
        }
      } else {
        throw new Error("This file can't be queued because it has already been processed or was rejected.");
      }
    }
  }, {
    key: "_enqueueThumbnail",
    value: function _enqueueThumbnail(file) {
      var _this9 = this;

      if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) {
        this._thumbnailQueue.push(file);
        return setTimeout(function () {
          return _this9._processThumbnailQueue();
        }, 0); // Deferring the call
      }
    }
  }, {
    key: "_processThumbnailQueue",
    value: function _processThumbnailQueue() {
      var _this10 = this;

      if (this._processingThumbnail || this._thumbnailQueue.length === 0) {
        return;
      }

      this._processingThumbnail = true;
      var file = this._thumbnailQueue.shift();
      return this.createThumbnail(file, this.options.thumbnailWidth, this.options.thumbnailHeight, this.options.thumbnailMethod, true, function (dataUrl) {
        _this10.emit("thumbnail", file, dataUrl);
        _this10._processingThumbnail = false;
        return _this10._processThumbnailQueue();
      });
    }

    // Can be called by the user to remove a file

  }, {
    key: "removeFile",
    value: function removeFile(file) {
      if (file.status === Dropzone.UPLOADING) {
        this.cancelUpload(file);
      }
      this.files = without(this.files, file);

      this.emit("removedfile", file);
      if (this.files.length === 0) {
        return this.emit("reset");
      }
    }

    // Removes all files that aren't currently processed from the list

  }, {
    key: "removeAllFiles",
    value: function removeAllFiles(cancelIfNecessary) {
      // Create a copy of files since removeFile() changes the @files array.
      if (cancelIfNecessary == null) {
        cancelIfNecessary = false;
      }
      for (var _iterator18 = this.files.slice(), _isArray18 = true, _i19 = 0, _iterator18 = _isArray18 ? _iterator18 : _iterator18[Symbol.iterator]();;) {
        var _ref17;

        if (_isArray18) {
          if (_i19 >= _iterator18.length) break;
          _ref17 = _iterator18[_i19++];
        } else {
          _i19 = _iterator18.next();
          if (_i19.done) break;
          _ref17 = _i19.value;
        }

        var file = _ref17;

        if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) {
          this.removeFile(file);
        }
      }
      return null;
    }

    // Resizes an image before it gets sent to the server. This function is the default behavior of
    // `options.transformFile` if `resizeWidth` or `resizeHeight` are set. The callback is invoked with
    // the resized blob.

  }, {
    key: "resizeImage",
    value: function resizeImage(file, width, height, resizeMethod, callback) {
      var _this11 = this;

      return this.createThumbnail(file, width, height, resizeMethod, false, function (dataUrl, canvas) {
        if (canvas == null) {
          // The image has not been resized
          return callback(file);
        } else {
          var resizeMimeType = _this11.options.resizeMimeType;

          if (resizeMimeType == null) {
            resizeMimeType = file.type;
          }
          var resizedDataURL = canvas.toDataURL(resizeMimeType, _this11.options.resizeQuality);
          if (resizeMimeType === 'image/jpeg' || resizeMimeType === 'image/jpg') {
            // Now add the original EXIF information
            resizedDataURL = ExifRestore.restore(file.dataURL, resizedDataURL);
          }
          return callback(Dropzone.dataURItoBlob(resizedDataURL));
        }
      });
    }
  }, {
    key: "createThumbnail",
    value: function createThumbnail(file, width, height, resizeMethod, fixOrientation, callback) {
      var _this12 = this;

      var fileReader = new FileReader();

      fileReader.onload = function () {

        file.dataURL = fileReader.result;

        // Don't bother creating a thumbnail for SVG images since they're vector
        if (file.type === "image/svg+xml") {
          if (callback != null) {
            callback(fileReader.result);
          }
          return;
        }

        return _this12.createThumbnailFromUrl(file, width, height, resizeMethod, fixOrientation, callback);
      };

      return fileReader.readAsDataURL(file);
    }
  }, {
    key: "createThumbnailFromUrl",
    value: function createThumbnailFromUrl(file, width, height, resizeMethod, fixOrientation, callback, crossOrigin) {
      var _this13 = this;

      // Not using `new Image` here because of a bug in latest Chrome versions.
      // See https://github.com/enyo/dropzone/pull/226
      var img = document.createElement("img");

      if (crossOrigin) {
        img.crossOrigin = crossOrigin;
      }

      img.onload = function () {
        var loadExif = function loadExif(callback) {
          return callback(1);
        };
        if (typeof EXIF !== 'undefined' && EXIF !== null && fixOrientation) {
          loadExif = function loadExif(callback) {
            return EXIF.getData(img, function () {
              return callback(EXIF.getTag(this, 'Orientation'));
            });
          };
        }

        return loadExif(function (orientation) {
          file.width = img.width;
          file.height = img.height;

          var resizeInfo = _this13.options.resize.call(_this13, file, width, height, resizeMethod);

          var canvas = document.createElement("canvas");
          var ctx = canvas.getContext("2d");

          canvas.width = resizeInfo.trgWidth;
          canvas.height = resizeInfo.trgHeight;

          if (orientation > 4) {
            canvas.width = resizeInfo.trgHeight;
            canvas.height = resizeInfo.trgWidth;
          }

          switch (orientation) {
            case 2:
              // horizontal flip
              ctx.translate(canvas.width, 0);
              ctx.scale(-1, 1);
              break;
            case 3:
              // 180° rotate left
              ctx.translate(canvas.width, canvas.height);
              ctx.rotate(Math.PI);
              break;
            case 4:
              // vertical flip
              ctx.translate(0, canvas.height);
              ctx.scale(1, -1);
              break;
            case 5:
              // vertical flip + 90 rotate right
              ctx.rotate(0.5 * Math.PI);
              ctx.scale(1, -1);
              break;
            case 6:
              // 90° rotate right
              ctx.rotate(0.5 * Math.PI);
              ctx.translate(0, -canvas.height);
              break;
            case 7:
              // horizontal flip + 90 rotate right
              ctx.rotate(0.5 * Math.PI);
              ctx.translate(canvas.width, -canvas.height);
              ctx.scale(-1, 1);
              break;
            case 8:
              // 90° rotate left
              ctx.rotate(-0.5 * Math.PI);
              ctx.translate(-canvas.width, 0);
              break;
          }

          // This is a bugfix for iOS' scaling bug.
          drawImageIOSFix(ctx, img, resizeInfo.srcX != null ? resizeInfo.srcX : 0, resizeInfo.srcY != null ? resizeInfo.srcY : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, resizeInfo.trgX != null ? resizeInfo.trgX : 0, resizeInfo.trgY != null ? resizeInfo.trgY : 0, resizeInfo.trgWidth, resizeInfo.trgHeight);

          var thumbnail = canvas.toDataURL("image/png");

          if (callback != null) {
            return callback(thumbnail, canvas);
          }
        });
      };

      if (callback != null) {
        img.onerror = callback;
      }

      return img.src = file.dataURL;
    }

    // Goes through the queue and processes files if there aren't too many already.

  }, {
    key: "processQueue",
    value: function processQueue() {
      var parallelUploads = this.options.parallelUploads;

      var processingLength = this.getUploadingFiles().length;
      var i = processingLength;

      // There are already at least as many files uploading than should be
      if (processingLength >= parallelUploads) {
        return;
      }

      var queuedFiles = this.getQueuedFiles();

      if (!(queuedFiles.length > 0)) {
        return;
      }

      if (this.options.uploadMultiple) {
        // The files should be uploaded in one request
        return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength));
      } else {
        while (i < parallelUploads) {
          if (!queuedFiles.length) {
            return;
          } // Nothing left to process
          this.processFile(queuedFiles.shift());
          i++;
        }
      }
    }

    // Wrapper for `processFiles`

  }, {
    key: "processFile",
    value: function processFile(file) {
      return this.processFiles([file]);
    }

    // Loads the file, then calls finishedLoading()

  }, {
    key: "processFiles",
    value: function processFiles(files) {
      for (var _iterator19 = files, _isArray19 = true, _i20 = 0, _iterator19 = _isArray19 ? _iterator19 : _iterator19[Symbol.iterator]();;) {
        var _ref18;

        if (_isArray19) {
          if (_i20 >= _iterator19.length) break;
          _ref18 = _iterator19[_i20++];
        } else {
          _i20 = _iterator19.next();
          if (_i20.done) break;
          _ref18 = _i20.value;
        }

        var file = _ref18;

        file.processing = true; // Backwards compatibility
        file.status = Dropzone.UPLOADING;

        this.emit("processing", file);
      }

      if (this.options.uploadMultiple) {
        this.emit("processingmultiple", files);
      }

      return this.uploadFiles(files);
    }
  }, {
    key: "_getFilesWithXhr",
    value: function _getFilesWithXhr(xhr) {
      var files = void 0;
      return files = this.files.filter(function (file) {
        return file.xhr === xhr;
      }).map(function (file) {
        return file;
      });
    }

    // Cancels the file upload and sets the status to CANCELED
    // **if** the file is actually being uploaded.
    // If it's still in the queue, the file is being removed from it and the status
    // set to CANCELED.

  }, {
    key: "cancelUpload",
    value: function cancelUpload(file) {
      if (file.status === Dropzone.UPLOADING) {
        var groupedFiles = this._getFilesWithXhr(file.xhr);
        for (var _iterator20 = groupedFiles, _isArray20 = true, _i21 = 0, _iterator20 = _isArray20 ? _iterator20 : _iterator20[Symbol.iterator]();;) {
          var _ref19;

          if (_isArray20) {
            if (_i21 >= _iterator20.length) break;
            _ref19 = _iterator20[_i21++];
          } else {
            _i21 = _iterator20.next();
            if (_i21.done) break;
            _ref19 = _i21.value;
          }

          var groupedFile = _ref19;

          groupedFile.status = Dropzone.CANCELED;
        }
        if (typeof file.xhr !== 'undefined') {
          file.xhr.abort();
        }
        for (var _iterator21 = groupedFiles, _isArray21 = true, _i22 = 0, _iterator21 = _isArray21 ? _iterator21 : _iterator21[Symbol.iterator]();;) {
          var _ref20;

          if (_isArray21) {
            if (_i22 >= _iterator21.length) break;
            _ref20 = _iterator21[_i22++];
          } else {
            _i22 = _iterator21.next();
            if (_i22.done) break;
            _ref20 = _i22.value;
          }

          var _groupedFile = _ref20;

          this.emit("canceled", _groupedFile);
        }
        if (this.options.uploadMultiple) {
          this.emit("canceledmultiple", groupedFiles);
        }
      } else if (file.status === Dropzone.ADDED || file.status === Dropzone.QUEUED) {
        file.status = Dropzone.CANCELED;
        this.emit("canceled", file);
        if (this.options.uploadMultiple) {
          this.emit("canceledmultiple", [file]);
        }
      }

      if (this.options.autoProcessQueue) {
        return this.processQueue();
      }
    }
  }, {
    key: "resolveOption",
    value: function resolveOption(option) {
      if (typeof option === 'function') {
        for (var _len3 = arguments.length, args = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
          args[_key3 - 1] = arguments[_key3];
        }

        return option.apply(this, args);
      }
      return option;
    }
  }, {
    key: "uploadFile",
    value: function uploadFile(file) {
      return this.uploadFiles([file]);
    }
  }, {
    key: "uploadFiles",
    value: function uploadFiles(files) {
      var _this14 = this;

      this._transformFiles(files, function (transformedFiles) {
        if (files[0].upload.chunked) {
          // This file should be sent in chunks!

          // If the chunking option is set, we **know** that there can only be **one** file, since
          // uploadMultiple is not allowed with this option.
          var file = files[0];
          var transformedFile = transformedFiles[0];
          var startedChunkCount = 0;

          file.upload.chunks = [];

          var handleNextChunk = function handleNextChunk() {
            var chunkIndex = 0;

            // Find the next item in file.upload.chunks that is not defined yet.
            while (file.upload.chunks[chunkIndex] !== undefined) {
              chunkIndex++;
            }

            // This means, that all chunks have already been started.
            if (chunkIndex >= file.upload.totalChunkCount) return;

            startedChunkCount++;

            var start = chunkIndex * _this14.options.chunkSize;
            var end = Math.min(start + _this14.options.chunkSize, file.size);

            var dataBlock = {
              name: _this14._getParamName(0),
              data: transformedFile.webkitSlice ? transformedFile.webkitSlice(start, end) : transformedFile.slice(start, end),
              filename: file.upload.filename,
              chunkIndex: chunkIndex
            };

            file.upload.chunks[chunkIndex] = {
              file: file,
              index: chunkIndex,
              dataBlock: dataBlock, // In case we want to retry.
              status: Dropzone.UPLOADING,
              progress: 0,
              retries: 0 // The number of times this block has been retried.
            };

            _this14._uploadData(files, [dataBlock]);
          };

          file.upload.finishedChunkUpload = function (chunk) {
            var allFinished = true;
            chunk.status = Dropzone.SUCCESS;

            // Clear the data from the chunk
            chunk.dataBlock = null;

            for (var i = 0; i < file.upload.totalChunkCount; i++) {
              if (file.upload.chunks[i] === undefined) {
                return handleNextChunk();
              }
              if (file.upload.chunks[i].status !== Dropzone.SUCCESS) {
                allFinished = false;
              }
            }

            if (allFinished) {
              _this14.options.chunksUploaded(file, function () {
                _this14._finished(files, '', null);
              });
            }
          };

          if (_this14.options.parallelChunkUploads) {
            for (var i = 0; i < file.upload.totalChunkCount; i++) {
              handleNextChunk();
            }
          } else {
            handleNextChunk();
          }
        } else {
          var dataBlocks = [];
          for (var _i23 = 0; _i23 < files.length; _i23++) {
            dataBlocks[_i23] = {
              name: _this14._getParamName(_i23),
              data: transformedFiles[_i23],
              filename: files[_i23].upload.filename
            };
          }
          _this14._uploadData(files, dataBlocks);
        }
      });
    }

    /// Returns the right chunk for given file and xhr

  }, {
    key: "_getChunk",
    value: function _getChunk(file, xhr) {
      for (var i = 0; i < file.upload.totalChunkCount; i++) {
        if (file.upload.chunks[i] !== undefined && file.upload.chunks[i].xhr === xhr) {
          return file.upload.chunks[i];
        }
      }
    }

    // This function actually uploads the file(s) to the server.
    // If dataBlocks contains the actual data to upload (meaning, that this could either be transformed
    // files, or individual chunks for chunked upload).

  }, {
    key: "_uploadData",
    value: function _uploadData(files, dataBlocks) {
      var _this15 = this;

      var xhr = new XMLHttpRequest();

      // Put the xhr object in the file objects to be able to reference it later.
      for (var _iterator22 = files, _isArray22 = true, _i24 = 0, _iterator22 = _isArray22 ? _iterator22 : _iterator22[Symbol.iterator]();;) {
        var _ref21;

        if (_isArray22) {
          if (_i24 >= _iterator22.length) break;
          _ref21 = _iterator22[_i24++];
        } else {
          _i24 = _iterator22.next();
          if (_i24.done) break;
          _ref21 = _i24.value;
        }

        var file = _ref21;

        file.xhr = xhr;
      }
      if (files[0].upload.chunked) {
        // Put the xhr object in the right chunk object, so it can be associated later, and found with _getChunk
        files[0].upload.chunks[dataBlocks[0].chunkIndex].xhr = xhr;
      }

      var method = this.resolveOption(this.options.method, files);
      var url = this.resolveOption(this.options.url, files);
      xhr.open(method, url, true);

      // Setting the timeout after open because of IE11 issue: https://gitlab.com/meno/dropzone/issues/8
      xhr.timeout = this.resolveOption(this.options.timeout, files);

      // Has to be after `.open()`. See https://github.com/enyo/dropzone/issues/179
      xhr.withCredentials = !!this.options.withCredentials;

      xhr.onload = function (e) {
        _this15._finishedUploading(files, xhr, e);
      };

      xhr.onerror = function () {
        _this15._handleUploadError(files, xhr);
      };

      // Some browsers do not have the .upload property
      var progressObj = xhr.upload != null ? xhr.upload : xhr;
      progressObj.onprogress = function (e) {
        return _this15._updateFilesUploadProgress(files, xhr, e);
      };

      var headers = {
        "Accept": "application/json",
        "Cache-Control": "no-cache",
        "X-Requested-With": "XMLHttpRequest"
      };

      if (this.options.headers) {
        Dropzone.extend(headers, this.options.headers);
      }

      for (var headerName in headers) {
        var headerValue = headers[headerName];
        if (headerValue) {
          xhr.setRequestHeader(headerName, headerValue);
        }
      }

      var formData = new FormData();

      // Adding all @options parameters
      if (this.options.params) {
        var additionalParams = this.options.params;
        if (typeof additionalParams === 'function') {
          additionalParams = additionalParams.call(this, files, xhr, files[0].upload.chunked ? this._getChunk(files[0], xhr) : null);
        }

        for (var key in additionalParams) {
          var value = additionalParams[key];
          formData.append(key, value);
        }
      }

      // Let the user add additional data if necessary
      for (var _iterator23 = files, _isArray23 = true, _i25 = 0, _iterator23 = _isArray23 ? _iterator23 : _iterator23[Symbol.iterator]();;) {
        var _ref22;

        if (_isArray23) {
          if (_i25 >= _iterator23.length) break;
          _ref22 = _iterator23[_i25++];
        } else {
          _i25 = _iterator23.next();
          if (_i25.done) break;
          _ref22 = _i25.value;
        }

        var _file = _ref22;

        this.emit("sending", _file, xhr, formData);
      }
      if (this.options.uploadMultiple) {
        this.emit("sendingmultiple", files, xhr, formData);
      }

      this._addFormElementData(formData);

      // Finally add the files
      // Has to be last because some servers (eg: S3) expect the file to be the last parameter
      for (var i = 0; i < dataBlocks.length; i++) {
        var dataBlock = dataBlocks[i];
        formData.append(dataBlock.name, dataBlock.data, dataBlock.filename);
      }

      this.submitRequest(xhr, formData, files);
    }

    // Transforms all files with this.options.transformFile and invokes done with the transformed files when done.

  }, {
    key: "_transformFiles",
    value: function _transformFiles(files, done) {
      var _this16 = this;

      var transformedFiles = [];
      // Clumsy way of handling asynchronous calls, until I get to add a proper Future library.
      var doneCounter = 0;

      var _loop = function _loop(i) {
        _this16.options.transformFile.call(_this16, files[i], function (transformedFile) {
          transformedFiles[i] = transformedFile;
          if (++doneCounter === files.length) {
            done(transformedFiles);
          }
        });
      };

      for (var i = 0; i < files.length; i++) {
        _loop(i);
      }
    }

    // Takes care of adding other input elements of the form to the AJAX request

  }, {
    key: "_addFormElementData",
    value: function _addFormElementData(formData) {
      // Take care of other input elements
      if (this.element.tagName === "FORM") {
        for (var _iterator24 = this.element.querySelectorAll("input, textarea, select, button"), _isArray24 = true, _i26 = 0, _iterator24 = _isArray24 ? _iterator24 : _iterator24[Symbol.iterator]();;) {
          var _ref23;

          if (_isArray24) {
            if (_i26 >= _iterator24.length) break;
            _ref23 = _iterator24[_i26++];
          } else {
            _i26 = _iterator24.next();
            if (_i26.done) break;
            _ref23 = _i26.value;
          }

          var input = _ref23;

          var inputName = input.getAttribute("name");
          var inputType = input.getAttribute("type");
          if (inputType) inputType = inputType.toLowerCase();

          // If the input doesn't have a name, we can't use it.
          if (typeof inputName === 'undefined' || inputName === null) continue;

          if (input.tagName === "SELECT" && input.hasAttribute("multiple")) {
            // Possibly multiple values
            for (var _iterator25 = input.options, _isArray25 = true, _i27 = 0, _iterator25 = _isArray25 ? _iterator25 : _iterator25[Symbol.iterator]();;) {
              var _ref24;

              if (_isArray25) {
                if (_i27 >= _iterator25.length) break;
                _ref24 = _iterator25[_i27++];
              } else {
                _i27 = _iterator25.next();
                if (_i27.done) break;
                _ref24 = _i27.value;
              }

              var option = _ref24;

              if (option.selected) {
                formData.append(inputName, option.value);
              }
            }
          } else if (!inputType || inputType !== "checkbox" && inputType !== "radio" || input.checked) {
            formData.append(inputName, input.value);
          }
        }
      }
    }

    // Invoked when there is new progress information about given files.
    // If e is not provided, it is assumed that the upload is finished.

  }, {
    key: "_updateFilesUploadProgress",
    value: function _updateFilesUploadProgress(files, xhr, e) {
      var progress = void 0;
      if (typeof e !== 'undefined') {
        progress = 100 * e.loaded / e.total;

        if (files[0].upload.chunked) {
          var file = files[0];
          // Since this is a chunked upload, we need to update the appropriate chunk progress.
          var chunk = this._getChunk(file, xhr);
          chunk.progress = progress;
          chunk.total = e.total;
          chunk.bytesSent = e.loaded;
          var fileProgress = 0,
              fileTotal = void 0,
              fileBytesSent = void 0;
          file.upload.progress = 0;
          file.upload.total = 0;
          file.upload.bytesSent = 0;
          for (var i = 0; i < file.upload.totalChunkCount; i++) {
            if (file.upload.chunks[i] !== undefined && file.upload.chunks[i].progress !== undefined) {
              file.upload.progress += file.upload.chunks[i].progress;
              file.upload.total += file.upload.chunks[i].total;
              file.upload.bytesSent += file.upload.chunks[i].bytesSent;
            }
          }
          file.upload.progress = file.upload.progress / file.upload.totalChunkCount;
        } else {
          for (var _iterator26 = files, _isArray26 = true, _i28 = 0, _iterator26 = _isArray26 ? _iterator26 : _iterator26[Symbol.iterator]();;) {
            var _ref25;

            if (_isArray26) {
              if (_i28 >= _iterator26.length) break;
              _ref25 = _iterator26[_i28++];
            } else {
              _i28 = _iterator26.next();
              if (_i28.done) break;
              _ref25 = _i28.value;
            }

            var _file2 = _ref25;

            _file2.upload.progress = progress;
            _file2.upload.total = e.total;
            _file2.upload.bytesSent = e.loaded;
          }
        }
        for (var _iterator27 = files, _isArray27 = true, _i29 = 0, _iterator27 = _isArray27 ? _iterator27 : _iterator27[Symbol.iterator]();;) {
          var _ref26;

          if (_isArray27) {
            if (_i29 >= _iterator27.length) break;
            _ref26 = _iterator27[_i29++];
          } else {
            _i29 = _iterator27.next();
            if (_i29.done) break;
            _ref26 = _i29.value;
          }

          var _file3 = _ref26;

          this.emit("uploadprogress", _file3, _file3.upload.progress, _file3.upload.bytesSent);
        }
      } else {
        // Called when the file finished uploading

        var allFilesFinished = true;

        progress = 100;

        for (var _iterator28 = files, _isArray28 = true, _i30 = 0, _iterator28 = _isArray28 ? _iterator28 : _iterator28[Symbol.iterator]();;) {
          var _ref27;

          if (_isArray28) {
            if (_i30 >= _iterator28.length) break;
            _ref27 = _iterator28[_i30++];
          } else {
            _i30 = _iterator28.next();
            if (_i30.done) break;
            _ref27 = _i30.value;
          }

          var _file4 = _ref27;

          if (_file4.upload.progress !== 100 || _file4.upload.bytesSent !== _file4.upload.total) {
            allFilesFinished = false;
          }
          _file4.upload.progress = progress;
          _file4.upload.bytesSent = _file4.upload.total;
        }

        // Nothing to do, all files already at 100%
        if (allFilesFinished) {
          return;
        }

        for (var _iterator29 = files, _isArray29 = true, _i31 = 0, _iterator29 = _isArray29 ? _iterator29 : _iterator29[Symbol.iterator]();;) {
          var _ref28;

          if (_isArray29) {
            if (_i31 >= _iterator29.length) break;
            _ref28 = _iterator29[_i31++];
          } else {
            _i31 = _iterator29.next();
            if (_i31.done) break;
            _ref28 = _i31.value;
          }

          var _file5 = _ref28;

          this.emit("uploadprogress", _file5, progress, _file5.upload.bytesSent);
        }
      }
    }
  }, {
    key: "_finishedUploading",
    value: function _finishedUploading(files, xhr, e) {
      var response = void 0;

      if (files[0].status === Dropzone.CANCELED) {
        return;
      }

      if (xhr.readyState !== 4) {
        return;
      }

      if (xhr.responseType !== 'arraybuffer' && xhr.responseType !== 'blob') {
        response = xhr.responseText;

        if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) {
          try {
            response = JSON.parse(response);
          } catch (error) {
            e = error;
            response = "Invalid JSON response from server.";
          }
        }
      }

      this._updateFilesUploadProgress(files);

      if (!(200 <= xhr.status && xhr.status < 300)) {
        this._handleUploadError(files, xhr, response);
      } else {
        if (files[0].upload.chunked) {
          files[0].upload.finishedChunkUpload(this._getChunk(files[0], xhr));
        } else {
          this._finished(files, response, e);
        }
      }
    }
  }, {
    key: "_handleUploadError",
    value: function _handleUploadError(files, xhr, response) {
      if (files[0].status === Dropzone.CANCELED) {
        return;
      }

      if (files[0].upload.chunked && this.options.retryChunks) {
        var chunk = this._getChunk(files[0], xhr);
        if (chunk.retries++ < this.options.retryChunksLimit) {
          this._uploadData(files, [chunk.dataBlock]);
          return;
        } else {
          console.warn('Retried this chunk too often. Giving up.');
        }
      }

      for (var _iterator30 = files, _isArray30 = true, _i32 = 0, _iterator30 = _isArray30 ? _iterator30 : _iterator30[Symbol.iterator]();;) {
        var _ref29;

        if (_isArray30) {
          if (_i32 >= _iterator30.length) break;
          _ref29 = _iterator30[_i32++];
        } else {
          _i32 = _iterator30.next();
          if (_i32.done) break;
          _ref29 = _i32.value;
        }

        var file = _ref29;

        this._errorProcessing(files, response || this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr);
      }
    }
  }, {
    key: "submitRequest",
    value: function submitRequest(xhr, formData, files) {
      xhr.send(formData);
    }

    // Called internally when processing is finished.
    // Individual callbacks have to be called in the appropriate sections.

  }, {
    key: "_finished",
    value: function _finished(files, responseText, e) {
      for (var _iterator31 = files, _isArray31 = true, _i33 = 0, _iterator31 = _isArray31 ? _iterator31 : _iterator31[Symbol.iterator]();;) {
        var _ref30;

        if (_isArray31) {
          if (_i33 >= _iterator31.length) break;
          _ref30 = _iterator31[_i33++];
        } else {
          _i33 = _iterator31.next();
          if (_i33.done) break;
          _ref30 = _i33.value;
        }

        var file = _ref30;

        file.status = Dropzone.SUCCESS;
        this.emit("success", file, responseText, e);
        this.emit("complete", file);
      }
      if (this.options.uploadMultiple) {
        this.emit("successmultiple", files, responseText, e);
        this.emit("completemultiple", files);
      }

      if (this.options.autoProcessQueue) {
        return this.processQueue();
      }
    }

    // Called internally when processing is finished.
    // Individual callbacks have to be called in the appropriate sections.

  }, {
    key: "_errorProcessing",
    value: function _errorProcessing(files, message, xhr) {
      for (var _iterator32 = files, _isArray32 = true, _i34 = 0, _iterator32 = _isArray32 ? _iterator32 : _iterator32[Symbol.iterator]();;) {
        var _ref31;

        if (_isArray32) {
          if (_i34 >= _iterator32.length) break;
          _ref31 = _iterator32[_i34++];
        } else {
          _i34 = _iterator32.next();
          if (_i34.done) break;
          _ref31 = _i34.value;
        }

        var file = _ref31;

        file.status = Dropzone.ERROR;
        this.emit("error", file, message, xhr);
        this.emit("complete", file);
      }
      if (this.options.uploadMultiple) {
        this.emit("errormultiple", files, message, xhr);
        this.emit("completemultiple", files);
      }

      if (this.options.autoProcessQueue) {
        return this.processQueue();
      }
    }
  }], [{
    key: "uuidv4",
    value: function uuidv4() {
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0,
            v = c === 'x' ? r : r & 0x3 | 0x8;
        return v.toString(16);
      });
    }
  }]);

  return Dropzone;
}(Emitter);

Dropzone.initClass();

Dropzone.version = "5.3.1";

// This is a map of options for your different dropzones. Add configurations
// to this object for your different dropzone elemens.
//
// Example:
//
//     Dropzone.options.myDropzoneElementId = { maxFilesize: 1 };
//
// To disable autoDiscover for a specific element, you can set `false` as an option:
//
//     Dropzone.options.myDisabledElementId = false;
//
// And in html:
//
//     <form action="/upload" id="my-dropzone-element-id" class="dropzone"></form>
Dropzone.options = {};

// Returns the options for an element or undefined if none available.
Dropzone.optionsForElement = function (element) {
  // Get the `Dropzone.options.elementId` for this element if it exists
  if (element.getAttribute("id")) {
    return Dropzone.options[camelize(element.getAttribute("id"))];
  } else {
    return undefined;
  }
};

// Holds a list of all dropzone instances
Dropzone.instances = [];

// Returns the dropzone for given element if any
Dropzone.forElement = function (element) {
  if (typeof element === "string") {
    element = document.querySelector(element);
  }
  if ((element != null ? element.dropzone : undefined) == null) {
    throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone.");
  }
  return element.dropzone;
};

// Set to false if you don't want Dropzone to automatically find and attach to .dropzone elements.
Dropzone.autoDiscover = true;

// Looks for all .dropzone elements and creates a dropzone for them
Dropzone.discover = function () {
  var dropzones = void 0;
  if (document.querySelectorAll) {
    dropzones = document.querySelectorAll(".dropzone");
  } else {
    dropzones = [];
    // IE :(
    var checkElements = function checkElements(elements) {
      return function () {
        var result = [];
        for (var _iterator33 = elements, _isArray33 = true, _i35 = 0, _iterator33 = _isArray33 ? _iterator33 : _iterator33[Symbol.iterator]();;) {
          var _ref32;

          if (_isArray33) {
            if (_i35 >= _iterator33.length) break;
            _ref32 = _iterator33[_i35++];
          } else {
            _i35 = _iterator33.next();
            if (_i35.done) break;
            _ref32 = _i35.value;
          }

          var el = _ref32;

          if (/(^| )dropzone($| )/.test(el.className)) {
            result.push(dropzones.push(el));
          } else {
            result.push(undefined);
          }
        }
        return result;
      }();
    };
    checkElements(document.getElementsByTagName("div"));
    checkElements(document.getElementsByTagName("form"));
  }

  return function () {
    var result = [];
    for (var _iterator34 = dropzones, _isArray34 = true, _i36 = 0, _iterator34 = _isArray34 ? _iterator34 : _iterator34[Symbol.iterator]();;) {
      var _ref33;

      if (_isArray34) {
        if (_i36 >= _iterator34.length) break;
        _ref33 = _iterator34[_i36++];
      } else {
        _i36 = _iterator34.next();
        if (_i36.done) break;
        _ref33 = _i36.value;
      }

      var dropzone = _ref33;

      // Create a dropzone unless auto discover has been disabled for specific element
      if (Dropzone.optionsForElement(dropzone) !== false) {
        result.push(new Dropzone(dropzone));
      } else {
        result.push(undefined);
      }
    }
    return result;
  }();
};

// Since the whole Drag'n'Drop API is pretty new, some browsers implement it,
// but not correctly.
// So I created a blacklist of userAgents. Yes, yes. Browser sniffing, I know.
// But what to do when browsers *theoretically* support an API, but crash
// when using it.
//
// This is a list of regular expressions tested against navigator.userAgent
//
// ** It should only be used on browser that *do* support the API, but
// incorrectly **
//
Dropzone.blacklistedBrowsers = [
// The mac os and windows phone version of opera 12 seems to have a problem with the File drag'n'drop API.
/opera.*(Macintosh|Windows Phone).*version\/12/i];

// Checks if the browser is supported
Dropzone.isBrowserSupported = function () {
  var capableBrowser = true;

  if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) {
    if (!("classList" in document.createElement("a"))) {
      capableBrowser = false;
    } else {
      // The browser supports the API, but may be blacklisted.
      for (var _iterator35 = Dropzone.blacklistedBrowsers, _isArray35 = true, _i37 = 0, _iterator35 = _isArray35 ? _iterator35 : _iterator35[Symbol.iterator]();;) {
        var _ref34;

        if (_isArray35) {
          if (_i37 >= _iterator35.length) break;
          _ref34 = _iterator35[_i37++];
        } else {
          _i37 = _iterator35.next();
          if (_i37.done) break;
          _ref34 = _i37.value;
        }

        var regex = _ref34;

        if (regex.test(navigator.userAgent)) {
          capableBrowser = false;
          continue;
        }
      }
    }
  } else {
    capableBrowser = false;
  }

  return capableBrowser;
};

Dropzone.dataURItoBlob = function (dataURI) {
  // convert base64 to raw binary data held in a string
  // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
  var byteString = atob(dataURI.split(',')[1]);

  // separate out the mime component
  var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

  // write the bytes of the string to an ArrayBuffer
  var ab = new ArrayBuffer(byteString.length);
  var ia = new Uint8Array(ab);
  for (var i = 0, end = byteString.length, asc = 0 <= end; asc ? i <= end : i >= end; asc ? i++ : i--) {
    ia[i] = byteString.charCodeAt(i);
  }

  // write the ArrayBuffer to a blob
  return new Blob([ab], { type: mimeString });
};

// Returns an array without the rejected item
var without = function without(list, rejectedItem) {
  return list.filter(function (item) {
    return item !== rejectedItem;
  }).map(function (item) {
    return item;
  });
};

// abc-def_ghi -> abcDefGhi
var camelize = function camelize(str) {
  return str.replace(/[\-_](\w)/g, function (match) {
    return match.charAt(1).toUpperCase();
  });
};

// Creates an element from string
Dropzone.createElement = function (string) {
  var div = document.createElement("div");
  div.innerHTML = string;
  return div.childNodes[0];
};

// Tests if given element is inside (or simply is) the container
Dropzone.elementInside = function (element, container) {
  if (element === container) {
    return true;
  } // Coffeescript doesn't support do/while loops
  while (element = element.parentNode) {
    if (element === container) {
      return true;
    }
  }
  return false;
};

Dropzone.getElement = function (el, name) {
  var element = void 0;
  if (typeof el === "string") {
    element = document.querySelector(el);
  } else if (el.nodeType != null) {
    element = el;
  }
  if (element == null) {
    throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element.");
  }
  return element;
};

Dropzone.getElements = function (els, name) {
  var el = void 0,
      elements = void 0;
  if (els instanceof Array) {
    elements = [];
    try {
      for (var _iterator36 = els, _isArray36 = true, _i38 = 0, _iterator36 = _isArray36 ? _iterator36 : _iterator36[Symbol.iterator]();;) {
        if (_isArray36) {
          if (_i38 >= _iterator36.length) break;
          el = _iterator36[_i38++];
        } else {
          _i38 = _iterator36.next();
          if (_i38.done) break;
          el = _i38.value;
        }

        elements.push(this.getElement(el, name));
      }
    } catch (e) {
      elements = null;
    }
  } else if (typeof els === "string") {
    elements = [];
    for (var _iterator37 = document.querySelectorAll(els), _isArray37 = true, _i39 = 0, _iterator37 = _isArray37 ? _iterator37 : _iterator37[Symbol.iterator]();;) {
      if (_isArray37) {
        if (_i39 >= _iterator37.length) break;
        el = _iterator37[_i39++];
      } else {
        _i39 = _iterator37.next();
        if (_i39.done) break;
        el = _i39.value;
      }

      elements.push(el);
    }
  } else if (els.nodeType != null) {
    elements = [els];
  }

  if (elements == null || !elements.length) {
    throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those.");
  }

  return elements;
};

// Asks the user the question and calls accepted or rejected accordingly
//
// The default implementation just uses `window.confirm` and then calls the
// appropriate callback.
Dropzone.confirm = function (question, accepted, rejected) {
  if (window.confirm(question)) {
    return accepted();
  } else if (rejected != null) {
    return rejected();
  }
};

// Validates the mime type like this:
//
// https://developer.mozilla.org/en-US/docs/HTML/Element/input#attr-accept
Dropzone.isValidFile = function (file, acceptedFiles) {
  if (!acceptedFiles) {
    return true;
  } // If there are no accepted mime types, it's OK
  acceptedFiles = acceptedFiles.split(",");

  var mimeType = file.type;
  var baseMimeType = mimeType.replace(/\/.*$/, "");

  for (var _iterator38 = acceptedFiles, _isArray38 = true, _i40 = 0, _iterator38 = _isArray38 ? _iterator38 : _iterator38[Symbol.iterator]();;) {
    var _ref35;

    if (_isArray38) {
      if (_i40 >= _iterator38.length) break;
      _ref35 = _iterator38[_i40++];
    } else {
      _i40 = _iterator38.next();
      if (_i40.done) break;
      _ref35 = _i40.value;
    }

    var validType = _ref35;

    validType = validType.trim();
    if (validType.charAt(0) === ".") {
      if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) {
        return true;
      }
    } else if (/\/\*$/.test(validType)) {
      // This is something like a image/* mime type
      if (baseMimeType === validType.replace(/\/.*$/, "")) {
        return true;
      }
    } else {
      if (mimeType === validType) {
        return true;
      }
    }
  }

  return false;
};

// Augment jQuery
if (typeof jQuery !== 'undefined' && jQuery !== null) {
  jQuery.fn.dropzone = function (options) {
    return this.each(function () {
      return new Dropzone(this, options);
    });
  };
}

if (typeof module !== 'undefined' && module !== null) {
  module.exports = Dropzone;
} else {
  window.Dropzone = Dropzone;
}

// Dropzone file status codes
Dropzone.ADDED = "added";

Dropzone.QUEUED = "queued";
// For backwards compatibility. Now, if a file is accepted, it's either queued
// or uploading.
Dropzone.ACCEPTED = Dropzone.QUEUED;

Dropzone.UPLOADING = "uploading";
Dropzone.PROCESSING = Dropzone.UPLOADING; // alias

Dropzone.CANCELED = "canceled";
Dropzone.ERROR = "error";
Dropzone.SUCCESS = "success";

/*

 Bugfix for iOS 6 and 7
 Source: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios
 based on the work of https://github.com/stomita/ios-imagefile-megapixel

 */

// Detecting vertical squash in loaded image.
// Fixes a bug which squash image vertically while drawing into canvas for some images.
// This is a bug in iOS6 devices. This function from https://github.com/stomita/ios-imagefile-megapixel
var detectVerticalSquash = function detectVerticalSquash(img) {
  var iw = img.naturalWidth;
  var ih = img.naturalHeight;
  var canvas = document.createElement("canvas");
  canvas.width = 1;
  canvas.height = ih;
  var ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0);

  var _ctx$getImageData = ctx.getImageData(1, 0, 1, ih),
      data = _ctx$getImageData.data;

  // search image edge pixel position in case it is squashed vertically.


  var sy = 0;
  var ey = ih;
  var py = ih;
  while (py > sy) {
    var alpha = data[(py - 1) * 4 + 3];

    if (alpha === 0) {
      ey = py;
    } else {
      sy = py;
    }

    py = ey + sy >> 1;
  }
  var ratio = py / ih;

  if (ratio === 0) {
    return 1;
  } else {
    return ratio;
  }
};

// A replacement for context.drawImage
// (args are for source and destination).
var drawImageIOSFix = function drawImageIOSFix(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {
  var vertSquashRatio = detectVerticalSquash(img);
  return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);
};

// Based on MinifyJpeg
// Source: http://www.perry.cz/files/ExifRestorer.js
// http://elicon.blog57.fc2.com/blog-entry-206.html

var ExifRestore = function () {
  function ExifRestore() {
    _classCallCheck(this, ExifRestore);
  }

  _createClass(ExifRestore, null, [{
    key: "initClass",
    value: function initClass() {
      this.KEY_STR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
    }
  }, {
    key: "encode64",
    value: function encode64(input) {
      var output = '';
      var chr1 = undefined;
      var chr2 = undefined;
      var chr3 = '';
      var enc1 = undefined;
      var enc2 = undefined;
      var enc3 = undefined;
      var enc4 = '';
      var i = 0;
      while (true) {
        chr1 = input[i++];
        chr2 = input[i++];
        chr3 = input[i++];
        enc1 = chr1 >> 2;
        enc2 = (chr1 & 3) << 4 | chr2 >> 4;
        enc3 = (chr2 & 15) << 2 | chr3 >> 6;
        enc4 = chr3 & 63;
        if (isNaN(chr2)) {
          enc3 = enc4 = 64;
        } else if (isNaN(chr3)) {
          enc4 = 64;
        }
        output = output + this.KEY_STR.charAt(enc1) + this.KEY_STR.charAt(enc2) + this.KEY_STR.charAt(enc3) + this.KEY_STR.charAt(enc4);
        chr1 = chr2 = chr3 = '';
        enc1 = enc2 = enc3 = enc4 = '';
        if (!(i < input.length)) {
          break;
        }
      }
      return output;
    }
  }, {
    key: "restore",
    value: function restore(origFileBase64, resizedFileBase64) {
      if (!origFileBase64.match('data:image/jpeg;base64,')) {
        return resizedFileBase64;
      }
      var rawImage = this.decode64(origFileBase64.replace('data:image/jpeg;base64,', ''));
      var segments = this.slice2Segments(rawImage);
      var image = this.exifManipulation(resizedFileBase64, segments);
      return "data:image/jpeg;base64," + this.encode64(image);
    }
  }, {
    key: "exifManipulation",
    value: function exifManipulation(resizedFileBase64, segments) {
      var exifArray = this.getExifArray(segments);
      var newImageArray = this.insertExif(resizedFileBase64, exifArray);
      var aBuffer = new Uint8Array(newImageArray);
      return aBuffer;
    }
  }, {
    key: "getExifArray",
    value: function getExifArray(segments) {
      var seg = undefined;
      var x = 0;
      while (x < segments.length) {
        seg = segments[x];
        if (seg[0] === 255 & seg[1] === 225) {
          return seg;
        }
        x++;
      }
      return [];
    }
  }, {
    key: "insertExif",
    value: function insertExif(resizedFileBase64, exifArray) {
      var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', '');
      var buf = this.decode64(imageData);
      var separatePoint = buf.indexOf(255, 3);
      var mae = buf.slice(0, separatePoint);
      var ato = buf.slice(separatePoint);
      var array = mae;
      array = array.concat(exifArray);
      array = array.concat(ato);
      return array;
    }
  }, {
    key: "slice2Segments",
    value: function slice2Segments(rawImageArray) {
      var head = 0;
      var segments = [];
      while (true) {
        var length;
        if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 218) {
          break;
        }
        if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 216) {
          head += 2;
        } else {
          length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3];
          var endPoint = head + length + 2;
          var seg = rawImageArray.slice(head, endPoint);
          segments.push(seg);
          head = endPoint;
        }
        if (head > rawImageArray.length) {
          break;
        }
      }
      return segments;
    }
  }, {
    key: "decode64",
    value: function decode64(input) {
      var output = '';
      var chr1 = undefined;
      var chr2 = undefined;
      var chr3 = '';
      var enc1 = undefined;
      var enc2 = undefined;
      var enc3 = undefined;
      var enc4 = '';
      var i = 0;
      var buf = [];
      // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
      var base64test = /[^A-Za-z0-9\+\/\=]/g;
      if (base64test.exec(input)) {
        console.warn('There were invalid base64 characters in the input text.\nValid base64 characters are A-Z, a-z, 0-9, \'+\', \'/\',and \'=\'\nExpect errors in decoding.');
      }
      input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
      while (true) {
        enc1 = this.KEY_STR.indexOf(input.charAt(i++));
        enc2 = this.KEY_STR.indexOf(input.charAt(i++));
        enc3 = this.KEY_STR.indexOf(input.charAt(i++));
        enc4 = this.KEY_STR.indexOf(input.charAt(i++));
        chr1 = enc1 << 2 | enc2 >> 4;
        chr2 = (enc2 & 15) << 4 | enc3 >> 2;
        chr3 = (enc3 & 3) << 6 | enc4;
        buf.push(chr1);
        if (enc3 !== 64) {
          buf.push(chr2);
        }
        if (enc4 !== 64) {
          buf.push(chr3);
        }
        chr1 = chr2 = chr3 = '';
        enc1 = enc2 = enc3 = enc4 = '';
        if (!(i < input.length)) {
          break;
        }
      }
      return buf;
    }
  }]);

  return ExifRestore;
}();

ExifRestore.initClass();

/*
 * contentloaded.js
 *
 * Author: Diego Perini (diego.perini at gmail.com)
 * Summary: cross-browser wrapper for DOMContentLoaded
 * Updated: 20101020
 * License: MIT
 * Version: 1.2
 *
 * URL:
 * http://javascript.nwbox.com/ContentLoaded/
 * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
 */

// @win window reference
// @fn function reference
var contentLoaded = function contentLoaded(win, fn) {
  var done = false;
  var top = true;
  var doc = win.document;
  var root = doc.documentElement;
  var add = doc.addEventListener ? "addEventListener" : "attachEvent";
  var rem = doc.addEventListener ? "removeEventListener" : "detachEvent";
  var pre = doc.addEventListener ? "" : "on";
  var init = function init(e) {
    if (e.type === "readystatechange" && doc.readyState !== "complete") {
      return;
    }
    (e.type === "load" ? win : doc)[rem](pre + e.type, init, false);
    if (!done && (done = true)) {
      return fn.call(win, e.type || e);
    }
  };

  var poll = function poll() {
    try {
      root.doScroll("left");
    } catch (e) {
      setTimeout(poll, 50);
      return;
    }
    return init("poll");
  };

  if (doc.readyState !== "complete") {
    if (doc.createEventObject && root.doScroll) {
      try {
        top = !win.frameElement;
      } catch (error) {}
      if (top) {
        poll();
      }
    }
    doc[add](pre + "DOMContentLoaded", init, false);
    doc[add](pre + "readystatechange", init, false);
    return win[add](pre + "load", init, false);
  }
};

// As a single function to be able to write tests.
Dropzone._autoDiscoverFunction = function () {
  if (Dropzone.autoDiscover) {
    return Dropzone.discover();
  }
};
contentLoaded(window, Dropzone._autoDiscoverFunction);

function __guard__(value, transform) {
  return typeof value !== 'undefined' && value !== null ? transform(value) : undefined;
}
function __guardMethod__(obj, methodName, transform) {
  if (typeof obj !== 'undefined' && obj !== null && typeof obj[methodName] === 'function') {
    return transform(obj, methodName);
  } else {
    return undefined;
  }
}
;
