<commit_before>// Category View
// =============

// Includes file dependencies
define([
    "jquery",
    "backbone",
    "moment",
    "text!../templates/character-print-view.html",
    "text!../templates/character-history-selected-view.html",
    "text!../templates/character-history-view.html",
    "../helpers/VampirePrintHelper"
], function( $, Backbone, moment, character_print_view_html, character_history_selected_view_html, character_history_view_html, VampirePrintHelper) {

    // Extends Backbone.View
    var View = Backbone.View.extend( {

        // The View Constructor
        initialize: function() {
            var self = this;

            _.bindAll(this,
                "render",
                "format_simpletext",
                "format_attribute_value",
                "format_attribute_focus",
                "format_skill",
                "format_specializations"
            );

            self.sheetTemplate = _.template(character_print_view_html);
            self.selectedTemplate = _.template(character_history_selected_view_html);
        },

        register: function(character, changeId) {
            var self = this;
            var p = Parse.Promise.as([]);

            if (character !== self.character) {
                if (self.character) {
                    self.stopListening(self.character);
                    if (self.character.recorded_changes) {
                        self.stopListening(self.character.recorded_changes);
                    }
                }
                self.character = character;

                p = self.character.get_recorded_changes(function (rc) {
                    self.listenTo(rc, "add", self.render);
                    self.listenTo(rc, "reset", self.render);
                    if (self.character.recorded_changes.length > 0) {
                        _.defer(self.render);
                    }
                });
            }

            return p.then(function () {
                Parse.Promise.as(self);
            });
        },

        events: {
            "change": "update_selected",
        },

        format_entry: function(log, entry) {
            if (_.isUndefined(log)) {
                console.log("Undefined log");
                return "Undefined log";
            }
            if (log.get(entry)) {
                return log.get(entry);
            }
            var attr = log[entry];
            if (_.isDate(attr)) {
                return moment(attr).format('lll');
            }
            return attr;
        },

        update_selected: function (e) {
            var self = this;
            var selectedIndex = _.parseInt(this.$(e.target).val());
            self.idForPickedIndex = selectedIndex;
            self._render_viewing(true);

            var selectedId = this.$("#history-changes-" + selectedIndex).val();
            var changesToApply = _.chain(self.character.recorded_changes.models).takeRightWhile(function (model) {
                return model.id != selectedId;
            }).reverse().value();
            var c = self.character.get_transformed(changesToApply);
            self._render_sheet(c, true);
        },

        _render_viewing: function(enhance) {
            var self = this;
            var sendId = self.idForPickedIndex;
            if (_.isUndefined(sendId)) {
                sendId = self.character.recorded_changes.models.length - 1;
            }
            this.$el.find("#history-viewing").html(this.selectedTemplate({
                "character": this.character,
                "logs": self.character.recorded_changes.models,
                "format_entry": this.format_entry,
                idForPickedIndex: sendId,
            }));
            if (enhance) {
                this.$el.find("#history-viewing").enhanceWithin();
            }
        },

        _render_sheet: function(characterOverride, enhance) {
            var self = this;
            self.character_override = characterOverride || self.character;
            var c = self.character_override;
            var sortedSkills = c.get_sorted_skills();
            var groupedSkills = c.get_grouped_skills(sortedSkills, 3);
            this.$el.find("#history-sheet").html(this.sheetTemplate({
                "character": c,
                "skills": sortedSkills,
                "groupedSkills": groupedSkills,
                format_simpletext: this.format_simpletext,
                format_attribute_value: this.format_attribute_value,
                format_attribute_focus: this.format_attribute_focus,
                format_skill: this.format_skill,
                format_specializations: this.format_specializations,} ));
            if (enhance) {
                this.$el.find("#history-sheet").enhanceWithin();
            }
        },

        // Renders all of the Category models on the UI
        render: function() {
            var self = this;

            var sendId = self.idForPickedIndex;
            if (_.isUndefined(sendId)) {
                sendId = self.character.recorded_changes.models.length - 1;
            }

            // Sets the view's template property
            this.template = _.template(character_history_view_html)({
                    "character": this.character,
                    "logs": this.character.recorded_changes.models,
                    "format_entry": this.format_entry,
                    idForPickedIndex: sendId,
                 });

            // Renders the view's template inside of the current listview element
            this.$el.find("#history-main").html(this.template);

            this._render_viewing();

            this._render_sheet();

            this.$el.enhanceWithin();

            // Maintains chainability
            return this;

        }

    } );

    _.extend(View.prototype, VampirePrintHelper);

    // Returns the View class
    return View;

} );<commit_msg>Update history view to use LayoutView<commit_after>// Category View
// =============

// Includes file dependencies
define([
    "underscore",
    "jquery",
    "backbone",
    "marionette",
    "parse",
    "moment",
    "text!../templates/character-print-view.html",
    "text!../templates/character-history-selected-view.html",
    "text!../templates/character-history-view.html",
    "../helpers/VampirePrintHelper"
], function( _, $, Backbone, Marionette, Parse, moment, character_print_view_html, character_history_selected_view_html, character_history_view_html, VampirePrintHelper) {

    var MainView = Marionette.ItemView.extend({
        template: _.template(character_history_view_html),
        templateHelpers: function () {
            var self = this;
            return {
                "character": this.model,
                "logs": this.model.recorded_changes.models,
                idForPickedIndex: self.picked.get("value")
            }
        },
        modelEvents: {
            "saved": "update_then_render"
        },
        events: {
            "change": "update_picked"
        },
        initialize: function(options) {
            this.picked = options.picked;
            this.override = options.override;

            _.bindAll(this, "templateHelpers");
        },
        update_picked: function (e) {
            var self = this;
            var selectedIndex = _.parseInt(this.$(e.target).val());
            self.picked.set("value", selectedIndex);

            var selectedId = this.$("#history-changes-" + selectedIndex).val();
            var changesToApply = _.chain(self.model.recorded_changes.models).takeRightWhile(function (model) {
                return model.id != selectedId;
            }).reverse().value();
            var c = self.model.get_transformed(changesToApply);
            self.override.set("character", c);
        },
        update_then_render: function() {
            var self = this;
            self.model.update_recorded_changes().then(function () {
                self.render();
            });
        },
        onRender: function() {
            this.$el.enhanceWithin();
        }
    });

    var ViewingView = Marionette.ItemView.extend({
        template: _.template(character_history_selected_view_html),
        templateHelpers: function () {
            var self = this;
            return {
                "character": this.model,
                "logs": this.model.recorded_changes.models,
                "format_entry": this.format_entry,
                idForPickedIndex: self.picked.get("value")
            }
        },
        modelEvents: {
            "add": "render",
            "reset": "render"
        },
        initialize: function(options) {
            this.picked = options.picked;

            this.listenTo(
                this.picked,
                "change",
                _.debounce(this.render, 100, { trailing: true}));

            _.bindAll(this, "templateHelpers");
        },
        format_entry: function(log, entry) {
            if (_.isUndefined(log)) {
                console.log("Undefined log");
                return "Undefined log";
            }
            if (log.get(entry)) {
                return log.get(entry);
            }
            var attr = log[entry];
            if (_.isDate(attr)) {
                return moment(attr).format('lll');
            }
            return attr;
        },
        onRender: function() {
            this.$el.enhanceWithin();
        }
    });

    var SheetView = Marionette.ItemView.extend({
        template: _.template(character_print_view_html),
        templateHelpers: function () {
            var self = this;
            var character = self.override.get("character") || self.model
            var sortedSkills = character.get_sorted_skills();
            return {
                "character": character,
                "skills": sortedSkills,
                "groupedSkills": character.get_grouped_skills(sortedSkills),
                format_simpletext: this.format_simpletext,
                format_attribute_value: this.format_attribute_value,
                format_attribute_focus: this.format_attribute_focus,
                format_skill: this.format_skill,
                format_specializations: this.format_specializations
            }
        },
        modelEvents: {
            "change": "renderIfNoOverride",
        },
        initialize: function(options) {
            this.override = options.override;
            this.listenTo(
                this.override,
                "change",
                _.debounce(this.render, 100, { trailing: true}));

            _.bindAll(
                this,
                "templateHelpers",
                "format_simpletext",
                "format_attribute_value",
                "format_attribute_focus",
                "format_skill",
                "format_specializations"
            );

        },
        renderIfNoOverride: function() {
            var self = this;
            if (self.override.get("character") == null) {
                return;
            }
            return self.render();
        },
        onRender: function() {
            this.$el.enhanceWithin();
        }
    })
    _.extend(SheetView.prototype, VampirePrintHelper);

    var LayoutView = Marionette.LayoutView.extend({
        tagName: "div",
        regions: {
            main: "#history-main",
            viewing: "#history-viewing",
            sheet: "#history-sheet"
        },

        register: function(model) {
            var self = this;
            var p = Parse.Promise.as([]);

            if (model != self.model) {
                self.model = model;
                self.picked = new Backbone.Model({value: 0});
                self.override = new Backbone.Model({character: null});

                p = self.model.get_recorded_changes().then(function () {
                    self.picked.set("value", self.model.recorded_changes.models.length - 1);

                    // Set up child views now
                    self.showChildView('main', new MainView({
                        model: self.model,
                        picked: self.picked,
                        override: self.override
                    }));
                    self.showChildView('viewing', new ViewingView({
                        model: self.model,
                        picked: self.picked
                    }));
                    self.showChildView('sheet', new SheetView({
                        model: self.model,
                        override: self.override
                    }));
                });
            }

            return p.then(function () {
                Parse.Promise.as(self);
            });
        },
        onRender: function () {
            this.$el.enhanceWithin();
        }
    });

    return LayoutView;

} );<|endoftext|>


