<commit_before>angular.module('feedbackcontrol', [])
.directive('transform', function(FeedbackSignal) {
    return {
        restrict: 'A'
      , link: function($scope, element, attrs) {

            var currentUrl = window.location.pathname;

            $scope.$watch('checkFeedbackStatus', function() {
                $(element).bind('click', function(e) {
                    var me = $(element);
                    $scope.mystatus = FeedbackSignal.get_data();
                    var data = $scope.mystatus;

                    if(data.status == 'flag' || data.status == 'unflag') {
                        var feed = $.parseJSON($(this).attr('data-feed'));
                        var policy = $(this).attr("return-policy");
                        if(feed.status == "unflag") {
                            feed.status = "flag";
                            $(this).removeAttr("style");
                            var repackaged_json = JSON.stringify(feed);
                            $(this).attr('data-feed', repackaged_json);
                        } else {
                            feed.status = "unflag";
                            $(this).attr("style", "background-position: -194px -31px");
                            var repackaged_json = JSON.stringify(feed);
                            $(this).attr('data-feed', repackaged_json);
                        }
                        $(".checky-box-container").show();
                    } else {
                        if(currentUrl.match(/inbox\/all|deleted/g)) {
                            if(data.id.length > 0) {
                                hide_the_children(me);
                                $(".checky-box-container").show();
                            }
                        }

                        if(currentUrl.match(/published/g)) {
                            //returning published feedback to the inbox
                            if(me.attr('return-policy') == 1) {
                                hide_the_children(me);
                                $(".checky-box-container").show();
                            }

                            //unfeaturing feedback and switching UI controls to published state.
                            if(me.attr("return") == "unfeature") {
                                console.log('unfeature and switch UI to published state');
                                var state = {
                                    activate: {'background-position': '-64px -0px'}
                                  , deactivate_sibling: {'background-position': '-32px -31px'}
                                  , activation_color: 'unfeature'
                                  , state_change_inbox: '{"status": "feature", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "feature"}'
                                  , state_change: '{"status": "inbox", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                                  , present_status: "publish"
                                }
                                published_state(me, '.publish', 'Feature Feedback', state);
                            }

                            if(data.status == "feature") {
                                var state = {
                                    activate: {'background-position': '-64px -31px'}
                                  , deactivate_sibling: {'background-position': '-32px 0px'}
                                  , activation_color: 'featured'
                                  , state_change_inbox: '{"status": "unfeature", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "feature"}'
                                  , state_change: '{"status": "publish", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                                  , present_status: "feature"
                                }
                                published_state(me, '.publish', 'Publish Feedback', state);
                            }

                            if(data.status == "publish") {
                                var state = {
                                    activate: {'background-position': '-32px -31px'}
                                  , deactivate_sibling: {'background-position': '-64px 0px'}
                                  , activation_color: 'published'
                                  , state_change_inbox: '{"status": "inbox", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                                  , state_change: '{"status": "feature", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "feature"}'
                                  , present_status: "publish"
                                }
                                published_state(me, '.feature', 'Feature Feedback', state);
                            }

                            if(data.status == "delete" || data.status == "fileas") {
                                hide_the_children(me);
                                $(".checky-box-container").show();
                            }
                        }

                        if(currentUrl.match(/filed/g)) {
                            var data_status = data.status;
                            if(data_status == "publish" || data_status == "feature" || data_status == "delete") {
                                hide_the_children(me);
                                $(".checky-box-container").show();
                            }

                            if(data_status == "fileas") {
                                $(me).parents(".dashboard-feedback")
                                       .children("div.feedback-contents")
                                       .children(".responsive-padding")
                                       .children(".feedback-details")
                                       .children(".filed")
                                       .html($(me).text())
                            }
                        }
                    }

                    e.preventDefault();
                });
            });
        }
    }
})
.directive('undo', function(FeedbackSignal, FeedbackControlService) {
    return {
        restrict: 'A'
      , link: function($scope, element, attrs) {
            var currentUrl = window.location.pathname;
            $scope.$watch('checkFeedbackStatus', function() {
                $(element).bind("click", function(e) {
                    $scope.mystatus = FeedbackSignal.get_data();
                    var data = $scope.mystatus;

                    $(".checky-box-container").hide();
                    if (data.id instanceof Array) {
                        for(var i=0; i < data.id.length ; i++) {
                            var feedback = $(".dashboard-feedback[feedback=" + data.id[i] + "]");

                            feedback.show();
                            $(feedback).parents('.feedback-group').show();

                            if(currentUrl.match(/inbox\/all|deleted|published/g)) {
                                var catpicks = $(".dashboard-feedback[feedback=" + data.id[i] + "] li .cat-picks");
                                catpicks.css({'background': '#598499'});
                            }
                        }
                    } else {
                        var feedback = $(".dashboard-feedback[feedback=" + data.id + "]");

                        feedback.show();
                        $(feedback).parents('.feedback-group').show();

                        if(currentUrl.match(/inbox\/all|deleted|published/g)) {
                            var catpicks = $(".dashboard-feedback[feedback=" + data.id + "] li .cat-picks");
                            catpicks.css({'background': '#598499'});
                        }

                        var checkbox = $(".feed-checkbox[value=" + data.id + "]");

                        if(checkbox.is(":checked")) {
                            checkbox.click();
                        }
                    }

                    if($(".sorter-checkbox").is(":checked")) {
                        $(".sorter-checkbox").click();
                    }

                    if($('.feed-checkbox').is(":checked")) {
                        $('.feed-checkbox').prop("checked", false);
                    }

                    e.preventDefault();
                });
            })
        }
    }
})
.directive('close', function(FeedbackControlService) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind("click", function(e) {
                $(".checky-box-container").hide();
                FeedbackControlService.expunge();
                e.preventDefault();
            });
        }
    }
})
.directive('feedcheckbox', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            var checkbox = $(element);

            checkbox.bind('change', function() {
                if(checkbox.is(":checked")) {
                    checkbox.parents('.dashboard-feedback').css({'background-color': '#F7F7F7'});
                } else {
                    checkbox.parents('.dashboard-feedback').css({'background-color': '#FFF'});
                }
            });

        }
    }
})
.directive('statuschange', function(FeedbackService) {
    return {
        restrict: 'A'
      , scope: {
            feedid: "@feedid"
          , statustype: "@statustype"
        }
      , link: function(scope, element, attrs) {
            $(element).bind('change', function() {
                var status_class, value;
                var myvalue = $(this).val();
                if(scope.statustype == "status") {
                   status_class = ".status-line";
                   console.log(myvalue);
                   if(myvalue == "new") { value = "New"; }
                   if(myvalue == "inprogress") { value = "In Progress"; }
                   if(myvalue == "closed") { value = "Closed"; }
                } else {
                   status_class = ".priority-line";
                   console.log(myvalue);
                   if(myvalue == 0) { value = "Low"; }
                   if(myvalue == 60) { value = "Medium"; }
                   if(myvalue == 100) { value = "High"; }
                }

                $(this).parents(".dashboard-feedback")
                       .children("div.feedback-contents")
                       .children(".responsive-padding")
                       .children(".feedback-details")
                       .children(".feedback-details-status")
                       .children(status_class)
                       .html(value)

                FeedbackService.inline_change($(this).val(), scope.feedid, scope.statustype);
            })
        }
    }
})
.directive('deleteBlock', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                $(this).parents('.custom-att').fadeOut(400, function() {
                     var new_uploaded_images = new Array;
                     var new_attached_link;

                     var div = $(this).parents('.uploaded-images-and-links');
                     var images = div.find('.uploaded_image');
                     var media_attachment = div.find('.attached_link');

                     var remove_image = {
                        'small_url'    :$(this).find('.small-image-url').val(),
                        'medium_url'   :$(this).find('.medium-image-url').val(),
                        'large_url'    :$(this).find('.large-image-url').val()
                     }

                    if(images.length > 0){
                        var us = images.not(":hidden");
                        for(var i=0; i < us.length; i++) {
                            new_uploaded_images.push({
                                'name': $(us[i]).find('.image-name').val()
                            });
                        }
                    }

                    if(!media_attachment.is(":hidden")) {
                        new_attached_link = {
                            title           : media_attachment.find('.link-title').val(),
                            description     : media_attachment.find('.link-description').val(),
                            image           : media_attachment.find('.link-image').val(),
                            url             : media_attachment.find('.link-url').val(),
                            video           : media_attachment.find('.link-video').val(),
                        }
                    }

                    var remaining = {
                        uploaded_images : new_uploaded_images
                      , attached_link   : new_attached_link
                    }

                    var attachment_data = {
                        feedbackId      : div.find('.attachment_feedback_id').val()
                      , attachments     : remaining
                      , remove_image    : remove_image
                    }

                    //place this in service you lazy bastard!
                    $.ajax({
                        type: "POST"
                      , url: "/inbox/update_feedback_attachment"
                      , dataType: "json"
                      , data: attachment_data
                    });
                });
                e.preventDefault();
            })
        }
    }
})
.directive('flag', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                var feedid = $(this).attr('feedid');
                var flag = $(".flag-span[feedid=" + feedid + "]");
                if(!flag.hasClass("feedback-details-flag")) {
                    flag.addClass("feedback-details-flag");
                    flag.html("FLAGGED");
                } else {
                    flag.removeClass("feedback-details-flag");
                    flag.html("");
                }
                e.preventDefault();
            })
        }
    }
});

