<commit_before>angular.module('Calculator', ['ReportCard'])

.factory('Regex', function() {
    return {
        letterGradeRegex: /^[a-zA-Z-+]{1,3}$/,
        numberGradeRegex: /^[0-9.]{1,5}$/,
        creditWeightRegex: /^[0-9.]{1,4}$/
    };
})

.factory('Calculate', ["ReportCard", 'Results', 'Regex',
    function(ReportCard, Results, Regex) {
        //filter ReportCard for all valid grades
        function filterGrades(grades, type) {
            for (var i = 0; i < ReportCard.semesters.length; i++) { //iterate through all the semesters
                for (var j = 0; j < ReportCard.semesters[i].length; j++) { //iterate through all the grades in the semesters
                    var grade = ReportCard.semesters[i][j];
                    if (type === "letter") {
                        if (grade && grade.value && grade.creditWeight && grade.value.match(Regex.letterGradeRegex) && grade.creditWeight.match(Regex.creditWeightRegex)) {
                            grades.push({
                            	value: grade.value.toUpperCase(),
                            	creditWeight: Number(grade.creditWeight)
                            });
                        }
                    } else if (type === "number") {
                        if (grade && grade.value && grade.creditWeight && grade.value.match(Regex.numberGradeRegex) && grade.creditWeight.match(Regex.creditWeightRegex)) {
                            grades.push({
                            	value: Number(grade.value),
                            	creditWeight: Number(grade.creditWeight)
                            });
                        }
                    }
                }
            }
        }
        //formats the results data structure for display
        function setUpResults(Results,selectedUniversity) {
            for (var gradeConversion in selectedUniversity.gradeConversions) {
                if (selectedUniversity.gradeConversions.hasOwnProperty(gradeConversion)) {
                    var conversion = {
	                    type: selectedUniversity.gradeConversions[gradeConversion].type,
	                    name: selectedUniversity.gradeConversions[gradeConversion].name,
	                    min: selectedUniversity.gradeConversions[gradeConversion].min_range,
	                    max: selectedUniversity.gradeConversions[gradeConversion].max_range,
	                    result: null,
	                    totalCredits: 0,
	                    totalGrade: 0
               	 	};
                	Results[gradeConversion]=conversion;
                }
            }
            return Results;
        }
        //Converts a grade to its equivalent gpa value by looking at the grade conversion data
        function convertGradeToGPA(grade, selectedGradeConversion){
        	//formatting the input grades
        	 if(selectedGradeConversion.type==="number"){
        	 	grade=Math.round(Number(grade));
        	 }

        	 for(var i=0;i<selectedGradeConversion.gpaConversion.length;i++){
        	 	if(selectedGradeConversion.type==='number'){
        	 		if(grade>=selectedGradeConversion.gpaConversion[i].min && grade<=selectedGradeConversion.gpaConversion[i].max){
        	 			return selectedGradeConversion.gpaConversion[i].value;
        	 		}
        	 	}
        	 	else if (selectedGradeConversion.type==="letter"){
        	 		if(selectedGradeConversion.gpaConversion[i].letters.indexOf(grade)>-1){
        	 			return selectedGradeConversion.gpaConversion[i].value;
        	 		}
        	 	}
        	 	else{
        	 		console.error('Invalid grade conversion type from dataset');
        	 	}
        	 }
        }
        //converts a gpa to the equivalient grade. If its like a percentage where a range of percentages equal to a single
        //gpa, it will take the average of those percentages. If the input is like 12-point where is point is equivalent
        //to a single gpa, it will take the average of min and max and so it will still equal to the grade
        //if the output grade is letter, it will pick the maximum gpa thats less than the input grade
        function convertGPAToGrade(gpa, selectedGradeConversion){
            if(selectedGradeConversion.type==='letter'){
                gpa=Math.round(gpa*10)/10;
                var maximumGPA=0;
                for(var i=0;i<selectedGradeConversion.gpaConversion.length;i++){

                    if (gpa>=selectedGradeConversion.gpaConversion[i].value && maximumGPA<selectedGradeConversion.gpaConversion[i].value){
                        maximumGPA=selectedGradeConversion.gpaConversion[i].value;
                    }
                }
                for(var i=0;i<selectedGradeConversion.gpaConversion.length;i++){
                    if(selectedGradeConversion.gpaConversion[i].value===maximumGPA){
                        return selectedGradeConversion.gpaConversion[i].letters[0];
                    }
                }
            }
            else if (selectedGradeConversion.type==='number'){
                for(var i=0;i<selectedGradeConversion.gpaConversion.length;i++){
                    if(selectedGradeConversion.gpaConversion[i].value===gpa){
                        return (selectedGradeConversion.gpaConversion[i].min+selectedGradeConversion.gpaConversion[i].max)/2;
                    }
                }
            }
            else{
                console.error('Invalid grade conversion type from dataset');
            }

        }
        function calculateFinalResult(Results,selectedUniversity){
        	for(var outputGradeKey in Results){
        		if(Results.hasOwnProperty(outputGradeKey)){
                    if(Results[outputGradeKey].type==="number"){
                        Results[outputGradeKey].result=Results[outputGradeKey].totalGrade/Results[outputGradeKey].totalCredits;
                    }
        			else if(Results[outputGradeKey].type==="letter"){
                        var finalGPA=Results[outputGradeKey].totalGrade/Results[outputGradeKey].totalCredits;
                        Results[outputGradeKey].result= convertGPAToGrade(finalGPA,selectedUniversity.gradeConversions[outputGradeKey]);
                    }
                    else{
                        console.error('Wrong output grade conversion type in results. Must be either letter or number');
                    }
        		}
        	}
        }
        return function(university) {
            var input_grades = [];
            var output_grades = [];
            var selectedUniversity = university.selected.value;
            var selectedGradeConversion = selectedUniversity.gradeConversions[university.selectedGradeInput];
            var type = selectedGradeConversion.type;

            //setup input grades
            filterGrades(input_grades, type);

            //set up results
            setUpResults(Results,selectedUniversity);
            //if number, calculate its respective number and calculate gpa and convert backwards to everything else
            //if letter, simply calculate gpa, then convert backwards to everything else
            for (var i = 0; i < input_grades.length; i++) {
                if (type === "number") { //convert each input grade to gpa and then to output grade, unless the output grade is same as the input grade
                   	for (var gradeConversionKey in selectedUniversity.gradeConversions) {
	                	if (selectedUniversity.gradeConversions.hasOwnProperty(gradeConversionKey)) {
                           var outputGradeConversion=selectedUniversity.gradeConversions[gradeConversionKey]; //the grade conversion type to convert to
	                       if(university.selectedGradeInput===gradeConversionKey){ //if the input grade is the same as the output grade, no conversion needed
	                       		Results[university.selectedGradeInput].totalGrade+=input_grades[i].value*input_grades[i].creditWeight;
	                       		Results[university.selectedGradeInput].totalCredits+=input_grades[i].creditWeight;
	                       }
	                       else{
                                if(outputGradeConversion.type==="letter"){ //do a gpa conversion, calculate final gpa, the convert to letter grade since we cant add up letter grades
                                    Results[gradeConversionKey].totalGrade+=convertGradeToGPA(input_grades[i].value,selectedGradeConversion)*input_grades[i].creditWeight;
                                    Results[gradeConversionKey].totalCredits+=input_grades[i].creditWeight;
                                }
                                else if(outputGradeConversion.type==="number"){ //do a gpa conversion first and convert to the the output grade (ie. Percentage -> GPA -> 12-Point)
                                    Results[gradeConversionKey].totalGrade+=convertGPAToGrade(convertGradeToGPA(input_grades[i].value,selectedGradeConversion),outputGradeConversion)*input_grades[i].creditWeight;
                                    Results[gradeConversionKey].totalCredits+=input_grades[i].creditWeight;
                                }
                                else{
                                    console.error('Grade conversions types can either be letter or number');
                                }
	                       }
	                    }
	                }
                }
                else if (type==="letter"){

                }
            }

            calculateFinalResult(Results,selectedUniversity);
            console.log(Results);
        };
    }
]);<commit_msg>Implemented letter input conversion<commit_after>angular.module('Calculator', ['ReportCard'])

.factory('Regex', function() {
    return {
        letterGradeRegex: /^[a-zA-Z-+]{1,3}$/,
        numberGradeRegex: /^[0-9.]{1,5}$/,
        creditWeightRegex: /^[0-9.]{1,4}$/
    };
})