<commit_before>var source = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sollicitudin, mi in ultrices tincidunt, nisl libero gravida sem, imperdiet gravida justo turpis vel mi. Morbi consequat gravida ligula, ut lacinia tortor dignissim vel. Nunc quis hendrerit dolor. Pellentesque elit enim, lacinia at tellus eget, lacinia dapibus neque. Pellentesque vitae urna nisi. Aenean a hendrerit augue. Maecenas tellus sem, laoreet id auctor non, vulputate quis sem. Aenean sagittis condimentum arcu non volutpat. Maecenas consequat ante eu quam viverra, et venenatis dui posuere. Quisque et cursus quam. In cursus ante vitae erat blandit, a aliquet risus mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed venenatis feugiat fringilla. Proin et hendrerit dui. Sed aliquam finibus sodales. Etiam at risus sit amet nunc rhoncus maximus. Fusce faucibus luctus leo tincidunt lobortis. Nulla facilisis, nisi sed tincidunt maximus, turpis ligula dignissim lorem, at lacinia metus orci non erat. Fusce in purus porta nulla tristique faucibus pharetra ut diam. Praesent non facilisis libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam tristique non erat et blandit. Praesent aliquet eleifend erat imperdiet tristique. Praesent ac lectus enim. Aliquam erat volutpat. Quisque vulputate mauris id sapien posuere accumsan. Quisque sit amet ligula nec lectus auctor finibus. Aliquam mi felis, faucibus at efficitur et, vestibulum quis ipsum. Nam sem nunc, posuere ac turpis eget, consectetur blandit arcu. Nulla euismod arcu arcu, non ullamcorper felis consectetur vel. Sed consequat lorem in mi mattis, quis volutpat leo congue. Nulla sodales quam sed lobortis dapibus. Nunc lobortis eros ac diam porta, quis auctor justo ornare. Nam tempor lectus erat, quis condimentum nunc iaculis sit amet. Nam quis dolor felis. Nunc pulvinar, nisi sit amet consectetur ullamcorper, ante urna fermentum mi, posuere pharetra quam diam eget lectus. Maecenas nec elementum leo, non ultricies orci. Nulla sem purus, commodo eu sem sit amet, bibendum feugiat ligula. Cras faucibus enim a mi dignissim, non dignissim lacus vehicula. Sed bibendum tortor nec hendrerit fermentum. Nam pulvinar commodo nulla vitae molestie. Sed ultrices tortor et augue eleifend porttitor. Ut hendrerit sagittis arcu in bibendum. Nunc nibh arcu, dapibus eu sapien non, vestibulum fringilla mi. Fusce elementum erat eget sem laoreet tempus. Phasellus tempus in magna ut aliquet. Suspendisse vitae dolor at velit eleifend laoreet. Nulla a turpis turpis. Pellentesque fermentum ipsum dapibus felis mollis ullamcorper. Sed nec sollicitudin leo. Integer vel neque vitae lectus porta luctus et et mi. Proin efficitur ex quam. In bibendum fringilla maximus. Donec viverra tempor posuere. Donec mauris mi, maximus in lectus in, accumsan viverra enim. Cras semper faucibus arcu a mattis. Etiam elit augue, fermentum id est gravida, laoreet faucibus nisi. Mauris semper, nisl vestibulum aliquam pulvinar, mi diam ultricies nisi, id auctor diam arcu id est. Integer a massa pretium, convallis felis at, pharetra lorem. Pellentesque bibendum urna quis tortor blandit luctus. Fusce euismod ex quis tortor mollis iaculis. Vivamus posuere ac sem a condimentum. Duis condimentum dui non metus molestie, eget fringilla ligula egestas. Pellentesque orci erat, vehicula et orci quis, suscipit efficitur purus. Praesent elementum mollis lacus eu luctus. Integer dictum tellus quis dolor maximus ultrices. Cras varius libero eget magna placerat, ut porta diam sodales. Mauris rutrum viverra lorem et interdum. Sed lobortis placerat efficitur. Praesent tortor turpis, facilisis vel est ut, sagittis molestie elit. Nullam sit amet ante eu est fermentum efficitur sit amet nec sapien. Duis at cursus mauris. Vivamus congue arcu metus, ut ornare odio dignissim nec. Vestibulum eu luctus orci. Pellentesque id euismod massa. Nulla tincidunt vitae diam id laoreet. Suspendisse dui dolor, auctor ut purus vel, faucibus cursus leo. Donec auctor, sapien gravida efficitur tincidunt, nunc nibh dictum velit, vel rhoncus eros lacus vitae turpis. Sed arcu turpis, posuere a ligula ut, bibendum tincidunt tortor. Integer ut est sed ante suscipit sodales. Sed quis dolor et massa gravida feugiat. Mauris vehicula ligula sed eleifend bibendum. Praesent viverra mollis neque, rhoncus efficitur nisl porttitor ac. Aliquam id laoreet justo. Suspendisse vitae sodales magna. Sed interdum iaculis dui sed faucibus. Suspendisse et tincidunt arcu. Donec vel rhoncus augue, a varius ex. Nulla sed eros dignissim ante auctor vulputate sed et enim. Cras tincidunt, enim sit amet mollis fermentum, magna lectus volutpat nisi, vitae convallis ipsum elit sed eros. Nullam ac arcu fermentum nisi suscipit interdum. Donec mattis felis id cursus varius. Etiam a scelerisque quam. Aliquam erat volutpat. Nulla urna velit, luctus at rhoncus non, fermentum non erat. Nunc tempus, risus rhoncus hendrerit mattis, mi eros gravida mi, at finibus ante metus a sapien. Cras hendrerit orci eu euismod faucibus. Aliquam finibus urna ipsum, non luctus diam euismod sed. Aenean non eleifend enim, efficitur facilisis sem. Donec quis est nec sem tincidunt vestibulum quis sed ligula. Donec lectus mauris, faucibus sit amet sollicitudin vel, rhoncus quis diam. Phasellus vel ex elementum, condimentum turpis a, volutpat quam. Cras malesuada pretium nisl, eu congue ipsum iaculis sit amet. Mauris eget imperdiet quam. Morbi porta sit amet nunc vitae placerat. Cras mattis tempus tortor vel gravida. Suspendisse imperdiet in tortor in mollis. Aliquam erat volutpat. Nam eu imperdiet sapien. Nulla venenatis purus eu purus vulputate, eget viverra massa fermentum. In consectetur vehicula purus ut condimentum. Vestibulum in nisi id augue viverra rutrum a in sapien. Phasellus sit amet metus quis ligula malesuada fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus id ultricies odio. Duis ut velit venenatis, scelerisque sapien dapibus, fringilla elit. Nulla id turpis pellentesque, iaculis nisl non, mollis mauris. Suspendisse ultricies, odio at auctor viverra, erat ipsum commodo purus, ac elementum tortor neque sit amet sem. Maecenas aliquet eu ante ut molestie. Vestibulum ut massa nec urna malesuada egestas. Sed non ligula urna. Nam porta et eros vitae dapibus. Praesent pellentesque augue in dui cursus aliquet. Cras id massa elementum, tempus arcu vel, gravida nulla. Duis eu lacus volutpat, vulputate sem ullamcorper, semper sem. Fusce mauris diam, porttitor non quam non, commodo ultricies risus. Mauris nec imperdiet lorem, non volutpat ex. Maecenas bibendum ex sit amet.";
var words = source.split(" ");
var sentences = indexes(words, ".");

sentences.unshift(words[0]);
sentences.pop();

function indexes(source) {
    var output = [];

    for (var i = 0; i < source.length; i++) {
        if (source[i].indexOf(".") !== -1) {
            output.push(source[i + 1]);
        }
    }

    return output;
}