function published_state(obj, sibling_id, msg, state) {
    //kill me....
    if(state.activation_color == 'featured') {
        obj.parents('.dashboard-feedback').addClass(state.activation_color);
        obj.parents('.dashboard-feedback').removeClass('published');
        obj.children('.action-tooltip').children('span').html("Unfeature");
        obj.attr('return', 'unfeature');
        obj.siblings(sibling_id).attr('return-policy', 0);
    }

    if(state.activation_color == 'published') {
        obj.parents('.dashboard-feedback').addClass(state.activation_color);
        obj.parents('.dashboard-feedback').removeClass('featured');
        obj.children('.action-tooltip').children('span').html("Return to Inbox");
        obj.attr('return-policy', 1);
        obj.siblings(sibling_id).attr('return', 'feature');
    }

    if(state.activation_color == 'unfeature') {
        obj.parents('.dashboard-feedback').addClass('published');
        obj.parents('.dashboard-feedback').removeClass('featured');

        console.log(obj.children('.action-tooltip').children('span'));
        console.log(obj.siblings('.publish').children('.action-tooltip').children('span'));

        obj.children('.action-tooltip').children('span').html("Feature Pwet Feedback");
        obj.siblings('.publish').children('.action-tooltip').children('span').html("Return to Pwet");

        obj.attr('return', 'feature');
        obj.siblings(sibling_id).attr('return-policy', 1);
    }

    obj.css(state.activate);
    obj.siblings(sibling_id).css(state.deactivate_sibling);
    obj.siblings(sibling_id).children('.action-tooltip').children('span').html(msg);
    obj.siblings(sibling_id).attr('data-feed', state.state_change);
    obj.attr('data-feed', state.state_change_inbox);

    var origin_cat_data = obj.siblings('.save')
                             .children('div.the-categories-menu')
                             .children('.the-categories-menu-content')
                             .children(".the-categories")
                             .children(".grids")
                             .children('li')
                             .children('a');

    for(var i=0;i<origin_cat_data.length;i++) {
        var cat = $(origin_cat_data[i]);

        var feed = $.parseJSON(cat.attr('data-feed'));
        feed.status = "fileas";
        feed.origin = state.present_status

        var repackaged_json = JSON.stringify(feed);
        cat.attr('data-feed', repackaged_json);
    }

    var action_delete = obj.parents('.grids').siblings('.grids').children('.action-delete');
    var delete_button = obj.siblings('.save')
                           .children('div.the-categories-menu')
                           .children('.the-categories-menu-content')
                           .children(".the-categories-delete")
                           .children('a');

    var delete_feed_attr = $.parseJSON(action_delete.attr('data-feed'));
    delete_feed_attr.origin = state.present_status;
    var repackaged_feed_attr = JSON.stringify(delete_feed_attr);

    action_delete.attr('data-feed', repackaged_feed_attr);
    delete_button.attr('data-feed', repackaged_feed_attr);
}

function hide_the_children(obj) {
    obj.parents('.dashboard-feedback').hide();
    var child_count = obj.parents('.feedback-group').children('.dashboard-feedback:visible');
    if(child_count.length == 0) {
        obj.parents('.feedback-group').hide();
    }
}
<commit_msg>yummy<commit_after>angular.module('feedbackcontrol', [])
.directive('transform', function(FeedbackSignal) {
    return {
        restrict: 'A'
      , link: function($scope, element, attrs) {

            var currentUrl = window.location.pathname;

            $scope.$watch('checkFeedbackStatus', function() {
                $(element).bind('click', function(e) {
                    var me = $(element);
                    $scope.mystatus = FeedbackSignal.get_data();
                    var data = $scope.mystatus;

                    if(data.status == 'flag' || data.status == 'unflag') {
                        var feed = $.parseJSON($(this).attr('data-feed'));
                        var policy = $(this).attr("return-policy");
                        if(feed.status == "unflag") {
                            feed.status = "flag";
                            $(this).removeAttr("style");
                            var repackaged_json = JSON.stringify(feed);
                            $(this).attr('data-feed', repackaged_json);
                        } else {
                            feed.status = "unflag";
                            $(this).attr("style", "background-position: -194px -31px");
                            var repackaged_json = JSON.stringify(feed);
                            $(this).attr('data-feed', repackaged_json);
                        }
                        $(".checky-box-container").show();
                    } else {
                        if(currentUrl.match(/inbox\/all|deleted/g)) {
                            if(data.id.length > 0) {
                                hide_the_children(me);
                                $(".checky-box-container").show();
                            }
                        }

                        if(currentUrl.match(/published/g)) {
                            //returning published feedback to the inbox
                            if(me.attr('return-policy') == 1) {
                                hide_the_children(me);
                                $(".checky-box-container").show();
                            }

                            //unfeaturing feedback and switching UI controls to published state.
                            if(me.attr("return") == "unfeature") {
                                console.log('unfeature and switch UI to published state');
                                var state = {
                                    activate: {'background-position': '-64px -0px'}
                                  , deactivate_sibling: {'background-position': '-32px -31px'}
                                  , activation_color: 'unfeature'
                                  , state_change_inbox: '{"status": "feature", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "feature"}'
                                  , state_change: '{"status": "inbox", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                                  , present_status: "publish"
                                }
                                published_state(me, '.publish', 'Publish Feedback', state);
                            }

                            if(data.status == "feature") {
                                var state = {
                                    activate: {'background-position': '-64px -31px'}
                                  , deactivate_sibling: {'background-position': '-32px 0px'}
                                  , activation_color: 'featured'
                                  , state_change_inbox: '{"status": "unfeature", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "feature"}'
                                  , state_change: '{"status": "publish", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                                  , present_status: "feature"
                                }
                                published_state(me, '.publish', 'Publish Feedback', state);
                            }

                            if(data.status == "publish") {
                                var state = {
                                    activate: {'background-position': '-32px -31px'}
                                  , deactivate_sibling: {'background-position': '-64px 0px'}
                                  , activation_color: 'published'
                                  , state_change_inbox: '{"status": "inbox", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                                  , state_change: '{"status": "feature", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "feature"}'
                                  , present_status: "publish"
                                }
                                published_state(me, '.feature', 'Feature Feedback', state);
                            }

                            if(data.status == "delete" || data.status == "fileas") {
                                hide_the_children(me);
                                $(".checky-box-container").show();
                            }
                        }

                        if(currentUrl.match(/filed/g)) {
                            var data_status = data.status;
                            if(data_status == "publish" || data_status == "feature" || data_status == "delete") {
                                hide_the_children(me);
                                $(".checky-box-container").show();
                            }

                            if(data_status == "fileas") {
                                $(me).parents(".dashboard-feedback")
                                       .children("div.feedback-contents")
                                       .children(".responsive-padding")
                                       .children(".feedback-details")
                                       .children(".filed")
                                       .html($(me).text())
                            }
                        }
                    }

                    e.preventDefault();
                });
            });
        }
    }
})
.directive('undo', function(FeedbackSignal, FeedbackControlService) {
    return {
        restrict: 'A'
      , link: function($scope, element, attrs) {
            var currentUrl = window.location.pathname;
            $scope.$watch('checkFeedbackStatus', function() {
                $(element).bind("click", function(e) {
                    $scope.mystatus = FeedbackSignal.get_data();
                    var data = $scope.mystatus;

                    $(".checky-box-container").hide();
                    if (data.id instanceof Array) {
                        for(var i=0; i < data.id.length ; i++) {
                            var feedback = $(".dashboard-feedback[feedback=" + data.id[i] + "]");

                            feedback.show();
                            $(feedback).parents('.feedback-group').show();

                            if(currentUrl.match(/inbox\/all|deleted|published/g)) {
                                var catpicks = $(".dashboard-feedback[feedback=" + data.id[i] + "] li .cat-picks");
                                catpicks.css({'background': '#598499'});
                            }
                        }
                    } else {
                        var feedback = $(".dashboard-feedback[feedback=" + data.id + "]");

                        feedback.show();
                        $(feedback).parents('.feedback-group').show();

                        if(currentUrl.match(/inbox\/all|deleted|published/g)) {
                            var catpicks = $(".dashboard-feedback[feedback=" + data.id + "] li .cat-picks");
                            catpicks.css({'background': '#598499'});
                        }

                        var checkbox = $(".feed-checkbox[value=" + data.id + "]");

                        if(checkbox.is(":checked")) {
                            checkbox.click();
                        }
                    }

                    if($(".sorter-checkbox").is(":checked")) {
                        $(".sorter-checkbox").click();
                    }

                    if($('.feed-checkbox').is(":checked")) {
                        $('.feed-checkbox').prop("checked", false);
                    }

                    e.preventDefault();
                });
            })
        }
    }
})
.directive('close', function(FeedbackControlService) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind("click", function(e) {
                $(".checky-box-container").hide();
                FeedbackControlService.expunge();
                e.preventDefault();
            });
        }
    }
})
.directive('feedcheckbox', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            var checkbox = $(element);

            checkbox.bind('change', function() {
                if(checkbox.is(":checked")) {
                    checkbox.parents('.dashboard-feedback').css({'background-color': '#F7F7F7'});
                } else {
                    checkbox.parents('.dashboard-feedback').css({'background-color': '#FFF'});
                }
            });

        }
    }
})
.directive('statuschange', function(FeedbackService) {
    return {
        restrict: 'A'
      , scope: {
            feedid: "@feedid"
          , statustype: "@statustype"
        }
      , link: function(scope, element, attrs) {
            $(element).bind('change', function() {
                var status_class, value;
                var myvalue = $(this).val();
                if(scope.statustype == "status") {
                   status_class = ".status-line";
                   console.log(myvalue);
                   if(myvalue == "new") { value = "New"; }
                   if(myvalue == "inprogress") { value = "In Progress"; }
                   if(myvalue == "closed") { value = "Closed"; }
                } else {
                   status_class = ".priority-line";
                   console.log(myvalue);
                   if(myvalue == 0) { value = "Low"; }
                   if(myvalue == 60) { value = "Medium"; }
                   if(myvalue == 100) { value = "High"; }
                }

                $(this).parents(".dashboard-feedback")
                       .children("div.feedback-contents")
                       .children(".responsive-padding")
                       .children(".feedback-details")
                       .children(".feedback-details-status")
                       .children(status_class)
                       .html(value)

                FeedbackService.inline_change($(this).val(), scope.feedid, scope.statustype);
            })
        }
    }
})
.directive('deleteBlock', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                $(this).parents('.custom-att').fadeOut(400, function() {
                     var new_uploaded_images = new Array;
                     var new_attached_link;

                     var div = $(this).parents('.uploaded-images-and-links');
                     var images = div.find('.uploaded_image');
                     var media_attachment = div.find('.attached_link');

                     var remove_image = {
                        'small_url'    :$(this).find('.small-image-url').val(),
                        'medium_url'   :$(this).find('.medium-image-url').val(),
                        'large_url'    :$(this).find('.large-image-url').val()
                     }

                    if(images.length > 0){
                        var us = images.not(":hidden");
                        for(var i=0; i < us.length; i++) {
                            new_uploaded_images.push({
                                'name': $(us[i]).find('.image-name').val()
                            });
                        }
                    }

                    if(!media_attachment.is(":hidden")) {
                        new_attached_link = {
                            title           : media_attachment.find('.link-title').val(),
                            description     : media_attachment.find('.link-description').val(),
                            image           : media_attachment.find('.link-image').val(),
                            url             : media_attachment.find('.link-url').val(),
                            video           : media_attachment.find('.link-video').val(),
                        }
                    }

                    var remaining = {
                        uploaded_images : new_uploaded_images
                      , attached_link   : new_attached_link
                    }

                    var attachment_data = {
                        feedbackId      : div.find('.attachment_feedback_id').val()
                      , attachments     : remaining
                      , remove_image    : remove_image
                    }

                    //place this in service you lazy bastard!
                    $.ajax({
                        type: "POST"
                      , url: "/inbox/update_feedback_attachment"
                      , dataType: "json"
                      , data: attachment_data
                    });
                });
                e.preventDefault();
            })
        }
    }
})
.directive('flag', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                var feedid = $(this).attr('feedid');
                var flag = $(".flag-span[feedid=" + feedid + "]");
                if(!flag.hasClass("feedback-details-flag")) {
                    flag.addClass("feedback-details-flag");
                    flag.html("FLAGGED");
                } else {
                    flag.removeClass("feedback-details-flag");
                    flag.html("");
                }
                e.preventDefault();
            })
        }
    }
});