.factory('Calculate', ["ReportCard", 'Results', 'Regex',
    function(ReportCard, Results, Regex) {
        //filter ReportCard for all valid grades
        function filterGrades(grades, type) {
            for (var i = 0; i < ReportCard.semesters.length; i++) { //iterate through all the semesters
                for (var j = 0; j < ReportCard.semesters[i].length; j++) { //iterate through all the grades in the semesters
                    var grade = ReportCard.semesters[i][j];
                    if (type === "letter") {
                        if (grade && grade.value && grade.creditWeight && grade.value.match(Regex.letterGradeRegex) && grade.creditWeight.match(Regex.creditWeightRegex)) {
                            grades.push({
                            	value: grade.value.toUpperCase(),
                            	creditWeight: Number(grade.creditWeight)
                            });
                        }
                    } else if (type === "number") {
                        if (grade && grade.value && grade.creditWeight && grade.value.match(Regex.numberGradeRegex) && grade.creditWeight.match(Regex.creditWeightRegex)) {
                            grades.push({
                            	value: Number(grade.value),
                            	creditWeight: Number(grade.creditWeight)
                            });
                        }
                    }
                }
            }
        }
        //formats the results data structure for display
        function setUpResults(Results,selectedUniversity) {
            for (var gradeConversion in selectedUniversity.gradeConversions) {
                if (selectedUniversity.gradeConversions.hasOwnProperty(gradeConversion)) {
                    var conversion = {
	                    type: selectedUniversity.gradeConversions[gradeConversion].type,
	                    name: selectedUniversity.gradeConversions[gradeConversion].name,
	                    min: selectedUniversity.gradeConversions[gradeConversion].min_range,
	                    max: selectedUniversity.gradeConversions[gradeConversion].max_range,
	                    result: null,
	                    totalCredits: 0,
	                    totalGrade: 0
               	 	};
                	Results[gradeConversion]=conversion;
                }
            }
            return Results;
        }
        //Converts a grade to its equivalent gpa value by looking at the grade conversion data
        function convertGradeToGPA(grade, selectedGradeConversion){
        	//formatting the input grades
        	 if(selectedGradeConversion.type==="number"){
        	 	grade=Math.round(Number(grade));
        	 }

        	 for(var i=0;i<selectedGradeConversion.gpaConversion.length;i++){
        	 	if(selectedGradeConversion.type==='number'){
        	 		if(grade>=selectedGradeConversion.gpaConversion[i].min && grade<=selectedGradeConversion.gpaConversion[i].max){
        	 			return selectedGradeConversion.gpaConversion[i].value;
        	 		}
        	 	}
        	 	else if (selectedGradeConversion.type==="letter"){
        	 		if(selectedGradeConversion.gpaConversion[i].letters.indexOf(grade)>-1){
        	 			return selectedGradeConversion.gpaConversion[i].value;
        	 		}
        	 	}
        	 	else{
        	 		console.error('Invalid grade conversion type from dataset');
        	 	}
        	 }
        }
        //converts a gpa to the equivalient grade. If its like a percentage where a range of percentages equal to a single
        //gpa, it will take the average of those percentages. If the input is like 12-point where is point is equivalent
        //to a single gpa, it will take the average of min and max and so it will still equal to the grade
        //if the output grade is letter, it will pick the maximum gpa thats less than the input grade
        function convertGPAToGrade(gpa, selectedGradeConversion){
            if(selectedGradeConversion.type==='letter'){
                gpa=Math.round(gpa*10)/10;
                var maximumGPA=0;
                for(var i=0;i<selectedGradeConversion.gpaConversion.length;i++){

                    if (gpa>=selectedGradeConversion.gpaConversion[i].value && maximumGPA<selectedGradeConversion.gpaConversion[i].value){
                        maximumGPA=selectedGradeConversion.gpaConversion[i].value;
                    }
                }
                for(var i=0;i<selectedGradeConversion.gpaConversion.length;i++){
                    if(selectedGradeConversion.gpaConversion[i].value===maximumGPA){
                        return selectedGradeConversion.gpaConversion[i].letters[0];
                    }
                }
            }
            else if (selectedGradeConversion.type==='number'){
                for(var i=0;i<selectedGradeConversion.gpaConversion.length;i++){
                    if(selectedGradeConversion.gpaConversion[i].value===gpa){
                        return (selectedGradeConversion.gpaConversion[i].min+selectedGradeConversion.gpaConversion[i].max)/2;
                    }
                }
            }
            else{
                console.error('Invalid grade conversion type from dataset');
            }

        }
        function calculateFinalResult(Results,selectedUniversity){
        	for(var outputGradeKey in Results){
        		if(Results.hasOwnProperty(outputGradeKey)){
                    if(Results[outputGradeKey].type==="number"){
                        Results[outputGradeKey].result=Results[outputGradeKey].totalGrade/Results[outputGradeKey].totalCredits;
                    }
        			else if(Results[outputGradeKey].type==="letter"){
                        var finalGPA=Results[outputGradeKey].totalGrade/Results[outputGradeKey].totalCredits;
                        Results[outputGradeKey].result= convertGPAToGrade(finalGPA,selectedUniversity.gradeConversions[outputGradeKey]);
                    }
                    else{
                        console.error('Wrong output grade conversion type in results. Must be either letter or number');
                    }
        		}
        	}
        }
        return function(university) {
            var input_grades = [];
            var output_grades = [];
            var selectedUniversity = university.selected.value;
            var selectedGradeConversion = selectedUniversity.gradeConversions[university.selectedGradeInput];
            var type = selectedGradeConversion.type;

            //setup input grades
            filterGrades(input_grades, type);

            //set up results
            setUpResults(Results,selectedUniversity);
            //if number, calculate its respective number and calculate gpa and convert backwards to everything else
            //if letter, simply calculate gpa, then convert backwards to everything else
            for (var i = 0; i < input_grades.length; i++) {
                if (type === "number") { //convert each input grade to gpa and then to output grade, unless the output grade is same as the input grade
                   	for (var gradeConversionKey in selectedUniversity.gradeConversions) {
	                	if (selectedUniversity.gradeConversions.hasOwnProperty(gradeConversionKey)) {
                           var outputGradeConversion=selectedUniversity.gradeConversions[gradeConversionKey]; //the grade conversion type to convert to
	                       if(university.selectedGradeInput===gradeConversionKey){ //if the input grade is the same as the output grade, no conversion needed
	                       		Results[university.selectedGradeInput].totalGrade+=input_grades[i].value*input_grades[i].creditWeight;
	                       		Results[university.selectedGradeInput].totalCredits+=input_grades[i].creditWeight;
	                       }
	                       else{
                                if(outputGradeConversion.type==="letter"){ //do a gpa conversion, calculate final gpa, the convert to letter grade since we cant add up letter grades
                                    Results[gradeConversionKey].totalGrade+=convertGradeToGPA(input_grades[i].value,selectedGradeConversion)*input_grades[i].creditWeight;
                                    Results[gradeConversionKey].totalCredits+=input_grades[i].creditWeight;
                                }
                                else if(outputGradeConversion.type==="number"){ //do a gpa conversion first and convert to the the output grade (ie. Percentage -> GPA -> 12-Point)
                                    Results[gradeConversionKey].totalGrade+=convertGPAToGrade(convertGradeToGPA(input_grades[i].value,selectedGradeConversion),outputGradeConversion)*input_grades[i].creditWeight;
                                    Results[gradeConversionKey].totalCredits+=input_grades[i].creditWeight;
                                }
                                else{
                                    console.error('Grade conversions types can either be letter or number');
                                }
	                       }
	                    }
	                }
                }
                else if (type==="letter"){
                	for (var gradeConversionKey in selectedUniversity.gradeConversions) {
                        if (selectedUniversity.gradeConversions.hasOwnProperty(gradeConversionKey)) {
                           var outputGradeConversion=selectedUniversity.gradeConversions[gradeConversionKey];
                            if(outputGradeConversion.type==="letter"){
                                Results[gradeConversionKey].totalGrade+=convertGradeToGPA(input_grades[i].value,selectedGradeConversion)*input_grades[i].creditWeight;
                                Results[gradeConversionKey].totalCredits+=input_grades[i].creditWeight;
                            }
                            else if(outputGradeConversion.type==="number"){ //do a gpa conversion first and convert to the the output grade (ie. Percentage -> GPA -> 12-Point)
                                Results[gradeConversionKey].totalGrade+=convertGPAToGrade(convertGradeToGPA(input_grades[i].value,selectedGradeConversion),outputGradeConversion)*input_grades[i].creditWeight;
                                Results[gradeConversionKey].totalCredits+=input_grades[i].creditWeight;
                            }
                            else{
                                console.error('Grade conversions types can either be letter or number');
                            }
                        }
                    }
                }
            }

            calculateFinalResult(Results,selectedUniversity);
            console.log(Results);
        };
    }
]);<|endoftext|>


<commit_before>exports.http = {
    host: 'localhost',
    port: 8080,
};

exports.logger = {
    level: process.env.DEBUG ? 'debug' : 'info',
};

exports.mongoose = {
    host: 'localhost',
    port: 27017,
    base: 'test',
};<commit_msg>[src] update default host<commit_after>exports.http = {
    host: '0.0.0.0',
    port: 8080,
};

exports.logger = {
    level: process.env.DEBUG ? 'debug' : 'info',
};

exports.mongoose = {
    host: 'localhost',
    port: 27017,
    base: 'test',
};<|endoftext|>


<commit_before>module.exports = {
    "ssl": {
        "enabled": true,
        "contentSecurityPolicy": {
            "directives": {
                "scriptSrc": ["https://use.fontawesome.com/", "https://www.googletagmanager.com/", "'unsafe-inline' js/modernizr-2.0.6.js"],
                "fontSrc": ["https://use.fontawesome.com/"],
                "connectSrc": ["https://www.google-analytics.com"],
                "styleSrc": ["https://use.fontawesome.com", "'unsafe-inline' js/modernizr-2.0.6.js"]
            }
        }
    },
    "subdomains": {
        "index": {
            "aliases": ["www"],
            "template": "ken"
        }
    },

    "rendering": {
        "overrideViewEngine": ["liquid", "ejs"]
    },

    "favicon": "img/KenEuckerLLCLogo.jpg"
}<commit_msg>Changing to a different favicon<commit_after>module.exports = {
    "ssl": {
        "enabled": true,
        "contentSecurityPolicy": {
            "directives": {
                "scriptSrc": ["https://use.fontawesome.com/", "https://www.googletagmanager.com/", "'unsafe-inline' js/modernizr-2.0.6.js"],
                "fontSrc": ["https://use.fontawesome.com/"],
                "connectSrc": ["https://www.google-analytics.com"],
                "styleSrc": ["https://use.fontawesome.com", "'unsafe-inline' js/modernizr-2.0.6.js"]
            }
        }
    },
    "subdomains": {
        "index": {
            "aliases": ["www"],
            "template": "ken"
        }
    },

    "rendering": {
        "overrideViewEngine": ["liquid", "ejs"]
    },

    // "favicon": "img/KenEuckerLLCLogo.jpg",
}<|endoftext|>


<commit_before>var $ = require('jquery-browserify'),
    Vector = require('./Vector'),
    AABB = require('./AABB'),
    World = require('./World'),
    Solid = require('./Solid'),
    fs = require('fs'),
    vertShader = fs.readFileSync(__dirname + '/vert.glsl'),
    fragShader = fs.readFileSync(__dirname + '/frag.glsl');

module.exports = Dust;

function Dust() {
    var self = this;

    this.socket = io.connect('http://192.168.1.77:9966');

    this.WIDTH  = $('#canvainer').width();
    this.HEIGHT = $('#canvainer').height();

    this.gl = this.getGL();
    this.shaderProgram = this.getShaderProgram(vertShader, fragShader);
    this.gl.useProgram(this.shaderProgram);

    this.projectionMatrix = makeProjectionMatrix(this.WIDTH, this.HEIGHT);
    this.modelViewMatrix = [];

    this.uProjectionMatrix = this.gl.getUniformLocation(this.shaderProgram, 'projectionMatrix');
    this.uModelViewMatrix = this.gl.getUniformLocation(this.shaderProgram, 'modelViewMatrix');

    this.loadIdentity();
    this.setBuffer();

    this.world = this.initWorld();
    this.selectionBox = null;
    this.grid = new Array2D(this.WIDTH, this.HEIGHT);
}

Dust.prototype.getGL = function() {
    htmlCanvas = "<canvas width=" + "\"" + this.WIDTH + "\"" + "height=" + "\"" + this.HEIGHT + "\"" + "></canvas>";

    $('#canvainer').append(htmlCanvas);

    return $('canvas').get(0).getContext('webgl');
};

Dust.prototype.initWorld = function() {
    // Define world
    var gravity = new Vector(0.0, 50),
        worldBounds = new AABB(0, 0, this.WIDTH, this.HEIGHT);

    var world = new World({
        forces: gravity,
        bounds: worldBounds
    });

    var solid = new Solid(100, 10, 100, 300);
    world.pushSolid(solid);

    return world;
};

Dust.prototype.updateWorld = function(dt) {
    //this.world.update(dt);
};

Dust.prototype.drawWorld = function() {
    var self = this;

    this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);

    for (var x = 0; x < this.grid.length; x++) {
        for (var y = 0; y < this.grid[x].length; y++) {
            var cell = this.grid[x][y];

            switch(cell) {
                case 0:
                    break;
                case 1:
                    this.mvTranslate(x, y, 0);

                    this.gl.uniformMatrix4fv(this.uProjectionMatrix, false, this.projectionMatrix);

                    this.gl.uniformMatrix4fv(this.uModelViewMatrix, false, this.modelViewMatrix);

                    //this.gl.drawArrays(this.gl.TRIANGLES, 0, 6);
                    this.gl.drawElements(this.gl.TRIANGLE_STRIP, 4, this.gl.UNSIGNED_SHORT, 0);

                    break;
                default:
                    break;
            }
        }
    }

};

Dust.prototype.resizeSelection = function(w, h) {
    this.selectionBox.resize(w, h);
};

Dust.prototype.moveSelection = function(vec) {
    this.selectionBox.move(vec);
};

Dust.prototype.drawSelection = function(x, y, w, h) {
    this.selectionBox = new Solid(w, h, x, y);
};

Dust.prototype.spawnSolid = function(x, y, w, h) {
    var s = new Solid(w, h, x, y);
    this.world.pushSolid(s);
};

Dust.prototype.spawnDust = function(x, y) {
    var n = 50,
        area = 10;
    for (var i = 0; i < n; i++) {
        x = Math.round((x - area/2) + area*Math.random());
        y = Math.round((y - area/2) + area*Math.random());
        s = new Vector(x, y);

        //if(!this.world.collides(s) && s.within(this.world.bounds)) this.world.pushSand(s);

        this.grid[s.x][s.y] = 1;
    }
};

// If a solid exists here, it will be sandified
Dust.prototype.sandifySolid = function(vec) {
    var s = this.world.collides(vec);
    if(s) {
        for (var x = 0; x < s.w; x++) {
            for (var y = 0; y < s.h; y++) {
                var sand = new Vector(x + s.pos.x, y + s.pos.y);
                this.world.pushSand(sand);
            }
        }
        var index = this.world.solids.indexOf(s);
        this.world.solids.splice(index, 1);
    }
};