function lorem(wordcount) {
    var random = Math.floor(Math.random() * sentences.length);
    var max = words.length - wordcount;

    if (random > max) {
        lorem(wordcount);
    }

    var start = sentences[random];
    var pos = words.indexOf(start);
    var output = [];

    for (var i = pos; i < pos + wordcount; i++) {
        output.push(words[i]);
    }

    document.write(output.join(" "));
}
<commit_msg>Replace var with const and let<commit_after>const source = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sollicitudin, mi in ultrices tincidunt, nisl libero gravida sem, imperdiet gravida justo turpis vel mi. Morbi consequat gravida ligula, ut lacinia tortor dignissim vel. Nunc quis hendrerit dolor. Pellentesque elit enim, lacinia at tellus eget, lacinia dapibus neque. Pellentesque vitae urna nisi. Aenean a hendrerit augue. Maecenas tellus sem, laoreet id auctor non, vulputate quis sem. Aenean sagittis condimentum arcu non volutpat. Maecenas consequat ante eu quam viverra, et venenatis dui posuere. Quisque et cursus quam. In cursus ante vitae erat blandit, a aliquet risus mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed venenatis feugiat fringilla. Proin et hendrerit dui. Sed aliquam finibus sodales. Etiam at risus sit amet nunc rhoncus maximus. Fusce faucibus luctus leo tincidunt lobortis. Nulla facilisis, nisi sed tincidunt maximus, turpis ligula dignissim lorem, at lacinia metus orci non erat. Fusce in purus porta nulla tristique faucibus pharetra ut diam. Praesent non facilisis libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam tristique non erat et blandit. Praesent aliquet eleifend erat imperdiet tristique. Praesent ac lectus enim. Aliquam erat volutpat. Quisque vulputate mauris id sapien posuere accumsan. Quisque sit amet ligula nec lectus auctor finibus. Aliquam mi felis, faucibus at efficitur et, vestibulum quis ipsum. Nam sem nunc, posuere ac turpis eget, consectetur blandit arcu. Nulla euismod arcu arcu, non ullamcorper felis consectetur vel. Sed consequat lorem in mi mattis, quis volutpat leo congue. Nulla sodales quam sed lobortis dapibus. Nunc lobortis eros ac diam porta, quis auctor justo ornare. Nam tempor lectus erat, quis condimentum nunc iaculis sit amet. Nam quis dolor felis. Nunc pulvinar, nisi sit amet consectetur ullamcorper, ante urna fermentum mi, posuere pharetra quam diam eget lectus. Maecenas nec elementum leo, non ultricies orci. Nulla sem purus, commodo eu sem sit amet, bibendum feugiat ligula. Cras faucibus enim a mi dignissim, non dignissim lacus vehicula. Sed bibendum tortor nec hendrerit fermentum. Nam pulvinar commodo nulla vitae molestie. Sed ultrices tortor et augue eleifend porttitor. Ut hendrerit sagittis arcu in bibendum. Nunc nibh arcu, dapibus eu sapien non, vestibulum fringilla mi. Fusce elementum erat eget sem laoreet tempus. Phasellus tempus in magna ut aliquet. Suspendisse vitae dolor at velit eleifend laoreet. Nulla a turpis turpis. Pellentesque fermentum ipsum dapibus felis mollis ullamcorper. Sed nec sollicitudin leo. Integer vel neque vitae lectus porta luctus et et mi. Proin efficitur ex quam. In bibendum fringilla maximus. Donec viverra tempor posuere. Donec mauris mi, maximus in lectus in, accumsan viverra enim. Cras semper faucibus arcu a mattis. Etiam elit augue, fermentum id est gravida, laoreet faucibus nisi. Mauris semper, nisl vestibulum aliquam pulvinar, mi diam ultricies nisi, id auctor diam arcu id est. Integer a massa pretium, convallis felis at, pharetra lorem. Pellentesque bibendum urna quis tortor blandit luctus. Fusce euismod ex quis tortor mollis iaculis. Vivamus posuere ac sem a condimentum. Duis condimentum dui non metus molestie, eget fringilla ligula egestas. Pellentesque orci erat, vehicula et orci quis, suscipit efficitur purus. Praesent elementum mollis lacus eu luctus. Integer dictum tellus quis dolor maximus ultrices. Cras letius libero eget magna placerat, ut porta diam sodales. Mauris rutrum viverra lorem et interdum. Sed lobortis placerat efficitur. Praesent tortor turpis, facilisis vel est ut, sagittis molestie elit. Nullam sit amet ante eu est fermentum efficitur sit amet nec sapien. Duis at cursus mauris. Vivamus congue arcu metus, ut ornare odio dignissim nec. Vestibulum eu luctus orci. Pellentesque id euismod massa. Nulla tincidunt vitae diam id laoreet. Suspendisse dui dolor, auctor ut purus vel, faucibus cursus leo. Donec auctor, sapien gravida efficitur tincidunt, nunc nibh dictum velit, vel rhoncus eros lacus vitae turpis. Sed arcu turpis, posuere a ligula ut, bibendum tincidunt tortor. Integer ut est sed ante suscipit sodales. Sed quis dolor et massa gravida feugiat. Mauris vehicula ligula sed eleifend bibendum. Praesent viverra mollis neque, rhoncus efficitur nisl porttitor ac. Aliquam id laoreet justo. Suspendisse vitae sodales magna. Sed interdum iaculis dui sed faucibus. Suspendisse et tincidunt arcu. Donec vel rhoncus augue, a letius ex. Nulla sed eros dignissim ante auctor vulputate sed et enim. Cras tincidunt, enim sit amet mollis fermentum, magna lectus volutpat nisi, vitae convallis ipsum elit sed eros. Nullam ac arcu fermentum nisi suscipit interdum. Donec mattis felis id cursus letius. Etiam a scelerisque quam. Aliquam erat volutpat. Nulla urna velit, luctus at rhoncus non, fermentum non erat. Nunc tempus, risus rhoncus hendrerit mattis, mi eros gravida mi, at finibus ante metus a sapien. Cras hendrerit orci eu euismod faucibus. Aliquam finibus urna ipsum, non luctus diam euismod sed. Aenean non eleifend enim, efficitur facilisis sem. Donec quis est nec sem tincidunt vestibulum quis sed ligula. Donec lectus mauris, faucibus sit amet sollicitudin vel, rhoncus quis diam. Phasellus vel ex elementum, condimentum turpis a, volutpat quam. Cras malesuada pretium nisl, eu congue ipsum iaculis sit amet. Mauris eget imperdiet quam. Morbi porta sit amet nunc vitae placerat. Cras mattis tempus tortor vel gravida. Suspendisse imperdiet in tortor in mollis. Aliquam erat volutpat. Nam eu imperdiet sapien. Nulla venenatis purus eu purus vulputate, eget viverra massa fermentum. In consectetur vehicula purus ut condimentum. Vestibulum in nisi id augue viverra rutrum a in sapien. Phasellus sit amet metus quis ligula malesuada fringilla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus id ultricies odio. Duis ut velit venenatis, scelerisque sapien dapibus, fringilla elit. Nulla id turpis pellentesque, iaculis nisl non, mollis mauris. Suspendisse ultricies, odio at auctor viverra, erat ipsum commodo purus, ac elementum tortor neque sit amet sem. Maecenas aliquet eu ante ut molestie. Vestibulum ut massa nec urna malesuada egestas. Sed non ligula urna. Nam porta et eros vitae dapibus. Praesent pellentesque augue in dui cursus aliquet. Cras id massa elementum, tempus arcu vel, gravida nulla. Duis eu lacus volutpat, vulputate sem ullamcorper, semper sem. Fusce mauris diam, porttitor non quam non, commodo ultricies risus. Mauris nec imperdiet lorem, non volutpat ex. Maecenas bibendum ex sit amet.";
const words = source.split(" ");
let sentences = indexes(words, ".");

sentences.unshift(words[0]);
sentences.pop();

function indexes(source) {
    let output = [];

    for (let i = 0; i < source.length; i++) {
        if (source[i].indexOf(".") !== -1) {
            output.push(source[i + 1]);
        }
    }

    return output;
}

function lorem(wordcount) {
    let random = Math.floor(Math.random() * sentences.length);
    let max = words.length - wordcount;

    if (random > max) {
        lorem(wordcount);
    }

    let start = sentences[random];
    let pos = words.indexOf(start);
    let output = [];

    for (let i = pos; i < pos + wordcount; i++) {
        output.push(words[i]);
    }

    document.write(output.join(" "));
}
<|endoftext|>


<commit_before>/*
Flot plugin for adding panning and zooming capabilities to a plot.

The default behaviour is double click and scrollwheel up/down to zoom
in, drag to pan. The plugin defines plot.zoom({ center }),
plot.zoomOut() and plot.pan(offset) so you easily can add custom
controls. It also fires a "plotpan" and "plotzoom" event when
something happens, useful for synchronizing plots.

Options:

  zoom: {
    interactive: false
    trigger: "dblclick" // or "click" for single click
    amount: 1.5         // 2 = 200% (zoom in), 0.5 = 50% (zoom out)
  }

  pan: {
    interactive: false
    cursor: "move"      // CSS mouse cursor value used when dragging, e.g. "pointer"
    frameRate: 20
  }

  xaxis, yaxis, x2axis, y2axis: {
    zoomRange: null  // or [number, number] (min range, max range) or false
    panRange: null   // or [number, number] (min, max) or false
  }

"interactive" enables the built-in drag/click behaviour. If you enable
interactive for pan, then you'll have a basic plot that supports
moving around; the same for zoom.

"amount" specifies the default amount to zoom in (so 1.5 = 150%)
relative to the current viewport.

"cursor" is a standard CSS mouse cursor string used for visual
feedback to the user when dragging.

"frameRate" specifies the maximum number of times per second the plot
will update itself while the user is panning around on it (set to null
to disable intermediate pans, the plot will then not update until the
mouse button is released).

"zoomRange" is the interval in which zooming can happen, e.g. with
zoomRange: [1, 100] the zoom will never scale the axis so that the
difference between min and max is smaller than 1 or larger than 100.
You can set either end to null to ignore, e.g. [1, null]. If you set
zoomRange to false, zooming on that axis will be disabled.

"panRange" confines the panning to stay within a range, e.g. with
panRange: [-10, 20] panning stops at -10 in one end and at 20 in the
other. Either can be null, e.g. [-10, null]. If you set
panRange to false, panning on that axis will be disabled.

Example API usage:

  plot = $.plot(...);

  // zoom default amount in on the pixel (10, 20)
  plot.zoom({ center: { left: 10, top: 20 } });

  // zoom out again
  plot.zoomOut({ center: { left: 10, top: 20 } });

  // zoom 200% in on the pixel (10, 20)
  plot.zoom({ amount: 2, center: { left: 10, top: 20 } });

  // pan 100 pixels to the left and 20 down
  plot.pan({ left: -100, top: 20 })

Here, "center" specifies where the center of the zooming should
happen. Note that this is defined in pixel space, not the space of the
data points (you can use the p2c helpers on the axes in Flot to help
you convert between these).

"amount" is the amount to zoom the viewport relative to the current
range, so 1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is
70% (zoom out). You can set the default in the options.

*/

