<commit_before>$(function() {
    function PrintHistoryViewModel(parameters) {
        var self = this;

        self.loginState = parameters[0];
        self.global_settings = parameters[1];
        self.users = parameters[2];

        self.totalTime = ko.observable();
        self.totalUsage = ko.observable();
        self.isPrinting = ko.observable(undefined);

        self.spool_inventory = ko.observableArray([]);
        self.spool_inventory_base = ko.observableArray([]);
        self.availableCurrencies = ko.observableArray(['$', '€', '£']);

        self.itemForEditing = ko.observable();

        var HistoryItem = function(data) {
            this.id = ko.observable();
            this.fileName = ko.observable();
            this.success = ko.observable();
            this.filamentVolume = ko.observable();
            this.filamentLength = ko.observable();
            this.timestamp = ko.observable();
            this.printTime = ko.observable();
            this.note = ko.observable();
            this.spool = ko.observable();
            this.user = ko.observable();

            this.successful = ko.computed(function() {
                return this.success() == 1;
            }, this);
            this.filamentUsage = ko.computed(self.formatFilament, this);
            this.formatedDate = ko.computed(function () {
                return formatDate(this.timestamp());
            }, this);
            this.formatedTimeAgo = ko.computed(function () {
                return formatTimeAgo(this.timestamp());
            }, this);
            this.formatedDuration = ko.computed(function () {
                return formatDuration(this.printTime());
            }, this);

            this.update(data);
        }

        HistoryItem.prototype.update = function (data) {
            var updateData = data || {}

            this.id(updateData.id);
            this.fileName(updateData.fileName);
            this.success(updateData.success);
            this.filamentVolume(updateData.filamentVolume || 0);
            this.filamentLength(updateData.filamentLength || 0);
            this.timestamp(updateData.timestamp || 0);
            this.printTime(updateData.printTime || 0);
            this.note(updateData.note || "");
            this.spool(updateData.spool || "");
            this.user(updateData.user || "");
        };

        self.onHistoryTab = false;
        self.dataIsStale = true;
        self.requestingData = false;
        self.pureData = {};
        self.lastMonthGraphMinimum = ko.observable(moment(new Date()).subtract(1, 'months').valueOf());

        self.onStartup = function () {
            self.detailsDialog = $("#printhistory_details_dialog");
            self.detailsDialog.on('hidden', self.onCancelDetails);
        }

        self.onBeforeBinding = function () {
            self.settings = self.global_settings.settings.plugins.printhistory;
            self.spool_inventory(self.settings.spool_inventory.slice(0));
            self.spool_inventory_base(self.settings.spool_inventory);
        };

        self.onAfterTabChange = function(current, previous) {
            self.onHistoryTab = current == "#tab_plugin_printhistory"
            self.updatePlots();
        }

        self.fromCurrentData = function (data) {
            var isPrinting = data.state.flags.printing;

            if (isPrinting != self.isPrinting()) {
                self.requestData();
            }

            self.isPrinting(isPrinting);
        };

        self.requestData = function(params) {
            var force = false;

            if (_.isObject(params)) {
                force = params.force;
            }

            if (!self.onHistoryTab) {
                self.dataIsStale = true;
                return;
            }
            //console.log('PrintHistory - request data');
            if (self.requestingData) {
                return;
            }
            self.requestingData = true;

            $.ajax({
                url: "plugin/printhistory/history",
                type: "GET",
                data: {force: force},
                dataType: "json",
                success: self.fromResponse
            }).always(function () {
                self.requestingData = false;
            });
        };

        self.fromResponse = function(data) {
            var dataRows = ko.utils.arrayMap(data.history, function (data) {
                return new HistoryItem(data);
            });

            self.dataIsStale = false;
            self.listHelper.updateItems(dataRows);
            self.updatePlots();
        };

        self.removeFile = function(id) {
            $.ajax({
                url: "plugin/printhistory/history/" + id(),
                type: "DELETE",
                dataType: "json",
                success: function(data) {
                    self.fromResponse(data);
                }
            });
        };

        self.formatFilament = function() {
            var tool0 = "";
            var tool1 = "";
            var output = "";

            if (this.filamentLength() != undefined) {
                tool0 += formatFilament({length: this.filamentLength(), volume: this.filamentVolume()});
            }

            //if (data.hasOwnProperty('filamentLength2') && data.filamentLength2 != 0) {
            //    tool1 += formatFilament({length: data.filamentLength2, volume: data.filamentVolume2});
            //}

            if (tool0 !== "" && tool1 !== "") {
                output = "Tool0: " + tool0 + "
Tool1: " + tool1;
            } else {
                if (tool0 !== "") {
                    output = tool0;
                } else {
                    output = tool1;
                }
            }

            return output;
        };

        self.export = function(type) {
            if (self.listHelper.items().length > 0) {
                return "plugin/printhistory/export/" + type + "?apikey=" + UI_API_KEY;
            } else {
                return false;
            }
        };

        self.changeGraphRange = function (range) {
            if (range == 'week') {
                self.lastMonthGraphMinimum(moment(new Date()).subtract(1, 'weeks').valueOf());
            } else if (range == 'month'){
                self.lastMonthGraphMinimum(moment(new Date()).subtract(1, 'months').valueOf());
            } else {
                self.lastMonthGraphMinimum(moment(new Date()).subtract(1, 'quarter').valueOf());
            }

            self.updatePlots();
        };

        function printhistoryLabelFormatter(label, series) {
            return "
" + label + "
" + Math.round(series.percent) + "%
";
        }

        self.updatePlots = function() {
            if (!self.onHistoryTab) {
                return;
            }

            if (self.dataIsStale) {
                self.requestData();
                return;
            }

            var lastmonth_graph = $("#printhistory-lastmonth-graph");
            var success_graph = $("#printhistory-success-graph");

            var lastmonthGraphOptions = {
                series: {
                    stack: 0,
                    bars: {
                        show: true,
                        barWidth: 1000*60*60*24*0.6,
                        lineWidth: 0,
                        fill: 1,
                        align: "center"
                    }
                },
                yaxis: {
                    tickDecimals: 0,
                    min: 0
                },
                xaxis: {
                    mode: "time",
                    minTickSize: [1, "day"],
                    min: self.lastMonthGraphMinimum(),
                    max: new Date().getTime(),
                    timeformat: "%m-%d"
                },
                legend: {
                    show: false
                }
            };

            var successGraphOptions = {
                series: {
                    pie: {
                        show: true,
                        radius: 1,
                        label: {
                            show: true,
                            radius: 1/2,
                            formatter: printhistoryLabelFormatter,
                            background: {
                                opacity: 0.5
                            }
                        }
                    }
                },
                legend: {
                    show: false
                }
            };

            var successCount = 0;
            var failureCount = 0;

            var agreggateSuccess = {};
            var agreggateFailure = {};

            _.each(_.keys(self.pureData), function(key) {
                var day = moment.unix(self.pureData[key].timestamp).hour(0).minute(0).second(0).millisecond(0).valueOf();

                if (self.pureData[key].success == true) {
                    successCount += 1;

                    if (!agreggateSuccess.hasOwnProperty(day)) {
                        agreggateSuccess[day] = 0;
                    }
                    agreggateSuccess[day] += 1;
                } else {
                    failureCount += 1;

                    if (!agreggateFailure.hasOwnProperty(day)) {
                        agreggateFailure[day] = 0;
                    }
                    agreggateFailure[day] += 1;
                }
            });

            var successArr = [];
            var failureArr = [];

            _.each(_.keys(agreggateSuccess), function(key) {
                successArr.push([key, agreggateSuccess[key]]);
            });

            _.each(_.keys(agreggateFailure), function(key) {
                failureArr.push([key, agreggateFailure[key]]);
            });

            var lastmonth_data = [
                { label: "Success", color: '#31C448', data: successArr},
                { label: "Failure", color: '#FF0000', data: failureArr}
            ];

            var success_data = [
                { label: "Success", color: '#31C448', data: successCount},
                { label: "Failure", color: '#FF0000', data: failureCount}
            ];

            $.plot(lastmonth_graph, lastmonth_data, lastmonthGraphOptions);
            $.plot(success_graph, success_data, successGraphOptions);
        };

        /*
         * -----------
         *  SETTINGS
         * -----------
         */
        self.addNewSpool = function() {
            self.spool_inventory.push({name: "New", price:0, currency: "$"});
        };

        self.removeSpool = function(spool) {
            self.spool_inventory.remove(spool);
        };

        self.onSettingsHidden = function() {
            self.spool_inventory(self.spool_inventory_base.slice(0));
        };

        self.onSettingsBeforeSave = function () {
            self.global_settings.settings.plugins.printhistory.spool_inventory(self.spool_inventory.slice(0));
        }

        /*
         * -----------
         *   DETAILS
         * -----------
         */
        self.showDetailsDialog = function(selectedData) {
            if (self.detailsDialog) {
                self.itemForEditing(new HistoryItem(ko.mapping.toJS(selectedData)));

                self.detailsDialog.modal("show");
            }
        };

        self.onCancelDetails = function (event) {
            if (event.target.id == "printhistory_details_dialog") {
                self.itemForEditing(null);
            }
        }

        self.addUpdateDetails = function(event) {
            var icon = $(".btn-primary i", self.detailsDialog);
            icon.addClass("icon-spinner icon-spin");

            var payload = {
                id: self.itemForEditing().id(),
                note: self.itemForEditing().note(),
                spool: self.itemForEditing().spool(),
                user: self.itemForEditing().user(),
                success: self.itemForEditing().success()
            }

            $.ajax({
                url: "plugin/printhistory/details",
                type: "PUT",
                data: JSON.stringify(payload),
                dataType: "json",
                contentType: "application/json; charset=UTF-8",
                success: self.closeDetails
            }).always(function() {
                icon.removeClass("icon-spinner icon-spin");
            });
        };

        self.closeDetails = function(data) {
            self.fromResponse(data);

            self.listHelper.selectNone();

            self.detailsDialog.modal("hide");
        };

        self.listHelper = new ItemListHelper(
            "historyItems",
            {
                "fileNameAsc": function (a, b) {
                    // sorts ascending
                    if (a.fileName().toLocaleLowerCase()  b.fileName().toLocaleLowerCase()) return 1;
                    return 0;
                },
                "fileNameDesc": function (a, b) {
                    // sorts ascending
                    if (a.fileName().toLocaleLowerCase()  b.fileName().toLocaleLowerCase()) return -1;
                    return 0;
                },
                "timestampAsc": function (a, b) {
                    // sorts descending
                    if (a.timestamp() > b.timestamp()) return 1;
                    if (a.timestamp()  b.timestamp()) return -1;
                    if (a.timestamp()  b.printTime()) return 1;
                    if (a.printTime()  b.printTime()) return -1;
                    if (a.printTime() < b.printTime()) return 1;
                    return 0;
                }
            },
            {
                "successful": function (item) {
                    return (item.success() == 1);
                }
            },
            "timestamp", [], ["successful"], 10
        );

        self.listHelper.items.subscribe(function(newValue) {
            var totalTime = 0;
            var totalUsage = {
                length: 0,
                volume: 0
            };

            var itemList = newValue;
            for (var i = 0; i < itemList.length; i++) {
                totalTime += itemList[i].printTime();

                totalUsage.length += itemList[i].filamentLength();
                totalUsage.volume += itemList[i].filamentVolume();
            }

            self.totalTime(formatDuration(totalTime));
            self.totalUsage(formatFilament(totalUsage));
        });

        self.fileNameSort = function() {
            if (self.listHelper.currentSorting() == "fileNameAsc") {
                self.listHelper.changeSorting("fileNameDesc");
            } else {
                self.listHelper.changeSorting("fileNameAsc");
            }
        };

        self.timeStampSort = function() {
            if (self.listHelper.currentSorting() == "timestampDesc") {
                self.listHelper.changeSorting("timestampAsc");
            } else {
                self.listHelper.changeSorting("timestampDesc");
            }
        };

        self.printTimeSort = function() {
            if (self.listHelper.currentSorting() == "printTimeDesc") {
                self.listHelper.changeSorting("printTimeAsc");
            } else {
                self.listHelper.changeSorting("printTimeDesc");
            }
        };

        self.sortOrder = function(orderType) {
            var order = "";

            if (orderType == "fileName") {
                order = (self.listHelper.currentSorting() == 'fileNameAsc') ? '(' + _('ascending') + ')' : (self.listHelper.currentSorting() == 'fileNameDesc') ? '(' + _('descending') + ')' : '';
            } else if (orderType == "timestamp") {
                order = (self.listHelper.currentSorting() == 'timestampAsc') ? '(' + _('ascending') + ')' : (self.listHelper.currentSorting() == 'timestampDesc') ? '(' + _('descending') + ')' : '';
            } else {
                order = (self.listHelper.currentSorting() == 'printTimeAsc') ? '(' + _('ascending') + ')' : (self.listHelper.currentSorting() == 'printTimeDesc') ? '(' + _('descending') + ')' : '';
            }

            return order;
        };
    }

    ADDITIONAL_VIEWMODELS.push({
        construct: PrintHistoryViewModel,
        name: "PrintHistoryViewModel",
        dependencies: ["loginStateViewModel", "settingsViewModel", "usersViewModel"],
        elements: ["#tab_plugin_printhistory", "#settings_plugin_printhistory"]
});
});<commit_msg>Fixed graphs<commit_after>$(function() {
    function PrintHistoryViewModel(parameters) {
        var self = this;

        self.loginState = parameters[0];
        self.global_settings = parameters[1];
        self.users = parameters[2];

        self.totalTime = ko.observable();
        self.totalUsage = ko.observable();
        self.isPrinting = ko.observable(undefined);

        self.spool_inventory = ko.observableArray([]);
        self.spool_inventory_base = ko.observableArray([]);
        self.availableCurrencies = ko.observableArray(['$', '€', '£']);

        self.itemForEditing = ko.observable();

        var HistoryItem = function(data) {
            this.id = ko.observable();
            this.fileName = ko.observable();
            this.success = ko.observable();
            this.filamentVolume = ko.observable();
            this.filamentLength = ko.observable();
            this.timestamp = ko.observable();
            this.printTime = ko.observable();
            this.note = ko.observable();
            this.spool = ko.observable();
            this.user = ko.observable();

            this.successful = ko.computed(function() {
                return this.success() == 1;
            }, this);
            this.filamentUsage = ko.computed(self.formatFilament, this);
            this.formatedDate = ko.computed(function () {
                return formatDate(this.timestamp());
            }, this);
            this.formatedTimeAgo = ko.computed(function () {
                return formatTimeAgo(this.timestamp());
            }, this);
            this.formatedDuration = ko.computed(function () {
                return formatDuration(this.printTime());
            }, this);

            this.update(data);
        }

        HistoryItem.prototype.update = function (data) {
            var updateData = data || {}

            this.id(updateData.id);
            this.fileName(updateData.fileName);
            this.success(updateData.success);
            this.filamentVolume(updateData.filamentVolume || 0);
            this.filamentLength(updateData.filamentLength || 0);
            this.timestamp(updateData.timestamp || 0);
            this.printTime(updateData.printTime || 0);
            this.note(updateData.note || "");
            this.spool(updateData.spool || "");
            this.user(updateData.user || "");
        };

        self.onHistoryTab = false;
        self.dataIsStale = true;
        self.requestingData = false;
        self.pureData = {};
        self.lastMonthGraphMinimum = ko.observable(moment(new Date()).subtract(1, 'months').valueOf());

        self.onStartup = function () {
            self.detailsDialog = $("#printhistory_details_dialog");
            self.detailsDialog.on('hidden', self.onCancelDetails);
        }

        self.onBeforeBinding = function () {
            self.settings = self.global_settings.settings.plugins.printhistory;
            self.spool_inventory(self.settings.spool_inventory.slice(0));
            self.spool_inventory_base(self.settings.spool_inventory);
        };

        self.onAfterTabChange = function(current, previous) {
            self.onHistoryTab = current == "#tab_plugin_printhistory"
            self.updatePlots();
        }

        self.fromCurrentData = function (data) {
            var isPrinting = data.state.flags.printing;

            if (isPrinting != self.isPrinting()) {
                self.requestData();
            }

            self.isPrinting(isPrinting);
        };

        self.requestData = function(params) {
            var force = false;

            if (_.isObject(params)) {
                force = params.force;
            }

            if (!self.onHistoryTab) {
                self.dataIsStale = true;
                return;
            }
            //console.log('PrintHistory - request data');
            if (self.requestingData) {
                return;
            }
            self.requestingData = true;

            $.ajax({
                url: "plugin/printhistory/history",
                type: "GET",
                data: {force: force},
                dataType: "json",
                success: self.fromResponse
            }).always(function () {
                self.requestingData = false;
            });
        };

        self.fromResponse = function(data) {
            var dataRows = ko.utils.arrayMap(data.history, function (data) {
                return new HistoryItem(data);
            });

            self.pureData = data.history;

            self.dataIsStale = false;
            self.listHelper.updateItems(dataRows);
            self.updatePlots();
        };

        self.removeFile = function(id) {
            $.ajax({
                url: "plugin/printhistory/history/" + id(),
                type: "DELETE",
                dataType: "json",
                success: function(data) {
                    self.fromResponse(data);
                }
            });
        };

        self.formatFilament = function() {
            var tool0 = "";
            var tool1 = "";
            var output = "";

            if (this.filamentLength() != undefined) {
                tool0 += formatFilament({length: this.filamentLength(), volume: this.filamentVolume()});
            }

            //if (data.hasOwnProperty('filamentLength2') && data.filamentLength2 != 0) {
            //    tool1 += formatFilament({length: data.filamentLength2, volume: data.filamentVolume2});
            //}

            if (tool0 !== "" && tool1 !== "") {
                output = "Tool0: " + tool0 + "
Tool1: " + tool1;
            } else {
                if (tool0 !== "") {
                    output = tool0;
                } else {
                    output = tool1;
                }
            }

            return output;
        };

        self.export = function(type) {
            if (self.listHelper.items().length > 0) {
                return "plugin/printhistory/export/" + type + "?apikey=" + UI_API_KEY;
            } else {
                return false;
            }
        };

        self.changeGraphRange = function (range) {
            if (range == 'week') {
                self.lastMonthGraphMinimum(moment(new Date()).subtract(1, 'weeks').valueOf());
            } else if (range == 'month'){
                self.lastMonthGraphMinimum(moment(new Date()).subtract(1, 'months').valueOf());
            } else {
                self.lastMonthGraphMinimum(moment(new Date()).subtract(1, 'quarter').valueOf());
            }

            self.updatePlots();
        };

        function printhistoryLabelFormatter(label, series) {
            return "
" + label + "
" + Math.round(series.percent) + "%
";
        }

        self.updatePlots = function() {
            if (!self.onHistoryTab) {
                return;
            }

            if (self.dataIsStale) {
                self.requestData();
                return;
            }

            var lastmonth_graph = $("#printhistory-lastmonth-graph");
            var success_graph = $("#printhistory-success-graph");

            var lastmonthGraphOptions = {
                series: {
                    stack: 0,
                    bars: {
                        show: true,
                        barWidth: 1000*60*60*24*0.6,
                        lineWidth: 0,
                        fill: 1,
                        align: "center"
                    }
                },
                yaxis: {
                    tickDecimals: 0,
                    min: 0
                },
                xaxis: {
                    mode: "time",
                    minTickSize: [1, "day"],
                    min: self.lastMonthGraphMinimum(),
                    max: new Date().getTime(),
                    timeformat: "%m-%d"
                },
                legend: {
                    show: false
                }
            };

            var successGraphOptions = {
                series: {
                    pie: {
                        show: true,
                        radius: 1,
                        label: {
                            show: true,
                            radius: 1/2,
                            formatter: printhistoryLabelFormatter,
                            background: {
                                opacity: 0.5
                            }
                        }
                    }
                },
                legend: {
                    show: false
                }
            };

            var successCount = 0;
            var failureCount = 0;

            var agreggateSuccess = {};
            var agreggateFailure = {};

            _.each(_.keys(self.pureData), function(key) {
                var day = moment.unix(self.pureData[key].timestamp).hour(0).minute(0).second(0).millisecond(0).valueOf();

                if (self.pureData[key].success == 1) {
                    successCount += 1;

                    if (!agreggateSuccess.hasOwnProperty(day)) {
                        agreggateSuccess[day] = 0;
                    }
                    agreggateSuccess[day] += 1;
                } else {
                    failureCount += 1;

                    if (!agreggateFailure.hasOwnProperty(day)) {
                        agreggateFailure[day] = 0;
                    }
                    agreggateFailure[day] += 1;
                }
            });

            var successArr = [];
            var failureArr = [];

            _.each(_.keys(agreggateSuccess), function(key) {
                successArr.push([key, agreggateSuccess[key]]);
            });

            _.each(_.keys(agreggateFailure), function(key) {
                failureArr.push([key, agreggateFailure[key]]);
            });

            var lastmonth_data = [
                { label: "Success", color: '#31C448', data: successArr},
                { label: "Failure", color: '#FF0000', data: failureArr}
            ];

            var success_data = [
                { label: "Success", color: '#31C448', data: successCount},
                { label: "Failure", color: '#FF0000', data: failureCount}
            ];

            $.plot(lastmonth_graph, lastmonth_data, lastmonthGraphOptions);
            $.plot(success_graph, success_data, successGraphOptions);
        };

        /*
         * -----------
         *  SETTINGS
         * -----------
         */
        self.addNewSpool = function() {
            self.spool_inventory.push({name: "New", price:0, currency: "$"});
        };

        self.removeSpool = function(spool) {
            self.spool_inventory.remove(spool);
        };

        self.onSettingsHidden = function() {
            self.spool_inventory(self.spool_inventory_base.slice(0));
        };

        self.onSettingsBeforeSave = function () {
            self.global_settings.settings.plugins.printhistory.spool_inventory(self.spool_inventory.slice(0));
        }

        /*
         * -----------
         *   DETAILS
         * -----------
         */
        self.showDetailsDialog = function(selectedData) {
            if (self.detailsDialog) {
                self.itemForEditing(new HistoryItem(ko.mapping.toJS(selectedData)));

                self.detailsDialog.modal("show");
            }
        };

        self.onCancelDetails = function (event) {
            if (event.target.id == "printhistory_details_dialog") {
                self.itemForEditing(null);
            }
        }

        self.addUpdateDetails = function(event) {
            var icon = $(".btn-primary i", self.detailsDialog);
            icon.addClass("icon-spinner icon-spin");

            var payload = {
                id: self.itemForEditing().id(),
                note: self.itemForEditing().note(),
                spool: self.itemForEditing().spool(),
                user: self.itemForEditing().user(),
                success: self.itemForEditing().success()
            }

            $.ajax({
                url: "plugin/printhistory/details",
                type: "PUT",
                data: JSON.stringify(payload),
                dataType: "json",
                contentType: "application/json; charset=UTF-8",
                success: self.closeDetails
            }).always(function() {
                icon.removeClass("icon-spinner icon-spin");
            });
        };

        self.closeDetails = function(data) {
            self.fromResponse(data);

            self.listHelper.selectNone();

            self.detailsDialog.modal("hide");
        };

        self.listHelper = new ItemListHelper(
            "historyItems",
            {
                "fileNameAsc": function (a, b) {
                    // sorts ascending
                    if (a.fileName().toLocaleLowerCase()  b.fileName().toLocaleLowerCase()) return 1;
                    return 0;
                },
                "fileNameDesc": function (a, b) {
                    // sorts ascending
                    if (a.fileName().toLocaleLowerCase()  b.fileName().toLocaleLowerCase()) return -1;
                    return 0;
                },
                "timestampAsc": function (a, b) {
                    // sorts descending
                    if (a.timestamp() > b.timestamp()) return 1;
                    if (a.timestamp()  b.timestamp()) return -1;
                    if (a.timestamp()  b.printTime()) return 1;
                    if (a.printTime()  b.printTime()) return -1;
                    if (a.printTime() < b.printTime()) return 1;
                    return 0;
                }
            },
            {
                "successful": function (item) {
                    return (item.success() == 1);
                }
            },
            "timestamp", [], ["successful"], 10
        );

        self.listHelper.items.subscribe(function(newValue) {
            var totalTime = 0;
            var totalUsage = {
                length: 0,
                volume: 0
            };

            var itemList = newValue;
            for (var i = 0; i < itemList.length; i++) {
                totalTime += itemList[i].printTime();

                totalUsage.length += itemList[i].filamentLength();
                totalUsage.volume += itemList[i].filamentVolume();
            }

            self.totalTime(formatDuration(totalTime));
            self.totalUsage(formatFilament(totalUsage));
        });

        self.fileNameSort = function() {
            if (self.listHelper.currentSorting() == "fileNameAsc") {
                self.listHelper.changeSorting("fileNameDesc");
            } else {
                self.listHelper.changeSorting("fileNameAsc");
            }
        };

        self.timeStampSort = function() {
            if (self.listHelper.currentSorting() == "timestampDesc") {
                self.listHelper.changeSorting("timestampAsc");
            } else {
                self.listHelper.changeSorting("timestampDesc");
            }
        };

        self.printTimeSort = function() {
            if (self.listHelper.currentSorting() == "printTimeDesc") {
                self.listHelper.changeSorting("printTimeAsc");
            } else {
                self.listHelper.changeSorting("printTimeDesc");
            }
        };

        self.sortOrder = function(orderType) {
            var order = "";

            if (orderType == "fileName") {
                order = (self.listHelper.currentSorting() == 'fileNameAsc') ? '(' + _('ascending') + ')' : (self.listHelper.currentSorting() == 'fileNameDesc') ? '(' + _('descending') + ')' : '';
            } else if (orderType == "timestamp") {
                order = (self.listHelper.currentSorting() == 'timestampAsc') ? '(' + _('ascending') + ')' : (self.listHelper.currentSorting() == 'timestampDesc') ? '(' + _('descending') + ')' : '';
            } else {
                order = (self.listHelper.currentSorting() == 'printTimeAsc') ? '(' + _('ascending') + ')' : (self.listHelper.currentSorting() == 'printTimeDesc') ? '(' + _('descending') + ')' : '';
            }

            return order;
        };
    }

    ADDITIONAL_VIEWMODELS.push({
        construct: PrintHistoryViewModel,
        name: "PrintHistoryViewModel",
        dependencies: ["loginStateViewModel", "settingsViewModel", "usersViewModel"],
        elements: ["#tab_plugin_printhistory", "#settings_plugin_printhistory"]
});
});<|endoftext|>