function published_state(obj, sibling_id, msg, state) {
    //kill me....
    if(state.activation_color == 'featured') {
        obj.parents('.dashboard-feedback').addClass(state.activation_color);
        obj.parents('.dashboard-feedback').removeClass('published');
        obj.children('.action-tooltip').children('span').html("Unfeature");
        obj.attr('return', 'unfeature');
        obj.siblings(sibling_id).attr('return-policy', 0);
    }

    if(state.activation_color == 'published') {
        obj.parents('.dashboard-feedback').addClass(state.activation_color);
        obj.parents('.dashboard-feedback').removeClass('featured');
        obj.children('.action-tooltip').children('span').html("Return to Inbox");
        obj.attr('return-policy', 1);
        obj.siblings(sibling_id).attr('return', 'feature');
    }

    if(state.activation_color == 'unfeature') {
        obj.parents('.dashboard-feedback').addClass('published');
        obj.parents('.dashboard-feedback').removeClass('featured');
        obj.children('.action-tooltip').children('span').html("Feature Feedback");
        obj.attr('return', 'feature');
        obj.siblings(sibling_id).attr('return-policy', 1);
    }

    obj.css(state.activate);
    obj.siblings(sibling_id).css(state.deactivate_sibling);
    obj.siblings(sibling_id).children('.action-tooltip').children('span').html(msg);
    obj.siblings(sibling_id).attr('data-feed', state.state_change);
    obj.attr('data-feed', state.state_change_inbox);

    var origin_cat_data = obj.siblings('.save')
                             .children('div.the-categories-menu')
                             .children('.the-categories-menu-content')
                             .children(".the-categories")
                             .children(".grids")
                             .children('li')
                             .children('a');

    for(var i=0;i<origin_cat_data.length;i++) {
        var cat = $(origin_cat_data[i]);

        var feed = $.parseJSON(cat.attr('data-feed'));
        feed.status = "fileas";
        feed.origin = state.present_status

        var repackaged_json = JSON.stringify(feed);
        cat.attr('data-feed', repackaged_json);
    }

    var action_delete = obj.parents('.grids').siblings('.grids').children('.action-delete');
    var delete_button = obj.siblings('.save')
                           .children('div.the-categories-menu')
                           .children('.the-categories-menu-content')
                           .children(".the-categories-delete")
                           .children('a');

    var delete_feed_attr = $.parseJSON(action_delete.attr('data-feed'));
    delete_feed_attr.origin = state.present_status;
    var repackaged_feed_attr = JSON.stringify(delete_feed_attr);

    action_delete.attr('data-feed', repackaged_feed_attr);
    delete_button.attr('data-feed', repackaged_feed_attr);
}

function hide_the_children(obj) {
    obj.parents('.dashboard-feedback').hide();
    var child_count = obj.parents('.feedback-group').children('.dashboard-feedback:visible');
    if(child_count.length == 0) {
        obj.parents('.feedback-group').hide();
    }
}
<|endoftext|>


<commit_before>/**
 * @package     hubzero-cms
 * @file        components/com_time/assets/js/records.js
 * @copyright   Copyright 2005-2011 Purdue University. All rights reserved.
 * @license     http://www.gnu.org/licenses/lgpl-3.0.html LGPLv3
 */

//-----------------------------------------------------------
//  Ensure we have our namespace
//-----------------------------------------------------------
if (!HUB) {
	var HUB = {};
}
if (!HUB.Plugins) {
	HUB.Plugins = {};
}
if (!jq) {
	var jq = $;
}

//----------------------------------------------------------
// Time Records
//----------------------------------------------------------
HUB.Plugins.TimeRecords = {
	jQuery: jq,

	initialize: function() {
		var $ = this.jQuery;

		// Initialize variables
		var hub      = $("#hub_id");
		var column   = $('#filter-column');
		var operator = $('#filter-operator');

		// Show add filters box
		$('#add-filters').css('display', 'block');

		// Add change event to hub select box (filter tasks list by selected hub) - ('edit' view)
		hub.change(function(event) {
			// Create a ajax call to get the tasks
			$.ajax({
				url: "/api/time/indexTasks",
				data: "hid="+hub.val()+"&pactive=1",
				dataType: "json",
				cache: false,
				success: function(json){
					// If success, update the list of tasks based on the chosen hub
					var options = '';

					if(json.tasks.length > 0) {
						for (var i = 0; i < json.tasks.length; i++) {
							options += '<option value="' + json.tasks[i].id + '">' + json.tasks[i].name + '</option>';
						}
					} else {
						options = '<option value="">No tasks for this hub</option>';
					}
					$("#task").html(options);

					if (!!$.prototype.HUBfancyselect) {
						$('#task').prev('.fs-dropdown').remove();
						$('#task').HUBfancyselect({
							'showSearch'         : true,
							'searchPlaceholder'  : 'seach...'
						});
					}
				}
			});
		});

		if ($('#filter-table').length) {
			HUB.Plugins.TimeRecords.col_change();

			// Capture change events on the column field
			column.on('change', HUB.Plugins.TimeRecords.col_change);
			operator.on('change', HUB.Plugins.TimeRecords.operator_change);
		}
	}, // end initialize

	col_change: function() {
		var $ = HUB.Plugins.TimeRecords.jQuery;

		// Initialize variables
		var table    = $('#filter-table');
		var column   = $('#filter-column');
		var value    = $('#filter-value');
		var operator = $('#filter-operator');

		if(operator.val() != "like") {
			if(column.val().search("date") < 0) {
				// Create a ajax call to get relevent value options
				$.ajax({
					url: "/api/time/getValues",
					data: "table="+table.val()+"&column="+column.val(),
					dataType: "json",
					cache: false,
					success: function(json){
						// If success, update the list of values based on the chosen column
						var options = '';
						if(json.values.length > 0) {
							for (var i = 0; i < json.values.length; i++) {
								options += '<option value="' + json.values[i].value + '">' + json.values[i].display + '</option>';
							}
						} else {
							options = '<option value="">No values are available</option>';
						}
						value.replaceWith("<select name=\"q[value]\" id=\"filter-value\"></select>");
						$('#filter-value').html(options);
					}
				});
			} else {
				value.replaceWith("<input name=\"q[value]\" id=\"filter-value\" class=\"hadDatepicker\" type=text />");
				$('.hadDatepicker').datepicker({ dateFormat: 'yy-mm-dd' });
			}
		}
	}, // end col_change

	operator_change: function() {
		var $ = HUB.Plugins.TimeRecords.jQuery;

		// Initialize variables
		var operator = $('#filter-operator');
		var value    = $('#filter-value');

		if (operator.val() == "like") {
			value.replaceWith("<input name=\"q[value]\" id=\"filter-value\" type=text />");
		} else {
			value.replaceWith("<select name=\"q[value]\" id=\"filter-value\"></select>");
			HUB.Plugins.TimeRecords.col_change();
		}
	} // end operator_change
};