// Compiles a shader program from given sources
Dust.prototype.getShaderProgram = function(vert, frag) {
    var vertexShader = this.gl.createShader(this.gl.VERTEX_SHADER),
        fragmentShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);

    this.gl.shaderSource(vertexShader, vert);
    this.gl.shaderSource(fragmentShader, frag);

    this.gl.compileShader(vertexShader);
    this.gl.compileShader(fragmentShader);

    if(!this.gl.getShaderParameter(vertexShader, this.gl.COMPILE_STATUS)) {
        console.error("Vertex shader won't compile mate: ", this.gl.getShaderInfoLog(vertexShader));
    }

    if(!this.gl.getShaderParameter(fragmentShader, this.gl.COMPILE_STATUS)) {
        console.error("Fragment shader won't compile mate: ", this.gl.getShaderInfoLog(fragmentShader));
    }

    var program = this.gl.createProgram();

    this.gl.attachShader(program, vertexShader);
    this.gl.attachShader(program, fragmentShader);
    this.gl.linkProgram(program);

    return program;
};

Dust.prototype.setBuffer = function() {
    this.dustBuffer = this.gl.createBuffer();
    this.indexBuffer = this.gl.createBuffer();

    this.floatArray = new Float32Array([
            -1.0,  1.0,
            -1.0, -1.0,
            1.0,   1.0,
            1.0,  -1.0]);
    this.indexArray = new Uint16Array([
            0, 1, 2, 3]);

    this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.dustBuffer);
    this.gl.bufferData(this.gl.ARRAY_BUFFER, this.floatArray, this.gl.STATIC_DRAW);

    this.positionAttribute = this.gl.getAttribLocation(this.shaderProgram, "position");
    this.gl.enableVertexAttribArray(this.positionAttribute);
    this.gl.vertexAttribPointer(this.positionAttribute, 2, this.gl.FLOAT, false, 0, 0);

    this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
    this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, this.indexArray, this.gl.STATIC_DRAW);
};

Dust.prototype.loadIdentity = function() {
    this.modelViewMatrix = [
            1, 0, 0, 0,
            0, 1, 0, 0,
            0, 0, 1, 0,
            0, 0, 0, 1
        ];
};

Dust.prototype.mvTranslate = function(x, y, z) {
    x -= this.WIDTH / 2;
    y -= this.HEIGHT / 2;

    this.modelViewMatrix[12] = x;
    this.modelViewMatrix[13] = y;
    this.modelViewMatrix[14] = z;
};

// Assorted functions
function Array2D(w, h) {
    var array = [];

    for (var x = 0; x < w; x++) {
        array[x] = [];
        for (var y = 0; y < h; y++) {
            array[x][y] = 0;
        }
    }

    return array;
}

function makeProjectionMatrix(width, height) {
    return [
        2 / width, 0,           0, 0,
        0,         -2 / height, 0, 0,
        0,         0,           1, 0,
        0,         0,           0, 1
    ];
}
//new THREE.OrthographicCamera(this.WIDTH / -2, this.WIDTH / 2, this.HEIGHT / 2, this.HEIGHT / -2, 1, -1);

<commit_msg>Sand settles<commit_after>var $ = require('jquery-browserify'),
    Vector = require('./Vector'),
    AABB = require('./AABB'),
    World = require('./World'),
    Solid = require('./Solid'),
    fs = require('fs'),
    vertShader = fs.readFileSync(__dirname + '/vert.glsl'),
    fragShader = fs.readFileSync(__dirname + '/frag.glsl');

module.exports = Dust;

function Dust() {
    var self = this;

    this.socket = io.connect('http://192.168.1.77:9966');

    this.WIDTH  = $('#canvainer').width();
    this.HEIGHT = $('#canvainer').height();

    this.gl = this.getGL();
    this.shaderProgram = this.getShaderProgram(vertShader, fragShader);
    this.gl.useProgram(this.shaderProgram);

    this.projectionMatrix = makeProjectionMatrix(this.WIDTH, this.HEIGHT);
    this.modelViewMatrix = [];

    this.uProjectionMatrix = this.gl.getUniformLocation(this.shaderProgram, 'projectionMatrix');
    this.uModelViewMatrix = this.gl.getUniformLocation(this.shaderProgram, 'modelViewMatrix');

    this.gl.uniformMatrix4fv(this.uProjectionMatrix, false, this.projectionMatrix);

    this.loadIdentity();
    this.setBuffer();

    this.world = null; //this.initWorld();
    this.grid = new Array2D(this.WIDTH, this.HEIGHT);
    this.bounds = new AABB(0, 0, this.WIDTH, this.HEIGHT); // TODO make code use AABB
    this.sands = [];

    this.selectionBox = null;
}

Dust.prototype.getGL = function() {
    htmlCanvas = "<canvas width=" + "\"" + this.WIDTH + "\"" + "height=" + "\"" + this.HEIGHT + "\"" + "></canvas>";

    $('#canvainer').append(htmlCanvas);

    return $('canvas').get(0).getContext('webgl');
};

Dust.prototype.initWorld = function() {
    // Define world
    var gravity = new Vector(0.0, 50),
        worldBounds = new AABB(0, 0, this.WIDTH, this.HEIGHT);

    var world = new World({
        forces: gravity,
        bounds: worldBounds
    });

    var solid = new Solid(100, 10, 100, 300);
    world.pushSolid(solid);

    return world;
};

Dust.prototype.updateWorld = function(dt) {
    //this.world.update(dt);

    for (var i = 0; i < this.sands.length; i++) {
        var sand = this.sands[i];

        if(sand.x >= 0 && sand.y >= 0 && sand.x <= (this.WIDTH - 1) && sand.y <= (this.HEIGHT - 1)) {

            if(this.grid[sand.x][sand.y + 1] === 0) {
                sand.y += 1;
                this.grid[sand.x][sand.y - 1] = 0;
                this.grid[sand.x][sand.y] = 1;
            }
        }
    }
};

Dust.prototype.drawWorld = function() {
    var self = this;

    this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);

    for (var x = 0; x < this.grid.length; x++) {
        for (var y = 0; y < this.grid[x].length; y++) {
            var cell = this.grid[x][y];

            switch(cell) {
                case 0:
                    break;
                case 1:
                    this.mvTranslate(x, y, 0);

                    this.gl.uniformMatrix4fv(this.uModelViewMatrix, false, this.modelViewMatrix);

                    this.gl.drawElements(this.gl.TRIANGLE_STRIP, 4, this.gl.UNSIGNED_SHORT, 0);

                    break;
                default:
                    break;
            }
        }
    }

};

Dust.prototype.resizeSelection = function(w, h) {
    this.selectionBox.resize(w, h);
};

Dust.prototype.moveSelection = function(vec) {
    this.selectionBox.move(vec);
};

Dust.prototype.drawSelection = function(x, y, w, h) {
    this.selectionBox = new Solid(w, h, x, y);
};

Dust.prototype.spawnSolid = function(x, y, w, h) {
    var s = new Solid(w, h, x, y);
    this.world.pushSolid(s);
};

Dust.prototype.spawnDust = function(x, y) {
    var n = 50,
        area = 10;

    for (var i = 0; i < n; i++) {
        x = Math.round((x - area/2) + area*Math.random()) - 1;
        y = Math.round((y - area/2) + area*Math.random()) - 1;

        if(x >= 0 && y >= 0 && (x <= this.WIDTH) && y <= (this.HEIGHT - 1)) {
            var s = new Vector(x, y);

            //if(!this.world.collides(s) && s.within(this.world.bounds)) this.world.pushSand(s);

            this.sands.push(s);
        }
    }
};

// If a solid exists here, it will be sandified
Dust.prototype.sandifySolid = function(vec) {
    var s = this.world.collides(vec);
    if(s) {
        for (var x = 0; x < s.w; x++) {
            for (var y = 0; y < s.h; y++) {
                var sand = new Vector(x + s.pos.x, y + s.pos.y);
                this.world.pushSand(sand);
            }
        }
        var index = this.world.solids.indexOf(s);
        this.world.solids.splice(index, 1);
    }
};

// Compiles a shader program from given sources
Dust.prototype.getShaderProgram = function(vert, frag) {
    var vertexShader = this.gl.createShader(this.gl.VERTEX_SHADER),
        fragmentShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);

    this.gl.shaderSource(vertexShader, vert);
    this.gl.shaderSource(fragmentShader, frag);

    this.gl.compileShader(vertexShader);
    this.gl.compileShader(fragmentShader);

    if(!this.gl.getShaderParameter(vertexShader, this.gl.COMPILE_STATUS)) {
        console.error("Vertex shader won't compile mate: ", this.gl.getShaderInfoLog(vertexShader));
    }

    if(!this.gl.getShaderParameter(fragmentShader, this.gl.COMPILE_STATUS)) {
        console.error("Fragment shader won't compile mate: ", this.gl.getShaderInfoLog(fragmentShader));
    }

    var program = this.gl.createProgram();

    this.gl.attachShader(program, vertexShader);
    this.gl.attachShader(program, fragmentShader);
    this.gl.linkProgram(program);

    return program;
};

Dust.prototype.setBuffer = function() {
    this.dustBuffer = this.gl.createBuffer();
    this.indexBuffer = this.gl.createBuffer();

    this.floatArray = new Float32Array([
            -1.0,  1.0,
            -1.0, -1.0,
            1.0,   1.0,
            1.0,  -1.0]);
    this.indexArray = new Uint16Array([
            0, 1, 2, 3]);

    this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.dustBuffer);
    this.gl.bufferData(this.gl.ARRAY_BUFFER, this.floatArray, this.gl.STATIC_DRAW);

    this.positionAttribute = this.gl.getAttribLocation(this.shaderProgram, "position");
    this.gl.enableVertexAttribArray(this.positionAttribute);
    this.gl.vertexAttribPointer(this.positionAttribute, 2, this.gl.FLOAT, false, 0, 0);

    this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
    this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, this.indexArray, this.gl.STATIC_DRAW);
};

Dust.prototype.loadIdentity = function() {
    this.modelViewMatrix = [
            1, 0, 0, 0,
            0, 1, 0, 0,
            0, 0, 1, 0,
            0, 0, 0, 1
        ];
};

Dust.prototype.mvTranslate = function(x, y, z) {
    x -= this.WIDTH / 2;
    y -= this.HEIGHT / 2;

    this.modelViewMatrix[12] = x;
    this.modelViewMatrix[13] = y;
    this.modelViewMatrix[14] = z;
};

// Assorted functions
function Array2D(w, h) {
    var array = [];

    for (var x = 0; x < w; x++) {
        array[x] = [];
        for (var y = 0; y < h; y++) {
            array[x][y] = 0;
        }
    }

    return array;
}

function makeProjectionMatrix(width, height) {
    return [
        2 / width, 0,           0, 0,
        0,         -2 / height, 0, 0,
        0,         0,           1, 0,
        0,         0,           0, 1
    ];
}
//new THREE.OrthographicCamera(this.WIDTH / -2, this.WIDTH / 2, this.HEIGHT / 2, this.HEIGHT / -2, 1, -1);

<|endoftext|>


<commit_before>let weave = require(  '..' )

let assert = require( 'assert' )
let http = require( 'http' )
let path = require( 'path' )
let { URL } = require( 'url' )

function test( testPath, method, headers ) {
  let options = Object.assign( new URL( testPath, 'http://localhost:8378/' ), {
    method, headers
  })

  return new Promise( ( fulfill, reject ) => {
    http.request( options, ( error, reponse ) => {
      if ( error ) return reject( error )
      let total = ''
      response.setEncoding( 'utf-8' )
      response.on( 'data', data => total += data )
      response.on( 'end', () => fulfill( total ) )
    }).end()
  })
}

function lf( localFilePath ) {
  return path.join( __dirname, localFilePath )
}

let garden = weave.createGarden( 'weave tests' )
weave.configuration.logOutputPath = lf( 'tests.log' )
// weave.verbose()