<commit_before>/* Contains ASCII tiles used for the crypt level generation. */

const RG = require('../src/rg');
RG.Random = require('../src/random');

const Crypt = {};
Crypt.tiles = {};

Crypt.tiles.filler = `
name:FILLER
X=#
Y=#

#X###X#
Y######
#######
#######
#######
Y######
#######`;

Crypt.tiles.start = [
`
dir:NSEW
name:start_nsew
X=#
Y=#

#X#+#X#
Y.....#
#.#.#.#
+.###.+
#.#.#.#
Y.....#
###+###`,

`
dir:SEW
name:start_sew
X=#
Y=#

#X###X#
Y.....#
#.#.#.#
+.###.+
#.#.#.#
Y.....#
###+###`,

`
dir:NEW
name:start_new
X=#
Y=#

#X#+#X#
Y.....#
#.#.#.#
+.###.+
#.#.#.#
Y.....#
#######`,

`
dir:NSE
name:start_nse
X=#
Y=#

#X#+#X#
Y.....#
#.#.#.#
#..#..+
#.#.#.#
Y.....#
###+###`,

`
dir:NSW
name:start_nsw
X=#
Y=#

#X#+#X#
Y.....#
#.#.#.#
+..#..#
#.#.#.#
Y.....#
###+###`
];