jQuery(document).ready(function($){
	HUB.Plugins.TimeRecords.initialize();
});<commit_msg>[HUBZERO][#6344][COM_TIME] make sure to retain currently selected item when filtering tasks list<commit_after>/**
 * @package     hubzero-cms
 * @file        components/com_time/assets/js/records.js
 * @copyright   Copyright 2005-2011 Purdue University. All rights reserved.
 * @license     http://www.gnu.org/licenses/lgpl-3.0.html LGPLv3
 */

//-----------------------------------------------------------
//  Ensure we have our namespace
//-----------------------------------------------------------
if (!HUB) {
	var HUB = {};
}
if (!HUB.Plugins) {
	HUB.Plugins = {};
}
if (!jq) {
	var jq = $;
}

//----------------------------------------------------------
// Time Records
//----------------------------------------------------------
HUB.Plugins.TimeRecords = {
	jQuery: jq,

	initialize: function() {
		var $ = this.jQuery;

		// Initialize variables
		var hub      = $("#hub_id");
		var column   = $('#filter-column');
		var operator = $('#filter-operator');

		// Show add filters box
		$('#add-filters').css('display', 'block');

		// Add change event to hub select box (filter tasks list by selected hub) - ('edit' view)
		hub.change(function(event) {
			// First, grab the currently select task
			var task = $('#task').val();

			// Create a ajax call to get the tasks
			$.ajax({
				url: "/api/time/indexTasks",
				data: "hid="+hub.val()+"&pactive=1",
				dataType: "json",
				cache: false,
				success: function(json){
					// If success, update the list of tasks based on the chosen hub
					var options = '';

					if(json.tasks.length > 0) {
						for (var i = 0; i < json.tasks.length; i++) {
							options += '<option value="';
							options += json.tasks[i].id;
							options += '"';
							if (json.tasks[i].id == task) {
								options += ' selected="selected"';
							}
							options += '>';
							options += json.tasks[i].name;
							options += '</option>';
						}
					} else {
						options = '<option value="">No tasks for this hub</option>';
					}
					$("#task").html(options);

					if (!!$.prototype.HUBfancyselect) {
						$('#task').prev('.fs-dropdown').remove();
						$('#task').HUBfancyselect({
							'showSearch'         : true,
							'searchPlaceholder'  : 'search...'
						});
					}
				}
			});
		});

		if ($('#filter-table').length) {
			HUB.Plugins.TimeRecords.col_change();

			// Capture change events on the column field
			column.on('change', HUB.Plugins.TimeRecords.col_change);
			operator.on('change', HUB.Plugins.TimeRecords.operator_change);
		}
	}, // end initialize

	col_change: function() {
		var $ = HUB.Plugins.TimeRecords.jQuery;

		// Initialize variables
		var table    = $('#filter-table');
		var column   = $('#filter-column');
		var value    = $('#filter-value');
		var operator = $('#filter-operator');

		if(operator.val() != "like") {
			if(column.val().search("date") < 0) {
				// Create a ajax call to get relevent value options
				$.ajax({
					url: "/api/time/getValues",
					data: "table="+table.val()+"&column="+column.val(),
					dataType: "json",
					cache: false,
					success: function(json){
						// If success, update the list of values based on the chosen column
						var options = '';
						if(json.values.length > 0) {
							for (var i = 0; i < json.values.length; i++) {
								options += '<option value="' + json.values[i].value + '">' + json.values[i].display + '</option>';
							}
						} else {
							options = '<option value="">No values are available</option>';
						}
						value.replaceWith("<select name=\"q[value]\" id=\"filter-value\"></select>");
						$('#filter-value').html(options);
					}
				});
			} else {
				value.replaceWith("<input name=\"q[value]\" id=\"filter-value\" class=\"hadDatepicker\" type=text />");
				$('.hadDatepicker').datepicker({ dateFormat: 'yy-mm-dd' });
			}
		}
	}, // end col_change

	operator_change: function() {
		var $ = HUB.Plugins.TimeRecords.jQuery;

		// Initialize variables
		var operator = $('#filter-operator');
		var value    = $('#filter-value');

		if (operator.val() == "like") {
			value.replaceWith("<input name=\"q[value]\" id=\"filter-value\" type=text />");
		} else {
			value.replaceWith("<select name=\"q[value]\" id=\"filter-value\"></select>");
			HUB.Plugins.TimeRecords.col_change();
		}
	} // end operator_change
};

jQuery(document).ready(function($){
	HUB.Plugins.TimeRecords.initialize();
});<|endoftext|>


<commit_before>#!/usr/bin/env node
var st = require('../st.js')
var http = require('http')
var port = +(process.env.PORT || 1337)
var dir = ''
var cacheSize = 0
var dot = false
var index = true
var cache = true
var age = null

for (var i = 2; i < process.argv.length; i++) {
  switch (process.argv[i]) {
    case '-p':
    case '--port':
      port = +(process.argv[++i])
      break

    case '-d':
    case '--dir':
      dir = process.argv[++i]
      break

    case '-.':
    case '--dot':
      dot = process.argv[++i]
      if (dot === undefined || dot === 'true') dot = true
      else if (dot === 'false') dot = false
      else if (dot.charAt(0) === '-') {
        --i
        dot = true
      }
      break

    case '-n.':
    case '--no-dot':
      dot = false
      break

    case '-i':
    case '--index':
      index = process.argv[++i]
      if (index === undefined || index === 'true') index = true
      if (index === 'false') index = false
      if (index.charAt(0) === '-') {
        --i
        index = true
      }
      break

    case '-ni':
    case '--no-index':
      index = false
      break

    case '-h':
    case '--help':
      help()
      process.exit(0)

    case '-nc':
    case '--no-cache':
      cache = false
      break

    case '-a':
    case '--age':
      age = process.argv[++i]
      if (isNaN(age)) {
        throw new Error('invalid age: ' + JSON.stringify(age))
      }
      age = +age
      break
  }
}

function help () {
  console.log(
['st'
,'Static file server in node'
,''
,'Options:'
,''
,'-h --help             Show this help'
,''
,'-p --port PORT        Listen on PORT (default=1337)'
,''
,'-d --dir DIRECTORY    Serve the contents of DIRECTORY (default=cwd)'
,''
,'-i --index [INDEX]    Use the specified INDEX filename as the result'
,'                      when a directory is requested.  Set to "true"'
,'                      to turn autoindexing on, or "false" to turn it'
,'                      off.  If no INDEX is provided, then it will turn'
,'                      autoindexing on.  (default=true)'
,''
,'-ni --no-index        Same as "--index false"'
,''
,'-. --dot [DOT]        Allow .files to be served.  Set to "false" to'
,'                      disable.'
,''
,'-n. --no-dot          Same as "--dot false"'
,''
,'-nc --no-cache        Turn off all caching.'
,''
,'-a --age AGE          Max age (in ms) of cache entries.'
].join('\n'))
}

if (isNaN(port)) throw new Error('invalid port: '+port)

var opt = {
  url: '/',
  path: dir,
  index: index,
  dot: dot,
  cache: {
    fd: {},
    stat: {},
    index: {},
    readdir: {},
    content: {}
  }
}

if (cache === false) {
  Object.keys(opt.cache).forEach(function (k) {
    opt.cache[k].max = 0
  })
} else {
  if (age) {
    Object.keys(opt.cache).forEach(function (k) {
      opt.cache[k].maxAge = age
    })
  }
  // maybe other cache-manipulating CLI flags?
}

var mount = st(opt)

http.createServer(function (q, s) {
  if (mount(q, s)) return
  s.statusCode = 404
  s.end('not found')
}).listen(port)

console.log('listening at http://127.0.0.1:' + port)
<commit_msg>-nc sets cache to false, proper no cache<commit_after>#!/usr/bin/env node
var st = require('../st.js')
var http = require('http')
var port = +(process.env.PORT || 1337)
var dir = ''
var cacheSize = 0
var dot = false
var index = true
var cache = true
var age = null

for (var i = 2; i < process.argv.length; i++) {
  switch (process.argv[i]) {
    case '-p':
    case '--port':
      port = +(process.argv[++i])
      break

    case '-d':
    case '--dir':
      dir = process.argv[++i]
      break

    case '-.':
    case '--dot':
      dot = process.argv[++i]
      if (dot === undefined || dot === 'true') dot = true
      else if (dot === 'false') dot = false
      else if (dot.charAt(0) === '-') {
        --i
        dot = true
      }
      break

    case '-n.':
    case '--no-dot':
      dot = false
      break

    case '-i':
    case '--index':
      index = process.argv[++i]
      if (index === undefined || index === 'true') index = true
      if (index === 'false') index = false
      if (index.charAt(0) === '-') {
        --i
        index = true
      }
      break

    case '-ni':
    case '--no-index':
      index = false
      break

    case '-h':
    case '--help':
      help()
      process.exit(0)

    case '-nc':
    case '--no-cache':
      cache = false
      break

    case '-a':
    case '--age':
      age = process.argv[++i]
      if (isNaN(age)) {
        throw new Error('invalid age: ' + JSON.stringify(age))
      }
      age = +age
      break
  }
}

function help () {
  console.log(
['st'
,'Static file server in node'
,''
,'Options:'
,''
,'-h --help             Show this help'
,''
,'-p --port PORT        Listen on PORT (default=1337)'
,''
,'-d --dir DIRECTORY    Serve the contents of DIRECTORY (default=cwd)'
,''
,'-i --index [INDEX]    Use the specified INDEX filename as the result'
,'                      when a directory is requested.  Set to "true"'
,'                      to turn autoindexing on, or "false" to turn it'
,'                      off.  If no INDEX is provided, then it will turn'
,'                      autoindexing on.  (default=true)'
,''
,'-ni --no-index        Same as "--index false"'
,''
,'-. --dot [DOT]        Allow .files to be served.  Set to "false" to'
,'                      disable.'
,''
,'-n. --no-dot          Same as "--dot false"'
,''
,'-nc --no-cache        Turn off all caching.'
,''
,'-a --age AGE          Max age (in ms) of cache entries.'
].join('\n'))
}

if (isNaN(port)) throw new Error('invalid port: '+port)

var opt = {
  url: '/',
  path: dir,
  index: index,
  dot: dot,
  cache: {
    fd: {},
    stat: {},
    index: {},
    readdir: {},
    content: {}
  }
}

if (cache === false) {
  opt.cache = false
} else {
  if (age) {
    Object.keys(opt.cache).forEach(function (k) {
      opt.cache[k].maxAge = age
    })
  }
  // maybe other cache-manipulating CLI flags?
}

var mount = st(opt)

http.createServer(function (q, s) {
  if (mount(q, s)) return
  s.statusCode = 404
  s.end('not found')
}).listen(port)

console.log('listening at http://127.0.0.1:' + port)
<|endoftext|>


<commit_before>
(function($) {
	$.fn.btsListFilter = function(inputEl, opts) {

		'use strict';

		var self = this,
			searchlist$ = $(this),
			inputEl$ = $(inputEl),
			cancelEl$,
			items$ = searchlist$,
			callData,
			callReq;	//last callData execution

		opts = $.extend({
			delay: 300,
			minLength: 1,
			initial: true,
			casesensitive: false,
			eventKey: 'keyup',
			resetOnBlur: true,
			sourceData: null,
			sourceTmpl: '{title}',
			sourceNode: function(data) {
				return tmpl(opts.sourceTmpl, data);
			},
			emptyNode: function(data) {
				return 'No Results';
			},
			itemClassTmp: 'bts-dynamic-item',
			itemEl: '.list-group-item',
			itemChild: null,
			itemFilter: function(item, val) {
				//val = val.replace(new RegExp("^[.]$|[\[\]|()*]",'g'),'');
				//val = val.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
				val = val && val.replace(new RegExp("[({[^.$*+?\\\]})]","g"),'');

				var text = $(item).text(),
					i = opts.initial?'^':'',
					regSearch = new RegExp(i + val, opts.casesensitive?'':'i');
				return regSearch.test( text );
			},
			cancelNode: function() {
				return '';
			}
		}, opts);

		function tmpl(str, data) {
			return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
				return data[key] || '';
			});
		}

		function debouncer(func, timeout) {
			var timeoutID;
			timeout = timeout || 300;
			return function () {
				var scope = this , args = arguments;
				clearTimeout( timeoutID );
				timeoutID = setTimeout( function () {
					func.apply( scope , Array.prototype.slice.call( args ) );
				}, timeout);
			};
		}

		self.reset = function() {
			inputEl$.val('').trigger(opts.eventKey);
		};

		if($.isFunction(opts.cancelNode)) {

			cancelEl$ = $(opts.cancelNode.call(self));

			inputEl$.after( cancelEl$ );
			inputEl$.parents('.form-group').addClass('has-feedback');

			if(!inputEl$.prev().is('.control-label'))
				cancelEl$.css({top: 0})

			cancelEl$.on('click', self.reset);
		}

		inputEl$.on(opts.eventKey, debouncer(function(e) {

			var val = $(this).val();

			if(opts.itemEl)
				items$ = searchlist$.find(opts.itemEl);

			if(opts.itemChild)
				items$ = items$.find(opts.itemChild);

			var contains = items$.filter(function(){
					return opts.itemFilter.call(self, this, val);
				}),
				containsNot = items$.not(contains);

			if (opts.itemChild){
				contains = contains.parents(opts.itemEl);
				containsNot = containsNot.parents(opts.itemEl).hide();
			}

			if(val!=='' && val.length >= opts.minLength)
			{
				contains.show();
				containsNot.hide();

				if($.type(opts.sourceData)==='function')
				{
					contains.hide();
					containsNot.hide();

					if(callReq)
					{
						if($.isFunction(callReq.abort))
							callReq.abort();
						else if($.isFunction(callReq.stop))
							callReq.stop();
					}

					callReq = opts.sourceData.call(self, val, function(data) {
						callReq = null;
						contains.hide();
						containsNot.hide();
						searchlist$.find('.'+opts.itemClassTmp).remove();

						if(!data || data.length===0)
							$( opts.emptyNode.call(self) ).addClass(opts.itemClassTmp).appendTo(searchlist$);
						else
							for(var i in data)
								$( opts.sourceNode.call(self, data[i]) ).addClass(opts.itemClassTmp).appendTo(searchlist$);
					});
				}
				else {
                    searchlist$.find('.'+opts.itemClassTmp).remove();

                    if(contains.length===0)
						$( opts.emptyNode.call(self) ).addClass(opts.itemClassTmp).appendTo(searchlist$);
				}

			}
			else
			{
				contains.show();
				containsNot.show();
				searchlist$.find('.'+opts.itemClassTmp).remove();
			}
		}, opts.delay));

		if(opts.resetOnBlur)
			inputEl$.on('blur', function(e) {
				self.reset();
			});

		return searchlist$;
	};

})(jQuery);
<commit_msg>Fix #19<commit_after>
(function($) {
	$.fn.btsListFilter = function(inputEl, opts) {

		'use strict';

		var self = this,
			searchlist$ = $(this),
			inputEl$ = $(inputEl),
			cancelEl$,
			items$ = searchlist$,
			callData,
			callReq;	//last callData execution

		opts = $.extend({
			delay: 300,
			minLength: 1,
			initial: true,
			casesensitive: false,
			eventKey: 'keyup',
			resetOnBlur: true,
			sourceData: null,
			sourceTmpl: '{title}',
			sourceNode: function(data) {
				return tmpl(opts.sourceTmpl, data);
			},
			emptyNode: function(data) {
				return 'No Results';
			},
			itemClassTmp: 'bts-dynamic-item',
			itemEl: '.list-group-item',
			itemChild: null,
			itemFilter: function(item, val) {
				//val = val.replace(new RegExp("^[.]$|[\[\]|()*]",'g'),'');
				//val = val.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
				val = val && val.replace(new RegExp("[({[^.$*+?\\\]})]","g"),'');

				var text = $(item).text(),
					i = opts.initial?'^':'',
					regSearch = new RegExp(i + val, opts.casesensitive?'':'i');
				return regSearch.test( text );
			},
			cancelNode: function() {
				return '';
			}
		}, opts);

		function tmpl(str, data) {
			return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
				return data[key] || '';
			});
		}

		function debouncer(func, timeout) {
			var timeoutID;
			timeout = timeout || 300;
			return function () {
				var scope = this , args = arguments;
				clearTimeout( timeoutID );
				timeoutID = setTimeout( function () {
					func.apply( scope , Array.prototype.slice.call( args ) );
				}, timeout);
			};
		}

		self.reset = function() {
			inputEl$.val('').trigger(opts.eventKey);
		};

		if($.isFunction(opts.cancelNode)) {

			cancelEl$ = $(opts.cancelNode.call(self));

			inputEl$.after( cancelEl$ );
			inputEl$.parents('.form-group').addClass('has-feedback');

			if(!inputEl$.prev().is('.control-label'))
				cancelEl$.css({top: 0});

			cancelEl$.css({'pointer-events': 'auto'});

			cancelEl$.on('click', self.reset);
		}

		inputEl$.on(opts.eventKey, debouncer(function(e) {

			var val = $(this).val();

			if(opts.itemEl)
				items$ = searchlist$.find(opts.itemEl);

			if(opts.itemChild)
				items$ = items$.find(opts.itemChild);

			var contains = items$.filter(function(){
					return opts.itemFilter.call(self, this, val);
				}),
				containsNot = items$.not(contains);

			if (opts.itemChild){
				contains = contains.parents(opts.itemEl);
				containsNot = containsNot.parents(opts.itemEl).hide();
			}

			if(val!=='' && val.length >= opts.minLength)
			{
				contains.show();
				containsNot.hide();

				if($.type(opts.sourceData)==='function')
				{
					contains.hide();
					containsNot.hide();

					if(callReq)
					{
						if($.isFunction(callReq.abort))
							callReq.abort();
						else if($.isFunction(callReq.stop))
							callReq.stop();
					}

					callReq = opts.sourceData.call(self, val, function(data) {
						callReq = null;
						contains.hide();
						containsNot.hide();
						searchlist$.find('.'+opts.itemClassTmp).remove();

						if(!data || data.length===0)
							$( opts.emptyNode.call(self) ).addClass(opts.itemClassTmp).appendTo(searchlist$);
						else
							for(var i in data)
								$( opts.sourceNode.call(self, data[i]) ).addClass(opts.itemClassTmp).appendTo(searchlist$);
					});
				}
				else {
                    searchlist$.find('.'+opts.itemClassTmp).remove();

                    if(contains.length===0)
						$( opts.emptyNode.call(self) ).addClass(opts.itemClassTmp).appendTo(searchlist$);
				}

			}
			else
			{
				contains.show();
				containsNot.show();
				searchlist$.find('.'+opts.itemClassTmp).remove();
			}
		}, opts.delay));

		if(opts.resetOnBlur)
			inputEl$.on('blur', function(e) {
				self.reset();
			});

		return searchlist$;
	};

})(jQuery);
<|endoftext|>