context( 'weave', function () {
  let httpRoot, weaveApp, newApp, anonymous, conf

  before( function () {
    httpRoot = lf( '../http/mocha' )

    conf = {
      'location': httpRoot,
      'mimeTypes': weave.createDictionary( lf( 'mocha.mimes' ) ),
      'errorPages': {
        404: 'test.d'
      },
      'indexes': {
        'test.a': 0,
        'test.b': 1,
        'test.c': 2
      }
    }

    weaveApp = weave( 'test', conf )
    newApp = new weave.App({ appName: 'test2' })
    anonymous = weave()

    weaveApp.link( 'localhost:8378' )
  })

  describe( 'constructing a new app', function () {
    it( 'should return an instance of weave.App', function () {
      assert( weaveApp instanceof weave.App )
    })

    it( 'should properly name the app', function () {
      assert( weaveApp.appName === 'test' )
      assert( newApp.appName === 'test2' )
      assert( anonymous.appName === undefined )
    })

    it( 'should properly configure apps', function () {
      assert( weaveApp.configuration.location === httpRoot )
    })
  })

  // describe( 'resolve index depths', function () {
  //   [ 'Test A', 'Test B', 'Test C', 'Test D' ].forEach( ( name, depth ) => {
  //     it( `should resolve to the correct index based on depth ${depth}`, function ( done ) {
  //       test( '/depth'.repeat( depth ) )
  //         .then( text => garden.log( text ) )
  //         .then( () => done() )
  //     })
  //   })
  // })
})

context( 'dictionary', function () {

})

context( 'gardens', function () {

})
<commit_msg>Having a live server prevents the tests from passing<commit_after>let weave = require(  '..' )

let assert = require( 'assert' )
let http = require( 'http' )
let path = require( 'path' )
let { URL } = require( 'url' )

function test( testPath, method, headers ) {
  let options = Object.assign( new URL( testPath, 'http://localhost:8378/' ), {
    method, headers
  })

  return new Promise( ( fulfill, reject ) => {
    http.request( options, ( error, reponse ) => {
      if ( error ) return reject( error )
      let total = ''
      response.setEncoding( 'utf-8' )
      response.on( 'data', data => total += data )
      response.on( 'end', () => fulfill( total ) )
    }).end()
  })
}

function lf( localFilePath ) {
  return path.join( __dirname, localFilePath )
}

let garden = weave.createGarden( 'weave tests' )
weave.configuration.logOutputPath = lf( 'tests.log' )
// weave.verbose()

context( 'weave', function () {
  let httpRoot, weaveApp, newApp, anonymous, conf

  before( function () {
    httpRoot = lf( '../http/mocha' )

    conf = {
      'location': httpRoot,
      'mimeTypes': weave.createDictionary( lf( 'mocha.mimes' ) ),
      'errorPages': {
        404: 'test.d'
      },
      'indexes': {
        'test.a': 0,
        'test.b': 1,
        'test.c': 2
      }
    }

    weaveApp = weave( 'test', conf )
    newApp = new weave.App({ appName: 'test2' })
    anonymous = weave()

    // weaveApp.link( 'localhost:8378' )
  })

  describe( 'constructing a new app', function () {
    it( 'should return an instance of weave.App', function () {
      assert( weaveApp instanceof weave.App )
    })

    it( 'should properly name the app', function () {
      assert( weaveApp.appName === 'test' )
      assert( newApp.appName === 'test2' )
      assert( anonymous.appName === undefined )
    })

    it( 'should properly configure apps', function () {
      assert( weaveApp.configuration.location === httpRoot )
    })
  })

  // describe( 'resolve index depths', function () {
  //   [ 'Test A', 'Test B', 'Test C', 'Test D' ].forEach( ( name, depth ) => {
  //     it( `should resolve to the correct index based on depth ${depth}`, function ( done ) {
  //       test( '/depth'.repeat( depth ) )
  //         .then( text => garden.log( text ) )
  //         .then( () => done() )
  //     })
  //   })
  // })
})

context( 'dictionary', function () {

})

context( 'gardens', function () {

})
<|endoftext|>


<commit_before>/* global $, localStorage */

import haikunate from 'haikunator';
import React from 'react';
import { clone } from 'lodash';
import Header from './Header';
import Footer from './Footer';
import Platform from './sections/Platform';
import StaticSiteGenerator from './sections/StaticSiteGenerator';
import JsLibrary from './sections/JsLibrary';
import Framework from './sections/Framework';
import TemplateEngine from './sections/TemplateEngine';
import CssFramework from './sections/CssFramework';
import CssPreprocessor from './sections/CssPreprocessor';
import BuildTool from './sections/BuildTool';
import Testing from './sections/Testing'
import Database from './sections/Database';
import Authentication from './sections/Authentication';
import JsFramework from './sections/JsFramework';
import Deployment from './sections/Deployment';
import NextSteps from './sections/NextSteps';

class Home extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleGenerateLibraryName = this.handleGenerateLibraryName.bind(this);
    this.handleAutoScroll = this.handleAutoScroll.bind(this);
    this.handleReduceAnimations = this.handleReduceAnimations.bind(this);
    this.clickDownload = this.clickDownload.bind(this);
    this.state = {};
  }

  componentDidMount() {
    try {
      const autoScroll = localStorage.getItem('autoScroll');
      const reduceAnimations = localStorage.getItem('reduceAnimations');
      this.setState({
        autoScroll: autoScroll === 'true',
        reduceAnimations: reduceAnimations === 'true'
      });
    } catch (e) {
      console.warn(e);
    }
  }

  clickDownload() {
    const state = this.state;
    const downloadBtn = this.refs.downloadBtn;

    // Google Analytics event
    // ga("send","event","Customize","Download","Customize and Download")

    if (!state.platform) {
      return this.setState({ platformValidationError: 'Please select a platfsForm.' });
    } else if (state.platform === 'html5' && !state.staticSiteGenerator) {
      return this.setState({ staticSiteGeneratorValidationError: 'Please select a static site generator.' });
    } else if (state.platform === 'library' && !state.jsLibraryName) {
      return this.setState({ jsLibraryValidationError: 'Please enter a library name.' });
    } else if (!state.framework) {
      return this.setState({ frameworkValidationError: 'Please select a framework.' });
    } else if (!state.templateEngine) {
      return this.setState({ templateEngineValidationError: 'Please select a template engine.' });
    } else if (!state.cssFramework) {
      return this.setState({ cssFrameworkValidationError: 'Please select a CSS framework.' });
    } else if (!state.cssPreprocessor) {
      return this.setState({ cssPreprocessorValidationError: 'Please select a CSS preprocessor.' });
    } else if (!state.jsFramework) {
      return this.setState({ jsFrameworkValidationError: 'Please make a selection.' });
    } else if (!state.buildTool) {
      return this.setState({ buildToolValidationError: 'Please select a build tool.' });
    } else if (!state.testing) {
      return this.setState({ testingValidationError: 'Please select a testing framework.' });
    } else if (!state.database) {
      return this.setState({ databaseValidationError: 'Please select a database.' });
    } else if (!state.authentication && state.database !== 'none') {
      return this.setState({ authenticationValidationError: 'Please check all that apply.' });
    }

    // Show next steps component
      this.setState({ showNextSteps: true });
    if (state.autoScroll) {
      $(this.refs.nextSteps).velocity('scroll');
    }

    const data = clone(state);
    data.appName = haikunate({ tokenLength: 0 });

    if (data.jsFramework === 'none') {
      data.jsFramework = null;
    }

    // Convert ES6 set to array
    data.authentication = data.authentication ? Array.from(data.authentication) : [];
    data.frameworkOptions = data.frameworkOptions ? Array.from(data.frameworkOptions) : [];
    data.reactOptions = data.reactOptions ? Array.from(data.reactOptions) : [];
    data.jsLibraryOptions = data.jsLibraryOptions ? Array.from(data.jsLibraryOptions) : [];

    $.ajax({
      url: '/download',
      method: 'POST',
      contentType: 'application/json; charset=utf-8',
      data: JSON.stringify(data)
    }).done((response, status, request) => {
      $(downloadBtn).removeAttr('disabled');

      const disp = request.getResponseHeader('Content-Disposition');
      if (disp && disp.search('attachment') !== -1) {
        const form = $('<form method="POST" action="/download">');
        $.each(data, (k, v) => {
          form.append($(`<input type="hidden" name="${k}" value="${v}">`));
        });
        $('body').append(form);
        form.submit();
      }
    }).fail((jqXHR) => {
      window.notie.alert(3, jqXHR.responseText, 2.5);
    });
  }

  handleGenerateLibraryName() {
    const newState = clone(this.state);
    newState.jsLibraryName = haikunate({ tokenLength: 0 });
    newState.jsLibraryValidationError = null;
    this.setState(newState);
  }

  handleChange(event) {
    const name = event.target.name;
    const value = event.target.value;
    const isChecked = event.target.checked;
    const state = clone(this.state);
    const refs = this.refs;

    switch (name) {
      case 'beginner':
        state.beginner = isChecked;
        break;

      case 'platformRadios':
        const whitelist = ['showModal', 'beginner', 'autoScroll', 'reduceAnimations'];
        for (const key in state) {
          if (state.hasOwnProperty(key)) {
            if (whitelist.indexOf(key) === -1) {
              state[key] = null;
            }
          }
        }
        state.platform = value;
        if (state.autoScroll) {
          $(refs.platform).velocity('scroll');
        }
        state.platformValidationError = null;
        break;

      case 'staticSiteGeneratorRadios':
        if (!state.staticSiteGenerator && state.autoScroll) {
          $(refs.staticSiteGenerator).velocity('scroll');
        }
        state.staticSiteGenerator = value;
        state.staticSiteGeneratorValidationError = null;
        break;

      case 'jsLibraryOptionsCheckboxes':
        state.jsLibraryOptions = state.jsLibraryOptions || new Set();
        if (isChecked) {
          state.jsLibraryOptions.add(value);
        } else {
          state.jsLibraryOptions.delete(value);
        }
        break;

      case 'jsLibraryName':
        state.jsLibraryName = value;
        state.jsLibraryValidationError = null;
        break;

      case 'jsLibraryAuthor':
        state.jsLibraryAuthor = value;
        break;

      case 'jsLibraryGithubUsername':
        state.jsLibraryGithubUsername = value;
        break;

      case 'jsLibraryLicenseRadios':
        state.jsLibraryLicense = value;
        break;

      case 'frameworkRadios':
        if (!state.framework && state.autoScroll) {
          $(refs.framework).velocity('scroll');
        }
        state.framework = value;
        state.frameworkValidationError = null;

        break;

      case 'frameworkOptionsCheckboxes':
        state.frameworkOptions = state.frameworkOptions || new Set();
        if (isChecked) {
          state.frameworkOptions.add(value);
        } else {
          state.frameworkOptions.delete(value);
        }
        break;

      case 'templateEngineRadios':
        if (!state.templateEngine && state.autoScroll) {
          $(refs.templateEngine).velocity('scroll');
        }
        state.templateEngineValidationError = null;
        state.templateEngine = value;
        break;

      case 'cssFrameworkRadios':
        if (!state.cssFramework && state.autoScroll) {
          $(refs.cssFramework).velocity('scroll');
        }
        if (state.cssPreprocessor) {
          state.cssPreprocessor = null;
        }
        state.cssFrameworkValidationError = null;
        state.cssFramework = value;
        break;

      case 'cssPreprocessorRadios':
        if (!state.cssPreprocessor && state.autoScroll) {
          $(refs.cssPreprocessor).velocity('scroll');
        }
        state.cssPreprocessor = value;
        state.cssPreprocessorValidationError = null;
        break;

      case 'jsFrameworkRadios':
        if (!state.jsFramework && state.autoScroll) {
          $(refs.jsFramework).velocity('scroll');
        }
        state.jsFramework = value;
        state.jsFrameworkValidationError = null;
        break;

      case 'reactOptionsCheckboxes':
        state.reactOptions = state.reactOptions || new Set();
        if (isChecked) {
          state.reactOptions.add(value);
        } else {
          state.reactOptions.delete(value);
        }
        break;

      case 'buildToolRadios':
        if (!state.buildTool && state.autoScroll) {
          $(refs.buildTool).velocity('scroll');
        }
        state.buildTool = value;
        state.buildToolValidationError = null;
        break;

      case 'testingRadios':
        if (!state.testing && state.autoScroll) {
          $(refs.testing).velocity('scroll');
        }
        state.testing = value;
        state.testingValidationError = null;
        break;

      case 'databaseRadios':
        if (!state.database && state.autoScroll) {
          $(refs.database).velocity('scroll');
        }
        if (value === 'none' && state.authentication) {
          state.authentication.clear();
        }
        state.database = value;
        state.databaseValidationError = null;
        break;

      case 'authenticationCheckboxes':
        state.authentication = state.authentication || new Set();

        const requiresEmail = (
          state.authentication.has('facebook') ||
          state.authentication.has('google') ||
          state.authentication.has('twitter')
        );

        if (isChecked) {
          if (value === 'none') {
            state.authentication.clear();
          } else {
            state.authentication.add(value);
            if (value === 'facebook' || value === 'google' || value === 'twitter') {
              state.authentication.add('email');
            }
          }
          state.authenticationValidationError = null;
        } else {
          if (value === 'email' && requiresEmail) { return; }
          state.authentication.delete(value);
        }
        break;

      case 'deploymentRadios':
        if (!state.deployment && state.autoScroll) {
          $(refs.deployment).velocity('scroll');
        }
        state.deployment = value;
        break;

      default:
      // Handle default case
    }

    this.setState(state);
  }

  handleAutoScroll(event) {
    this.setState({ autoScroll: !event.target.checked });
    try {
      localStorage.setItem('autoScroll', !event.target.checked);
    } catch(e) {
      console.warn(e);
    }
  }

  handleReduceAnimations(event) {
    this.setState({ reduceAnimations: event.target.checked });
    try {
      localStorage.setItem('reduceAnimations', event.target.checked);
    } catch (e) {
      console.warn(e);
    }
  }

  render() {
    const state = this.state;
    const settingsCheckboxes = (

              <input type="checkbox" name="beginner" value={state.beginner} onChange={this.handleChange}/>
              Beginner-friendly Stack

              <input type="checkbox" name="autoScroll" value={state.autoScroll} onChange={this.handleAutoScroll} checked={!state.autoScroll}/>
              Disable auto-scroll

              <input type="checkbox" name="reduceAnimations" value={state.reduceAnimations} onChange={this.handleReduceAnimations} checked={state.reduceAnimations}/>
              Reduce Animations

    );

    const platform = (
      <Platform {...state} handleChange={this.handleChange}/>
    );

    const staticSiteGenerator = state.platform === 'html5' ? (
      <StaticSiteGenerator {...state} handleChange={this.handleChange}/>
    ) : null;

    const jsLibrary = state.platform === 'library' ? (
      <JsLibrary {...state} handleChange={this.handleChange} handleGenerateLibraryName={this.handleGenerateLibraryName}/>
    ) : null;

    const framework = state.platform === 'node' ? (
      <Framework {...state} handleChange={this.handleChange}/>
    ) : null;

    const templateEngine = state.framework ? (
      <TemplateEngine {...state} handleChange={this.handleChange}/>
    ) : null;

    const cssFramework = state.templateEngine ? (
      <CssFramework {...state} handleChange={this.handleChange}/>
    ) : null;

    const cssPreprocessor = state.cssFramework ? (
      <CssPreprocessor {...state} handleChange={this.handleChange}/>
    ) : null;

    const jsFramework = state.cssPreprocessor  && state.platform === 'node' ? (
      <JsFramework {...state} handleChange={this.handleChange}/>
    ) : null;

    const buildTool = ((state.jsFramework && state.jsFramework !== 'none') || (state.cssPreprocessor && state.cssPreprocessor !== 'css')) && state.platform === 'node' ? (
      <BuildTool {...state} handleChange={this.handleChange}/>
    ) : null;

    const testing = (state.buildTool || state.cssPreprocessor === 'css' && state.jsFramework === 'none') && state.platform === 'node' ? (
      <Testing {...state} handleChange={this.handleChange}/>
    ) : null;

    const database = state.testing ? (
      <Database {...state} handleChange={this.handleChange}/>
    ) : null;

    const authentication = state.database ? (
      <Authentication {...state} handleChange={this.handleChange}/>
    ) : null;

    const deployment = (state.authentication || state.database === 'none') ? (
      <Deployment {...state} handleChange={this.handleChange}/>
    ) : null;
    //
    // const download = state.deployment || state.staticSiteGenerator || state.platform === 'library' ? (
    //   <button ref="downloadBtn" className="btn btn-block btn-mega btn-success" onClick={this.clickDownload}>Compile and
    //     Download</button>
    // ) : null;

    const download = (
      <button ref="downloadBtn" className="btn btn-block btn-mega btn-success" onClick={this.clickDownload}>Compile and
        Download</button>
    );

    const consulting = download ? (

           Request 1-on-1 consulting service. Rates may vary.

    ) : null;

    const nextSteps = state.showNextSteps ? (
      <NextSteps {...state}/>
    ) : null;

    return (

          {settingsCheckboxes}

{platform}

{framework}

{staticSiteGenerator}

{jsLibrary}

{templateEngine}

{cssFramework}

{cssPreprocessor}

{jsFramework}

{buildTool}

{testing}

{database}

{authentication}

{deployment}

{download}

{consulting}

{nextSteps}

    );
  }
}