// Omni-directionals
Crypt.tiles.omni = [
`
dir:NSEW
name:omni
X=#
Y=#

#X#.#X#
Y.....#
#.....#
...#...
#.....#
Y.....#
###.###`,

`
dir:NSEW
name:omni
X=#
Y=#

#X#.#X#
Y.....#
#.#.#.#
...#...
#.#.#.#
Y.....#
###.###`,
`
dir:NSEW
name:omni
X=#
Y=#

#.X.X.#
Y.....#
#..#..#
..###..
#..#..#
Y.....#
###.###`,

`
name:omni
dir:NSEW
X=#
Y=#

#X...X#
.......
Y..#..#
..###..
Y..#..#
.......
##...##`,

`
name:omni
dir:NSEW
X=.
Y=.

..X.X..
.##.##.
Y#...#.
...#...
Y#...#.
.##.##.
.......`,

`
name:omni
dir:NSEW
X=.
Y=.

#.X.X.#
###.###
Y#...#.
...#...
Y#...#.
###.###
#.....#`,

`
name:omni
dir:NSEW
X=.
Y=.

..X.X..
.##.##.
Y##.##.
.......
Y##.##.
.##.##.
.......`,

`
dir:NSEW
name:omni
X=.
Y=.

..X.X..
.##.##.
Y#...#.
.#...#.
Y#...#.
.##.##.
.......`
];

// Terminals (one exit only)
Crypt.tiles.term = [
`
dir:N
name:term
X=#
Y=#

#X#.#X#
#.....#
Y.#.#.#
###.###
Y.....#
#.....#
#######`,

`
dir:N
name:term
X=#
Y=#

#X#.#X#
#.....#
Y.#.#.#
###.###
Y##.###
##...##
#######`,

`
dir:S
name:term
X=#
Y=#

#X###X#
#.....#
Y.#.#.#
###.###
Y.#.#.#
#.....#
##...##`,

`
dir:S
name:term
X=#
Y=#

#X###X#
#######
Y######
###.###
Y.....#
#.....#
##...##`,

`
dir:W
name:term
X=#
Y=#

#X###X#
#.....#
Y.#.#.#
...####
Y.#.#.#
#.....#
#######`,

`
dir:W
name:term
X=#
Y=#

#X###X#
#.#...#
Y.#.###
..#...#
Y.###.#
#.....#
#######`,

`
dir:E
name:term
X=#
Y=#

#X###X#
#.....#
Y..#..#
#..#...
Y.###.#
#.....#
#######`,

`
dir:E
name:term
X=#
Y=#

#X###X#
#.....#
Y...###
#...#..
Y.###.#
#.....#
#######`
];

// Corridors (2 exits on opposite sides)
Crypt.tiles.corridor = [
`
dir:NS
name:corridor
X=#
Y=#

#X...X#
##...##
Y#...##
##...##
Y#...##
##...##
##...##`,

`
dir:NS
name:corridor
X=#
Y=#

#X...X#
#.....#
Y#...##
#.....#
Y#...##
#.....#
##...##`,

`
dir:EW
name:corridor
X=#
Y=#

#X###X#
#######
Y......
.......
Y......
#######
#######`,

`
dir:EW
name:corridor
X=#
Y=#

#X###X#
#.#.#.#
Y.....#
.......
Y.....#
#.#.#.#
#######`
];