<commit_before>/*global define*/
define([
    '../Core/RuntimeError',
    '../Core/GoogleEarthEnterpriseMetadata',
    './createTaskProcessorWorker',
    '../ThirdParty/pako_inflate'
], function(
    RuntimeError,
    GoogleEarthEnterpriseMetadata,
    createTaskProcessorWorker,
    pako) {
    'use strict';

    // Datatype sizes
    var sizeOfUint16 = Uint16Array.BYTES_PER_ELEMENT;
    var sizeOfInt32 = Int32Array.BYTES_PER_ELEMENT;
    var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT;

    var Types = {
        METADATA : 0,
        TERRAIN : 1
    };

    Types.fromString = function(s) {
        if (s === 'Metadata') {
            return Types.METADATA;
        } else if (s === 'Terrain') {
            return Types.TERRAIN;
        }
    };

    function decodeGoogleEarthEnterpriseTerrainPacket(parameters, transferableObjects) {
        var type = Types.fromString(parameters.type);
        var buffer = parameters.buffer;
        GoogleEarthEnterpriseMetadata.decode(buffer);

        var uncompressedTerrain = uncompressPacket(buffer);
        buffer = uncompressedTerrain.buffer;
        var length = uncompressedTerrain.length;

        switch (type) {
            case Types.METADATA:
                return processMetadata(buffer, length, parameters.quadKey);
            case Types.TERRAIN:
                return processTerrain(buffer, length, transferableObjects);
        }

    }

    var qtMagic = 32301;

    function processMetadata(buffer, totalSize, quadKey) {
        var dv = new DataView(buffer);
        var offset = 0;
        var magic = dv.getUint32(offset, true);
        offset += sizeOfUint32;
        if (magic !== qtMagic) {
            throw new RuntimeError('Invalid magic');
        }

        var dataTypeId = dv.getUint32(offset, true);
        offset += sizeOfUint32;
        if (dataTypeId !== 1) {
            throw new RuntimeError('Invalid data type. Must be 1 for QuadTreePacket');
        }

        // Tile format version
        var quadVersion = dv.getUint32(offset, true);
        offset += sizeOfUint32;
        if (quadVersion !== 2) {
            throw new RuntimeError('Invalid QuadTreePacket version. Only version 2 is supported.');
        }

        var numInstances = dv.getInt32(offset, true);
        offset += sizeOfInt32;

        var dataInstanceSize = dv.getInt32(offset, true);
        offset += sizeOfInt32;
        if (dataInstanceSize !== 32) {
            throw new RuntimeError('Invalid instance size.');
        }

        var dataBufferOffset = dv.getInt32(offset, true);
        offset += sizeOfInt32;

        var dataBufferSize = dv.getInt32(offset, true);
        offset += sizeOfInt32;

        var metaBufferSize = dv.getInt32(offset, true);
        offset += sizeOfInt32;

        // Offset from beginning of packet (instances + current offset)
        if (dataBufferOffset !== (numInstances * dataInstanceSize + offset)) {
            throw new RuntimeError('Invalid dataBufferOffset');
        }

        // Verify the packets is all there header + instances + dataBuffer + metaBuffer
        if (dataBufferOffset + dataBufferSize + metaBufferSize !== totalSize) {
            throw new RuntimeError('Invalid packet offsets');
        }

        // Read all the instances
        var instances = [];
        for (var i = 0; i < numInstances; ++i) {
            var bitfield = dv.getUint8(offset);
            ++offset;

            ++offset; // 2 byte align

            var cnodeVersion = dv.getUint16(offset, true);
            offset += sizeOfUint16;

            var imageVersion = dv.getUint16(offset, true);
            offset += sizeOfUint16;

            var terrainVersion = dv.getUint16(offset, true);
            offset += sizeOfUint16;

            // Number of channels stored in the dataBuffer
            offset += sizeOfUint16;

            offset += sizeOfUint16; // 4 byte align

            // Channel type offset into dataBuffer
            offset += sizeOfInt32;

            // Channel version offset into dataBuffer
            offset += sizeOfInt32;

            offset += 8; // Ignore image neighbors for now

            // Data providers aren't used
            ++offset; // Image provider
            ++offset; // Terrain provider
            offset += sizeOfUint16; // 4 byte align

            instances.push(new GoogleEarthEnterpriseMetadata.TileInformation(bitfield, cnodeVersion,
                imageVersion, terrainVersion));
        }

        var tileInfo = [];
        var index = 0;

        function populateTiles(parentKey, parent, level) {
            var isLeaf = false;
            if (level === 4) {
                if (parent.hasSubtree()) {
                    return; // We have a subtree, so just return
                }

                isLeaf = true; // No subtree, so set all children to null
            }
            for (var i = 0; i < 4; ++i) {
                var childKey = parentKey + i.toString();
                if (isLeaf) {
                    // No subtree so set all children to null
                    tileInfo[childKey] = null;
                } else if (level < 4) {
                    // We are still in the middle of the subtree, so add child
                    //  only if their bits are set, otherwise set child to null.
                    if (!parent.hasChild(i)) {
                        tileInfo[childKey] = null;
                    } else {
                        if (index === numInstances) {
                            console.log('Incorrect number of instances');
                            return;
                        }

                        var instance = instances[index++];
                        instance.setParent(parent);
                        tileInfo[childKey] = instance;
                        populateTiles(childKey, instance, level + 1);
                    }
                }
            }
        }

        var level = 0;
        var root = instances[index++];
        if (quadKey === '') {
            // Root tile has data at its root and one less level
            ++level;
        } else {
            tileInfo[quadKey] = root; // This will only contain the child bitmask
        }

        populateTiles(quadKey, root, level);

        return tileInfo;
    }

    function processTerrain(buffer, totalSize, transferableObjects) {
        var dv = new DataView(buffer);

        var offset = 0;
        var terrainTiles = [];
        while (offset < totalSize) {
            // Each tile is split into 4 parts
            var tileStart = offset;
            for (var quad = 0; quad < 4; ++quad) {
                var size = dv.getUint32(offset, true);
                offset += sizeOfUint32;
                offset += size;
            }
            var tile = buffer.slice(tileStart, offset);
            transferableObjects.push(tile);
            terrainTiles.push(tile);
        }

        return terrainTiles;
    }

    var compressedMagic = 0x7468dead;
    var compressedMagicSwap = 0xadde6874;

    function uncompressPacket(data) {
        // The layout of this decoded data is
        // Magic Uint32
        // Size Uint32
        // [GZipped chunk of Size bytes]

        // Pullout magic and verify we have the correct data
        var dv = new DataView(data);
        var offset = 0;
        var magic = dv.getUint32(offset, true);
        offset += sizeOfUint32;
        if (magic !== compressedMagic && magic !== compressedMagicSwap) {
            throw new RuntimeError('Invalid magic');
        }

        // Get the size of the compressed buffer
        var size = dv.getUint32(offset, true);
        offset += sizeOfUint32;
        if (magic === compressedMagicSwap) {
            size = ((size >>> 24) & 0x000000ff) |
                   ((size >>> 8) & 0x0000ff00) |
                   ((size << 8) & 0x00ff0000) |
                   ((size << 24) & 0xff000000);
        }

        var compressedPacket = new Uint8Array(data, offset);
        var uncompressedPacket = pako.inflate(compressedPacket);

        if (uncompressedPacket.length !== size) {
            throw new RuntimeError('Size of packet doesn\'t match header');
        }

        return uncompressedPacket;
    }

    return createTaskProcessorWorker(decodeGoogleEarthEnterpriseTerrainPacket);
});
<commit_msg>Cleanup<commit_after>/*global define*/
define([
    '../Core/RuntimeError',
    '../Core/GoogleEarthEnterpriseMetadata',
    './createTaskProcessorWorker',
    '../ThirdParty/pako_inflate'
], function(
    RuntimeError,
    GoogleEarthEnterpriseMetadata,
    createTaskProcessorWorker,
    pako) {
    'use strict';

    // Datatype sizes
    var sizeOfUint16 = Uint16Array.BYTES_PER_ELEMENT;
    var sizeOfInt32 = Int32Array.BYTES_PER_ELEMENT;
    var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT;

    var Types = {
        METADATA : 0,
        TERRAIN : 1
    };

    Types.fromString = function(s) {
        if (s === 'Metadata') {
            return Types.METADATA;
        } else if (s === 'Terrain') {
            return Types.TERRAIN;
        }
    };

    function decodeGoogleEarthEnterpriseTerrainPacket(parameters, transferableObjects) {
        var type = Types.fromString(parameters.type);
        var buffer = parameters.buffer;
        GoogleEarthEnterpriseMetadata.decode(buffer);

        var uncompressedTerrain = uncompressPacket(buffer);
        buffer = uncompressedTerrain.buffer;
        var length = uncompressedTerrain.length;

        switch (type) {
            case Types.METADATA:
                return processMetadata(buffer, length, parameters.quadKey);
            case Types.TERRAIN:
                return processTerrain(buffer, length, transferableObjects);
        }

    }

    var qtMagic = 32301;

    function processMetadata(buffer, totalSize, quadKey) {
        var dv = new DataView(buffer);
        var offset = 0;
        var magic = dv.getUint32(offset, true);
        offset += sizeOfUint32;
        if (magic !== qtMagic) {
            throw new RuntimeError('Invalid magic');
        }

        var dataTypeId = dv.getUint32(offset, true);
        offset += sizeOfUint32;
        if (dataTypeId !== 1) {
            throw new RuntimeError('Invalid data type. Must be 1 for QuadTreePacket');
        }

        // Tile format version
        var quadVersion = dv.getUint32(offset, true);
        offset += sizeOfUint32;
        if (quadVersion !== 2) {
            throw new RuntimeError('Invalid QuadTreePacket version. Only version 2 is supported.');
        }

        var numInstances = dv.getInt32(offset, true);
        offset += sizeOfInt32;

        var dataInstanceSize = dv.getInt32(offset, true);
        offset += sizeOfInt32;
        if (dataInstanceSize !== 32) {
            throw new RuntimeError('Invalid instance size.');
        }

        var dataBufferOffset = dv.getInt32(offset, true);
        offset += sizeOfInt32;

        var dataBufferSize = dv.getInt32(offset, true);
        offset += sizeOfInt32;

        var metaBufferSize = dv.getInt32(offset, true);
        offset += sizeOfInt32;

        // Offset from beginning of packet (instances + current offset)
        if (dataBufferOffset !== (numInstances * dataInstanceSize + offset)) {
            throw new RuntimeError('Invalid dataBufferOffset');
        }

        // Verify the packets is all there header + instances + dataBuffer + metaBuffer
        if (dataBufferOffset + dataBufferSize + metaBufferSize !== totalSize) {
            throw new RuntimeError('Invalid packet offsets');
        }

        // Read all the instances
        var instances = [];
        for (var i = 0; i < numInstances; ++i) {
            var bitfield = dv.getUint8(offset);
            ++offset;

            ++offset; // 2 byte align

            var cnodeVersion = dv.getUint16(offset, true);
            offset += sizeOfUint16;

            var imageVersion = dv.getUint16(offset, true);
            offset += sizeOfUint16;

            var terrainVersion = dv.getUint16(offset, true);
            offset += sizeOfUint16;

            // Number of channels stored in the dataBuffer
            offset += sizeOfUint16;

            offset += sizeOfUint16; // 4 byte align

            // Channel type offset into dataBuffer
            offset += sizeOfInt32;

            // Channel version offset into dataBuffer
            offset += sizeOfInt32;

            offset += 8; // Ignore image neighbors for now

            // Data providers aren't used
            ++offset; // Image provider
            ++offset; // Terrain provider
            offset += sizeOfUint16; // 4 byte align

            instances.push(new GoogleEarthEnterpriseMetadata.TileInformation(bitfield, cnodeVersion,
                imageVersion, terrainVersion));
        }

        var tileInfo = [];
        var index = 0;

        function populateTiles(parentKey, parent, level) {
            var isLeaf = false;
            if (level === 4) {
                if (parent.hasSubtree()) {
                    return; // We have a subtree, so just return
                }

                isLeaf = true; // No subtree, so set all children to null
            }
            for (var i = 0; i < 4; ++i) {
                var childKey = parentKey + i.toString();
                if (isLeaf) {
                    // No subtree so set all children to null
                    tileInfo[childKey] = null;
                } else if (level < 4) {
                    // We are still in the middle of the subtree, so add child
                    //  only if their bits are set, otherwise set child to null.
                    if (!parent.hasChild(i)) {
                        tileInfo[childKey] = null;
                    } else {
                        if (index === numInstances) {
                            console.log('Incorrect number of instances');
                            return;
                        }

                        var instance = instances[index++];
                        instance.setParent(parent);
                        tileInfo[childKey] = instance;
                        populateTiles(childKey, instance, level + 1);
                    }
                }
            }
        }

        var level = 0;
        var root = instances[index++];
        if (quadKey === '') {
            // Root tile has data at its root and one less level
            ++level;
        } else {
            tileInfo[quadKey] = root; // This will only contain the child bitmask
        }

        populateTiles(quadKey, root, level);

        return tileInfo;
    }

    function processTerrain(buffer, totalSize, transferableObjects) {
        var dv = new DataView(buffer);

        var offset = 0;
        var terrainTiles = [];
        while (offset < totalSize) {
            // Each tile is split into 4 parts
            var tileStart = offset;
            for (var quad = 0; quad < 4; ++quad) {
                var size = dv.getUint32(offset, true);
                offset += sizeOfUint32;
                offset += size;
            }
            var tile = buffer.slice(tileStart, offset);
            transferableObjects.push(tile);
            terrainTiles.push(tile);
        }

        return terrainTiles;
    }

    var compressedMagic = 0x7468dead;
    var compressedMagicSwap = 0xadde6874;

    function uncompressPacket(data) {
        // The layout of this decoded data is
        // Magic Uint32
        // Size Uint32
        // [GZipped chunk of Size bytes]

        // Pullout magic and verify we have the correct data
        var dv = new DataView(data);
        var offset = 0;
        var magic = dv.getUint32(offset, true);
        offset += sizeOfUint32;
        if (magic !== compressedMagic && magic !== compressedMagicSwap) {
            throw new RuntimeError('Invalid magic');
        }

        // Get the size of the compressed buffer - the endianness depends on which magic was used
        var size = dv.getUint32(offset, (magic === compressedMagic));
        offset += sizeOfUint32;

        var compressedPacket = new Uint8Array(data, offset);
        var uncompressedPacket = pako.inflate(compressedPacket);

        if (uncompressedPacket.length !== size) {
            throw new RuntimeError('Size of packet doesn\'t match header');
        }

        return uncompressedPacket;
    }

    return createTaskProcessorWorker(decodeGoogleEarthEnterpriseTerrainPacket);
});
<|endoftext|>