export default Home;
<commit_msg>Don't auto scroll to next steps component<commit_after>/* global $, localStorage */

import haikunate from 'haikunator';
import React from 'react';
import { clone } from 'lodash';
import Header from './Header';
import Footer from './Footer';
import Platform from './sections/Platform';
import StaticSiteGenerator from './sections/StaticSiteGenerator';
import JsLibrary from './sections/JsLibrary';
import Framework from './sections/Framework';
import TemplateEngine from './sections/TemplateEngine';
import CssFramework from './sections/CssFramework';
import CssPreprocessor from './sections/CssPreprocessor';
import BuildTool from './sections/BuildTool';
import Testing from './sections/Testing'
import Database from './sections/Database';
import Authentication from './sections/Authentication';
import JsFramework from './sections/JsFramework';
import Deployment from './sections/Deployment';
import NextSteps from './sections/NextSteps';

class Home extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleGenerateLibraryName = this.handleGenerateLibraryName.bind(this);
    this.handleAutoScroll = this.handleAutoScroll.bind(this);
    this.handleReduceAnimations = this.handleReduceAnimations.bind(this);
    this.clickDownload = this.clickDownload.bind(this);
    this.state = {};
  }

  componentDidMount() {
    try {
      const autoScroll = localStorage.getItem('autoScroll');
      const reduceAnimations = localStorage.getItem('reduceAnimations');
      this.setState({
        autoScroll: autoScroll === 'true',
        reduceAnimations: reduceAnimations === 'true'
      });
    } catch (e) {
      console.warn(e);
    }
  }

  clickDownload() {
    const state = this.state;
    const downloadBtn = this.refs.downloadBtn;

    // Google Analytics event
    // ga("send","event","Customize","Download","Customize and Download")

    if (!state.platform) {
      return this.setState({ platformValidationError: 'Please select a platfsForm.' });
    } else if (state.platform === 'html5' && !state.staticSiteGenerator) {
      return this.setState({ staticSiteGeneratorValidationError: 'Please select a static site generator.' });
    } else if (state.platform === 'library' && !state.jsLibraryName) {
      return this.setState({ jsLibraryValidationError: 'Please enter a library name.' });
    } else if (!state.framework) {
      return this.setState({ frameworkValidationError: 'Please select a framework.' });
    } else if (!state.templateEngine) {
      return this.setState({ templateEngineValidationError: 'Please select a template engine.' });
    } else if (!state.cssFramework) {
      return this.setState({ cssFrameworkValidationError: 'Please select a CSS framework.' });
    } else if (!state.cssPreprocessor) {
      return this.setState({ cssPreprocessorValidationError: 'Please select a CSS preprocessor.' });
    } else if (!state.jsFramework) {
      return this.setState({ jsFrameworkValidationError: 'Please make a selection.' });
    } else if (!state.buildTool) {
      return this.setState({ buildToolValidationError: 'Please select a build tool.' });
    } else if (!state.testing) {
      return this.setState({ testingValidationError: 'Please select a testing framework.' });
    } else if (!state.database) {
      return this.setState({ databaseValidationError: 'Please select a database.' });
    } else if (!state.authentication && state.database !== 'none') {
      return this.setState({ authenticationValidationError: 'Please check all that apply.' });
    }

    // Show next steps component
    //   this.setState({ showNextSteps: true });
    // if (state.autoScroll) {
    //   $(this.refs.nextSteps).velocity('scroll');
    // }

    const data = clone(state);
    data.appName = haikunate({ tokenLength: 0 });

    if (data.jsFramework === 'none') {
      data.jsFramework = null;
    }

    // Convert ES6 set to array
    data.authentication = data.authentication ? Array.from(data.authentication) : [];
    data.frameworkOptions = data.frameworkOptions ? Array.from(data.frameworkOptions) : [];
    data.reactOptions = data.reactOptions ? Array.from(data.reactOptions) : [];
    data.jsLibraryOptions = data.jsLibraryOptions ? Array.from(data.jsLibraryOptions) : [];

    $.ajax({
      url: '/download',
      method: 'POST',
      contentType: 'application/json; charset=utf-8',
      data: JSON.stringify(data)
    }).done((response, status, request) => {
      $(downloadBtn).removeAttr('disabled');

      const disp = request.getResponseHeader('Content-Disposition');
      if (disp && disp.search('attachment') !== -1) {
        const form = $('<form method="POST" action="/download">');
        $.each(data, (k, v) => {
          form.append($(`<input type="hidden" name="${k}" value="${v}">`));
        });
        $('body').append(form);
        form.submit();
      }
    }).fail((jqXHR) => {
      window.notie.alert(3, jqXHR.responseText, 2.5);
    });
  }

  handleGenerateLibraryName() {
    const newState = clone(this.state);
    newState.jsLibraryName = haikunate({ tokenLength: 0 });
    newState.jsLibraryValidationError = null;
    this.setState(newState);
  }

  handleChange(event) {
    const name = event.target.name;
    const value = event.target.value;
    const isChecked = event.target.checked;
    const state = clone(this.state);
    const refs = this.refs;

    switch (name) {
      case 'beginner':
        state.beginner = isChecked;
        break;

      case 'platformRadios':
        const whitelist = ['showModal', 'beginner', 'autoScroll', 'reduceAnimations'];
        for (const key in state) {
          if (state.hasOwnProperty(key)) {
            if (whitelist.indexOf(key) === -1) {
              state[key] = null;
            }
          }
        }
        state.platform = value;
        if (state.autoScroll) {
          $(refs.platform).velocity('scroll');
        }
        state.platformValidationError = null;
        break;

      case 'staticSiteGeneratorRadios':
        if (!state.staticSiteGenerator && state.autoScroll) {
          $(refs.staticSiteGenerator).velocity('scroll');
        }
        state.staticSiteGenerator = value;
        state.staticSiteGeneratorValidationError = null;
        break;

      case 'jsLibraryOptionsCheckboxes':
        state.jsLibraryOptions = state.jsLibraryOptions || new Set();
        if (isChecked) {
          state.jsLibraryOptions.add(value);
        } else {
          state.jsLibraryOptions.delete(value);
        }
        break;

      case 'jsLibraryName':
        state.jsLibraryName = value;
        state.jsLibraryValidationError = null;
        break;

      case 'jsLibraryAuthor':
        state.jsLibraryAuthor = value;
        break;

      case 'jsLibraryGithubUsername':
        state.jsLibraryGithubUsername = value;
        break;

      case 'jsLibraryLicenseRadios':
        state.jsLibraryLicense = value;
        break;

      case 'frameworkRadios':
        if (!state.framework && state.autoScroll) {
          $(refs.framework).velocity('scroll');
        }
        state.framework = value;
        state.frameworkValidationError = null;

        break;

      case 'frameworkOptionsCheckboxes':
        state.frameworkOptions = state.frameworkOptions || new Set();
        if (isChecked) {
          state.frameworkOptions.add(value);
        } else {
          state.frameworkOptions.delete(value);
        }
        break;

      case 'templateEngineRadios':
        if (!state.templateEngine && state.autoScroll) {
          $(refs.templateEngine).velocity('scroll');
        }
        state.templateEngineValidationError = null;
        state.templateEngine = value;
        break;

      case 'cssFrameworkRadios':
        if (!state.cssFramework && state.autoScroll) {
          $(refs.cssFramework).velocity('scroll');
        }
        if (state.cssPreprocessor) {
          state.cssPreprocessor = null;
        }
        state.cssFrameworkValidationError = null;
        state.cssFramework = value;
        break;

      case 'cssPreprocessorRadios':
        if (!state.cssPreprocessor && state.autoScroll) {
          $(refs.cssPreprocessor).velocity('scroll');
        }
        state.cssPreprocessor = value;
        state.cssPreprocessorValidationError = null;
        break;

      case 'jsFrameworkRadios':
        if (!state.jsFramework && state.autoScroll) {
          $(refs.jsFramework).velocity('scroll');
        }
        state.jsFramework = value;
        state.jsFrameworkValidationError = null;
        break;

      case 'reactOptionsCheckboxes':
        state.reactOptions = state.reactOptions || new Set();
        if (isChecked) {
          state.reactOptions.add(value);
        } else {
          state.reactOptions.delete(value);
        }
        break;

      case 'buildToolRadios':
        if (!state.buildTool && state.autoScroll) {
          $(refs.buildTool).velocity('scroll');
        }
        state.buildTool = value;
        state.buildToolValidationError = null;
        break;

      case 'testingRadios':
        if (!state.testing && state.autoScroll) {
          $(refs.testing).velocity('scroll');
        }
        state.testing = value;
        state.testingValidationError = null;
        break;

      case 'databaseRadios':
        if (!state.database && state.autoScroll) {
          $(refs.database).velocity('scroll');
        }
        if (value === 'none' && state.authentication) {
          state.authentication.clear();
        }
        state.database = value;
        state.databaseValidationError = null;
        break;

      case 'authenticationCheckboxes':
        state.authentication = state.authentication || new Set();

        const requiresEmail = (
          state.authentication.has('facebook') ||
          state.authentication.has('google') ||
          state.authentication.has('twitter')
        );

        if (isChecked) {
          if (value === 'none') {
            state.authentication.clear();
          } else {
            state.authentication.add(value);
            if (value === 'facebook' || value === 'google' || value === 'twitter') {
              state.authentication.add('email');
            }
          }
          state.authenticationValidationError = null;
        } else {
          if (value === 'email' && requiresEmail) { return; }
          state.authentication.delete(value);
        }
        break;

      case 'deploymentRadios':
        if (!state.deployment && state.autoScroll) {
          $(refs.deployment).velocity('scroll');
        }
        state.deployment = value;
        break;

      default:
      // Handle default case
    }

    this.setState(state);
  }

  handleAutoScroll(event) {
    this.setState({ autoScroll: !event.target.checked });
    try {
      localStorage.setItem('autoScroll', !event.target.checked);
    } catch(e) {
      console.warn(e);
    }
  }

  handleReduceAnimations(event) {
    this.setState({ reduceAnimations: event.target.checked });
    try {
      localStorage.setItem('reduceAnimations', event.target.checked);
    } catch (e) {
      console.warn(e);
    }
  }

  render() {
    const state = this.state;
    const settingsCheckboxes = (

              <input type="checkbox" name="beginner" value={state.beginner} onChange={this.handleChange}/>
              Beginner-friendly Stack

              <input type="checkbox" name="autoScroll" value={state.autoScroll} onChange={this.handleAutoScroll} checked={!state.autoScroll}/>
              Disable auto-scroll

              <input type="checkbox" name="reduceAnimations" value={state.reduceAnimations} onChange={this.handleReduceAnimations} checked={state.reduceAnimations}/>
              Reduce Animations

    );

    const platform = (
      <Platform {...state} handleChange={this.handleChange}/>
    );

    const staticSiteGenerator = state.platform === 'html5' ? (
      <StaticSiteGenerator {...state} handleChange={this.handleChange}/>
    ) : null;

    const jsLibrary = state.platform === 'library' ? (
      <JsLibrary {...state} handleChange={this.handleChange} handleGenerateLibraryName={this.handleGenerateLibraryName}/>
    ) : null;

    const framework = state.platform === 'node' ? (
      <Framework {...state} handleChange={this.handleChange}/>
    ) : null;

    const templateEngine = state.framework ? (
      <TemplateEngine {...state} handleChange={this.handleChange}/>
    ) : null;

    const cssFramework = state.templateEngine ? (
      <CssFramework {...state} handleChange={this.handleChange}/>
    ) : null;

    const cssPreprocessor = state.cssFramework ? (
      <CssPreprocessor {...state} handleChange={this.handleChange}/>
    ) : null;

    const jsFramework = state.cssPreprocessor  && state.platform === 'node' ? (
      <JsFramework {...state} handleChange={this.handleChange}/>
    ) : null;

    const buildTool = ((state.jsFramework && state.jsFramework !== 'none') || (state.cssPreprocessor && state.cssPreprocessor !== 'css')) && state.platform === 'node' ? (
      <BuildTool {...state} handleChange={this.handleChange}/>
    ) : null;

    const testing = (state.buildTool || state.cssPreprocessor === 'css' && state.jsFramework === 'none') && state.platform === 'node' ? (
      <Testing {...state} handleChange={this.handleChange}/>
    ) : null;

    const database = state.testing ? (
      <Database {...state} handleChange={this.handleChange}/>
    ) : null;

    const authentication = state.database ? (
      <Authentication {...state} handleChange={this.handleChange}/>
    ) : null;

    const deployment = (state.authentication || state.database === 'none') ? (
      <Deployment {...state} handleChange={this.handleChange}/>
    ) : null;
    //
    // const download = state.deployment || state.staticSiteGenerator || state.platform === 'library' ? (
    //   <button ref="downloadBtn" className="btn btn-block btn-mega btn-success" onClick={this.clickDownload}>Compile and
    //     Download</button>
    // ) : null;

    const download = (
      <button ref="downloadBtn" className="btn btn-block btn-mega btn-success" onClick={this.clickDownload}>Compile and
        Download</button>
    );

    const consulting = download ? (

           Looking for additional help? Contact me directly by scheduling 1-on-1 help. Rates may vary.

    ) : null;

    const nextSteps = state.showNextSteps ? (
      <NextSteps {...state}/>
    ) : null;

    return (

          {settingsCheckboxes}

{platform}

{framework}

{staticSiteGenerator}

{jsLibrary}

{templateEngine}

{cssFramework}

{cssPreprocessor}

{jsFramework}

{buildTool}

{testing}

{database}

{authentication}

{deployment}

{download}

{consulting}

{nextSteps}

    );
  }
}