// First two dependencies, jquery.event.drag.js and
// jquery.mousewheel.js, we put them inline here to save people the
// effort of downloading them.

/*
jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
*/
(function(E){E.fn.drag=function(L,K,J){if(K){this.bind("dragstart",L)}if(J){this.bind("dragend",J)}return !L?this.trigger("drag"):this.bind("drag",K?K:L)};var A=E.event,B=A.special,F=B.drag={not:":input",distance:0,which:1,dragging:false,setup:function(J){J=E.extend({distance:F.distance,which:F.which,not:F.not},J||{});J.distance=I(J.distance);A.add(this,"mousedown",H,J);if(this.attachEvent){this.attachEvent("ondragstart",D)}},teardown:function(){A.remove(this,"mousedown",H);if(this===F.dragging){F.dragging=F.proxy=false}G(this,true);if(this.detachEvent){this.detachEvent("ondragstart",D)}}};B.dragstart=B.dragend={setup:function(){},teardown:function(){}};function H(L){var K=this,J,M=L.data||{};if(M.elem){K=L.dragTarget=M.elem;L.dragProxy=F.proxy||K;L.cursorOffsetX=M.pageX-M.left;L.cursorOffsetY=M.pageY-M.top;L.offsetX=L.pageX-L.cursorOffsetX;L.offsetY=L.pageY-L.cursorOffsetY}else{if(F.dragging||(M.which>0&&L.which!=M.which)||E(L.target).is(M.not)){return }}switch(L.type){case"mousedown":E.extend(M,E(K).offset(),{elem:K,target:L.target,pageX:L.pageX,pageY:L.pageY});A.add(document,"mousemove mouseup",H,M);G(K,false);F.dragging=null;return false;case !F.dragging&&"mousemove":if(I(L.pageX-M.pageX)+I(L.pageY-M.pageY)<M.distance){break}L.target=M.target;J=C(L,"dragstart",K);if(J!==false){F.dragging=K;F.proxy=L.dragProxy=E(J||K)[0]}case"mousemove":if(F.dragging){J=C(L,"drag",K);if(B.drop){B.drop.allowed=(J!==false);B.drop.handler(L)}if(J!==false){break}L.type="mouseup"}case"mouseup":A.remove(document,"mousemove mouseup",H);if(F.dragging){if(B.drop){B.drop.handler(L)}C(L,"dragend",K)}G(K,true);F.dragging=F.proxy=M.elem=false;break}return true}function C(M,K,L){M.type=K;var J=E.event.handle.call(L,M);return J===false?false:J||M.result}function I(J){return Math.pow(J,2)}function D(){return(F.dragging===false)}function G(K,J){if(!K){return }K.unselectable=J?"off":"on";K.onselectstart=function(){return J};if(K.style){K.style.MozUserSelect=J?"":"none"}}})(jQuery);

/* jquery.mousewheel.min.js
 * Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 *
 * Version: 3.0.2
 *
 * Requires: 1.2.2+
 */
(function(c){var a=["DOMMouseScroll","mousewheel"];c.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var d=a.length;d;){this.addEventListener(a[--d],b,false)}}else{this.onmousewheel=b}},teardown:function(){if(this.removeEventListener){for(var d=a.length;d;){this.removeEventListener(a[--d],b,false)}}else{this.onmousewheel=null}}};c.fn.extend({mousewheel:function(d){return d?this.bind("mousewheel",d):this.trigger("mousewheel")},unmousewheel:function(d){return this.unbind("mousewheel",d)}});function b(f){var d=[].slice.call(arguments,1),g=0,e=true;f=c.event.fix(f||window.event);f.type="mousewheel";if(f.wheelDelta){g=f.wheelDelta/120}if(f.detail){g=-f.detail/3}d.unshift(f,g);return c.event.handle.apply(this,d)}})(jQuery);

(function ($) {
    var options = {
        xaxis: {
            zoomRange: null, // or [number, number] (min range, max range)
            panRange: null // or [number, number] (min, max)
        },
        zoom: {
            interactive: false,
            trigger: "dblclick", // or "click" for single click
            amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out)
        },
        pan: {
            interactive: false,
            cursor: "move",
            frameRate: 20
        }
    };

    function init(plot) {
        function onZoomClick(e, zoomOut) {
            var c = plot.offset();
            c.left = e.pageX - c.left;
            c.top = e.pageY - c.top;
            if (zoomOut)
                plot.zoomOut({ center: c });
            else
                plot.zoom({ center: c });
        }

        function onMouseWheel(e, delta) {
            onZoomClick(e, delta < 0);
            return false;
        }

        var prevCursor = 'default', prevPageX = 0, prevPageY = 0,
            panTimeout = null;

        function onDragStart(e) {
            if (e.which != 1)  // only accept left-click
                return false;
            var c = plot.getPlaceholder().css('cursor');
            if (c)
                prevCursor = c;
            plot.getPlaceholder().css('cursor', plot.getOptions().pan.cursor);
            prevPageX = e.pageX;
            prevPageY = e.pageY;
        }

        function onDrag(e) {
            var frameRate = plot.getOptions().pan.frameRate;
            if (panTimeout || !frameRate)
                return;

            panTimeout = setTimeout(function () {
                plot.pan({ left: prevPageX - e.pageX,
                           top: prevPageY - e.pageY });
                prevPageX = e.pageX;
                prevPageY = e.pageY;

                panTimeout = null;
            }, 1 / frameRate * 1000);
        }

        function onDragEnd(e) {
            if (panTimeout) {
                clearTimeout(panTimeout);
                panTimeout = null;
            }

            plot.getPlaceholder().css('cursor', prevCursor);
            plot.pan({ left: prevPageX - e.pageX,
                       top: prevPageY - e.pageY });
        }

        function bindEvents(plot, eventHolder) {
            var o = plot.getOptions();
            if (o.zoom.interactive) {
                eventHolder[o.zoom.trigger](onZoomClick);
                eventHolder.mousewheel(onMouseWheel);
            }

            if (o.pan.interactive) {
                eventHolder.bind("dragstart", { distance: 10 }, onDragStart);
                eventHolder.bind("drag", onDrag);
                eventHolder.bind("dragend", onDragEnd);
            }
        }

        plot.zoomOut = function (args) {
            if (!args)
                args = {};

            if (!args.amount)
                args.amount = plot.getOptions().zoom.amount

            args.amount = 1 / args.amount;
            plot.zoom(args);
        }

        plot.zoom = function (args) {
            if (!args)
                args = {};

            var c = args.center,
                amount = args.amount || plot.getOptions().zoom.amount,
                w = plot.width(), h = plot.height();

            if (!c)
                c = { left: w / 2, top: h / 2 };

            var xf = c.left / w,
                yf = c.top / h,
                minmax = {
                    x: {
                        min: c.left - xf * w / amount,
                        max: c.left + (1 - xf) * w / amount
                    },
                    y: {
                        min: c.top - yf * h / amount,
                        max: c.top + (1 - yf) * h / amount
                    }
                };

            $.each(plot.getAxes(), function(_, axis) {
                var opts = axis.options,
                    min = minmax[axis.direction].min,
                    max = minmax[axis.direction].max,
                    zr = opts.zoomRange;

                if (zr === false) // no zooming on this axis
                    return;

                min = axis.c2p(min);
                max = axis.c2p(max);
                if (min > max) {
                    // make sure min < max
                    var tmp = min;
                    min = max;
                    max = tmp;
                }

                var range = max - min;
                if (zr &&
                    ((zr[0] != null && range < zr[0]) ||
                     (zr[1] != null && range > zr[1])))
                    return;

                opts.min = min;
                opts.max = max;
            });

            plot.setupGrid();
            plot.draw();

            if (!args.preventEvent)
                plot.getPlaceholder().trigger("plotzoom", [ plot, args ]);
        }

        plot.pan = function (args) {
            var delta = {
                x: +args.left,
                y: +args.top
            };

            if (isNaN(delta.x))
                delta.x = 0;
            if (isNaN(delta.y))
                delta.y = 0;

            $.each(plot.getAxes(), function (_, axis) {
                var opts = axis.options,
                    min, max, d = delta[axis.direction];

                min = axis.c2p(axis.p2c(axis.min) + d),
                max = axis.c2p(axis.p2c(axis.max) + d);

                var pr = opts.panRange;
                if (pr === false) // no panning on this axis
                    return;

                if (pr) {
                    // check whether we hit the wall
                    if (pr[0] != null && pr[0] > min) {
                        d = pr[0] - min;
                        min += d;
                        max += d;
                    }

                    if (pr[1] != null && pr[1] < max) {
                        d = pr[1] - max;
                        min += d;
                        max += d;
                    }
                }

                opts.min = min;
                opts.max = max;
            });

            plot.setupGrid();
            plot.draw();

            if (!args.preventEvent)
                plot.getPlaceholder().trigger("plotpan", [ plot ]);
        }

        function shutdown(plot, eventHolder) {
            eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick);
            eventHolder.unbind("mousewheel", onMouseWheel);
            eventHolder.unbind("dragstart", onDragStart);
            eventHolder.unbind("drag", onDrag);
            eventHolder.unbind("dragend", onDragEnd);
            if (panTimeout)
                clearTimeout(panTimeout);
        }

        plot.hooks.bindEvents.push(bindEvents);
        plot.hooks.shutdown.push(shutdown);
    }

    $.plot.plugins.push({
        init: init,
        options: options,
        name: 'navigate',
        version: '1.3'
    });
})(jQuery);
<commit_msg>Fixed overrun panRange while zooming<commit_after>/*
Flot plugin for adding panning and zooming capabilities to a plot.

The default behaviour is double click and scrollwheel up/down to zoom
in, drag to pan. The plugin defines plot.zoom({ center }),
plot.zoomOut() and plot.pan(offset) so you easily can add custom
controls. It also fires a "plotpan" and "plotzoom" event when
something happens, useful for synchronizing plots.

Options:

  zoom: {
    interactive: false
    trigger: "dblclick" // or "click" for single click
    amount: 1.5         // 2 = 200% (zoom in), 0.5 = 50% (zoom out)
  }

  pan: {
    interactive: false
    cursor: "move"      // CSS mouse cursor value used when dragging, e.g. "pointer"
    frameRate: 20
  }

  xaxis, yaxis, x2axis, y2axis: {
    zoomRange: null  // or [number, number] (min range, max range) or false
    panRange: null   // or [number, number] (min, max) or false
  }

"interactive" enables the built-in drag/click behaviour. If you enable
interactive for pan, then you'll have a basic plot that supports
moving around; the same for zoom.

"amount" specifies the default amount to zoom in (so 1.5 = 150%)
relative to the current viewport.

"cursor" is a standard CSS mouse cursor string used for visual
feedback to the user when dragging.

"frameRate" specifies the maximum number of times per second the plot
will update itself while the user is panning around on it (set to null
to disable intermediate pans, the plot will then not update until the
mouse button is released).

"zoomRange" is the interval in which zooming can happen, e.g. with
zoomRange: [1, 100] the zoom will never scale the axis so that the
difference between min and max is smaller than 1 or larger than 100.
You can set either end to null to ignore, e.g. [1, null]. If you set
zoomRange to false, zooming on that axis will be disabled.

"panRange" confines the panning to stay within a range, e.g. with
panRange: [-10, 20] panning stops at -10 in one end and at 20 in the
other. Either can be null, e.g. [-10, null]. If you set
panRange to false, panning on that axis will be disabled.

Example API usage:

  plot = $.plot(...);

  // zoom default amount in on the pixel (10, 20)
  plot.zoom({ center: { left: 10, top: 20 } });

  // zoom out again
  plot.zoomOut({ center: { left: 10, top: 20 } });

  // zoom 200% in on the pixel (10, 20)
  plot.zoom({ amount: 2, center: { left: 10, top: 20 } });

  // pan 100 pixels to the left and 20 down
  plot.pan({ left: -100, top: 20 })

Here, "center" specifies where the center of the zooming should
happen. Note that this is defined in pixel space, not the space of the
data points (you can use the p2c helpers on the axes in Flot to help
you convert between these).

"amount" is the amount to zoom the viewport relative to the current
range, so 1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is
70% (zoom out). You can set the default in the options.

*/