// Corners
Crypt.tiles.corner = [
`
dir:NW
name:corner
X=#
Y=#

#X...X#
###.###
Y....##
.....##
Y....##
#######
#######`,

`
dir:NW
name:corner
X=#
Y=#

#X#.#X#
#.....#
Y.....#
......#
Y.###.#
#.....#
#######`,

`
dir:NE
name:corner
X=.
Y=#

#X...X#
###.###
Y#...#.
##.....
Y#...#.
#######
#######`,

`
dir:NE
name:corner
X=#
Y=#

#X#.#X#
#.....#
Y.###.#
#......
Y.....#
#.....#
#######`,

`
dir:SE
name:corner
X=#
Y=#

#X###X#
###.###
Y#...#.
##.....
Y#...#.
###.###
###.###`,

`
dir:SE
name:corner
X=#
Y=#

#X###X#
#.#.#.#
Y#...##
#......
Y#...##
#.#.#.#
###.###`,

`
dir:SW
name:corner
X=#
Y=.

#X###X#
###.###
Y#...##
......#
Y#...##
###.###
###.###`
];

// The rest
Crypt.tiles.misc = [
`
dir:SEW
name:threeway
X=#
Y=.

#X###X#
###.###
Y#...#.
.......
Y#...#.
###.###
###.###`,

`
dir:SEW
name:threeway
X=#
Y=#

#X###X#
#.....#
Y.#.#.#
..#.#..
Y##.###
#.....#
#.....#`,

`
dir:NEW
name:threeway
X=#
Y=.

#X...X#
###.###
Y#...#.
.......
Y#...#.
#######
#######`,

`
dir:NSW
name:threeway
X=#
Y=#

#X...X#
###.###
Y#...##
......#
Y#...##
###.###
###.###`,

`
dir:NSE
name:threeway
X=#
Y=#

#X...X#
###.###
Y#...##
##.....
Y#...##
###.###
###.###`
];

Crypt.templates = {};

Crypt.templates.start = Crypt.tiles.start.map(tile => {
    return RG.Template.createTemplate(tile);
});

/* Returns the starting room for the crypt generation. Note that 'this' should
 * be bound to RG.Template.Level object. */
Crypt.startRoomFunc = function() {
    const tile = RG.RAND.arrayGetRand(Crypt.templates.start);
    let x = RG.RAND.getUniformInt(0, this.tilesX - 1);
    let y = RG.RAND.getUniformInt(0, this.tilesY - 1);
    switch (tile.getProp('name')) {
        case 'start_nsew': {
            x = Math.floor(this.tilesX / 2);
            y = Math.floor(this.tilesY / 2);
            break;
        }
        case 'start_sew': {
            y = 0;
            if (x === 0) {x += 1;}
            if (x === this.tilesX - 1) {x -= 1;}
            break;
        }
        case 'start_new': {
            y = this.tilesY - 1;
            if (x === 0) {x += 1;}
            if (x === this.tilesX - 1) {x -= 1;}
            break;
        }
        case 'start_nse': {
            x = 0;
            if (y === 0) {y += 1;}
            if (y === this.tilesY - 1) {y -= 1;}
            break;

        }
        case 'start_nsw': {
            x = this.tilesX - 1;
            if (y === 0) {y += 1;}
            if (y === this.tilesY - 1) {y -= 1;}
            break;

        }
        default: break;
    }

    return {
        x, y, room: tile
    };
};

Crypt.Models = {};

// Note that the starting rooms are not included in this list, thus they'll be
// placed only by the startRoomFunc
Crypt.Models.default = []
    .concat(Crypt.tiles.corner)
    .concat(Crypt.tiles.corridor)
    .concat(Crypt.tiles.omni)
    .concat(Crypt.tiles.term)
    .concat(Crypt.tiles.misc);

module.exports = Crypt;
<commit_msg>Added transformed templates.<commit_after>/* Contains ASCII tiles used for the crypt level generation. */

const RG = require('../src/rg');
RG.Random = require('../src/random');

const Crypt = {};
Crypt.tiles = {};

Crypt.tiles.filler = `
name:FILLER
X=#
Y=#

#X###X#
Y######
#######
#######
#######
Y######
#######`;

Crypt.tiles.start = [
`
dir:NSEW
name:start_nsew
X=#
Y=#

#X#+#X#
Y.....#
#.#.#.#
+.###.+
#.#.#.#
Y.....#
###+###`,

`
dir:SEW
name:start_sew
X=#
Y=#

#X###X#
Y.....#
#.#.#.#
+.###.+
#.#.#.#
Y.....#
###+###`,

`
dir:NEW
name:start_new
X=#
Y=#

#X#+#X#
Y.....#
#.#.#.#
+.###.+
#.#.#.#
Y.....#
#######`,

`
dir:NSE
name:start_nse
X=#
Y=#

#X#+#X#
Y.....#
#.#.#.#
#..#..+
#.#.#.#
Y.....#
###+###`,

`
dir:NSW
name:start_nsw
X=#
Y=#

#X#+#X#
Y.....#
#.#.#.#
+..#..#
#.#.#.#
Y.....#
###+###`
];

// Omni-directionals
Crypt.tiles.omni = [
`
dir:NSEW
name:omni
X=#
Y=#

#X#.#X#
Y.....#
#.....#
...#...
#.....#
Y.....#
###.###`,

`
dir:NSEW
name:omni
X=#
Y=#

#X#.#X#
Y.....#
#.#.#.#
...#...
#.#.#.#
Y.....#
###.###`,
`
dir:NSEW
name:omni
X=#
Y=#

#.X.X.#
Y.....#
#..#..#
..###..
#..#..#
Y.....#
###.###`,

`
name:omni
dir:NSEW
X=#
Y=#

#X...X#
.......
Y..#..#
..###..
Y..#..#
.......
##...##`,

`
name:omni
dir:NSEW
X=.
Y=.

..X.X..
.##.##.
Y#...#.
...#...
Y#...#.
.##.##.
.......`,

`
name:omni
dir:NSEW
X=.
Y=.

#.X.X.#
###.###
Y#...#.
...#...
Y#...#.
###.###
#.....#`,

`
name:omni
dir:NSEW
X=.
Y=.

..X.X..
.##.##.
Y##.##.
.......
Y##.##.
.##.##.
.......`,

`
dir:NSEW
name:omni
X=.
Y=.

..X.X..
.##.##.
Y#...#.
.#...#.
Y#...#.
.##.##.
.......`
];

// Terminals (one exit only)
Crypt.tiles.term = [
`
dir:N
name:term
X=#
Y=#

#X#.#X#
#.....#
Y.#.#.#
###.###
Y.....#
#.....#
#######`,

`
dir:N
name:term
X=#
Y=#

#X#.#X#
#.....#
Y.#.#.#
###.###
Y##.###
##...##
#######`,

`
dir:S
name:term
X=#
Y=#

#X###X#
#.....#
Y.#.#.#
###.###
Y.#.#.#
#.....#
##...##`,

`
dir:S
name:term
X=#
Y=#

#X###X#
#######
Y######
###.###
Y.....#
#.....#
##...##`,

`
dir:W
name:term
X=#
Y=#

#X###X#
#.....#
Y.#.#.#
...####
Y.#.#.#
#.....#
#######`,

`
dir:W
name:term
X=#
Y=#

#X###X#
#.#...#
Y.#.###
..#...#
Y.###.#
#.....#
#######`,

`
dir:E
name:term
X=#
Y=#

#X###X#
#.....#
Y..#..#
#..#...
Y.###.#
#.....#
#######`,

`
dir:E
name:term
X=#
Y=#

#X###X#
#.....#
Y...###
#...#..
Y.###.#
#.....#
#######`
];

// Corridors (2 exits on opposite sides)
Crypt.tiles.corridor = [
`
dir:NS
name:corridor
X=#
Y=#

#X...X#
##...##
Y#...##
##...##
Y#...##
##...##
##...##`,

`
dir:NS
name:corridor
X=#
Y=#

#X...X#
#.....#
Y#...##
#.....#
Y#...##
#.....#
##...##`,

`
dir:EW
name:corridor
X=#
Y=#

#X###X#
#######
Y......
.......
Y......
#######
#######`,

`
dir:EW
name:corridor
X=#
Y=#

#X###X#
#.#.#.#
Y.....#
.......
Y.....#
#.#.#.#
#######`
];

// Corners
Crypt.tiles.corner = [
`
dir:NW
name:corner
X=#
Y=#

#X...X#
###.###
Y....##
.....##
Y....##
#######
#######`,

`
dir:NW
name:corner
X=#
Y=#

#X#.#X#
#.....#
Y.....#
......#
Y.###.#
#.....#
#######`,

`
dir:NE
name:corner
X=.
Y=#

#X...X#
###.###
Y#...#.
##.....
Y#...#.
#######
#######`,

`
dir:NE
name:corner
X=#
Y=#

#X#.#X#
#.....#
Y.###.#
#......
Y.....#
#.....#
#######`,

`
dir:SE
name:corner
X=#
Y=#

#X###X#
###.###
Y#...#.
##.....
Y#...#.
###.###
###.###`,

`
dir:SE
name:corner
X=#
Y=#

#X###X#
#.#.#.#
Y#...##
#......
Y#...##
#.#.#.#
###.###`,

`
dir:SW
name:corner
X=#
Y=.

#X###X#
###.###
Y#...##
......#
Y#...##
###.###
###.###`
];

// The rest
Crypt.tiles.misc = [
`
dir:SEW
name:threeway
X=#
Y=.

#X###X#
###.###
Y#...#.
.......
Y#...#.
###.###
###.###`,

`
dir:SEW
name:threeway
X=#
Y=#

#X###X#
#.....#
Y.#.#.#
..#.#..
Y##.###
#.....#
#.....#`,

`
dir:NEW
name:threeway
X=#
Y=.

#X...X#
###.###
Y#...#.
.......
Y#...#.
#######
#######`,

`
dir:NSW
name:threeway
X=#
Y=#

#X...X#
###.###
Y#...##
......#
Y#...##
###.###
###.###`,

`
dir:NSE
name:threeway
X=#
Y=#

#X...X#
###.###
Y#...##
##.....
Y#...##
###.###
###.###`
];

Crypt.templates = {};

Crypt.templates.start = Crypt.tiles.start.map(tile => {
    return RG.Template.createTemplate(tile);
});