<commit_before>"use strict";

const Promise = require('bluebird');
const request = Promise.promisifyAll(require("request"));
const cheerio = require('cheerio');
const moment = require('moment');
const Food = require("../models/food");
const Menu = require("../models/menu");
const config = require('../config');
const timeHelper = require('../helpers/timeHelper');
const scraperHelper = require('./scraperHelper')

var LapastaUrl = config.scraper.lapastaUrl;

function _getWeekPlan() {
  return request.getAsync(LapastaUrl)
          .then(res => res.body)
          .then(body => _parseHTML(body));
}

function _parseHTML(html) {
  var weekPlan = new Array(7);

  // Lapasta is closed on Saturday and Sunday
  let closedMenu = new Menu();
  closedMenu.closed = true;
  weekPlan[5] = closedMenu;
  weekPlan[6] = closedMenu;

  // Init parser
  var $ = cheerio.load(html);

  // Load day-divs
  var dayDivs = $('#menue-container').find('.ce_text.block');

  // Get monday div and compare date to current date
  let mondayDate = moment(dayDivs.first().find("h2").text().split(", ")[1], "DD.MM.");
  if (mondayDate.isValid() && mondayDate.format("D.M") !== timeHelper.getMondayDate()) {
      return scraperHelper.invalidateMenus(weekPlan);
  }

  // weekdays
  for (let dayInWeek = 0; dayInWeek < 5; dayInWeek++) {
    var dayEntry = dayDivs.eq(dayInWeek);
    try {
        weekPlan[dayInWeek] = _parseDayMenu(dayEntry);
    } catch (ex) {
        console.log("error", ex)
        let errorMenu = new Menu();
        errorMenu.error = true;
        weekPlan[dayInWeek] = errorMenu;
    }
  }
  return weekPlan;
}