// First two dependencies, jquery.event.drag.js and
// jquery.mousewheel.js, we put them inline here to save people the
// effort of downloading them.

/*
jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
*/
(function(E){E.fn.drag=function(L,K,J){if(K){this.bind("dragstart",L)}if(J){this.bind("dragend",J)}return !L?this.trigger("drag"):this.bind("drag",K?K:L)};var A=E.event,B=A.special,F=B.drag={not:":input",distance:0,which:1,dragging:false,setup:function(J){J=E.extend({distance:F.distance,which:F.which,not:F.not},J||{});J.distance=I(J.distance);A.add(this,"mousedown",H,J);if(this.attachEvent){this.attachEvent("ondragstart",D)}},teardown:function(){A.remove(this,"mousedown",H);if(this===F.dragging){F.dragging=F.proxy=false}G(this,true);if(this.detachEvent){this.detachEvent("ondragstart",D)}}};B.dragstart=B.dragend={setup:function(){},teardown:function(){}};function H(L){var K=this,J,M=L.data||{};if(M.elem){K=L.dragTarget=M.elem;L.dragProxy=F.proxy||K;L.cursorOffsetX=M.pageX-M.left;L.cursorOffsetY=M.pageY-M.top;L.offsetX=L.pageX-L.cursorOffsetX;L.offsetY=L.pageY-L.cursorOffsetY}else{if(F.dragging||(M.which>0&&L.which!=M.which)||E(L.target).is(M.not)){return }}switch(L.type){case"mousedown":E.extend(M,E(K).offset(),{elem:K,target:L.target,pageX:L.pageX,pageY:L.pageY});A.add(document,"mousemove mouseup",H,M);G(K,false);F.dragging=null;return false;case !F.dragging&&"mousemove":if(I(L.pageX-M.pageX)+I(L.pageY-M.pageY)<M.distance){break}L.target=M.target;J=C(L,"dragstart",K);if(J!==false){F.dragging=K;F.proxy=L.dragProxy=E(J||K)[0]}case"mousemove":if(F.dragging){J=C(L,"drag",K);if(B.drop){B.drop.allowed=(J!==false);B.drop.handler(L)}if(J!==false){break}L.type="mouseup"}case"mouseup":A.remove(document,"mousemove mouseup",H);if(F.dragging){if(B.drop){B.drop.handler(L)}C(L,"dragend",K)}G(K,true);F.dragging=F.proxy=M.elem=false;break}return true}function C(M,K,L){M.type=K;var J=E.event.handle.call(L,M);return J===false?false:J||M.result}function I(J){return Math.pow(J,2)}function D(){return(F.dragging===false)}function G(K,J){if(!K){return }K.unselectable=J?"off":"on";K.onselectstart=function(){return J};if(K.style){K.style.MozUserSelect=J?"":"none"}}})(jQuery);

/* jquery.mousewheel.min.js
 * Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 *
 * Version: 3.0.2
 *
 * Requires: 1.2.2+
 */
(function(c){var a=["DOMMouseScroll","mousewheel"];c.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var d=a.length;d;){this.addEventListener(a[--d],b,false)}}else{this.onmousewheel=b}},teardown:function(){if(this.removeEventListener){for(var d=a.length;d;){this.removeEventListener(a[--d],b,false)}}else{this.onmousewheel=null}}};c.fn.extend({mousewheel:function(d){return d?this.bind("mousewheel",d):this.trigger("mousewheel")},unmousewheel:function(d){return this.unbind("mousewheel",d)}});function b(f){var d=[].slice.call(arguments,1),g=0,e=true;f=c.event.fix(f||window.event);f.type="mousewheel";if(f.wheelDelta){g=f.wheelDelta/120}if(f.detail){g=-f.detail/3}d.unshift(f,g);return c.event.handle.apply(this,d)}})(jQuery);