export default Home;
<|endoftext|>


<commit_before>var
path=require('path'),
apn=require('apn'),
args= require('pico-args'),
picoObj=require('pico-common').export('pico/obj'),
utils= require('../lib/utils'),
Session= require('../lib/Session'),
apnConnected = function(){ console.log('apn connected') },
apnDisconnected = function(){ console.log('apn dc') },
apnTimeout = function(){ console.log('apn timeout') },
apnTransmitted = function(notification, device){ console.log('apn send ok', device.toString('hex')) },
apnTransmissionError = function(errCode, notification, device){ console.log('apn send ko', errCode, device.toString('hex')) },
apnFeedback=function(feedback,sigslot){
    feedback.on('feedback', (items)=>{ // items = [{device, time}]
        sigslot.signal('webpush.feedback', Session.TYPE.WEBPUSH, items, 'apn')
    })
    feedback.on('feedbackError', console.error)
},
webpushCB=function(err, code, data){
	if (err) return console.error(err)
	console.log(data)
},
resolvePath=function(home, apnPath){
    return (path.isAbsolute(apnPath) ? apnPath : path.resolve(home, apnPath))
},
WebPush=function(config,sigslot){
	this.options=config.options
    if (config.apn){
        var apnCli=this.apnCli = new apn.Connection(config.apn)
        apnCli.on('connected', apnConnected)
        apnCli.on('disconnected', apnDisconnected)
        apnCli.on('timeout', apnTimeout)
        apnCli.on('transmitted', apnTransmitted)
        apnCli.on('transmissionError', apnTransmissionError)
        apnCli.on('socketError', console.error)

        // Setup a connection to the feedback service using a custom interval (10 seconds)
        apnFeedback(new apn.feedback(config.apn), sigslot)
    }
	if (config.gcm){
		this.gcm={
			url:config.gcm.endpoint,
			header:{
				"Authorization": `key=${config.gcm.key}`,
				"Content-Type": "application/json"
			}
		}
	}
	if (config.moz){
		this.moz={
			url:config.moz.endpoint,
			header:{
				"TTL": `${config.options.ttl}`,
			}
		}
	}
},
mozSend=function(url,header,keys,i,res,cb){
	if (keys.length >=i) return cb()
	utils.ajax('post',url+keys[i],null,header,(err,code,data)=>{
		if (err) return cb(err)
		res.push(data)
		mozSend(url,header,keys,++i,res,cb)
	})
}

WebPush.prototype={
	broadcast: function(tokens, ids, keys, title, content, urlargs, cb){
        var
		options=this.options,
		cli=this.apnCli

        if (cli && tokens){
            var msg = new apn.Notification()

            msg.setAlertTitle(title)
            msg.setAlertText(content)
            msg.setAlertAction('view')
			msg.urlArgs=urlargs
            msg.truncateAtWordEnd=true
            msg.expiry = options.ttl ? (Date.now()/1000) + options.ttl : 0
            msg.trim()

			cli.pushNotification(msg, tokens)
        }

        if (ids){
			var gcm=this.gcm
			utils.ajax('post',gcm.url,JSON.stringify({registration_ids:ids}),gcm.header,webpushCB)
        }

        if (keys){
			var moz=this.moz
			mozSend(moz.url,moz.header,keys,0,[],webpushCB)
        }
	}
}