/* Returns the starting room for the crypt generation. Note that 'this' should
 * be bound to RG.Template.Level object. */
Crypt.startRoomFunc = function() {
    const tile = RG.RAND.arrayGetRand(Crypt.templates.start);
    let x = RG.RAND.getUniformInt(0, this.tilesX - 1);
    let y = RG.RAND.getUniformInt(0, this.tilesY - 1);
    switch (tile.getProp('name')) {
        case 'start_nsew': {
            x = Math.floor(this.tilesX / 2);
            y = Math.floor(this.tilesY / 2);
            break;
        }
        case 'start_sew': {
            y = 0;
            if (x === 0) {x += 1;}
            if (x === this.tilesX - 1) {x -= 1;}
            break;
        }
        case 'start_new': {
            y = this.tilesY - 1;
            if (x === 0) {x += 1;}
            if (x === this.tilesX - 1) {x -= 1;}
            break;
        }
        case 'start_nse': {
            x = 0;
            if (y === 0) {y += 1;}
            if (y === this.tilesY - 1) {y -= 1;}
            break;

        }
        case 'start_nsw': {
            x = this.tilesX - 1;
            if (y === 0) {y += 1;}
            if (y === this.tilesY - 1) {y -= 1;}
            break;

        }
        default: break;
    }

    return {
        x, y, room: tile
    };
};

Crypt.Models = {};

// Note that the starting rooms are not included in this list, thus they'll be
// placed only by the startRoomFunc
Crypt.Models.default = []
    .concat(Crypt.tiles.corner)
    .concat(Crypt.tiles.corridor)
    .concat(Crypt.tiles.omni)
    .concat(Crypt.tiles.term)
    .concat(Crypt.tiles.misc);

Crypt.templates = Crypt.Models.default.map(tile => (
    RG.Template.createTemplate(tile)
));
const transformed = RG.Template.transformList(Crypt.templates);
Crypt.templates = Crypt.templates.concat(transformed);

module.exports = Crypt;
<|endoftext|>


<commit_before>
//Note:- caAERS has tweaked the validation.js

// ===================================================================
// Author: Kruttik Aggarwal <kruttikagarwal@@gmail.com>
//
//
// NOTICE: You may use this code for any purpose, commercial or
// private, without any further permission from the author. You may
// remove this notice from your final code if you wish.
//
// You may *NOT* re-distribute this code in any way except through its
// use. That means, you can include it in your product, or your web
// site, or any other form where the code is actually being used. You
// may not put the plain javascript up on your site for download or
// include it in your javascript libraries for download.
// If you wish to share this code with others, please just point them
// to the URL instead.
// Please DO NOT link directly to my .js files from your site. Copy
// the files to your server and use them there. Thank you.
// ===================================================================

// ------------------------------------------------------------------
// The css class names are case insensitive and define the validations
// an input should go thorgh before its validated and submitted.
// The following validations are provided out of box using commons-validations:
//
// Validation Type  | CSS Class Name     | usage
// -----------------+--------------------+-----------------------
// Required         | NOTEMPTY           | <[input][select][textarea] type=[text][password] class=validate-NOTEMPTY
// Minimum Length   | MINLENGTH          | <[input].... type=.... class=validate-MINLENGTH<length>
// Maximum Length   | MAXLENGTH          | <[input].... type=.... class=validate-MAXLENGTH<length>
// Email            | EMAIL              | <[input].... type=.... class=validate-EMAIL
// Credit Card      | VISA,etc           | <[input].... type=.... class=validate-VISA[etc]
// Zip code         | ZIPCODE            | <[input].... type=.... class=validate-ZIPCODE
// Zip or Postal    | ZIP_POSTAL_CODE    | <[input].... type=.... class=validate-ZIP_POSTAL_CODE
// US Phone No.     | US_PHONE_NO        | <[input].... type=.... class=validate-US_PHONE_NO
// Alphanumeric     | ALPHANUMERIC       | <[input].... type=.... class=validate-ALPHANUMERIC
// Numeric          | NUMERIC            | <[input].... type=.... class=validate-NUMERIC
// Alphabetic       | ALPHABETIC         | <[input].... type=.... class=validate-ALPHABETIC
// date             | DATE               | <[input].... type=.... class=validate-DATE[(<format>)]
//
// NOTE : For Multiple validation use JAVA 'and' notation ('&&').
// Example:
//  <[input].... type=.... class=validate-NOTEMPTY&&MINLENGTH7&&EMAIL
// ------------------------------------------------------------------

// VALIDATION ERROR DISPLAY:
// This javascript library provides two strategies of indicating validation error on the html page.
// These strategies can be handled by setting the ERROR_STRATEGY global variable.
// --> TEXT Strategy: this is the default strategy (ERROR_STRATEGY="text")
//     For each type of validation there is a default error message which can be overridden
//     by each html page by setting the global error message variables. e.g setting the ERROR_MSG_REQUIRED global
//     variable, a page can customize the Required Feild Error Message.
// --> Highlighting Strategy: this can be activated by setting Error strategy varibale to "highlight"
//     Defalt color is red. though this can be customized setting the global variable ERROR_HIGHTLIGHT_COLOR
//
// Callback Hooks:
// The validation framework provides a callback hook for html pages to pre process and post process validations.
// --> ValidationManager.submitPreProcess=function(formElement)                        :   Any page that provides and implementation of submitPreProcess(formElement)
//                                                              		 recieve a call back on the function. If the function return
// 																		 true then the form will be validated else the form will be submitted.
// --> ValidationManager.submitPostProcess= function(formElement, continurSubmission)   :   Any page that provides and implementation of submitPostProcess(formElement, continurSubmission)
//                                                              		  recieve a call back on the function. If the function return
// 																		  true then the form will be submitted else the submit will be ignored.
//