function _parseDayMenu(dayEntry) {
  var dayMenu = new Menu();
  var paragraphs = dayEntry.find("div");

  // todo: Handle special cases like "Feiertag", "Ruhetag",...
  if (paragraphs.length === 1) {
    //Special cases
    /*let pText = paragraphs.text();
    if (contains(pText, true, ["feiertag", "ruhetag", "wir machen pause", "wir haben geschlossen"])) {
      dayMenu.closed = true;
    } else if (contains(pText, true, ["Empfehlung"])) {
      dayMenu.noMenu = true;
    } else {
      let info = new Food(pText, null, true);
      dayMenu.mains.push(info);
    }*/
  } else {
    for (let i = 0; i < paragraphs.length; i++) {
      let pEntry = paragraphs.eq(i);

      let text = pEntry.text().trim();
      let name = scraperHelper.sanitizeName(text);

      let price = null; // todo: Ask Krissi about price

      let food = new Food(name, price);

      dayMenu.mains.push(food);
    }
  }

  return scraperHelper.setErrorOnEmpty(dayMenu);
}

module.exports = {
  getWeekPlan: _getWeekPlan
}
<commit_msg>Add La Paste Menu Price<commit_after>"use strict";

const Promise = require('bluebird');
const request = Promise.promisifyAll(require("request"));
const cheerio = require('cheerio');
const moment = require('moment');
const Food = require("../models/food");
const Menu = require("../models/menu");
const config = require('../config');
const timeHelper = require('../helpers/timeHelper');
const scraperHelper = require('./scraperHelper')

var LapastaUrl = config.scraper.lapastaUrl;

function _getWeekPlan() {
  return request.getAsync(LapastaUrl)
          .then(res => res.body)
          .then(body => _parseHTML(body));
}

function _parseHTML(html) {
  var weekPlan = new Array(7);

  // Lapasta is closed on Saturday and Sunday
  let closedMenu = new Menu();
  closedMenu.closed = true;
  weekPlan[5] = closedMenu;
  weekPlan[6] = closedMenu;

  // Init parser
  var $ = cheerio.load(html);

  // Load day-divs
  var dayDivs = $('#menue-container').find('.ce_text.block');

  // Get monday div and compare date to current date
  let mondayDate = moment(dayDivs.first().find("h2").text().split(", ")[1], "DD.MM.");
  if (mondayDate.isValid() && mondayDate.format("D.M") !== timeHelper.getMondayDate()) {
      return scraperHelper.invalidateMenus(weekPlan);
  }

  // weekdays
  for (let dayInWeek = 0; dayInWeek < 5; dayInWeek++) {
    var dayEntry = dayDivs.eq(dayInWeek);
    try {
        weekPlan[dayInWeek] = _parseDayMenu(dayEntry);
    } catch (ex) {
        console.log("error", ex)
        let errorMenu = new Menu();
        errorMenu.error = true;
        weekPlan[dayInWeek] = errorMenu;
    }
  }
  return weekPlan;
}

function _parseDayMenu(dayEntry) {
  var dayMenu = new Menu();
  var paragraphs = dayEntry.find("div");

  // todo: Handle special cases like "Feiertag", "Ruhetag",...
  if (paragraphs.length === 1) {
    //Special cases
    /*let pText = paragraphs.text();
    if (contains(pText, true, ["feiertag", "ruhetag", "wir machen pause", "wir haben geschlossen"])) {
      dayMenu.closed = true;
    } else if (contains(pText, true, ["Empfehlung"])) {
      dayMenu.noMenu = true;
    } else {
      let info = new Food(pText, null, true);
      dayMenu.mains.push(info);
    }*/
  } else {
    for (let i = 0; i < paragraphs.length; i++) {
      let pEntry = paragraphs.eq(i);

      let text = pEntry.text().trim();
      let name = scraperHelper.sanitizeName(text);

      let price = 7.8;

      let food = new Food(name, price);

      dayMenu.mains.push(food);
    }
  }

  return scraperHelper.setErrorOnEmpty(dayMenu);
}

module.exports = {
  getWeekPlan: _getWeekPlan
}
<|endoftext|>


<commit_before>angular.module('classeur.core.utils', [])
	.factory('clUid', function() {
		var alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
		var radix = alphabet.length;
		var length = 16;
		var mapper = Array.apply(null, new Array(length));

		function clUid() {
			return mapper.map(function() {
				return alphabet[Math.random() * radix | 0];
			}).join('');
		}
		return clUid;
	})
	.factory('clToast', function($mdToast) {
		return function(text) {
			$mdToast.show(
				$mdToast.simple()
				.content(text)
				.position('bottom right')
				.hideDelay(6000)
			);
		};
	})
	.factory('clPanel', function() {
		window.move.defaults = {
			duration: 0
		};

		function Panel(elt, selector) {
			elt = selector ? angular.element(elt[0].querySelector(selector)) : elt;
			this.$elt = elt;
			this.$$elt = elt[0];
		}

		Panel.prototype.css = function(attr, value) {
			this.$$elt.style[attr] = value !== undefined ? value : '';
			return this;
		};

		function styleSetter(attr, unit) {
			return function(value) {
				this.$$elt.style[attr] = value !== undefined ? value + unit : '';
				return this;
			};
		}

		[
			'width',
			'height',
			'top',
			'right',
			'bottom',
			'marginTop',
			'marginRight',
			'marginBottom',
			'marginLeft',
			'left'
		].forEach(function(attr) {
			Panel.prototype[attr] = styleSetter(attr, 'px');
		});

		Panel.prototype.move = function() {
			return window.move(this.$$elt).ease('out');
		};

		return function(elt, selector) {
			return new Panel(elt, selector);
		};
	})
	.factory('clDraggablePanel', function(clPanel) {
		var Hammer = window.Hammer;
		return function(elt, selector, x, y, rotation) {
			rotation = rotation || 0;
			var panel = clPanel(elt, selector);
			panel.move().rotate(rotation)
				.then().to(x, y).duration(180).ease('ease-out-back').pop()
				.end();

			var hammertime = new Hammer(panel.$$elt);
			hammertime.get('pan').set({
				direction: Hammer.DIRECTION_ALL,
				threshold: 0
			});
			hammertime.on('panmove', function(evt) {
				evt.preventDefault();
				panel.move().rotate(rotation).to(x + evt.deltaX, y + evt.deltaY).end();
			});
			hammertime.on('panend', function(evt) {
				x += evt.deltaX;
				y += evt.deltaY;
			});
			return panel;
		};
	})
	.factory('clLocalStorageObject', function() {

		function LocalStorageObject(prefix) {
			this.$globalPrefix = prefix ? prefix + '.' : '';
			this.$globalUpdateKey = this.$globalPrefix + 'u';
			this.$setId();
			var self = this; // Make sure we update the __proto__ object
			this.$readGlobalUpdate = function() {
				self.gUpdated = parseInt(localStorage[this.$globalUpdateKey]);
				isNaN(self.gUpdated) && this.$setGlobalUpdate(Date.now());
			};
			this.$setGlobalUpdate = function(updated) {
				self.gUpdated = updated;
				localStorage[this.$globalUpdateKey] = updated;
			};
			this.$readGlobalUpdate();
		}

		LocalStorageObject.prototype.$setId = function(id) {
			this.$localPrefix = this.$globalPrefix + (id ? id + '.' : '');
			this.$localUpdateKey = this.$localPrefix + 'u';
			this.$readLocalUpdate();
		};

		LocalStorageObject.prototype.$readAttr = function(name, defaultValue, parser) {
			var exists = true;
			var key = this.$localPrefix + name;
			var value = localStorage[key];
			if (value === undefined) {
				exists = false;
				value = defaultValue;
			}
			this['$' + name + 'Saved'] = value;
			value = parser ? parser(value) : value;
			this[name] = value;
			return exists;
		};

		LocalStorageObject.prototype.$checkAttr = function(name, defaultValue) {
			var key = this.$localPrefix + name;
			var value = localStorage[key] || defaultValue;
			if (value !== this['$' + name + 'Saved']) {
				return true;
			}
		};

		LocalStorageObject.prototype.$writeAttr = function(name, serializer, updated) {
			var value = serializer ? serializer(this[name]) : '' + this[name];
			if (value !== this['$' + name + 'Saved']) {
				var key = this.$localPrefix + name;
				if (!value) {
					localStorage.removeItem(key);
				} else {
					localStorage[key] = value;
				}
				this['$' + name + 'Saved'] = value;
				updated = updated || Date.now();
				this.$setLocalUpdate(updated);
				this.$setGlobalUpdate(updated);
				return true;
			}
		};

		LocalStorageObject.prototype.$freeAttr = function(name) {
			delete this[name];
			delete this['$' + name + 'Saved'];
		};

		LocalStorageObject.prototype.$checkLocalUpdate = function() {
			return this.updated != localStorage[this.$localUpdateKey];
		};

		LocalStorageObject.prototype.$readLocalUpdate = function() {
			this.updated = parseInt(localStorage[this.$localUpdateKey]);
			isNaN(this.updated) && this.$setLocalUpdate(Date.now());
		};

		LocalStorageObject.prototype.$setLocalUpdate = function(updated) {
			this.updated = updated;
			localStorage[this.$localUpdateKey] = updated;
		};

		LocalStorageObject.prototype.$checkGlobalUpdate = function() {
			return this.gUpdated != localStorage[this.$globalUpdateKey];
		};

		return function(prefix) {
			return new LocalStorageObject(prefix);
		};
	})
	.factory('clStateMgr', function($rootScope, clUid) {
		var stateKeyPrefix = 'state.';
		var stateMaxAge = 3600000; // 1 hour

		var currentDate = Date.now();
		var keyPrefix = /^cl\.state\.(.+)/;
		for (var key in localStorage) {
			var match = key.match(keyPrefix);
			if (match) {
				var stateAge = parseInt(match[1].split('.')[1] || 0);
				(currentDate - stateAge > stateMaxAge) && localStorage.removeItem(key);
			}
		}

		var clStateMgr = {
			saveState: function(state) {
				var stateId = clUid() + '.' + Date.now();
				localStorage[stateKeyPrefix + stateId] = JSON.stringify(state);
				return stateId;
			}
		};

		function checkState(stateId) {
			if (stateId) {
				var storedState = localStorage[stateKeyPrefix + stateId];
				if (storedState) {
					localStorage.removeItem(stateKeyPrefix + stateId);
					clStateMgr.checkedState = JSON.parse(storedState);
				}
			} else {
				clStateMgr.state = clStateMgr.checkedState;
				clStateMgr.checkedState = undefined;
			}
		}

		$rootScope.$on('$routeChangeStart', function(evt, next) {
			checkState(next.params.stateId);
		});

		return clStateMgr;
	})
	.factory('clSelectionListeningSvc', function($timeout) {
		var clSelectionListeningSvc = {};

		function saveSelection() {
			$timeout(function() {
				var selection = window.getSelection();
				clSelectionListeningSvc.range = selection.rangeCount && selection.getRangeAt(0);
			}, 25);
		}

		window.addEventListener('keyup', saveSelection);
		window.addEventListener('mouseup', saveSelection);
		window.addEventListener('contextmenu', saveSelection);
		return clSelectionListeningSvc;
	})
	.factory('clUriValidator', function() {
		var aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/,
			imgSrcSanitizationWhitelist = /^\s*(https?|ftp|file):|data:image\//;

		var msie = window.cledit.Utils.isMsie;

		var urlParsingNode = document.createElement("a");

		function urlResolve(url) {
			var href = url;

			if (msie) {
				// Normalize before parse.  Refer Implementation Notes on why this is
				// done in two steps on IE.
				urlParsingNode.setAttribute("href", href);
				href = urlParsingNode.href;
			}

			urlParsingNode.setAttribute('href', href);

			// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
			return {
				href: urlParsingNode.href,
				protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
				host: urlParsingNode.host,
				search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
				hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
				hostname: urlParsingNode.hostname,
				port: urlParsingNode.port,
				pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
					urlParsingNode.pathname : '/' + urlParsingNode.pathname
			};
		}

		return function(uri, isImage) {
			var regex = isImage ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist;
			var normalizedVal;
			normalizedVal = urlResolve(uri).href;
			if (normalizedVal === '' || normalizedVal.match(regex)) {
				return true;
			}
		};
	});