module.exports= {
    create: function(appConfig, libConfig, next){
        var config={
            // https://github.com/argon/node-apn/blob/master/doc/connection.markdown
            // https://github.com/argon/node-apn/blob/master/doc/feedback.markdown
            apn:{
                key:'apn_key.pem',
                cert:'apn_cert.pem',
				production:true,
                interval:3600
            },
            gcm:{
				endpoint:'https://android.googleapis.com/gcm/send',
                key:'YOUR_API_KEY_HERE'
            },
			moz:{
				endpoint:'https://updates.push.services.mozilla.com/wpush/v1'
            },
			options:{
				ttl:0
			}
        }

        args.print('Webpush Options',picoObj.extend(config,libConfig))

        var apn=config.apn

        apn.key=resolvePath(appConfig.path,apn.key)
        apn.cert=resolvePath(appConfig.path,apn.cert)

        return next(null, new WebPush(config,appConfig.sigslot))
    }
}
<commit_msg>fixed moz send<commit_after>var
path=require('path'),
apn=require('apn'),
args= require('pico-args'),
picoObj=require('pico-common').export('pico/obj'),
utils= require('../lib/utils'),
Session= require('../lib/Session'),
apnConnected = function(){ console.log('apn connected') },
apnDisconnected = function(){ console.log('apn dc') },
apnTimeout = function(){ console.log('apn timeout') },
apnTransmitted = function(notification, device){ console.log('apn send ok', device.toString('hex')) },
apnTransmissionError = function(errCode, notification, device){ console.log('apn send ko', errCode, device.toString('hex')) },
apnFeedback=function(feedback,sigslot){
    feedback.on('feedback', (items)=>{ // items = [{device, time}]
        sigslot.signal('webpush.feedback', Session.TYPE.WEBPUSH, items, 'apn')
    })
    feedback.on('feedbackError', console.error)
},
webpushCB=function(err, code, data){
	if (err) return console.error(err)
	if (data) console.log(data)
},
resolvePath=function(home, apnPath){
    return (path.isAbsolute(apnPath) ? apnPath : path.resolve(home, apnPath))
},
WebPush=function(config,sigslot){
	this.options=config.options
    if (config.apn){
        var apnCli=this.apnCli = new apn.Connection(config.apn)
        apnCli.on('connected', apnConnected)
        apnCli.on('disconnected', apnDisconnected)
        apnCli.on('timeout', apnTimeout)
        apnCli.on('transmitted', apnTransmitted)
        apnCli.on('transmissionError', apnTransmissionError)
        apnCli.on('socketError', console.error)

        // Setup a connection to the feedback service using a custom interval (10 seconds)
        apnFeedback(new apn.feedback(config.apn), sigslot)
    }
	if (config.gcm){
		this.gcm={
			url:config.gcm.endpoint,
			header:{
				"Authorization": `key=${config.gcm.key}`,
				"Content-Type": "application/json"
			}
		}
	}
	if (config.moz){
		this.moz={
			url:config.moz.endpoint,
			header:{
				"TTL": `${config.options.ttl}`,
			}
		}
	}
},
mozSend=function(url,header,keys,i,res,cb){
	if (keys.length <=i) return cb()
	utils.ajax('post',url+keys[i],null,header,(err,code,data)=>{
		if (err) return cb(err)
		res.push(data)
		mozSend(url,header,keys,++i,res,cb)
	})
}

WebPush.prototype={
	broadcast: function(tokens, ids, keys, title, content, urlargs){
        var
		options=this.options,
		cli=this.apnCli

        if (cli && tokens){
            var msg = new apn.Notification()

            msg.setAlertTitle(title)
            msg.setAlertText(content)
            msg.setAlertAction('view')
			msg.urlArgs=urlargs
            msg.truncateAtWordEnd=true
            msg.expiry = options.ttl ? (Date.now()/1000) + options.ttl : 0
            msg.trim()

			cli.pushNotification(msg, tokens)
        }

        if (ids){
			var gcm=this.gcm
			utils.ajax('post',gcm.url,JSON.stringify({registration_ids:ids}),gcm.header,webpushCB)
        }

        if (keys){
			var moz=this.moz
			mozSend(moz.url,moz.header,keys,0,[],webpushCB)
        }
	}
}

module.exports= {
    create: function(appConfig, libConfig, next){
        var config={
            // https://github.com/argon/node-apn/blob/master/doc/connection.markdown
            // https://github.com/argon/node-apn/blob/master/doc/feedback.markdown
            apn:{
                key:'apn_key.pem',
                cert:'apn_cert.pem',
				production:1,
                interval:3600
            },
            gcm:{
				endpoint:'https://android.googleapis.com/gcm/send',
                key:'YOUR_API_KEY_HERE'
            },
			moz:{
				endpoint:'https://updates.push.services.mozilla.com/wpush/v1/'
            },
			options:{
				ttl:0
			}
        }

        args.print('Webpush Options',picoObj.extend(config,libConfig))

        var apn=config.apn

        apn.key=resolvePath(appConfig.path,apn.key)
        apn.cert=resolvePath(appConfig.path,apn.cert)

        return next(null, new WebPush(config,appConfig.sigslot))
    }
}
<|endoftext|>


<commit_before>!(function(){
  var width = innerWidth,
      height = innerHeight;

  var x = width / 2,
      y = height / 2;

  var canvas = d3.select('#background-canvas').append("canvas")
      .attr("width", width)
      .attr("height", height)

  var ctx = canvas.node().getContext("2d");

  var shapes = [],
      curTime = 0,
      l = 8

  d3.timer(function(t){
    curTime = t

    shapes.forEach(function(s){
      if (t < s.start) return

      var u = (t - s.start)/(s.end - s.start)

      if (u > 1){
        u = 1
        s.done = true
      }

      ctx.fillStyle = s.fill
      if (s.type == 'rect'){
        var a0 = s.sV[0]*(1 - u) + s.eV[0]*u
        var a1 = s.sV[1]*(1 - u) + s.eV[1]*u
        var a2 = s.sV[2]*(1 - u) + s.eV[2]*u
        var a3 = s.sV[3]*(1 - u) + s.eV[3]*u
        ctx.fillRect(a0, a1, a2, a3)
      }
    })

    shapes = shapes.filter(function(s){ return !s.done })
  })

  // wave squares
  !(function(){
    var module = {sel: d3.select('#sec-2'), active: false}
    addModule(module)

    var colors = colorArray.slice(1, 4)
    var offset = 1

    setInterval(function(){
      if (!module.active) return
      var speed = Math.random()*.5 + .5
      offset++
      d3.range(0, width + l, l).forEach(function(x, i){
        d3.range(0, height + l, l).forEach(function(y, j){
          if (!!((i + j + offset) % 4)) return
          if (Math.random() < .3) return
          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: curTime + (i + j)*40*speed + Math.random()*200,
              sV: [x, y, 0, 0],
              eV: [x, y, l, l],
              fill: offset % 10 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 500
          shapes.push(shape)
        })
      })

    }, 1000)
  })()

  //sprial squares
  !(function(){
    var module = {sel: d3.select('#headerArt'), active: true}
    addModule(module)

    var colors = colorArray.slice(0, 3)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      offset++
      d3.range(0, width + l, l).forEach(function(x, i){
        d3.range(0, height + l, l).forEach(function(y, j){
          if (!!((i + j + offset) % 2)) return
          if (Math.random() < .3) return

          var d = Math.random() < .5  //shape moves down
          var r = Math.random() < .5  //shape moves up

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: curTime + d*1000 + r*1000 + (d && !r)*1000*2 + Math.random()*400,
              sV: [r ? x : x + l, d ? y : y + l, 0, 0],
              eV: [x, y, l, l],
              fill: offset % 18 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 500
          shapes.push(shape)
        })
      })

    }, 5/4*1000)
  })()

  //down wave
  !(function(){
    var module = {sel: d3.select('#sec-3'), active: false}
    addModule(module)

    var colors = colorArray.slice(2, 5)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      var speed = Math.random()*.5 + .5
      speed = 1
      offset++
      var m = offset % 4
      d3.range(0, width + l, l).forEach(function(x, i){
        d3.range(0, height + l, l).forEach(function(y, j){
          if (!((i + j + offset) % 5)) return
          if (Math.random() < .6) return

          var stagger = speed*40 + Math.random()*5
          var start = curTime
          var sV = []
          if        (m == 0){
            start += j*stagger
            sV = [x, y, l, 0]
          } else if (m == 1){
            start += (width /l - i)*stagger
            sV = [x + l, y, 0, l]
          } else if (m == 2){
            start += (height/l - j)*stagger
            sV = [x, y + l, l, 0]
          } else if (m == 3){
            start += i*stagger
            sV = [x, y, 0, l]
          }

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: start,
              sV: sV,
              eV: [x, y, l, l],
              fill: offset % 10 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 200*Math.random()
          shapes.push(shape)
        })
      })

    }, 2000)
  })()

})();

// OLD SVG BACKGROUND
// var svgWidth  = window.innerWidth,
//     svgHeight = window.innerHeight,

//     s = 25,
//     s = window.innerWidth/Math.floor(window.innerWidth/s)

// var backgroundSVG = d3.select('#background-canvas')
//   .append('svg')
//     .attr({height: svgHeight, width: svgWidth})

// //spinning squares
// !(function(){
//   var offset = 0,
//       width  = window.innerWidth,
//       height = window.innerHeight,
//       lastColorI = -1,
//       colors = colorArray.slice(0, 3)

//   var module = {sel: d3.select('#headerArt'), active: true}
//   addModule(module)

//   function drawSquares(){
//     setTimeout(drawSquares, 5/4*1000)

//     if (!module.active){
//       return backgroundSVG.selectAll('rect.spiral')
//           .filter(function(d){ return !d.started })
//         .transition()
//           .each('start', function(d){ d.started = true })
//     }

//     offset++

//     var squares = []
//     d3.range(0, width + s, s).forEach(function(x, i){
//       d3.range(0, height + s, s).forEach(function(y, j){
//         if ((i + j + offset) % 4) return
//         squares.push({x: x, y: y, i: i, j: j,
//           isLeft: Math.random() < .5,
//           isTop:  Math.random() < .5})
//       })
//     })

//     backgroundSVG.append('g.spin-square').dataAppend(squares, 'rect.spiral')
//         .attr('x', function(d){ return d.isLeft ? d.x : d.x + s })
//         .attr('y', function(d){ return d.isTop  ? d.y : d.y + s })
//         .attr({width: 0, height: 0})
//         .style('fill', randColor())
//       .transition()
//         // .ease('bounce')
//         .duration(1000)
//         .delay(function(d, i){
//           return d.isTop*1000 + d.isLeft*1000 + (d.isLeft && !d.isTop)*1000*2 + Math.random()*700 })
//         .each('start', function(d){ d.started = true })
//         .attr({width: s + 1, height: s + 1})
//         .attr({x: ƒ('x'), y: ƒ('y')})

//     var numGroups = backgroundSVG.selectAll('g.spin-square').size()
//     backgroundSVG.selectAll('g.spin-square')
//        .filter(function(d, i){ return i + 12 < numGroups })
//        .remove()

//   }
//   drawSquares()

//   function randColor(){
//     lastColorI = (lastColorI + 1) % colors.length
//     return colors[lastColorI]
//   }

// })()

// //wave squares
// !(function(){
//   var offset = 0,
//       width  = window.innerWidth,
//       height = window.innerHeight,
//       lastColorI = -1,
//       colors = colorArray.slice(1, 4)

//   var module = {sel: d3.select('#sec-2')}
//   addModule(module)

//   function drawSquares(){
//     setTimeout(drawSquares, 900)

//     if (!module.active){
//       return backgroundSVG.selectAll('rect.wave')
//           .filter(function(d){ return !d.started })
//         .transition()
//           .each('start', function(d){ d.started = true })
//     }

//     offset++

//     var squares = []
//     d3.range(0, width + s, s).forEach(function(x, i){
//       d3.range(0, height + s, s).forEach(function(y, j){
//         if ((i + j + offset + (Math.random() < .05 ? 1 : 0)) % 4) return
//         squares.push({x: x, y: y, i: i, j: j})
//       })
//     })

//     backgroundSVG.append('g.wave-square').dataAppend(squares, 'rect.wave')
//         .attr({x: ƒ('x'), y: ƒ('y')})
//         .attr({width: 0, height: 0})
//         .style('fill', randColor())
//       .transition()
//         .duration(500)
//         .delay(function(d, i){ return (d.i + d.j + Math.random()*16)*70 })
//         .attr({width: s + 1, height: s + 1})

//     var numGroups = backgroundSVG.selectAll('g.wave-square').size()
//     backgroundSVG.selectAll('g.wave-square')
//        .filter(function(d, i){ return i + 18 < numGroups })
//        .remove()

//   }
//   drawSquares()

//   function randColor(){
//     lastColorI = (lastColorI + 1) % colors.length
//     return colors[lastColorI]
//   }
// })()