var ValidationManager = Class.create()
var ValidationManager = {
    validate:true, //only if this flag is true, it will validate
    debug: false,
    currentFormVar:"",
    registeredInvokes: new Array(),
    ERROR_STRATEGY:"text",
    ERROR_HIGHTLIGHT_COLOR:"red",
    ERROR_MSG_REQUIRED:"Missing ",
    ERROR_MSG_PATTERN:"Invalid ",
    ERROR_MSG_MINLENGTH:"too short ",
    ERROR_MSG_MAXLENGTH:"too long ",
    ERROR_MSG_PHONE:"Invalid ",

    validateForm: function(submit) {
        formVar = submit ? Event.element(submit) : this
        submit ? Event.stop(submit) : null
        if (!ValidationManager.submitPreProcess(formVar)) {
            formVar._submit()
            return
        }
        var fields = Form.getElements(formVar)
        var checkFields = fields.findAll(function(field) {
            className = Element.classNames(field).detect(function(cls) {
                var v = cls.indexOf('validate') == 0
                return cls.indexOf('validate') == 0
            })
            return className == null ? false : className.length > 0
        })
        checkFields.each(ValidationManager.prepareField)
        if (ValidationManager.afterPrepareFeilds(formVar)) {
            flag = validateFields(checkFields, true)
            if (ValidationManager.submitPostProcess(formVar, flag, submit)) {
                ValidationManager.invokeAll(formVar)
                if (ValidationManager.debug) {
                    ValidationManager.currentFormVar = formVar
                    vLogString = "------------------
"
                    vLogString += "Form not submitted...
"
                    vLogString += "Form submit params:
"
                    vSubmitParams = Form.serialize(formVar).split("&")
                    for (vI = 0; vI < vSubmitParams.length; vI++)
                        vLogString += vSubmitParams[vI] + "
"
                    vLogString += "------------------
"
                    ValidationManager.log(vLogString)
                    ValidationManager.log("<input type='button' value='submit this form' onClick='ValidationManager.resumeSubmit()'/>")
                } else
                    formVar._submit()
            }
        }
    },
    submitPostProcess: function(formElement, validationFlag, submit) {
        //tabbedflow.js will disable the button on click,so if there is
        // validation error, makesure we enable the button back.

        if (!validationFlag) {
            if ((AE.clickSrc != null) && (!AE.clickSrc.visible())) {
                AE.clickSrc.show();
            }
        }
        AE.clickSrc = null;
        return validationFlag;
    },
    submitPreProcess: function(formElement) {
        return ValidationManager.validate;
    },
    afterPrepareFeilds: function(formElement) {
        return true
    },

    prepareField: function(element) {
        validationTypeStr = Element.classNames(element).detect(function(cls) {
            var v = cls.indexOf('validate') == 0
            return cls.indexOf('validate') == 0
        })
        validationTypeStr = validationTypeStr.substr(9)
        validations = validationTypeStr.split("&&")
        for (i = 0; i < validations.length; i++) {
            validationType = validations[i]
            if (validationType.toUpperCase() == 'NOTEMPTY' || validationType == '') {
                element.required = true
                element.requiredError = ValidationManager.ERROR_MSG_REQUIRED
            } else if (validationType.toUpperCase().indexOf('MINLENGTH') == 0) {
                element.minlength = parseInt(validationType.substr(9))
                element.minlengthError = ValidationManager.ERROR_MSG_MINLENGTH
            } else if (validationType.toUpperCase().indexOf('MAXLENGTH') == 0) {
                element.maxlength = parseInt(validationType.substr(9))
                element.maxlengthError = ValidationManager.ERROR_MSG_MAXLENGTH

            } else {
                element.pattern = validationType
                element.patternError = ValidationManager.ERROR_MSG_PATTERN
            }
        }
    },
    showError: function(element, msg) {
        strategies = ValidationManager.ERROR_STRATEGY.split("&&")
        for (i = 0; i < strategies.length; i++) {
            errorStrategy1 = strategies[i]
            if (errorStrategy1 == "text") {
                new Insertion.Bottom(element.parentNode, "

" + msg + element.title + "

")
            }
            if (errorStrategy1 == "highlight") {
                element.style._backgroundColor = element.style._backgroundColor ? element.style._backgroundColor : element.style.backgroundColor
                element.style.backgroundColor = ValidationManager.ERROR_HIGHTLIGHT_COLOR
            }
        }
    },
    removeError: function(element) {
        strategies = ValidationManager.ERROR_STRATEGY.split("&&")
        for (i = 0; i < strategies.length; i++) {
            errorStrategy2 = strategies[i]
            if (errorStrategy2 == "text") {
                msgId = element.name + "-msg"
                $(msgId) != null ? new Element.remove(msgId) : null
            }
            if (errorStrategy2 == "highlight") {
                element.style.backgroundColor = element.style._backgroundColor ? element.style._backgroundColor : element.style.backgroundColor
            }
        }
    },
    registerToInvoke: function(obj) {
        this.registeredInvokes.push(obj)
    },
    invokeAll: function(formElement) {
        for (vJ = 0; vJ < this.registeredInvokes.length; vJ++) {
            try {
                this.registeredInvokes[vJ].onValidateSubmit(formElement)
            } catch(error) {
                ValidationManager.log(error.message)
            }
        }
    },
    resumeSubmit: function() {
        this.currentFormVar._submit()
    },
    loggerDiv: "ValidationManagerLog",
    log: function(string) {
        if (ValidationManager.debug)
            document.getElementById(ValidationManager.loggerDiv) != null ? new Insertion.Bottom(ValidationManager.loggerDiv, string) : null
    },
    clearLog: function() {
        document.getElementById(ValidationManager.loggerDiv) != null ? new Element.update(ValidationManager.loggerDiv, "") : null
    },
    errorLog: function(str) {
        this.log("
----------------------
" + str + "
-------------------------
")
    },
    registerForm: function(formVariable) {
        formVariable._submit = formVariable.submit
        formVariable.submit = ValidationManager.validateForm
        Event.observe(formVariable, "submit", ValidationManager.validateForm)
    },

    setValidState: function(inputField, isValid) {
        if (isValid) {
            Element.removeClassName(inputField, "required");
            Element.removeClassName(inputField, "mandatory");
            Element.addClassName(inputField, "validField");
        } else {
            Element.removeClassName(inputField, "validField");
            Element.addClassName(inputField, "required");
        }
    },

    doFieldValidation: function(inputField) {
        ValidationManager.prepareField(inputField);
        var isValid = validateFields(new Array(inputField), false);
        ValidationManager.setValidState(inputField, isValid);
    },

    registerFields: function() {
        $$('input.required', 'input.mandatory', 'input.valueOK').each(function(inputField) {
            Event.observe(inputField, "keyup", function() {
                ValidationManager.doFieldValidation(inputField);
            });
        });

        $$('select.required', 'select.mandatory', 'select.valueOK').each(function(inputField) {
            Event.observe(inputField, "change", function() {
                ValidationManager.doFieldValidation(inputField);
            });
        });

        $$('textarea.required', 'textarea.mandatory', 'textarea.valueOK').each(function(inputField) {
            Event.observe(inputField, "keyup", function() {
                ValidationManager.doFieldValidation(inputField);
            });
        });

        $$('textarea.required', 'textarea.mandatory',  'textarea.valueOK', 'select.required', 'select.mandatory', 'select.valueOK', 'input.required', 'input.mandatory', 'input.valueOK').each(function(inputField) {
            Event.observe(inputField, "blur", function() {
                if (inputField.hasClassName("validField")) {
                    Element.removeClassName(inputField, "validField");
                    Element.removeClassName(inputField, "required");
                    Element.removeClassName(inputField, "mandatory");
                    Element.addClassName(inputField, "valueOK");
                };
            });
        });

    }
}

Event.observe(window, "load", function() {
    $$('form').each(function(formVar) {
        ValidationManager.registerForm(formVar);
    })

    ValidationManager.registerFields();
})
<commit_msg><commit_after>
//Note:- caAERS has tweaked the validation.js

// ===================================================================
// Author: Kruttik Aggarwal <kruttikagarwal@@gmail.com>
//
//
// NOTICE: You may use this code for any purpose, commercial or
// private, without any further permission from the author. You may
// remove this notice from your final code if you wish.
//
// You may *NOT* re-distribute this code in any way except through its
// use. That means, you can include it in your product, or your web
// site, or any other form where the code is actually being used. You
// may not put the plain javascript up on your site for download or
// include it in your javascript libraries for download.
// If you wish to share this code with others, please just point them
// to the URL instead.
// Please DO NOT link directly to my .js files from your site. Copy
// the files to your server and use them there. Thank you.
// ===================================================================

// ------------------------------------------------------------------
// The css class names are case insensitive and define the validations
// an input should go thorgh before its validated and submitted.
// The following validations are provided out of box using commons-validations:
//
// Validation Type  | CSS Class Name     | usage
// -----------------+--------------------+-----------------------
// Required         | NOTEMPTY           | <[input][select][textarea] type=[text][password] class=validate-NOTEMPTY
// Minimum Length   | MINLENGTH          | <[input].... type=.... class=validate-MINLENGTH<length>
// Maximum Length   | MAXLENGTH          | <[input].... type=.... class=validate-MAXLENGTH<length>
// Email            | EMAIL              | <[input].... type=.... class=validate-EMAIL
// Credit Card      | VISA,etc           | <[input].... type=.... class=validate-VISA[etc]
// Zip code         | ZIPCODE            | <[input].... type=.... class=validate-ZIPCODE
// Zip or Postal    | ZIP_POSTAL_CODE    | <[input].... type=.... class=validate-ZIP_POSTAL_CODE
// US Phone No.     | US_PHONE_NO        | <[input].... type=.... class=validate-US_PHONE_NO
// Alphanumeric     | ALPHANUMERIC       | <[input].... type=.... class=validate-ALPHANUMERIC
// Numeric          | NUMERIC            | <[input].... type=.... class=validate-NUMERIC
// Alphabetic       | ALPHABETIC         | <[input].... type=.... class=validate-ALPHABETIC
// date             | DATE               | <[input].... type=.... class=validate-DATE[(<format>)]
//
// NOTE : For Multiple validation use JAVA 'and' notation ('&&').
// Example:
//  <[input].... type=.... class=validate-NOTEMPTY&&MINLENGTH7&&EMAIL
// ------------------------------------------------------------------

// VALIDATION ERROR DISPLAY:
// This javascript library provides two strategies of indicating validation error on the html page.
// These strategies can be handled by setting the ERROR_STRATEGY global variable.
// --> TEXT Strategy: this is the default strategy (ERROR_STRATEGY="text")
//     For each type of validation there is a default error message which can be overridden
//     by each html page by setting the global error message variables. e.g setting the ERROR_MSG_REQUIRED global
//     variable, a page can customize the Required Feild Error Message.
// --> Highlighting Strategy: this can be activated by setting Error strategy varibale to "highlight"
//     Defalt color is red. though this can be customized setting the global variable ERROR_HIGHTLIGHT_COLOR
//
// Callback Hooks:
// The validation framework provides a callback hook for html pages to pre process and post process validations.
// --> ValidationManager.submitPreProcess=function(formElement)                        :   Any page that provides and implementation of submitPreProcess(formElement)
//                                                              		 recieve a call back on the function. If the function return
// 																		 true then the form will be validated else the form will be submitted.
// --> ValidationManager.submitPostProcess= function(formElement, continurSubmission)   :   Any page that provides and implementation of submitPostProcess(formElement, continurSubmission)
//                                                              		  recieve a call back on the function. If the function return
// 																		  true then the form will be submitted else the submit will be ignored.
//

var ValidationManager = Class.create()
var ValidationManager = {
    validate:true, //only if this flag is true, it will validate
    debug: false,
    currentFormVar:"",
    registeredInvokes: new Array(),
    ERROR_STRATEGY:"text",
    ERROR_HIGHTLIGHT_COLOR:"red",
    ERROR_MSG_REQUIRED:"Missing ",
    ERROR_MSG_PATTERN:"Invalid ",
    ERROR_MSG_MINLENGTH:"too short ",
    ERROR_MSG_MAXLENGTH:"too long ",
    ERROR_MSG_PHONE:"Invalid ",

    validateForm: function(submit) {
        formVar = submit ? Event.element(submit) : this
        submit ? Event.stop(submit) : null
        if (!ValidationManager.submitPreProcess(formVar)) {
            formVar._submit()
            return
        }
        var fields = Form.getElements(formVar)
        var checkFields = fields.findAll(function(field) {
            className = Element.classNames(field).detect(function(cls) {
                var v = cls.indexOf('validate') == 0
                return cls.indexOf('validate') == 0
            })
            return className == null ? false : className.length > 0
        })
        checkFields.each(ValidationManager.prepareField)
        if (ValidationManager.afterPrepareFeilds(formVar)) {
            flag = validateFields(checkFields, true)
            if (ValidationManager.submitPostProcess(formVar, flag, submit)) {
                ValidationManager.invokeAll(formVar)
                if (ValidationManager.debug) {
                    ValidationManager.currentFormVar = formVar
                    vLogString = "------------------
"
                    vLogString += "Form not submitted...
"
                    vLogString += "Form submit params:
"
                    vSubmitParams = Form.serialize(formVar).split("&")
                    for (vI = 0; vI < vSubmitParams.length; vI++)
                        vLogString += vSubmitParams[vI] + "
"
                    vLogString += "------------------
"
                    ValidationManager.log(vLogString)
                    ValidationManager.log("<input type='button' value='submit this form' onClick='ValidationManager.resumeSubmit()'/>")
                } else
                    formVar._submit()
            }
        }
    },
    submitPostProcess: function(formElement, validationFlag, submit) {
        //tabbedflow.js will disable the button on click,so if there is
        // validation error, makesure we enable the button back.

        if (!validationFlag) {
            if ((AE.clickSrc != null) && (!AE.clickSrc.visible())) {
                AE.clickSrc.show();
            }
        }
        AE.clickSrc = null;
        return validationFlag;
    },
    submitPreProcess: function(formElement) {
        return ValidationManager.validate;
    },
    afterPrepareFeilds: function(formElement) {
        return true
    },

    prepareField: function(element) {
        validationTypeStr = Element.classNames(element).detect(function(cls) {
            var v = cls.indexOf('validate') == 0
            return cls.indexOf('validate') == 0
        })
        validationTypeStr = validationTypeStr.substr(9)
        validations = validationTypeStr.split("&&")
        for (i = 0; i < validations.length; i++) {
            validationType = validations[i]
            if (validationType.toUpperCase() == 'NOTEMPTY' || validationType == '') {
                element.required = true
                element.requiredError = ValidationManager.ERROR_MSG_REQUIRED
            } else if (validationType.toUpperCase().indexOf('MINLENGTH') == 0) {
                element.minlength = parseInt(validationType.substr(9))
                element.minlengthError = ValidationManager.ERROR_MSG_MINLENGTH
            } else if (validationType.toUpperCase().indexOf('MAXLENGTH') == 0) {
                element.maxlength = parseInt(validationType.substr(9))
                element.maxlengthError = ValidationManager.ERROR_MSG_MAXLENGTH

            } else {
                element.pattern = validationType
                element.patternError = ValidationManager.ERROR_MSG_PATTERN
            }
        }
    },
    showError: function(element, msg) {
        strategies = ValidationManager.ERROR_STRATEGY.split("&&")
        for (i = 0; i < strategies.length; i++) {
            errorStrategy1 = strategies[i]
            if (errorStrategy1 == "text") {
                new Insertion.Bottom(element.parentNode, "

" + msg + element.title + "

")
            }
            if (errorStrategy1 == "highlight") {
                element.style._backgroundColor = element.style._backgroundColor ? element.style._backgroundColor : element.style.backgroundColor
                element.style.backgroundColor = ValidationManager.ERROR_HIGHTLIGHT_COLOR
            }
        }
    },
    removeError: function(element) {
        strategies = ValidationManager.ERROR_STRATEGY.split("&&")
        for (i = 0; i < strategies.length; i++) {
            errorStrategy2 = strategies[i]
            if (errorStrategy2 == "text") {
                msgId = element.name + "-msg"
                $(msgId) != null ? new Element.remove(msgId) : null
            }
            if (errorStrategy2 == "highlight") {
                element.style.backgroundColor = element.style._backgroundColor ? element.style._backgroundColor : element.style.backgroundColor
            }
        }
    },
    registerToInvoke: function(obj) {
        this.registeredInvokes.push(obj)
    },
    invokeAll: function(formElement) {
        for (vJ = 0; vJ < this.registeredInvokes.length; vJ++) {
            try {
                this.registeredInvokes[vJ].onValidateSubmit(formElement)
            } catch(error) {
                ValidationManager.log(error.message)
            }
        }
    },
    resumeSubmit: function() {
        this.currentFormVar._submit()
    },
    loggerDiv: "ValidationManagerLog",
    log: function(string) {
        if (ValidationManager.debug)
            document.getElementById(ValidationManager.loggerDiv) != null ? new Insertion.Bottom(ValidationManager.loggerDiv, string) : null
    },
    clearLog: function() {
        document.getElementById(ValidationManager.loggerDiv) != null ? new Element.update(ValidationManager.loggerDiv, "") : null
    },
    errorLog: function(str) {
        this.log("
----------------------
" + str + "
-------------------------
")
    },
    registerForm: function(formVariable) {
        formVariable._submit = formVariable.submit
        formVariable.submit = ValidationManager.validateForm
        Event.observe(formVariable, "submit", ValidationManager.validateForm)

        Event.observe(formVariable, "click", ValidationManager.formClick)
        Event.observe(formVariable, "domfocusout", ValidationManager.formBlur)
        Event.observe(formVariable, "keyup", ValidationManager.formKeyup)
        Event.observe(formVariable, "change", ValidationManager.formChange)
        Event.observe(formVariable, "focus", ValidationManager.formFocus)
    },

    setValidState: function(inputField, isValid) {
        if (isValid) {
            Element.removeClassName(inputField, "required");
            Element.removeClassName(inputField, "mandatory");
            Element.addClassName(inputField, "validField");
        } else {
            Element.removeClassName(inputField, "validField");
            Element.addClassName(inputField, "required");
        }
    },

    doFieldValidation: function(inputField) {
        ValidationManager.prepareField(inputField);
        var isValid = validateFields(new Array(inputField), false);
        ValidationManager.setValidState(inputField, isValid);
    },

    registerFields: function() {
        alert('registerFields');
        return;
        $$('input.required', 'input.mandatory', 'input.valueOK').each(function(inputField) {
            Event.stopObserving(inputField, "keyup");
            Event.observe(inputField, "keyup", function() {
                ValidationManager.doFieldValidation(inputField);
            });
        });

        $$('select.required', 'select.mandatory', 'select.valueOK').each(function(inputField) {
            Event.observe(inputField, "change", function() {
                ValidationManager.doFieldValidation(inputField);
            });
        });

        $$('textarea.required', 'textarea.mandatory', 'textarea.valueOK').each(function(inputField) {
            Event.observe(inputField, "keyup", function() {
                ValidationManager.doFieldValidation(inputField);
            });
        });

        $$('textarea.required', 'textarea.mandatory',  'textarea.valueOK', 'select.required', 'select.mandatory', 'select.valueOK', 'input.required', 'input.mandatory', 'input.valueOK').each(function(inputField) {
            Event.observe(inputField, "blur", function() {
                if (inputField.hasClassName("validField")) {
                    Element.removeClassName(inputField, "validField");
                    Element.removeClassName(inputField, "required");
                    Element.removeClassName(inputField, "mandatory");
                    Element.addClassName(inputField, "valueOK");
                };
            });
        });

    },

    getElement: function(event) {
        var inputField = Event.findElement(event, 'INPUT');
        if (inputField) return inputField;

        var inputField = Event.findElement(event, 'TEXTAREA');
        if (inputField) return inputField;

        var inputField = Event.findElement(event, 'SELECT');
        if (inputField) return inputField;

        return null;
    },

    formClick: function(event) {
        // var inputField = ValidationManager.getElement(event);
    },

    clearFieldCss: function(inputField) {
        if (inputField.hasClassName("validField")) {
            Element.removeClassName(inputField, "validField");
            Element.removeClassName(inputField, "required");
            Element.removeClassName(inputField, "mandatory");
            Element.addClassName(inputField, "valueOK");
        };
    },

    formChange: function(event) {
        var inputField = ValidationManager.getElement(event);
        if (inputField == null) return;
        if (inputField.type == "select-one" || inputField.type == "select-multiple") {
            if (inputField) ValidationManager.doFieldValidation(inputField);
        };
        inputField.onblur = function() {
            ValidationManager.clearFieldCss(inputField);
        }
    },

    formBlur: function(event) {
    },

    formFocus: function(event) {
    },

    formKeyup: function(event) {
        var inputField = ValidationManager.getElement(event);
        if (inputField.hasClassName("required") || inputField.hasClassName("mandatory") || inputField.hasClassName("valueOK") || inputField.hasClassName("validField")) {
            if (inputField) ValidationManager.doFieldValidation(inputField);
        }
    }
}

Event.observe(window, "load", function() {
    $$('form').each(function(formVar) {
        ValidationManager.registerForm(formVar);
    })
})
<|endoftext|>


<commit_before>import React from "react"
import { Box, Static } from "ink"
import isTTY from "../../../util/is-tty"
import { trackBuildError } from "gatsby-telemetry"

import { Spinner } from "../ink/components/spinner"
import { ProgressBar } from "../ink/components/progress-bar"
import { Message } from "../ink/components/messages"
import { Error } from "./components/error"
import Develop from "../ink/components/develop"

const showProgress = isTTY()

class CLI extends React.Component {
  state = {
    hasError: false,
  }

  memoizedReactElementsForMessages = []

  componentDidCatch(error, info) {
    trackBuildError(`INK`, {
      error: {
        stack: info.componentStack,
        text: error.message,
        context: {},
      },
    })
  }

  static getDerivedStateFromError(error) {
    return { hasError: true, error }
  }

  render() {
    const {
      logs: { messages, activities },
      showStatusBar,
    } = this.props

    const { hasError, error } = this.state

    if (hasError) {
      // You can render any custom fallback UI
      return (
        <Box flexDirection="row">
          <Message
            level="ACTIVITY_FAILED"
            text={`We've encountered an error: ${error.message}`}
          />
        </Box>
      )
    }

    /*
      Only operation on messages array is to push new message into it. Once
      message is there it can't change. Because of that we can do single
      transform from message object to react element and store it.
      This will avoid calling React.createElement completely for every message
      that can't change.
    */
    if (messages.length > this.memoizedReactElementsForMessages.length) {
      for (
        let index = this.memoizedReactElementsForMessages.length;
        index < messages.length;
        index++
      ) {
        const msg = messages[index]
        this.memoizedReactElementsForMessages.push(
          msg.level === `ERROR` ? (
            <Error details={msg} key={index} />
          ) : (
            <Message key={index} {...msg} />
          )
        )
      }
    }

    const spinners = []
    const progressBars = []
    if (showProgress) {
      Object.keys(activities).forEach(activityName => {
        const activity = activities[activityName]
        if (activity.status !== `IN_PROGRESS`) {
          return
        }
        if (activity.type === `spinner`) {
          spinners.push(activity)
        }
        if (activity.type === `progress` && activity.startTime) {
          progressBars.push(activity)
        }
      })
    }

    return (
      <Box flexDirection="column">
        <Box flexDirection="column">
          <Static>{this.memoizedReactElementsForMessages}</Static>

          {spinners.map(activity => (
            <Spinner key={activity.id} {...activity} />
          ))}

          {progressBars.map(activity => (
            <ProgressBar
              key={activity.id}
              message={activity.text}
              total={activity.total}
              current={activity.current}
              startTime={activity.startTime}
            />
          ))}
        </Box>
        {showStatusBar && <Develop />}
      </Box>
    )
  }
}

export default CLI
<commit_msg>fix(gatsby-cli): Fix import (#22388)<commit_after>import React from "react"
import { Box, Static } from "ink"
import { isTTY } from "../../../util/is-tty"
import { trackBuildError } from "gatsby-telemetry"

import { Spinner } from "../ink/components/spinner"
import { ProgressBar } from "../ink/components/progress-bar"
import { Message } from "../ink/components/messages"
import { Error } from "./components/error"
import Develop from "../ink/components/develop"

const showProgress = isTTY()

class CLI extends React.Component {
  state = {
    hasError: false,
  }

  memoizedReactElementsForMessages = []

  componentDidCatch(error, info) {
    trackBuildError(`INK`, {
      error: {
        stack: info.componentStack,
        text: error.message,
        context: {},
      },
    })
  }

  static getDerivedStateFromError(error) {
    return { hasError: true, error }
  }

  render() {
    const {
      logs: { messages, activities },
      showStatusBar,
    } = this.props

    const { hasError, error } = this.state

    if (hasError) {
      // You can render any custom fallback UI
      return (
        <Box flexDirection="row">
          <Message
            level="ACTIVITY_FAILED"
            text={`We've encountered an error: ${error.message}`}
          />
        </Box>
      )
    }

    /*
      Only operation on messages array is to push new message into it. Once
      message is there it can't change. Because of that we can do single
      transform from message object to react element and store it.
      This will avoid calling React.createElement completely for every message
      that can't change.
    */
    if (messages.length > this.memoizedReactElementsForMessages.length) {
      for (
        let index = this.memoizedReactElementsForMessages.length;
        index < messages.length;
        index++
      ) {
        const msg = messages[index]
        this.memoizedReactElementsForMessages.push(
          msg.level === `ERROR` ? (
            <Error details={msg} key={index} />
          ) : (
            <Message key={index} {...msg} />
          )
        )
      }
    }

    const spinners = []
    const progressBars = []
    if (showProgress) {
      Object.keys(activities).forEach(activityName => {
        const activity = activities[activityName]
        if (activity.status !== `IN_PROGRESS`) {
          return
        }
        if (activity.type === `spinner`) {
          spinners.push(activity)
        }
        if (activity.type === `progress` && activity.startTime) {
          progressBars.push(activity)
        }
      })
    }

    return (
      <Box flexDirection="column">
        <Box flexDirection="column">
          <Static>{this.memoizedReactElementsForMessages}</Static>

          {spinners.map(activity => (
            <Spinner key={activity.id} {...activity} />
          ))}

          {progressBars.map(activity => (
            <ProgressBar
              key={activity.id}
              message={activity.text}
              total={activity.total}
              current={activity.current}
              startTime={activity.startTime}
            />
          ))}
        </Box>
        {showStatusBar && <Develop />}
      </Box>
    )
  }
}

export default CLI
<|endoftext|>


<commit_before>module.exports = {
  extends: 'airbnb',
  env: {
    browser: true,
    jest: true,
  },
  plugins: ['flowtype'],
  parser: 'babel-eslint',
  rules: {
    'arrow-parens': 'always', // For Flow typing
    'flowtype/boolean-style': 'error',
    'flowtype/define-flow-type': 'error',
    'flowtype/delimiter-dangle': ['error', 'always-multiline'],
    'flowtype/generic-spacing': 'error',
    'flowtype/no-weak-types': 'error',
    'flowtype/require-parameter-type': 'off',
    'flowtype/require-return-type': 'off',
    'flowtype/require-valid-file-annotation': 'error',
    'flowtype/semi': 'error',
    'flowtype/space-after-type-colon': 'error',
    'flowtype/space-before-generic-bracket': 'error',
    'flowtype/space-before-type-colon': 'error',
    'flowtype/type-id-match': ['error', '^[A-Z][a-z]+(?:[A-Z][a-z]+)*$'],
    'flowtype/union-intersection-spacing': 'error',
    'flowtype/use-flow-type': 'error',
    'flowtype/valid-syntax': 'error',
    'import/no-extraneous-dependencies': [
      'error', {
        devDependencies: [
          '**/server/**/*',
          '**/config/**/*',
        ]
      }
    ],
    'max-len': 'off',
    'no-confusing-arrow': 'off',
  },
};
<commit_msg>Fix the arrow-parens rule<commit_after>module.exports = {
  extends: 'airbnb',
  env: {
    browser: true,
    jest: true,
  },
  plugins: ['flowtype'],
  parser: 'babel-eslint',
  rules: {
    'arrow-parens': ['error', 'always'], // For Flow typing
    'flowtype/boolean-style': 'error',
    'flowtype/define-flow-type': 'error',
    'flowtype/delimiter-dangle': ['error', 'always-multiline'],
    'flowtype/generic-spacing': 'error',
    'flowtype/no-weak-types': 'error',
    'flowtype/require-parameter-type': 'off',
    'flowtype/require-return-type': 'off',
    'flowtype/require-valid-file-annotation': 'error',
    'flowtype/semi': 'error',
    'flowtype/space-after-type-colon': 'error',
    'flowtype/space-before-generic-bracket': 'error',
    'flowtype/space-before-type-colon': 'error',
    'flowtype/type-id-match': ['error', '^[A-Z][a-z]+(?:[A-Z][a-z]+)*$'],
    'flowtype/union-intersection-spacing': 'error',
    'flowtype/use-flow-type': 'error',
    'flowtype/valid-syntax': 'error',
    'import/no-extraneous-dependencies': [
      'error', {
        devDependencies: [
          '**/server/**/*',
          '**/config/**/*',
        ]
      }
    ],
    'max-len': 'off',
    'no-confusing-arrow': 'off',
  },
};
<|endoftext|>


<commit_before>/*
 * The Web project Gruntfile.
 *
 * Copyright 2013 Palantir Technologies, Inc. All rights reserved.
 */

module.exports = function(grunt) {
  "use strict";

  var path = require("path");
  var cwd = process.cwd();

  // project configuration
  grunt.initConfig({
    concat: {
      license: {
        src: ["license_header.txt", "build/plottable.js"],
        dest: "build/plottable.js",
      },
    },
    ts: {
      dev: {
        src: ["src/*.ts"],
        out: "build/plottable.js",
        // watch: "src",
        options: {
          target: 'es5',
          sourceMap: true,
          declaration: true,
          removeComments: true
        }
      },
      test: {
        src: ["test/*.ts"],
        out: "build/tests.js",
        // watch: "test",
        options: {
          target: 'es5',
          sourceMap: true,
          declaration: false,
          removeComments: false
        }
      },
      examples: {
        src: ["examples/*.ts"],
        outDir: "build",
        // watch: "examples",
        options: {
          target: 'es5',
          sourceMap: true,
          declaration: false,
          removeComments: false
        }
      }
    },
    tslint: {
      options: {
        configuration: grunt.file.readJSON("tslint.json")
      },
      files: ["src/*.ts", "test/*.ts"]
    },
    watch: {
      "options": {
        livereload: true
      },
      "rebuild": {
        "tasks": ["compile"],
        "files": ["src/*.ts"]
      },
      "tests": {
        "tasks": ["ts:test", "tslint"],
        "files": ["test/**.ts"]
      },
      "examples": {
        "tasks": ["ts:examples", "tslint"],
        "files": ["examples/**.ts"]
      }
    },
    blanket_mocha: {
      all: ['tests.html'],
      options: {
        threshold: 60
      }
    },
    connect: {
      server: {
        options: {
          port: 7007,
          livereload: true
        }
      }
    }
  });

  require('load-grunt-tasks')(grunt);

  // default task (this is what runs when a task isn't specified)
  grunt.registerTask("default", "launch");

  grunt.registerTask("build" , ["compile", "watch"]);
  grunt.registerTask("launch", ["connect", "build"]);
  grunt.registerTask("compile",
    ["ts:dev", "ts:test", "ts:examples", "tslint", "concat:license"]
    );

  grunt.registerTask("test", ["blanket_mocha"]);

  grunt.registerTask("watch-test", ["blanket_mocha", "watch:test"]);
};
<commit_msg>Grunt Test now compiles before testing<commit_after>/*
 * The Web project Gruntfile.
 *
 * Copyright 2013 Palantir Technologies, Inc. All rights reserved.
 */

module.exports = function(grunt) {
  "use strict";

  var path = require("path");
  var cwd = process.cwd();

  // project configuration
  grunt.initConfig({
    concat: {
      license: {
        src: ["license_header.txt", "build/plottable.js"],
        dest: "build/plottable.js",
      },
    },
    ts: {
      dev: {
        src: ["src/*.ts"],
        out: "build/plottable.js",
        // watch: "src",
        options: {
          target: 'es5',
          sourceMap: true,
          declaration: true,
          removeComments: true
        }
      },
      test: {
        src: ["test/*.ts"],
        out: "build/tests.js",
        // watch: "test",
        options: {
          target: 'es5',
          sourceMap: true,
          declaration: false,
          removeComments: false
        }
      },
      examples: {
        src: ["examples/*.ts"],
        outDir: "build",
        // watch: "examples",
        options: {
          target: 'es5',
          sourceMap: true,
          declaration: false,
          removeComments: false
        }
      }
    },
    tslint: {
      options: {
        configuration: grunt.file.readJSON("tslint.json")
      },
      files: ["src/*.ts", "test/*.ts"]
    },
    watch: {
      "options": {
        livereload: true
      },
      "rebuild": {
        "tasks": ["compile"],
        "files": ["src/*.ts"]
      },
      "tests": {
        "tasks": ["ts:test", "tslint"],
        "files": ["test/**.ts"]
      },
      "examples": {
        "tasks": ["ts:examples", "tslint"],
        "files": ["examples/**.ts"]
      }
    },
    blanket_mocha: {
      all: ['tests.html'],
      options: {
        threshold: 60
      }
    },
    connect: {
      server: {
        options: {
          port: 7007,
          livereload: true
        }
      }
    }
  });

  require('load-grunt-tasks')(grunt);

  // default task (this is what runs when a task isn't specified)
  grunt.registerTask("default", "launch");

  grunt.registerTask("build" , ["compile", "watch"]);
  grunt.registerTask("launch", ["connect", "build"]);
  grunt.registerTask("compile",
    ["ts:dev", "ts:test", "ts:examples", "tslint", "concat:license"]
    );

  grunt.registerTask("test", ["compile", "blanket_mocha"]);

  grunt.registerTask("watch-test", ["blanket_mocha", "watch:test"]);
};
<|endoftext|>


<commit_before>var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:8080/my_database');

var Schema = mongoose.Schema;

// create a schema
var gameInfoSchema = new Schema({
  title: { type: String, required: true },
  descrption: { type: String },
  pictures: [ { type: String } ],
  videos: [ { type: String } ],
  link_facebook: { type: String },
  link_twitter: { type: String },
  link_google_plus: { type: String },
  download: { type: String },
  version: { type: String },
  username: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  admin: Boolean,
  location: String,
  created_at: Date,
  updated_at: Date
});

// the schema is useless so far
// we need to create a model using it
var gameInfo = mongoose.model('gameInfo', gameInfoSchema);

// make this available to our users in our Node applications
module.exports = gameInfo;<commit_msg>Correct syntaxes in game-info.js<commit_after>var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:8080/my_database');

var Schema = mongoose.Schema;

// create a schema
var gameInfoSchema = new Schema({
  title: { type: String, required: true },
  descrption: { type: String },
  pictures: [ { type: String } ],
  videos: [ { type: String } ],
  link_facebook: { type: String },
  link_twitter: { type: String },
  link_google_plus: { type: String },
  download: { type: String },
  version: { type: String },
  username: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  admin: { type: Boolean },
  location: { type: String },
  created_at: { type: Date },
  updated_at: { type: Date }
});

// the schema is useless so far
// we need to create a model using it
var gameInfo = mongoose.model('gameInfo', gameInfoSchema);

// make this available to our users in our Node applications
module.exports = gameInfo;<|endoftext|>