(function ($) {
    var options = {
        xaxis: {
            zoomRange: null, // or [number, number] (min range, max range)
            panRange: null // or [number, number] (min, max)
        },
        zoom: {
            interactive: false,
            trigger: "dblclick", // or "click" for single click
            amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out)
        },
        pan: {
            interactive: false,
            cursor: "move",
            frameRate: 20
        }
    };

    function init(plot) {
        function onZoomClick(e, zoomOut) {
            var c = plot.offset();
            c.left = e.pageX - c.left;
            c.top = e.pageY - c.top;
            if (zoomOut)
                plot.zoomOut({ center: c });
            else
                plot.zoom({ center: c });
        }

        function onMouseWheel(e, delta) {
            onZoomClick(e, delta < 0);
            return false;
        }

        var prevCursor = 'default', prevPageX = 0, prevPageY = 0,
            panTimeout = null;

        function onDragStart(e) {
            if (e.which != 1)  // only accept left-click
                return false;
            var c = plot.getPlaceholder().css('cursor');
            if (c)
                prevCursor = c;
            plot.getPlaceholder().css('cursor', plot.getOptions().pan.cursor);
            prevPageX = e.pageX;
            prevPageY = e.pageY;
        }

        function onDrag(e) {
            var frameRate = plot.getOptions().pan.frameRate;
            if (panTimeout || !frameRate)
                return;

            panTimeout = setTimeout(function () {
                plot.pan({ left: prevPageX - e.pageX,
                           top: prevPageY - e.pageY });
                prevPageX = e.pageX;
                prevPageY = e.pageY;

                panTimeout = null;
            }, 1 / frameRate * 1000);
        }

        function onDragEnd(e) {
            if (panTimeout) {
                clearTimeout(panTimeout);
                panTimeout = null;
            }

            plot.getPlaceholder().css('cursor', prevCursor);
            plot.pan({ left: prevPageX - e.pageX,
                       top: prevPageY - e.pageY });
        }

        function bindEvents(plot, eventHolder) {
            var o = plot.getOptions();
            if (o.zoom.interactive) {
                eventHolder[o.zoom.trigger](onZoomClick);
                eventHolder.mousewheel(onMouseWheel);
            }

            if (o.pan.interactive) {
                eventHolder.bind("dragstart", { distance: 10 }, onDragStart);
                eventHolder.bind("drag", onDrag);
                eventHolder.bind("dragend", onDragEnd);
            }
        }

        plot.zoomOut = function (args) {
            if (!args)
                args = {};

            if (!args.amount)
                args.amount = plot.getOptions().zoom.amount

            args.amount = 1 / args.amount;
            plot.zoom(args);
        }

        plot.zoom = function (args) {
            if (!args)
                args = {};

            var c = args.center,
                amount = args.amount || plot.getOptions().zoom.amount,
                w = plot.width(), h = plot.height();

            if (!c)
                c = { left: w / 2, top: h / 2 };

            var xf = c.left / w,
                yf = c.top / h,
                minmax = {
                    x: {
                        min: c.left - xf * w / amount,
                        max: c.left + (1 - xf) * w / amount
                    },
                    y: {
                        min: c.top - yf * h / amount,
                        max: c.top + (1 - yf) * h / amount
                    }
                };

            $.each(plot.getAxes(), function(_, axis) {
                var opts = axis.options,
                    min = minmax[axis.direction].min,
                    max = minmax[axis.direction].max,
                    zr = opts.zoomRange,
                    pr = opts.panRange;

                if (zr === false) // no zooming on this axis
                    return;

                min = axis.c2p(min);
                max = axis.c2p(max);
                if (min > max) {
                    // make sure min < max
                    var tmp = min;
                    min = max;
                    max = tmp;
                }

                //Check that we are in panRange
                if (pr) {
                    if (pr[0] != null && min < pr[0]) {
                        min = pr[0];
                    }
                    if (pr[1] != null && max > pr[1]) {
                        max = pr[1];
                    }
                }

                var range = max - min;
                if (zr &&
                    ((zr[0] != null && range < zr[0]) ||
                     (zr[1] != null && range > zr[1])))
                    return;

                opts.min = min;
                opts.max = max;
            });

            plot.setupGrid();
            plot.draw();

            if (!args.preventEvent)
                plot.getPlaceholder().trigger("plotzoom", [ plot, args ]);
        }

        plot.pan = function (args) {
            var delta = {
                x: +args.left,
                y: +args.top
            };

            if (isNaN(delta.x))
                delta.x = 0;
            if (isNaN(delta.y))
                delta.y = 0;

            $.each(plot.getAxes(), function (_, axis) {
                var opts = axis.options,
                    min, max, d = delta[axis.direction];

                min = axis.c2p(axis.p2c(axis.min) + d),
                max = axis.c2p(axis.p2c(axis.max) + d);

                var pr = opts.panRange;
                if (pr === false) // no panning on this axis
                    return;

                if (pr) {
                    // check whether we hit the wall
                    if (pr[0] != null && pr[0] > min) {
                        d = pr[0] - min;
                        min += d;
                        max += d;
                    }

                    if (pr[1] != null && pr[1] < max) {
                        d = pr[1] - max;
                        min += d;
                        max += d;
                    }
                }

                opts.min = min;
                opts.max = max;
            });

            plot.setupGrid();
            plot.draw();

            if (!args.preventEvent)
                plot.getPlaceholder().trigger("plotpan", [ plot ]);
        }

        function shutdown(plot, eventHolder) {
            eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick);
            eventHolder.unbind("mousewheel", onMouseWheel);
            eventHolder.unbind("dragstart", onDragStart);
            eventHolder.unbind("drag", onDrag);
            eventHolder.unbind("dragend", onDragEnd);
            if (panTimeout)
                clearTimeout(panTimeout);
        }

        plot.hooks.bindEvents.push(bindEvents);
        plot.hooks.shutdown.push(shutdown);
    }

    $.plot.plugins.push({
        init: init,
        options: options,
        name: 'navigate',
        version: '1.3'
    });
})(jQuery);
<|endoftext|>


<commit_before>// Copyright 2013-2015, University of Colorado Boulder

/**
 * Handles a visual Canvas layer of drawables.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */

define( function( require ) {
  'use strict';

  var inherit = require( 'PHET_CORE/inherit' );
  var Poolable = require( 'PHET_CORE/Poolable' );
  var cleanArray = require( 'PHET_CORE/cleanArray' );
  var Vector2 = require( 'DOT/Vector2' );
  var scenery = require( 'SCENERY/scenery' );
  var FittedBlock = require( 'SCENERY/display/FittedBlock' );
  var CanvasContextWrapper = require( 'SCENERY/util/CanvasContextWrapper' );
  var Renderer = require( 'SCENERY/display/Renderer' );
  var Util = require( 'SCENERY/util/Util' );

  function CanvasBlock( display, renderer, transformRootInstance, filterRootInstance ) {
    this.initialize( display, renderer, transformRootInstance, filterRootInstance );
  }

  scenery.register( 'CanvasBlock', CanvasBlock );

  inherit( FittedBlock, CanvasBlock, {
    initialize: function( display, renderer, transformRootInstance, filterRootInstance ) {
      this.initializeFittedBlock( display, renderer, transformRootInstance, FittedBlock.COMMON_ANCESTOR );

      this.filterRootInstance = filterRootInstance;

      this.dirtyDrawables = cleanArray( this.dirtyDrawables );

      if ( !this.domElement ) {
        //OHTWO TODO: support tiled Canvas handling (will need to wrap then in a div, or something)
        this.canvas = document.createElement( 'canvas' );
        this.canvas.style.position = 'absolute';
        this.canvas.style.left = '0';
        this.canvas.style.top = '0';
        this.canvas.style.pointerEvents = 'none';

        // unique ID so that we can support rasterization with Display.foreignObjectRasterization
        this.canvasId = this.canvas.id = 'scenery-canvas' + this.id;

        this.context = this.canvas.getContext( '2d' );

        // workaround for Chrome (WebKit) miterLimit bug: https://bugs.webkit.org/show_bug.cgi?id=108763
        this.context.miterLimit = 20;
        this.context.miterLimit = 10;

        this.wrapper = new CanvasContextWrapper( this.canvas, this.context );

        this.domElement = this.canvas;
      }

      // reset any fit transforms that were applied
      Util.prepareForTransform( this.canvas, this.forceAcceleration );
      Util.unsetTransform( this.canvas ); // clear out any transforms that could have been previously applied

      this.canvasDrawOffset = new Vector2();

      // store our backing scale so we don't have to look it up while fitting
      this.backingScale = ( renderer & Renderer.bitmaskCanvasLowResolution ) ? 1 : scenery.Util.backingScale( this.context );

      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( 'initialized #' + this.id );
      // TODO: dirty list of nodes (each should go dirty only once, easier than scanning all?)

      return this;
    },

    setSizeFullDisplay: function() {
      var size = this.display.getSize();
      this.canvas.width = size.width * this.backingScale;
      this.canvas.height = size.height * this.backingScale;
      this.canvas.style.width = size.width + 'px';
      this.canvas.style.height = size.height + 'px';
      this.wrapper.resetStyles();
      this.canvasDrawOffset.setXY( 0, 0 );
      Util.unsetTransform( this.canvas );
    },

    setSizeFitBounds: function() {
      var x = this.fitBounds.minX;
      var y = this.fitBounds.minY;
      this.canvasDrawOffset.setXY( -x, -y ); // subtract off so we have a tight fit
      //OHTWO TODO PERFORMANCE: see if we can get a speedup by putting the backing scale in our transform instead of with CSS?
      Util.setTransform( 'matrix(1,0,0,1,' + x + ',' + y + ')', this.canvas, this.forceAcceleration ); // reapply the translation as a CSS transform
      this.canvas.width = this.fitBounds.width * this.backingScale;
      this.canvas.height = this.fitBounds.height * this.backingScale;
      this.canvas.style.width = this.fitBounds.width + 'px';
      this.canvas.style.height = this.fitBounds.height + 'px';
      this.wrapper.resetStyles();
    },

    update: function() {
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( 'update #' + this.id );
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.push();

      if ( this.dirty && !this.disposed ) {
        this.dirty = false;

        while ( this.dirtyDrawables.length ) {
          this.dirtyDrawables.pop().update();
        }

        // udpate the fit BEFORE drawing, since it may change our offset
        this.updateFit();

        // for now, clear everything!
        this.context.setTransform( 1, 0, 0, 1, 0, 0 ); // identity
        this.context.clearRect( 0, 0, this.canvas.width, this.canvas.height ); // clear everything

        //OHTWO TODO: clipping handling!
        if ( this.filterRootInstance.node.clipArea ) {
          this.context.save();

          this.temporaryRecursiveClip( this.filterRootInstance );
        }

        //OHTWO TODO: PERFORMANCE: create an array for faster drawable iteration (this is probably a hellish memory access pattern)
        //OHTWO TODO: why is "drawable !== null" check needed
        for ( var drawable = this.firstDrawable; drawable !== null; drawable = drawable.nextDrawable ) {
          this.renderDrawable( drawable );
          if ( drawable === this.lastDrawable ) { break; }
        }

        if ( this.filterRootInstance.node.clipArea ) {
          this.context.restore();
          this.wrapper.resetStyles();
        }
      }

      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.pop();
    },

    //OHTWO TODO: rework and do proper clipping support
    temporaryRecursiveClip: function( instance ) {
      if ( instance.parent ) {
        this.temporaryRecursiveClip( instance.parent );
      }
      if ( instance.node.clipArea ) {
        //OHTWO TODO: reduce duplication here
        this.context.setTransform( this.backingScale, 0, 0, this.backingScale, this.canvasDrawOffset.x * this.backingScale, this.canvasDrawOffset.y * this.backingScale );
        instance.relativeTransform.matrix.canvasAppendTransform( this.context );

        // do the clipping
        this.context.beginPath();
        instance.node.clipArea.writeToContext( this.context );
        this.context.clip();
      }
    },

    renderDrawable: function( drawable ) {
      // do not paint invisible drawables
      if ( !drawable.visible ) {
        return;
      }

      // we're directly accessing the relative transform below, so we need to ensure that it is up-to-date
      assert && assert( drawable.instance.relativeTransform.isValidationNotNeeded() );

      var matrix = drawable.instance.relativeTransform.matrix;

      // set the correct (relative to the transform root) transform up, instead of walking the hierarchy (for now)
      //OHTWO TODO: should we start premultiplying these matrices to remove this bottleneck?
      this.context.setTransform( this.backingScale, 0, 0, this.backingScale, this.canvasDrawOffset.x * this.backingScale, this.canvasDrawOffset.y * this.backingScale );
      if ( drawable.instance !== this.transformRootInstance ) {
        matrix.canvasAppendTransform( this.context );
      }

      // paint using its local coordinate frame
      drawable.paintCanvas( this.wrapper, drawable.instance.node );
    },

    dispose: function() {
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( 'dispose #' + this.id );

      // clear references
      this.transformRootInstance = null;
      cleanArray( this.dirtyDrawables );

      // minimize memory exposure of the backing raster
      this.canvas.width = 0;
      this.canvas.height = 0;

      FittedBlock.prototype.dispose.call( this );
    },

    markDirtyDrawable: function( drawable ) {
      sceneryLog && sceneryLog.dirty && sceneryLog.dirty( 'markDirtyDrawable on CanvasBlock#' + this.id + ' with ' + drawable.toString() );

      assert && assert( drawable );

      if ( assert ) {
        // Catch infinite loops
        this.display.ensureNotPainting();
      }

      // TODO: instance check to see if it is a canvas cache (usually we don't need to call update on our drawables)
      this.dirtyDrawables.push( drawable );
      this.markDirty();
    },

    addDrawable: function( drawable ) {
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( '#' + this.id + '.addDrawable ' + drawable.toString() );

      FittedBlock.prototype.addDrawable.call( this, drawable );
    },

    removeDrawable: function( drawable ) {
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( '#' + this.id + '.removeDrawable ' + drawable.toString() );

      FittedBlock.prototype.removeDrawable.call( this, drawable );
    },

    onIntervalChange: function( firstDrawable, lastDrawable ) {
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( '#' + this.id + '.onIntervalChange ' + firstDrawable.toString() + ' to ' + lastDrawable.toString() );

      FittedBlock.prototype.onIntervalChange.call( this, firstDrawable, lastDrawable );
    },

    onPotentiallyMovedDrawable: function( drawable ) {
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( '#' + this.id + '.onPotentiallyMovedDrawable ' + drawable.toString() );
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.push();

      assert && assert( drawable.parentDrawable === this );

      // For now, mark it as dirty so that we redraw anything containing it. In the future, we could have more advanced
      // behavior that figures out the intersection-region for what was moved and what it was moved past, but that's
      // a harder problem.
      drawable.markDirty();

      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.pop();
    },

    toString: function() {
      return 'CanvasBlock#' + this.id + '-' + FittedBlock.fitString[ this.fit ];
    }
  } );

  Poolable.mixin( CanvasBlock, {
    constructorDuplicateFactory: function( pool ) {
      return function( display, renderer, transformRootInstance, filterRootInstance ) {
        if ( pool.length ) {
          sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( 'new from pool' );
          return pool.pop().initialize( display, renderer, transformRootInstance, filterRootInstance );
        }
        else {
          sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( 'new from constructor' );
          return new CanvasBlock( display, renderer, transformRootInstance, filterRootInstance );
        }
      };
    }
  } );

  return CanvasBlock;
} );
<commit_msg>Patch for clipping dirty updates, fixes https://github.com/phetsims/scenery/issues/521<commit_after>// Copyright 2013-2015, University of Colorado Boulder

/**
 * Handles a visual Canvas layer of drawables.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */

define( function( require ) {
  'use strict';

  var inherit = require( 'PHET_CORE/inherit' );
  var Poolable = require( 'PHET_CORE/Poolable' );
  var cleanArray = require( 'PHET_CORE/cleanArray' );
  var Vector2 = require( 'DOT/Vector2' );
  var scenery = require( 'SCENERY/scenery' );
  var FittedBlock = require( 'SCENERY/display/FittedBlock' );
  var CanvasContextWrapper = require( 'SCENERY/util/CanvasContextWrapper' );
  var Renderer = require( 'SCENERY/display/Renderer' );
  var Util = require( 'SCENERY/util/Util' );

  function CanvasBlock( display, renderer, transformRootInstance, filterRootInstance ) {
    this.initialize( display, renderer, transformRootInstance, filterRootInstance );
  }

  scenery.register( 'CanvasBlock', CanvasBlock );

  inherit( FittedBlock, CanvasBlock, {
    initialize: function( display, renderer, transformRootInstance, filterRootInstance ) {
      this.initializeFittedBlock( display, renderer, transformRootInstance, FittedBlock.COMMON_ANCESTOR );

      this.filterRootInstance = filterRootInstance;

      this.dirtyDrawables = cleanArray( this.dirtyDrawables );

      if ( !this.domElement ) {
        //OHTWO TODO: support tiled Canvas handling (will need to wrap then in a div, or something)
        this.canvas = document.createElement( 'canvas' );
        this.canvas.style.position = 'absolute';
        this.canvas.style.left = '0';
        this.canvas.style.top = '0';
        this.canvas.style.pointerEvents = 'none';

        // unique ID so that we can support rasterization with Display.foreignObjectRasterization
        this.canvasId = this.canvas.id = 'scenery-canvas' + this.id;

        this.context = this.canvas.getContext( '2d' );

        // workaround for Chrome (WebKit) miterLimit bug: https://bugs.webkit.org/show_bug.cgi?id=108763
        this.context.miterLimit = 20;
        this.context.miterLimit = 10;

        this.wrapper = new CanvasContextWrapper( this.canvas, this.context );

        this.domElement = this.canvas;
      }

      // reset any fit transforms that were applied
      Util.prepareForTransform( this.canvas, this.forceAcceleration );
      Util.unsetTransform( this.canvas ); // clear out any transforms that could have been previously applied

      this.canvasDrawOffset = new Vector2();

      // store our backing scale so we don't have to look it up while fitting
      this.backingScale = ( renderer & Renderer.bitmaskCanvasLowResolution ) ? 1 : scenery.Util.backingScale( this.context );

      this.clipDirtyListener = this.markDirty.bind( this );
      this.filterRootInstance.node.onStatic( 'clip', this.clipDirtyListener );

      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( 'initialized #' + this.id );
      // TODO: dirty list of nodes (each should go dirty only once, easier than scanning all?)

      return this;
    },

    setSizeFullDisplay: function() {
      var size = this.display.getSize();
      this.canvas.width = size.width * this.backingScale;
      this.canvas.height = size.height * this.backingScale;
      this.canvas.style.width = size.width + 'px';
      this.canvas.style.height = size.height + 'px';
      this.wrapper.resetStyles();
      this.canvasDrawOffset.setXY( 0, 0 );
      Util.unsetTransform( this.canvas );
    },

    setSizeFitBounds: function() {
      var x = this.fitBounds.minX;
      var y = this.fitBounds.minY;
      this.canvasDrawOffset.setXY( -x, -y ); // subtract off so we have a tight fit
      //OHTWO TODO PERFORMANCE: see if we can get a speedup by putting the backing scale in our transform instead of with CSS?
      Util.setTransform( 'matrix(1,0,0,1,' + x + ',' + y + ')', this.canvas, this.forceAcceleration ); // reapply the translation as a CSS transform
      this.canvas.width = this.fitBounds.width * this.backingScale;
      this.canvas.height = this.fitBounds.height * this.backingScale;
      this.canvas.style.width = this.fitBounds.width + 'px';
      this.canvas.style.height = this.fitBounds.height + 'px';
      this.wrapper.resetStyles();
    },

    update: function() {
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( 'update #' + this.id );
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.push();

      if ( this.dirty && !this.disposed ) {
        this.dirty = false;

        while ( this.dirtyDrawables.length ) {
          this.dirtyDrawables.pop().update();
        }

        // udpate the fit BEFORE drawing, since it may change our offset
        this.updateFit();

        // for now, clear everything!
        this.context.setTransform( 1, 0, 0, 1, 0, 0 ); // identity
        this.context.clearRect( 0, 0, this.canvas.width, this.canvas.height ); // clear everything

        //OHTWO TODO: clipping handling!
        if ( this.filterRootInstance.node.clipArea ) {
          this.context.save();

          this.temporaryRecursiveClip( this.filterRootInstance );
        }

        //OHTWO TODO: PERFORMANCE: create an array for faster drawable iteration (this is probably a hellish memory access pattern)
        //OHTWO TODO: why is "drawable !== null" check needed
        for ( var drawable = this.firstDrawable; drawable !== null; drawable = drawable.nextDrawable ) {
          this.renderDrawable( drawable );
          if ( drawable === this.lastDrawable ) { break; }
        }

        if ( this.filterRootInstance.node.clipArea ) {
          this.context.restore();
          this.wrapper.resetStyles();
        }
      }

      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.pop();
    },

    //OHTWO TODO: rework and do proper clipping support
    temporaryRecursiveClip: function( instance ) {
      if ( instance.parent ) {
        this.temporaryRecursiveClip( instance.parent );
      }
      if ( instance.node.clipArea ) {
        //OHTWO TODO: reduce duplication here
        this.context.setTransform( this.backingScale, 0, 0, this.backingScale, this.canvasDrawOffset.x * this.backingScale, this.canvasDrawOffset.y * this.backingScale );
        instance.relativeTransform.matrix.canvasAppendTransform( this.context );

        // do the clipping
        this.context.beginPath();
        instance.node.clipArea.writeToContext( this.context );
        this.context.clip();
      }
    },

    renderDrawable: function( drawable ) {
      // do not paint invisible drawables
      if ( !drawable.visible ) {
        return;
      }

      // we're directly accessing the relative transform below, so we need to ensure that it is up-to-date
      assert && assert( drawable.instance.relativeTransform.isValidationNotNeeded() );

      var matrix = drawable.instance.relativeTransform.matrix;

      // set the correct (relative to the transform root) transform up, instead of walking the hierarchy (for now)
      //OHTWO TODO: should we start premultiplying these matrices to remove this bottleneck?
      this.context.setTransform( this.backingScale, 0, 0, this.backingScale, this.canvasDrawOffset.x * this.backingScale, this.canvasDrawOffset.y * this.backingScale );
      if ( drawable.instance !== this.transformRootInstance ) {
        matrix.canvasAppendTransform( this.context );
      }

      // paint using its local coordinate frame
      drawable.paintCanvas( this.wrapper, drawable.instance.node );
    },

    dispose: function() {
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( 'dispose #' + this.id );

      this.filterRootInstance.node.offStatic( 'clip', this.clipDirtyListener );

      // clear references
      this.transformRootInstance = null;
      cleanArray( this.dirtyDrawables );

      // minimize memory exposure of the backing raster
      this.canvas.width = 0;
      this.canvas.height = 0;

      FittedBlock.prototype.dispose.call( this );
    },

    markDirtyDrawable: function( drawable ) {
      sceneryLog && sceneryLog.dirty && sceneryLog.dirty( 'markDirtyDrawable on CanvasBlock#' + this.id + ' with ' + drawable.toString() );

      assert && assert( drawable );

      if ( assert ) {
        // Catch infinite loops
        this.display.ensureNotPainting();
      }

      // TODO: instance check to see if it is a canvas cache (usually we don't need to call update on our drawables)
      this.dirtyDrawables.push( drawable );
      this.markDirty();
    },

    addDrawable: function( drawable ) {
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( '#' + this.id + '.addDrawable ' + drawable.toString() );

      FittedBlock.prototype.addDrawable.call( this, drawable );
    },

    removeDrawable: function( drawable ) {
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( '#' + this.id + '.removeDrawable ' + drawable.toString() );

      FittedBlock.prototype.removeDrawable.call( this, drawable );
    },

    onIntervalChange: function( firstDrawable, lastDrawable ) {
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( '#' + this.id + '.onIntervalChange ' + firstDrawable.toString() + ' to ' + lastDrawable.toString() );

      FittedBlock.prototype.onIntervalChange.call( this, firstDrawable, lastDrawable );
    },

    onPotentiallyMovedDrawable: function( drawable ) {
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( '#' + this.id + '.onPotentiallyMovedDrawable ' + drawable.toString() );
      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.push();

      assert && assert( drawable.parentDrawable === this );

      // For now, mark it as dirty so that we redraw anything containing it. In the future, we could have more advanced
      // behavior that figures out the intersection-region for what was moved and what it was moved past, but that's
      // a harder problem.
      drawable.markDirty();

      sceneryLog && sceneryLog.CanvasBlock && sceneryLog.pop();
    },

    toString: function() {
      return 'CanvasBlock#' + this.id + '-' + FittedBlock.fitString[ this.fit ];
    }
  } );

  Poolable.mixin( CanvasBlock, {
    constructorDuplicateFactory: function( pool ) {
      return function( display, renderer, transformRootInstance, filterRootInstance ) {
        if ( pool.length ) {
          sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( 'new from pool' );
          return pool.pop().initialize( display, renderer, transformRootInstance, filterRootInstance );
        }
        else {
          sceneryLog && sceneryLog.CanvasBlock && sceneryLog.CanvasBlock( 'new from constructor' );
          return new CanvasBlock( display, renderer, transformRootInstance, filterRootInstance );
        }
      };
    }
  } );

  return CanvasBlock;
} );
<|endoftext|>


<commit_before>/**
 * Represents Query class
 * @param {string} index: index provided within the query
 * @param {string} type: type of records ro be returned
 * @param {integer} size: limit of records to be returned
 * @param {object} query: query to be used by elasticsearch to return data
 * @param {array} fields: fields to be returned within provided query
 */
ElasticRest = function (index, type, size, query, fields) {

    // initial values
    this.index  = "";
    this.type   = "";
    this.size   = 0;
    this.query  = {
        match_all: {}
    };
    this.fields = [];

    // assigning provided values to local variables
    this.index  = index;
    this.type   = type;
    this.size   = size;
    this.query  = query;
    this.fields = fields;

    ElasticSearch = Meteor.npmRequire('elasticsearch');

    // create the client
    EsClientSource = new ElasticSearch.Client({
        host: Meteor.settings.elasticsearch.host
    });

    // make it fiber aware
    EsClient = Async.wrap(EsClientSource, ['index', 'search']);

    /**
     *  Search method
     */
    this.doSearch = function () {

        if(!this.query  || this.query   ==  {}  || this.query   ==  "") this.query  = { match_all: {} };

        var body = {
            query: this.query,
            size: this.size
        };

        if(!this.fields || this.fields  ==  []  || this.fields  ==  "") { } else { body.fields = this.fields; }

        var searchData = EsClient.search({
            index   : this.index,
            type    : this.type,
            body    : body
        });

        return searchData;
    };

};
<commit_msg>commented<commit_after>/**
 * Represents Query class
 * @param {string} index: index provided within the query
 * @param {string} type: type of records ro be returned
 * @param {integer} size: limit of records to be returned
 * @param {object} query: query to be used by elasticsearch to return data
 * @param {array} fields: fields to be returned within provided query
 */
ElasticRest = function (config, options) {

    console.log(config);
    console.log(options);

    //// initial values
    //this.index  = "";
    //this.type   = "";
    //this.size   = 0;
    //this.query  = {
    //    match_all: {}
    //};
    //this.fields = [];
    //
    //// assigning provided values to local variables
    //this.index  = index;
    //this.type   = type;
    //this.size   = size;
    //this.query  = query;
    //this.fields = fields;
    //

    ElasticSearch = Meteor.npmRequire('elasticsearch');

    // create the client
    EsClientSource = new ElasticSearch.Client({
        host: Meteor.settings.elasticsearch.host
    });

    // make it fiber aware
    EsClient = Async.wrap(EsClientSource, ['index', 'search']);

    ///**
    // *  Search method
    // */
    //this.doSearch = function () {
    //
    //    if(!this.query  || this.query   ==  {}  || this.query   ==  "") this.query  = { match_all: {} };
    //
    //    var body = {
    //        query: this.query,
    //        size: this.size
    //    };
    //
    //    if(!this.fields || this.fields  ==  []  || this.fields  ==  "") { } else { body.fields = this.fields; }
    //
    //    var searchData = EsClient.search({
    //        index   : this.index,
    //        type    : this.type,
    //        body    : body
    //    });
    //
    //
    //    return searchData;
    //};

    return EsClient;

};
<|endoftext|>