<commit_msg>responsive background<commit_after>!(function(){
  var width = innerWidth,
      height = innerHeight;

  var canvas = d3.select('#background-canvas').append("canvas")
      .attr({width: width, height: height})

  d3.select(window).on('resize.background', function(){
    width  = innerWidth
    height = innerHeight
    canvas.attr({width: width, height: height})
  })

  var ctx = canvas.node().getContext("2d");

  var shapes = [],
      curTime = 0,
      l = 8

  d3.timer(function(t){
    curTime = t

    shapes.forEach(function(s){
      if (t < s.start) return

      var u = (t - s.start)/(s.end - s.start)

      if (u > 1){
        u = 1
        s.done = true
      }

      ctx.fillStyle = s.fill
      if (s.type == 'rect'){
        var a0 = s.sV[0]*(1 - u) + s.eV[0]*u
        var a1 = s.sV[1]*(1 - u) + s.eV[1]*u
        var a2 = s.sV[2]*(1 - u) + s.eV[2]*u
        var a3 = s.sV[3]*(1 - u) + s.eV[3]*u
        ctx.fillRect(a0, a1, a2, a3)
      }
    })

    shapes = shapes.filter(function(s){ return !s.done })
  })

  // wave squares
  !(function(){
    var module = {sel: d3.select('#sec-2'), active: false}
    addModule(module)

    var colors = colorArray.slice(1, 4)
    var offset = 1

    setInterval(function(){
      if (!module.active) return
      var speed = Math.random()*.5 + .5
      offset++
      d3.range(0, width + l, l).forEach(function(x, i){
        d3.range(0, height + l, l).forEach(function(y, j){
          if (!!((i + j + offset) % 4)) return
          if (Math.random() < .3) return
          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: curTime + (i + j)*40*speed + Math.random()*200,
              sV: [x, y, 0, 0],
              eV: [x, y, l, l],
              fill: offset % 10 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 500
          shapes.push(shape)
        })
      })

    }, 1000)
  })()

  //sprial squares
  !(function(){
    var module = {sel: d3.select('#headerArt'), active: true}
    addModule(module)

    var colors = colorArray.slice(0, 3)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      offset++
      d3.range(0, width + l, l).forEach(function(x, i){
        d3.range(0, height + l, l).forEach(function(y, j){
          if (!!((i + j + offset) % 2)) return
          if (Math.random() < .3) return

          var d = Math.random() < .5  //shape moves down
          var r = Math.random() < .5  //shape moves up

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: curTime + d*1000 + r*1000 + (d && !r)*1000*2 + Math.random()*400,
              sV: [r ? x : x + l, d ? y : y + l, 0, 0],
              eV: [x, y, l, l],
              fill: offset % 18 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 500
          shapes.push(shape)
        })
      })

    }, 5/4*1000)
  })()

  //down wave
  !(function(){
    var module = {sel: d3.select('#sec-3'), active: false}
    addModule(module)

    var colors = colorArray.slice(2, 5)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      var speed = Math.random()*.5 + .5
      speed = 1
      offset++
      var m = offset % 4
      d3.range(0, width + l, l).forEach(function(x, i){
        d3.range(0, height + l, l).forEach(function(y, j){
          if (!((i + j + offset) % 5)) return
          if (Math.random() < .6) return

          var stagger = speed*40 + Math.random()*5
          var start = curTime
          var sV = []
          if        (m == 0){
            start += j*stagger
            sV = [x, y, l, 0]
          } else if (m == 1){
            start += (width /l - i)*stagger
            sV = [x + l, y, 0, l]
          } else if (m == 2){
            start += (height/l - j)*stagger
            sV = [x, y + l, l, 0]
          } else if (m == 3){
            start += i*stagger
            sV = [x, y, 0, l]
          }

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: start,
              sV: sV,
              eV: [x, y, l, l],
              fill: offset % 10 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 200*Math.random()
          shapes.push(shape)
        })
      })

    }, 2000)
  })()

})();

// OLD SVG BACKGROUND
// var svgWidth  = window.innerWidth,
//     svgHeight = window.innerHeight,

//     s = 25,
//     s = window.innerWidth/Math.floor(window.innerWidth/s)

// var backgroundSVG = d3.select('#background-canvas')
//   .append('svg')
//     .attr({height: svgHeight, width: svgWidth})

// //spinning squares
// !(function(){
//   var offset = 0,
//       width  = window.innerWidth,
//       height = window.innerHeight,
//       lastColorI = -1,
//       colors = colorArray.slice(0, 3)

//   var module = {sel: d3.select('#headerArt'), active: true}
//   addModule(module)

//   function drawSquares(){
//     setTimeout(drawSquares, 5/4*1000)

//     if (!module.active){
//       return backgroundSVG.selectAll('rect.spiral')
//           .filter(function(d){ return !d.started })
//         .transition()
//           .each('start', function(d){ d.started = true })
//     }

//     offset++

//     var squares = []
//     d3.range(0, width + s, s).forEach(function(x, i){
//       d3.range(0, height + s, s).forEach(function(y, j){
//         if ((i + j + offset) % 4) return
//         squares.push({x: x, y: y, i: i, j: j,
//           isLeft: Math.random() < .5,
//           isTop:  Math.random() < .5})
//       })
//     })

//     backgroundSVG.append('g.spin-square').dataAppend(squares, 'rect.spiral')
//         .attr('x', function(d){ return d.isLeft ? d.x : d.x + s })
//         .attr('y', function(d){ return d.isTop  ? d.y : d.y + s })
//         .attr({width: 0, height: 0})
//         .style('fill', randColor())
//       .transition()
//         // .ease('bounce')
//         .duration(1000)
//         .delay(function(d, i){
//           return d.isTop*1000 + d.isLeft*1000 + (d.isLeft && !d.isTop)*1000*2 + Math.random()*700 })
//         .each('start', function(d){ d.started = true })
//         .attr({width: s + 1, height: s + 1})
//         .attr({x: ƒ('x'), y: ƒ('y')})

//     var numGroups = backgroundSVG.selectAll('g.spin-square').size()
//     backgroundSVG.selectAll('g.spin-square')
//        .filter(function(d, i){ return i + 12 < numGroups })
//        .remove()

//   }
//   drawSquares()

//   function randColor(){
//     lastColorI = (lastColorI + 1) % colors.length
//     return colors[lastColorI]
//   }

// })()

// //wave squares
// !(function(){
//   var offset = 0,
//       width  = window.innerWidth,
//       height = window.innerHeight,
//       lastColorI = -1,
//       colors = colorArray.slice(1, 4)

//   var module = {sel: d3.select('#sec-2')}
//   addModule(module)

//   function drawSquares(){
//     setTimeout(drawSquares, 900)

//     if (!module.active){
//       return backgroundSVG.selectAll('rect.wave')
//           .filter(function(d){ return !d.started })
//         .transition()
//           .each('start', function(d){ d.started = true })
//     }

//     offset++

//     var squares = []
//     d3.range(0, width + s, s).forEach(function(x, i){
//       d3.range(0, height + s, s).forEach(function(y, j){
//         if ((i + j + offset + (Math.random() < .05 ? 1 : 0)) % 4) return
//         squares.push({x: x, y: y, i: i, j: j})
//       })
//     })

//     backgroundSVG.append('g.wave-square').dataAppend(squares, 'rect.wave')
//         .attr({x: ƒ('x'), y: ƒ('y')})
//         .attr({width: 0, height: 0})
//         .style('fill', randColor())
//       .transition()
//         .duration(500)
//         .delay(function(d, i){ return (d.i + d.j + Math.random()*16)*70 })
//         .attr({width: s + 1, height: s + 1})

//     var numGroups = backgroundSVG.selectAll('g.wave-square').size()
//     backgroundSVG.selectAll('g.wave-square')
//        .filter(function(d, i){ return i + 18 < numGroups })
//        .remove()

//   }
//   drawSquares()

//   function randColor(){
//     lastColorI = (lastColorI + 1) % colors.length
//     return colors[lastColorI]
//   }
// })()

<|endoftext|>


<commit_before>/*
 File drag and drop uploads
 */

const main = require('./main'),
	{etc, state} = main;

function dragonDrop(e) {
	e.stopPropagation();
	e.preventDefault();
	const {files} = e.dataTransfer;
	if (!files.length)
		return;
	let postForm = main.request('postForm');
	if (!postForm) {
		const thread = state.page.get('thread');
		if (thread)
			return main.request('openPostBox', thread);
		const section = e.target.closest('section');
		if (section)
			main.request('openPostBox', section.getAttribute('id'));
	}
	else {
		const attrs = postForm.model.attributes;
		if (attrs.uploading || attrs.uploaded)
			return;
	}

	if (!postForm)
		postForm = main.request('postForm');
	if (files.length > 1) {
		postForm.uploadError('Too many files.');
		return;
	}

	// Drag and drop does not supply a fakepath to file, so we have to use
	// a separate upload form from the postForm one. Meh.
	const extra = postForm.prepareUpload(),
		data = new FormData();
	data.append('image', files[0]);
	for (let key in extra) {
		data.append(key, extra[key]);
	}

	const xhr = new XMLHttpRequest();
	xhr.open('POST', etc.uploadURL());
	xhr.setRequestHeader('Accept', 'application/json');
	xhr.onreadystatechange = upload_shita;
	xhr.send(data);

	postForm.notifyUploading();
}

function upload_shita() {
	if (this.readyState != 4 || this.status == 202)
		return;
	const err = this.responseText;

	// Everything just fine. Don't need to report.
	if (!/legitimate imager response/.test(err))
		main.request('postForm').uploadError(err);
}

function stop_drag(e) {
	e.stopPropagation();
	e.preventDefault();
}

function setupUploadDrop(el) {
	go('dragenter', stop_drag);
	go('dragexit', stop_drag);
	go('dragover', stop_drag);
	go('drop', dragonDrop);

	function go(name, func) {
		el.addEventListener(name, func, false);
	}
}

if (!main.isMobile)
	main.defer(() => setupUploadDrop(main.$threads[0]));

<commit_msg>Fix image drag and drop on thread pages<commit_after>/*
 File drag and drop uploads
 */

const main = require('./main'),
	{etc, state} = main;

function dragonDrop(e) {
	e.stopPropagation();
	e.preventDefault();
	const {files} = e.dataTransfer;
	if (!files.length)
		return;
	let postForm = main.request('postForm');
	if (!postForm) {
		const thread = state.page.get('thread');
		if (thread)
			main.request('openPostBox', thread);
		else {
			const section = e.target.closest('section');
			if (section)
				main.request('openPostBox', section.getAttribute('id'));
		}
	}
	else {
		const attrs = postForm.model.attributes;
		if (attrs.uploading || attrs.uploaded)
			return;
	}

	if (!postForm)
		postForm = main.request('postForm');
	if (files.length > 1) {
		postForm.uploadError('Too many files.');
		return;
	}

	// Drag and drop does not supply a fakepath to file, so we have to use
	// a separate upload form from the postForm one. Meh.
	const extra = postForm.prepareUpload(),
		data = new FormData();
	data.append('image', files[0]);
	for (let key in extra) {
		data.append(key, extra[key]);
	}

	const xhr = new XMLHttpRequest();
	xhr.open('POST', etc.uploadURL());
	xhr.setRequestHeader('Accept', 'application/json');
	xhr.onreadystatechange = upload_shita;
	xhr.send(data);

	postForm.notifyUploading();
}

function upload_shita() {
	if (this.readyState != 4 || this.status == 202)
		return;
	const err = this.responseText;

	// Everything just fine. Don't need to report.
	if (!/legitimate imager response/.test(err))
		main.request('postForm').uploadError(err);
}

function stop_drag(e) {
	e.stopPropagation();
	e.preventDefault();
}

function setupUploadDrop(el) {
	go('dragenter', stop_drag);
	go('dragexit', stop_drag);
	go('dragover', stop_drag);
	go('drop', dragonDrop);

	function go(name, func) {
		el.addEventListener(name, func, false);
	}
}

if (!main.isMobile)
	main.defer(() => setupUploadDrop(main.$threads[0]));

<|endoftext|>