<commit_msg>Fixed write localstorage<commit_after>angular.module('classeur.core.utils', [])
	.factory('clUid', function() {
		var alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
		var radix = alphabet.length;
		var length = 16;
		var mapper = Array.apply(null, new Array(length));

		function clUid() {
			return mapper.map(function() {
				return alphabet[Math.random() * radix | 0];
			}).join('');
		}
		return clUid;
	})
	.factory('clToast', function($mdToast) {
		return function(text) {
			$mdToast.show(
				$mdToast.simple()
				.content(text)
				.position('bottom right')
				.hideDelay(6000)
			);
		};
	})
	.factory('clPanel', function() {
		window.move.defaults = {
			duration: 0
		};

		function Panel(elt, selector) {
			elt = selector ? angular.element(elt[0].querySelector(selector)) : elt;
			this.$elt = elt;
			this.$$elt = elt[0];
		}

		Panel.prototype.css = function(attr, value) {
			this.$$elt.style[attr] = value !== undefined ? value : '';
			return this;
		};

		function styleSetter(attr, unit) {
			return function(value) {
				this.$$elt.style[attr] = value !== undefined ? value + unit : '';
				return this;
			};
		}

		[
			'width',
			'height',
			'top',
			'right',
			'bottom',
			'marginTop',
			'marginRight',
			'marginBottom',
			'marginLeft',
			'left'
		].forEach(function(attr) {
			Panel.prototype[attr] = styleSetter(attr, 'px');
		});

		Panel.prototype.move = function() {
			return window.move(this.$$elt).ease('out');
		};

		return function(elt, selector) {
			return new Panel(elt, selector);
		};
	})
	.factory('clDraggablePanel', function(clPanel) {
		var Hammer = window.Hammer;
		return function(elt, selector, x, y, rotation) {
			rotation = rotation || 0;
			var panel = clPanel(elt, selector);
			panel.move().rotate(rotation)
				.then().to(x, y).duration(180).ease('ease-out-back').pop()
				.end();

			var hammertime = new Hammer(panel.$$elt);
			hammertime.get('pan').set({
				direction: Hammer.DIRECTION_ALL,
				threshold: 0
			});
			hammertime.on('panmove', function(evt) {
				evt.preventDefault();
				panel.move().rotate(rotation).to(x + evt.deltaX, y + evt.deltaY).end();
			});
			hammertime.on('panend', function(evt) {
				x += evt.deltaX;
				y += evt.deltaY;
			});
			return panel;
		};
	})
	.factory('clLocalStorageObject', function() {

		function LocalStorageObject(prefix) {
			this.$globalPrefix = prefix ? prefix + '.' : '';
			this.$globalUpdateKey = this.$globalPrefix + 'u';
			this.$setId();
			var self = this; // Make sure we update the __proto__ object
			this.$readGlobalUpdate = function() {
				self.gUpdated = parseInt(localStorage[this.$globalUpdateKey]);
				isNaN(self.gUpdated) && this.$setGlobalUpdate(Date.now());
			};
			this.$setGlobalUpdate = function(updated) {
				self.gUpdated = updated;
				localStorage[this.$globalUpdateKey] = updated;
			};
			this.$readGlobalUpdate();
		}

		LocalStorageObject.prototype.$setId = function(id) {
			this.$localPrefix = this.$globalPrefix + (id ? id + '.' : '');
			this.$localUpdateKey = this.$localPrefix + 'u';
			this.$readLocalUpdate();
		};

		LocalStorageObject.prototype.$readAttr = function(name, defaultValue, parser) {
			var exists = true;
			var key = this.$localPrefix + name;
			var value = localStorage[key];
			if (value === undefined) {
				exists = false;
				value = defaultValue;
			}
			this['$' + name + 'Saved'] = value;
			value = parser ? parser(value) : value;
			this[name] = value;
			return exists;
		};

		LocalStorageObject.prototype.$checkAttr = function(name, defaultValue) {
			var key = this.$localPrefix + name;
			var value = localStorage[key] || defaultValue;
			return value !== this['$' + name + 'Saved'];
		};

		LocalStorageObject.prototype.$writeAttr = function(name, serializer, updated) {
			var value = serializer ? serializer(this[name]) : '' + this[name];
			if (updated || value !== this['$' + name + 'Saved']) {
				var key = this.$localPrefix + name;
				if (!value) {
					localStorage.removeItem(key);
				} else {
					localStorage[key] = value;
				}
				this['$' + name + 'Saved'] = value;
				updated = updated || Date.now();
				this.$setLocalUpdate(updated);
				this.$setGlobalUpdate(updated);
				return true;
			}
		};

		LocalStorageObject.prototype.$freeAttr = function(name) {
			delete this[name];
			delete this['$' + name + 'Saved'];
		};

		LocalStorageObject.prototype.$checkLocalUpdate = function() {
			return this.updated != localStorage[this.$localUpdateKey];
		};

		LocalStorageObject.prototype.$readLocalUpdate = function() {
			this.updated = parseInt(localStorage[this.$localUpdateKey]);
			isNaN(this.updated) && this.$setLocalUpdate(Date.now());
		};

		LocalStorageObject.prototype.$setLocalUpdate = function(updated) {
			this.updated = updated;
			localStorage[this.$localUpdateKey] = updated;
		};

		LocalStorageObject.prototype.$checkGlobalUpdate = function() {
			return this.gUpdated != localStorage[this.$globalUpdateKey];
		};

		return function(prefix) {
			return new LocalStorageObject(prefix);
		};
	})
	.factory('clStateMgr', function($rootScope, clUid) {
		var stateKeyPrefix = 'state.';
		var stateMaxAge = 3600000; // 1 hour

		var currentDate = Date.now();
		var keyPrefix = /^cl\.state\.(.+)/;
		for (var key in localStorage) {
			var match = key.match(keyPrefix);
			if (match) {
				var stateAge = parseInt(match[1].split('.')[1] || 0);
				(currentDate - stateAge > stateMaxAge) && localStorage.removeItem(key);
			}
		}

		var clStateMgr = {
			saveState: function(state) {
				var stateId = clUid() + '.' + Date.now();
				localStorage[stateKeyPrefix + stateId] = JSON.stringify(state);
				return stateId;
			}
		};

		function checkState(stateId) {
			if (stateId) {
				var storedState = localStorage[stateKeyPrefix + stateId];
				if (storedState) {
					localStorage.removeItem(stateKeyPrefix + stateId);
					clStateMgr.checkedState = JSON.parse(storedState);
				}
			} else {
				clStateMgr.state = clStateMgr.checkedState;
				clStateMgr.checkedState = undefined;
			}
		}

		$rootScope.$on('$routeChangeStart', function(evt, next) {
			checkState(next.params.stateId);
		});

		return clStateMgr;
	})
	.factory('clSelectionListeningSvc', function($timeout) {
		var clSelectionListeningSvc = {};

		function saveSelection() {
			$timeout(function() {
				var selection = window.getSelection();
				clSelectionListeningSvc.range = selection.rangeCount && selection.getRangeAt(0);
			}, 25);
		}

		window.addEventListener('keyup', saveSelection);
		window.addEventListener('mouseup', saveSelection);
		window.addEventListener('contextmenu', saveSelection);
		return clSelectionListeningSvc;
	})
	.factory('clUriValidator', function() {
		var aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/,
			imgSrcSanitizationWhitelist = /^\s*(https?|ftp|file):|data:image\//;

		var msie = window.cledit.Utils.isMsie;

		var urlParsingNode = document.createElement("a");

		function urlResolve(url) {
			var href = url;

			if (msie) {
				// Normalize before parse.  Refer Implementation Notes on why this is
				// done in two steps on IE.
				urlParsingNode.setAttribute("href", href);
				href = urlParsingNode.href;
			}

			urlParsingNode.setAttribute('href', href);

			// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
			return {
				href: urlParsingNode.href,
				protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
				host: urlParsingNode.host,
				search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
				hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
				hostname: urlParsingNode.hostname,
				port: urlParsingNode.port,
				pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
					urlParsingNode.pathname : '/' + urlParsingNode.pathname
			};
		}

		return function(uri, isImage) {
			var regex = isImage ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist;
			var normalizedVal;
			normalizedVal = urlResolve(uri).href;
			if (normalizedVal === '' || normalizedVal.match(regex)) {
				return true;
			}
		};
	});
<|endoftext|>