<commit_before>// Optimisation information
// Data - type== count
// Data time (which is used for optimisation)
// Plotting time
// Coupling with original data
// Simulated
// Call one PWIDData, the other PWIDModel

// Extraction stage

// INside the model, it tells it how to run.
// Outside the model, it tells it where to find the results.

function OptimisationDataExtractionObject(){
	this.Name;
	this.GraphInterfaceID;
	this.StatisticType;
	this.ResultFunction;// ResultFunction(Population, Time), returns a vector of times. Should be a population statistic
	this.XLabel;
	this.YLabel;

	this.Data;// specified follwing setup (must be a statistic type (count, summary, ratio))
	this.Result;
	this.DataTime;// uses the time specified in the data
	this.GraphTime;// uses the range of times specified to show the full activity of the model

	this.ErrorFunction;// specifies how the error is determined. function()

	this.MultiSimResult;
	this.MultiSimData;
}

// prototype CreateStatistic

OptimisationDataExtractionObject.prototype.ExtractDataAndFindError=function(SimulationResult){// SimulationResult
	this.SimResult=this.ResultFunction(SimulationResult,  this.DataTime);
	var Error=this.ErrorFunction();

	return Error;
};

OptimisationDataExtractionObject.prototype.ErrorFunction=function(){// SimulationResult
	// Note that this can be alterred by setting obj.Errorfunction=SomeFunction;
	var ErrorVec=Minus(this.Data, this.Result);
	var Error=Sum(ErrorVec);
	return Error;
};

OptimisationDataExtractionObject.prototype.CreateGraphData=function(){

	// Create names and titles

	//this.Data.StatisticType="Data";

	this.Result=this.ResultFunction(SimulationResult,  this.GraphTime);

	var ThisCopy=DeepCopy(this);

	return ThisCopy;// this is safe to return over the worker-worker divide
};

OptimisationDataExtractionObject.prototype.SummariseMultipleSimulations=function(ArrayOfResults){
	// ArrayOfResult[Sim].Data, ArrayOfResult[Sim].Result

	// Take an array of Result, sort into data/sim results
	var SplitDataResult=TransposeArrObj(ArrayOfResults);
	// SplitDataResult.Data[Sim], SplitDataResult.Result[Sim]

	if (typeof(SplitDataResult.Result[0].Name)!="undefined"){
		this.Name=SplitDataResult.Result[0].Name;
	}
	if (typeof(SplitDataResult.Result[0].GraphInterfaceID)!="undefined"){
		this.GraphInterfaceID=SplitDataResult.Result[0].GraphInterfaceID;
	}
	if (){

	}
	this.StatisticType;
	this.ResultFunction;// ResultFunction(Population, Time), returns a vector of times. Should be a population statistic
	this.XLabel;
	this.YLabel;

	// Performs summary statistics on data
	this.MultiSimData=StatisticSelector(SplitDataResult.Data);
	// Performs summary statistics on the results
	this.MultiSimResult=StatisticSelector(SplitDataResult.Result);

	console.error("Here's where we need to pull in information from the this.MultiSimResult")

};

OptimisationDataExtractionObject.prototype.Graph=function(){
	// Takes summarised results  this.MultiSimResult this.MultiSimData

	// function to extract	data into the correct form
	var StructureForGraph95CI=function(InputStat){
		ReturnObject={};
		ReturnObject.Y=InputStat.Median;
		ReturnObject.X=InputStat.Time;
		ReturnObject.Lower=InputStat.Lower95Percentile;
		ReturnObject.Upper=InputStat.Upper95Percentile;
		return ReturnObject;
	};

	console.error("Below is not a great way to set up the x and y labels");
	this.XLabel=this.MultiSimResult

	var PlotSettings={};
	PlotSettings.Name=this.Name;
	PlotSettings.XLabel=this.XLabel;
	PlotSettings.YLabel=this.YLabel;

	var PlotData=

	//var PlotData=StructureForGraph95CI(SummarisedResult.EverIDU);
	//var PlotSettings=SettingsForGraph(SummarisedResult.EverIDU);
	//var PlotData=StructureForGraph95CI(SummarisedResult.LivingWithHCVInfection);
	//var PlotSettings=SettingsForGraph(SummarisedResult.LivingWithHCVInfection);

	PlotSettings.Name=this.Name;// what the object will be called later
	PlotSettings.ID=this.GraphInterfaceID;

	PlotSettings.PlotData={};
	//	 PlotSettings.PlotData.Plot=[]; can this be deleted?

	PlotSettings.PlotData.Data=StructureForGraph95CI(this.MultiSimData);
	PlotSettings.PlotData.Result=StructureForGraph95CI(this.MultiSimResult);

	PlotSettings.PlotFunction=function(PlotPlaceholder, PlotData){
		console.log(PlotData);
		return OptimisationPlot(PlotPlaceholder, PlotData.Data, PlotData.Result);
	};

	PlotSettings.Data=[];
	PlotSettings.Data.Download=function (){console.log('This runs when the button is pushed')};

	PWIDEntryPlotObject=new GeneralPlot(PlotSettings);// this must be global
	PWIDEntryPlotObject.Draw();

	//

};

// Needs to be a
function ExtractOptimisationResults(ResultsBySim){
	// ResultsBySim[Sim].Optimisation[SpecificStatCount]

	// Transpose to get at all the .Optimisation results
	var ResultsByStat=TransposeArrObj(ResultsBySim);
	// ResultsByStat.Optimisation[Sim][SpecificStatCount]
	var OptimisationArrayBySim=ResultsByStat.Optimisation;// Choose to operate only on the Optimisation results
	// OptimisationStatArray[Sim][SpecificStatCount]
	var OptimisationArrayByStat=Transpose(OptimisationArrayBySim);
	//OptimisationStatArray[SpecificStatCount][Sim]

	var Optimisation=[];
	for (var SpecificStatCount in OptimisationArrayByStat){
		Optimisation[SpecificStatCount]= new OptimisationDataExtractionObject();
		Optimisation[SpecificStatCount].SummariseMultipleSimulations(OptimisationArrayByStat[SpecificStatCount]);
	}

	return Optimisation;
}

// CREATE A SUB ELEMENT THAT DOES THE OPTIMSIATION
// Results.Optimisation.Stats // the arrays match
// Results.Optimisation.Data

function SetupOptimisationDataExtractionObjects(){
	// this function is run both internally to the model and on the interface
	var DEO=[];//Array of OptimisationDataExtractionObject

	new NewDEO=new OptimisationDataExtractionObject();
	NewDEO.Name="EverIDU";
	this.ResultFunction=EverIDUStats;
	this.ErrorFunction=function(){
		this.Result.Count
	};

	// For age based ever injected
	//for both sexes{
	//	for all ages in the Data

	//}

	for (var Count in DEO){
		DEO[Count].GraphInterfaceID="OptimisationPlot"+Count;
	}

	return DEO;//Array of OptimisationDataExtractionObject
}

<commit_msg>Cleaning up the optimisation<commit_after>// Optimisation information
// Data - type== count
// Data time (which is used for optimisation)
// Plotting time
// Coupling with original data
// Simulated
// Call one PWIDData, the other PWIDModel

// Extraction stage

// INside the model, it tells it how to run.
// Outside the model, it tells it where to find the results.

function OptimisationDataExtractionObject(){
	this.Name;
	this.GraphInterfaceID;
	this.StatisticType;
	this.ResultFunction;// ResultFunction(Population, Time), returns a vector of times. Should be a population statistic
	this.XLabel;
	this.YLabel;

	this.Data;// specified follwing setup (must be a statistic type (count, summary, ratio))
	this.Result;
	this.DataTime;// uses the time specified in the data
	this.GraphTime;// uses the range of times specified to show the full activity of the model

	this.ErrorFunction;// specifies how the error is determined. function()

	this.MultiSimResult;
	this.MultiSimData;

	this.GraphObject;
	this.DownloadData;
}

// prototype CreateStatistic

OptimisationDataExtractionObject.prototype.ExtractDataAndFindError=function(SimulationResult){// SimulationResult.Population
	this.SimResult=this.ResultFunction(SimulationResult,  this.DataTime);
	var Error=this.ErrorFunction();

	return Error;
};

OptimisationDataExtractionObject.prototype.ErrorFunction=function(){// SimulationResult
	// Note that this can be alterred by setting obj.Errorfunction=SomeFunction;
	var ErrorVec=Minus(this.Data, this.Result);
	var Error=Sum(ErrorVec);
	return Error;
};

OptimisationDataExtractionObject.prototype.CreateGraphData=function(SimulationResult){

	// Create names and titles

	//this.Data.StatisticType="Data";

	this.Result=this.ResultFunction(SimulationResult,  this.GraphTime);

	var ThisCopy=DeepCopy(this);

	return ThisCopy;// this is safe to return over the worker-worker divide
};

OptimisationDataExtractionObject.prototype.SummariseMultipleSimulations=function(ArrayOfResults){
	// ArrayOfResult[Sim].Data, ArrayOfResult[Sim].Result

	var FirstResult=ArrayOfResults[0];
	if (typeof(FirstResult.Name)!="undefined"){
		this.Name=FirstResult.Name;
	}
	if (typeof(FirstResult.GraphInterfaceID)!="undefined"){
		this.GraphInterfaceID=FirstResult.GraphInterfaceID;
	}
	if (typeof(FirstResult.StatisticType)!="undefined"){
		this.StatisticType=FirstResult.StatisticType;
	}
	if (typeof(FirstResult.XLabel)!="undefined"){
		this.XLabel=FirstResult.XLabel;
	}
	if (typeof(FirstResult.YLabel)!="undefined"){
		this.YLabel=FirstResult.YLabel;
	}

	// Take ArrayOfResults, sort into data/sim results
	var SplitDataResult=TransposeArrObj(ArrayOfResults);
	// SplitDataResult.Data[Sim], SplitDataResult.Result[Sim], and other SplitDataResult.Things that are quite useless

	// Performs summary statistics on data
	this.MultiSimData=StatisticSelector(SplitDataResult.Data);
	// Performs summary statistics on the results
	this.MultiSimResult=StatisticSelector(SplitDataResult.Result);

};

OptimisationDataExtractionObject.prototype.Graph=function(){
	// Takes summarised results  this.MultiSimResult this.MultiSimData

	// function to extract	data into the correct form
	var StructureForGraph95CI=function(InputStat){
		ReturnObject={};
		ReturnObject.Y=InputStat.Median;
		ReturnObject.X=InputStat.Time;
		ReturnObject.Lower=InputStat.Lower95Percentile;
		ReturnObject.Upper=InputStat.Upper95Percentile;
		return ReturnObject;
	};

	console.error("Below is not a great way to set up the x and y labels");
	this.XLabel=this.MultiSimResult

	var PlotSettings={};
	PlotSettings.Name=this.Name;
	PlotSettings.XLabel=this.XLabel;
	PlotSettings.YLabel=this.YLabel;
	PlotSettings.ID=this.GraphInterfaceID;

	PlotSettings.PlotData={};
	//	 PlotSettings.PlotData.Plot=[]; can this be deleted?

	PlotSettings.PlotData.Data=StructureForGraph95CI(this.MultiSimData);
	PlotSettings.PlotData.Result=StructureForGraph95CI(this.MultiSimResult);

	PlotSettings.PlotFunction=function(PlotPlaceholder, PlotData){
		console.log(PlotData);
		return OptimisationPlot(PlotPlaceholder, PlotData.Data, PlotData.Result);
	};

	PlotSettings.Data=[];
	PlotSettings.Data.Download=function (){console.log('This runs when the button is pushed')};

	this.GraphObject=new GeneralPlot(PlotSettings);// this must be global
	this.GraphObject.Draw();

	//

};

// Needs to be a
function ExtractOptimisationResults(ResultsBySim){
	// ResultsBySim[Sim].Optimisation[SpecificStatCount]

	// Transpose to get at all the .Optimisation results
	var ResultsByStat=TransposeArrObj(ResultsBySim);
	// ResultsByStat.Optimisation[Sim][SpecificStatCount]
	var OptimisationArrayBySim=ResultsByStat.Optimisation;// Choose to operate only on the Optimisation results
	// OptimisationStatArray[Sim][SpecificStatCount]
	var OptimisationArrayByStat=Transpose(OptimisationArrayBySim);
	//OptimisationStatArray[SpecificStatCount][Sim]

	var Optimisation=[];
	for (var SpecificStatCount in OptimisationArrayByStat){
		Optimisation[SpecificStatCount]= new OptimisationDataExtractionObject();
		Optimisation[SpecificStatCount].SummariseMultipleSimulations(OptimisationArrayByStat[SpecificStatCount]);
	}

	return Optimisation;
}

// CREATE A SUB ELEMENT THAT DOES THE OPTIMSIATION
// Results.Optimisation.Stats // the arrays match
// Results.Optimisation.Data

function SetupOptimisationDataExtractionObjects(){
	// this function is run both internally to the model and on the interface
	var DEO=[];//Array of OptimisationDataExtractionObject

	new NewDEO=new OptimisationDataExtractionObject();
	NewDEO.Name="EverIDU";
	this.ResultFunction=EverIDUStats;
	this.ErrorFunction=function(){
		this.Result.Count
	};

	// For age based ever injected
	//for both sexes{
	//	for all ages in the Data

	//}

	for (var Count in DEO){
		DEO[Count].GraphInterfaceID="OptimisationPlot"+Count;
	}

	return DEO;//Array of OptimisationDataExtractionObject
}

<|endoftext|>


<commit_before>/*global game,Phaser*/
var state = {};

var enemy, shots;

state.create = function() {
    shots = game.add.group();
    var background = game.add.tileSprite(0, 0, 800, 600, 'starfield');
    background.update = function() {
        this.tilePosition.y += 1200 * game.time.physicsElapsed;
    };
    var ship = game.add.sprite(0, 0, 'ship');
    game.physics.arcade.enable(ship);
    ship.anchor.set(0.5);
    ship.scale.set(0.4);
    ship.shotTimer = 0;
    ship.update = function() {
        ship.body.velocity.set(0);
        if (game.physics.arcade.distanceToPointer(ship) > 10)
            game.physics.arcade.moveToPointer(ship, 300);
        if ((this.shotTimer += game.time.physicsElapsed) >= .25) {
            this.shotTimer = 0;
            var shot = game.make.sprite(this.x, this.y, 'pix');
            shot.height = 8;
            shot.width = 4;
            shot.anchor.set(0.5);
            shot.tint = 0x00ff00;
            game.physics.arcade.enable(shot);
            shot.body.velocity.y = -600;
            shots.add(shot);
        }
    };

    enemy = game.add.sprite(0, 0, 'pix');
    enemy.height = enemy.width = 40;
    enemy.anchor.set(0.5);
    game.physics.arcade.enable(enemy);
    enemy.x = 300;
    enemy.y = 50;
    game.add.tween(enemy).to({
        y: 300,
        x: 500
    }, 2000, Phaser.Easing.Sinusoidal.InOut, true, 0, -1, true);
};

state.update = function() {
    game.physics.arcade.overlap(enemy, shots, function(enemy, shot) {
        shot.kill();
    });
};

module.exports = state;<commit_msg>Implement shot pooling.<commit_after>/*global game,Phaser*/
var state = {};

var enemies, shots;

state.create = function() {
    shots = game.add.physicsGroup();
    enemies = game.add.physicsGroup();

    var background = game.add.tileSprite(0, 0, 800, 600, 'starfield');
    background.update = function() {
        this.tilePosition.y += 1200 * game.time.physicsElapsed;
    };
    var ship = game.add.sprite(0, 0, 'ship');
    game.physics.arcade.enable(ship);
    ship.anchor.set(0.5);
    ship.scale.set(0.4);
    ship.shotTimer = 0;
    ship.update = function() {
        ship.body.velocity.set(0);
        if (game.physics.arcade.distanceToPointer(ship) > 5)
            game.physics.arcade.moveToPointer(ship, 300);
        if ((this.shotTimer += game.time.physicsElapsed) >= .25) {
            this.shotTimer = 0;
            var shot;
            if ((shot = shots.getFirstDead())) {
                shot.x = this.x;
                shot.y = this.y;
                shot.revive();
            }
            else {
                shot = game.make.sprite(this.x, this.y, 'pix');
                shot.height = 8;
                shot.width = 4;
                shot.anchor.set(0.5);
                shot.tint = 0x00ff00;
                shot.checkWorldBounds = true;
                shot.outOfBoundsKill = true;
                shots.add(shot);
                shot.body.velocity.y = -600;
            }
        }
    };

    var enemy = game.make.sprite(0, 0, 'pix');
    enemy.height = enemy.width = 40;
    enemy.anchor.set(0.5);
    enemy.x = 300;
    enemy.y = 50;
    game.add.tween(enemy).to({
        y: 300,
        x: 500
    }, 2000, Phaser.Easing.Sinusoidal.InOut, true, 0, -1, true);
    enemies.add(enemy);
};

state.update = function() {
    game.physics.arcade.overlap(enemies, shots, function(enemy, shot) {
        shot.kill();
    });
};

module.exports = state;<|endoftext|>


<commit_before>'use strict';

/*
 * 1. Check if the browser supports `position: sticky` natively or is too old to run the polyfill.
 *    If either of these is the case set `seppuku` flag. It will be checked later to disable key features
 *    of the polyfill, but the API will remain functional to avoid breaking things.
 */
let seppuku = false;
let isInitialized = false;

// Check for existence of window in case this is being imported on the server in an SSR app
const isWindowDefined = typeof window !== 'undefined';

// The polyfill cant’t function properly without `getComputedStyle`.
if (isWindowDefined && !window.getComputedStyle) seppuku = true;
// Dont’t get in a way if the browser supports `position: sticky` natively.
else {
    const testNode = document.createElement('div');

    if (
        ['', '-webkit-', '-moz-', '-ms-'].some(prefix => {
            try {
                testNode.style.position = prefix + 'sticky';
            }
            catch(e) {}

            return testNode.style.position != '';
        })
    ) seppuku = true;
}

/*
 * 2. “Global” vars used across the polyfill
 */

// Check if Shadow Root constructor exists to make further checks simpler
const shadowRootExists = typeof ShadowRoot !== 'undefined';

// Last saved scroll position
const scroll = {
    top: null,
    left: null
};

// Array of created Sticky instances
const stickies = [];

/*
 * 3. Utility functions
 */
function extend (targetObj, sourceObject) {
    for (var key in sourceObject) {
        if (sourceObject.hasOwnProperty(key)) {
            targetObj[key] = sourceObject[key];
        }
    }
}

function parseNumeric (val) {
    return parseFloat(val) || 0;
}

function getDocOffsetTop (node) {
    let docOffsetTop = 0;

    while (node) {
        docOffsetTop += node.offsetTop;
        node = node.offsetParent;
    }

    return docOffsetTop;
}

/*
 * 4. Sticky class
 */
class Sticky {
    constructor (node) {
        if (!(node instanceof HTMLElement))
            throw new Error('First argument must be HTMLElement');
        if (stickies.some(sticky => sticky._node === node))
            throw new Error('Stickyfill is already applied to this node');

        this._node = node;
        this._stickyMode = null;
        this._active = false;

        stickies.push(this);

        this.refresh();
    }

    refresh () {
        if (seppuku || this._removed) return;
        if (this._active) this._deactivate();

        const node = this._node;

        /*
         * 1. Save node computed props
         */
        const nodeComputedStyle = getComputedStyle(node);
        const nodeComputedProps = {
            top: nodeComputedStyle.top,
            display: nodeComputedStyle.display,
            marginTop: nodeComputedStyle.marginTop,
            marginBottom: nodeComputedStyle.marginBottom,
            marginLeft: nodeComputedStyle.marginLeft,
            marginRight: nodeComputedStyle.marginRight,
            cssFloat: nodeComputedStyle.cssFloat
        };

        /*
         * 2. Check if the node can be activated
         */
        if (
            isNaN(parseFloat(nodeComputedProps.top)) ||
            nodeComputedProps.display == 'table-cell' ||
            nodeComputedProps.display == 'none'
        ) return;

        this._active = true;

        /*
         * 3. Get necessary node parameters
         */
        const referenceNode = node.parentNode;
        const parentNode = shadowRootExists && referenceNode instanceof ShadowRoot? referenceNode.host: referenceNode;
        const nodeWinOffset = node.getBoundingClientRect();
        const parentWinOffset = parentNode.getBoundingClientRect();
        const parentComputedStyle = getComputedStyle(parentNode);

        this._parent = {
            node: parentNode,
            styles: {
                position: parentNode.style.position
            },
            offsetHeight: parentNode.offsetHeight
        };
        this._offsetToWindow = {
            left: nodeWinOffset.left,
            right: document.documentElement.clientWidth - nodeWinOffset.right
        };
        this._offsetToParent = {
            top: nodeWinOffset.top - parentWinOffset.top - parseNumeric(parentComputedStyle.borderTopWidth),
            left: nodeWinOffset.left - parentWinOffset.left - parseNumeric(parentComputedStyle.borderLeftWidth),
            right: -nodeWinOffset.right + parentWinOffset.right - parseNumeric(parentComputedStyle.borderRightWidth)
        };
        this._styles = {
            position: node.style.position,
            top: node.style.top,
            bottom: node.style.bottom,
            left: node.style.left,
            right: node.style.right,
            width: node.style.width,
            marginTop: node.style.marginTop,
            marginLeft: node.style.marginLeft,
            marginRight: node.style.marginRight
        };

        const nodeTopValue = parseNumeric(nodeComputedProps.top);
        this._limits = {
            start: nodeWinOffset.top + window.pageYOffset - nodeTopValue,
            end: parentWinOffset.top + window.pageYOffset + parentNode.offsetHeight -
                parseNumeric(parentComputedStyle.borderBottomWidth) - node.offsetHeight -
                nodeTopValue - parseNumeric(nodeComputedProps.marginBottom)
        };

        /*
         * 4. Ensure that the node will be positioned relatively to the parent node
         */
        const parentPosition = parentComputedStyle.position;

        if (
            parentPosition != 'absolute' &&
            parentPosition != 'relative'
        ) {
            parentNode.style.position = 'relative';
        }

        /*
         * 5. Recalc node position.
         *    It’s important to do this before clone injection to avoid scrolling bug in Chrome.
         */
        this._recalcPosition();

        /*
         * 6. Create a clone
         */
        const clone = this._clone = {};
        clone.node = document.createElement('div');

        // Apply styles to the clone
        extend(clone.node.style, {
            width: nodeWinOffset.right - nodeWinOffset.left + 'px',
            height: nodeWinOffset.bottom - nodeWinOffset.top + 'px',
            marginTop: nodeComputedProps.marginTop,
            marginBottom: nodeComputedProps.marginBottom,
            marginLeft: nodeComputedProps.marginLeft,
            marginRight: nodeComputedProps.marginRight,
            cssFloat: nodeComputedProps.cssFloat,
            padding: 0,
            border: 0,
            borderSpacing: 0,
            fontSize: '1em',
            position: 'static'
        });

        referenceNode.insertBefore(clone.node, node);
        clone.docOffsetTop = getDocOffsetTop(clone.node);
    }

    _recalcPosition () {
        if (!this._active || this._removed) return;

        const stickyMode = scroll.top <= this._limits.start? 'start': scroll.top >= this._limits.end? 'end': 'middle';

        if (this._stickyMode == stickyMode) return;

        switch (stickyMode) {
            case 'start':
                extend(this._node.style, {
                    position: 'absolute',
                    left: this._offsetToParent.left + 'px',
                    right: this._offsetToParent.right + 'px',
                    top: this._offsetToParent.top + 'px',
                    bottom: 'auto',
                    width: 'auto',
                    marginLeft: 0,
                    marginRight: 0,
                    marginTop: 0
                });
                break;

            case 'middle':
                extend(this._node.style, {
                    position: 'fixed',
                    left: this._offsetToWindow.left + 'px',
                    right: this._offsetToWindow.right + 'px',
                    top: this._styles.top,
                    bottom: 'auto',
                    width: 'auto',
                    marginLeft: 0,
                    marginRight: 0,
                    marginTop: 0
                });
                break;

            case 'end':
                extend(this._node.style, {
                    position: 'absolute',
                    left: this._offsetToParent.left + 'px',
                    right: this._offsetToParent.right + 'px',
                    top: 'auto',
                    bottom: 0,
                    width: 'auto',
                    marginLeft: 0,
                    marginRight: 0
                });
                break;
        }

        this._stickyMode = stickyMode;
    }

    _fastCheck () {
        if (!this._active || this._removed) return;

        if (
            Math.abs(getDocOffsetTop(this._clone.node) - this._clone.docOffsetTop) > 1 ||
            Math.abs(this._parent.node.offsetHeight - this._parent.offsetHeight) > 1
        ) this.refresh();
    }

    _deactivate () {
        if (!this._active || this._removed) return;

        this._clone.node.parentNode.removeChild(this._clone.node);
        delete this._clone;

        extend(this._node.style, this._styles);
        delete this._styles;

        // Check whether element’s parent node is used by other stickies.
        // If not, restore parent node’s styles.
        if (!stickies.some(sticky => sticky !== this && sticky._parent && sticky._parent.node === this._parent.node)) {
            extend(this._parent.node.style, this._parent.styles);
        }
        delete this._parent;

        this._stickyMode = null;
        this._active = false;

        delete this._offsetToWindow;
        delete this._offsetToParent;
        delete this._limits;
    }

    remove () {
        this._deactivate();

        stickies.some((sticky, index) => {
            if (sticky._node === this._node) {
                stickies.splice(index, 1);
                return true;
            }
        });

        this._removed = true;
    }
}

/*
 * 5. Stickyfill API
 */
const Stickyfill = {
    stickies,
    Sticky,

    forceSticky () {
        seppuku = false;

        if (!isInitialized) {
            init();
        }

        this.refreshAll();
    },

    addOne (node) {
        // Check whether it’s a node
        if (!(node instanceof HTMLElement)) {
            // Maybe it’s a node list of some sort?
            // Take first node from the list then
            if (node.length && node[0]) node = node[0];
            else return;
        }

        // Check if Stickyfill is already applied to the node
        // and return existing sticky
        for (var i = 0; i < stickies.length; i++) {
            if (stickies[i]._node === node) return stickies[i];
        }

        // Create and return new sticky
        return new Sticky(node);
    },

    add (nodeList) {
        // If it’s a node make an array of one node
        if (nodeList instanceof HTMLElement) nodeList = [nodeList];
        // Check if the argument is an iterable of some sort
        if (!nodeList.length) return;

        // Add every element as a sticky and return an array of created Sticky instances
        const addedStickies = [];

        for (let i = 0; i < nodeList.length; i++) {
            const node = nodeList[i];

            // If it’s not an HTMLElement – create an empty element to preserve 1-to-1
            // correlation with input list
            if (!(node instanceof HTMLElement)) {
                addedStickies.push(void 0);
                continue;
            }

            // If Stickyfill is already applied to the node
            // add existing sticky
            if (stickies.some(sticky => {
                if (sticky._node === node) {
                    addedStickies.push(sticky);
                    return true;
                }
            })) continue;

            // Create and add new sticky
            addedStickies.push(new Sticky(node));
        }

        return addedStickies;
    },

    refreshAll () {
        stickies.forEach(sticky => sticky.refresh());
    },

    removeOne (node) {
        // Check whether it’s a node
        if (!(node instanceof HTMLElement)) {
            // Maybe it’s a node list of some sort?
            // Take first node from the list then
            if (node.length && node[0]) node = node[0];
            else return;
        }

        // Remove the stickies bound to the nodes in the list
        stickies.some(sticky => {
            if (sticky._node === node) {
                sticky.remove();
                return true;
            }
        });
    },

    remove (nodeList) {
        // If it’s a node make an array of one node
        if (nodeList instanceof HTMLElement) nodeList = [nodeList];
        // Check if the argument is an iterable of some sort
        if (!nodeList.length) return;

        // Remove the stickies bound to the nodes in the list
        for (let i = 0; i < nodeList.length; i++) {
            const node = nodeList[i];

            stickies.some(sticky => {
                if (sticky._node === node) {
                    sticky.remove();
                    return true;
                }
            });
        }
    },

    removeAll () {
        while (stickies.length) stickies[0].remove();
    }
};

/*
 * 6. Setup events (unless the polyfill was disabled)
 */
function init () {
    isInitialized = true;

    // Watch for scroll position changes and trigger recalc/refresh if needed
    function checkScroll () {
        if (window.pageXOffset != scroll.left) {
            scroll.top = window.pageYOffset;
            scroll.left = window.pageXOffset;

            Stickyfill.refreshAll();
        }
        else if (window.pageYOffset != scroll.top) {
            scroll.top = window.pageYOffset;
            scroll.left = window.pageXOffset;

            // recalc position for all stickies
            stickies.forEach(sticky => sticky._recalcPosition());
        }
    }

    checkScroll();
    window.addEventListener('scroll', checkScroll);

    // Watch for window resizes and device orientation changes and trigger refresh
    window.addEventListener('resize', Stickyfill.refreshAll);
    window.addEventListener('orientationchange', Stickyfill.refreshAll);

    //Fast dirty check for layout changes every 500ms
    let fastCheckTimer;

    function startFastCheckTimer () {
        fastCheckTimer = setInterval(function () {
            stickies.forEach(sticky => sticky._fastCheck());
        }, 500);
    }

    function stopFastCheckTimer () {
        clearInterval(fastCheckTimer);
    }

    let docHiddenKey;
    let visibilityChangeEventName;

    if ('hidden' in document) {
        docHiddenKey = 'hidden';
        visibilityChangeEventName = 'visibilitychange';
    }
    else if ('webkitHidden' in document) {
        docHiddenKey = 'webkitHidden';
        visibilityChangeEventName = 'webkitvisibilitychange';
    }

    if (visibilityChangeEventName) {
        if (!document[docHiddenKey]) startFastCheckTimer();

        document.addEventListener(visibilityChangeEventName, () => {
            if (document[docHiddenKey]) {
                stopFastCheckTimer();
            }
            else {
                startFastCheckTimer();
            }
        });
    }
    else startFastCheckTimer();
}

if (isWindowDefined && !seppuku) init();

/*
 * 7. Expose Stickyfill
 */
if (typeof module != 'undefined' && module.exports) {
    module.exports = Stickyfill;
}
else if (isWindowDefined) {
    window.Stickyfill = Stickyfill;
}
<commit_msg>PR comments<commit_after>'use strict';

/*
 * 1. Check if the browser supports `position: sticky` natively or is too old to run the polyfill.
 *    If either of these is the case set `seppuku` flag. It will be checked later to disable key features
 *    of the polyfill, but the API will remain functional to avoid breaking things.
 */
let seppuku = false;

// The polyfill can’t function properly without `window` or `window.getComputedStyle`.
if (typeof window === 'undefined' || !window.getComputedStyle) seppuku = true;
// Dont’t get in a way if the browser supports `position: sticky` natively.
else {
    const testNode = document.createElement('div');

    if (
        ['', '-webkit-', '-moz-', '-ms-'].some(prefix => {
            try {
                testNode.style.position = prefix + 'sticky';
            }
            catch(e) {}

            return testNode.style.position != '';
        })
    ) seppuku = true;
}

/*
 * 2. “Global” vars used across the polyfill
 */
let isInitialized = false;

// Check if Shadow Root constructor exists to make further checks simpler
const shadowRootExists = typeof ShadowRoot !== 'undefined';

// Last saved scroll position
const scroll = {
    top: null,
    left: null
};

// Array of created Sticky instances
const stickies = [];

/*
 * 3. Utility functions
 */
function extend (targetObj, sourceObject) {
    for (var key in sourceObject) {
        if (sourceObject.hasOwnProperty(key)) {
            targetObj[key] = sourceObject[key];
        }
    }
}

function parseNumeric (val) {
    return parseFloat(val) || 0;
}

function getDocOffsetTop (node) {
    let docOffsetTop = 0;

    while (node) {
        docOffsetTop += node.offsetTop;
        node = node.offsetParent;
    }

    return docOffsetTop;
}

/*
 * 4. Sticky class
 */
class Sticky {
    constructor (node) {
        if (!(node instanceof HTMLElement))
            throw new Error('First argument must be HTMLElement');
        if (stickies.some(sticky => sticky._node === node))
            throw new Error('Stickyfill is already applied to this node');

        this._node = node;
        this._stickyMode = null;
        this._active = false;

        stickies.push(this);

        this.refresh();
    }

    refresh () {
        if (seppuku || this._removed) return;
        if (this._active) this._deactivate();

        const node = this._node;

        /*
         * 1. Save node computed props
         */
        const nodeComputedStyle = getComputedStyle(node);
        const nodeComputedProps = {
            top: nodeComputedStyle.top,
            display: nodeComputedStyle.display,
            marginTop: nodeComputedStyle.marginTop,
            marginBottom: nodeComputedStyle.marginBottom,
            marginLeft: nodeComputedStyle.marginLeft,
            marginRight: nodeComputedStyle.marginRight,
            cssFloat: nodeComputedStyle.cssFloat
        };

        /*
         * 2. Check if the node can be activated
         */
        if (
            isNaN(parseFloat(nodeComputedProps.top)) ||
            nodeComputedProps.display == 'table-cell' ||
            nodeComputedProps.display == 'none'
        ) return;

        this._active = true;

        /*
         * 3. Get necessary node parameters
         */
        const referenceNode = node.parentNode;
        const parentNode = shadowRootExists && referenceNode instanceof ShadowRoot? referenceNode.host: referenceNode;
        const nodeWinOffset = node.getBoundingClientRect();
        const parentWinOffset = parentNode.getBoundingClientRect();
        const parentComputedStyle = getComputedStyle(parentNode);

        this._parent = {
            node: parentNode,
            styles: {
                position: parentNode.style.position
            },
            offsetHeight: parentNode.offsetHeight
        };
        this._offsetToWindow = {
            left: nodeWinOffset.left,
            right: document.documentElement.clientWidth - nodeWinOffset.right
        };
        this._offsetToParent = {
            top: nodeWinOffset.top - parentWinOffset.top - parseNumeric(parentComputedStyle.borderTopWidth),
            left: nodeWinOffset.left - parentWinOffset.left - parseNumeric(parentComputedStyle.borderLeftWidth),
            right: -nodeWinOffset.right + parentWinOffset.right - parseNumeric(parentComputedStyle.borderRightWidth)
        };
        this._styles = {
            position: node.style.position,
            top: node.style.top,
            bottom: node.style.bottom,
            left: node.style.left,
            right: node.style.right,
            width: node.style.width,
            marginTop: node.style.marginTop,
            marginLeft: node.style.marginLeft,
            marginRight: node.style.marginRight
        };

        const nodeTopValue = parseNumeric(nodeComputedProps.top);
        this._limits = {
            start: nodeWinOffset.top + window.pageYOffset - nodeTopValue,
            end: parentWinOffset.top + window.pageYOffset + parentNode.offsetHeight -
                parseNumeric(parentComputedStyle.borderBottomWidth) - node.offsetHeight -
                nodeTopValue - parseNumeric(nodeComputedProps.marginBottom)
        };

        /*
         * 4. Ensure that the node will be positioned relatively to the parent node
         */
        const parentPosition = parentComputedStyle.position;

        if (
            parentPosition != 'absolute' &&
            parentPosition != 'relative'
        ) {
            parentNode.style.position = 'relative';
        }

        /*
         * 5. Recalc node position.
         *    It’s important to do this before clone injection to avoid scrolling bug in Chrome.
         */
        this._recalcPosition();

        /*
         * 6. Create a clone
         */
        const clone = this._clone = {};
        clone.node = document.createElement('div');

        // Apply styles to the clone
        extend(clone.node.style, {
            width: nodeWinOffset.right - nodeWinOffset.left + 'px',
            height: nodeWinOffset.bottom - nodeWinOffset.top + 'px',
            marginTop: nodeComputedProps.marginTop,
            marginBottom: nodeComputedProps.marginBottom,
            marginLeft: nodeComputedProps.marginLeft,
            marginRight: nodeComputedProps.marginRight,
            cssFloat: nodeComputedProps.cssFloat,
            padding: 0,
            border: 0,
            borderSpacing: 0,
            fontSize: '1em',
            position: 'static'
        });

        referenceNode.insertBefore(clone.node, node);
        clone.docOffsetTop = getDocOffsetTop(clone.node);
    }

    _recalcPosition () {
        if (!this._active || this._removed) return;

        const stickyMode = scroll.top <= this._limits.start? 'start': scroll.top >= this._limits.end? 'end': 'middle';

        if (this._stickyMode == stickyMode) return;

        switch (stickyMode) {
            case 'start':
                extend(this._node.style, {
                    position: 'absolute',
                    left: this._offsetToParent.left + 'px',
                    right: this._offsetToParent.right + 'px',
                    top: this._offsetToParent.top + 'px',
                    bottom: 'auto',
                    width: 'auto',
                    marginLeft: 0,
                    marginRight: 0,
                    marginTop: 0
                });
                break;

            case 'middle':
                extend(this._node.style, {
                    position: 'fixed',
                    left: this._offsetToWindow.left + 'px',
                    right: this._offsetToWindow.right + 'px',
                    top: this._styles.top,
                    bottom: 'auto',
                    width: 'auto',
                    marginLeft: 0,
                    marginRight: 0,
                    marginTop: 0
                });
                break;

            case 'end':
                extend(this._node.style, {
                    position: 'absolute',
                    left: this._offsetToParent.left + 'px',
                    right: this._offsetToParent.right + 'px',
                    top: 'auto',
                    bottom: 0,
                    width: 'auto',
                    marginLeft: 0,
                    marginRight: 0
                });
                break;
        }

        this._stickyMode = stickyMode;
    }

    _fastCheck () {
        if (!this._active || this._removed) return;

        if (
            Math.abs(getDocOffsetTop(this._clone.node) - this._clone.docOffsetTop) > 1 ||
            Math.abs(this._parent.node.offsetHeight - this._parent.offsetHeight) > 1
        ) this.refresh();
    }

    _deactivate () {
        if (!this._active || this._removed) return;

        this._clone.node.parentNode.removeChild(this._clone.node);
        delete this._clone;

        extend(this._node.style, this._styles);
        delete this._styles;

        // Check whether element’s parent node is used by other stickies.
        // If not, restore parent node’s styles.
        if (!stickies.some(sticky => sticky !== this && sticky._parent && sticky._parent.node === this._parent.node)) {
            extend(this._parent.node.style, this._parent.styles);
        }
        delete this._parent;

        this._stickyMode = null;
        this._active = false;

        delete this._offsetToWindow;
        delete this._offsetToParent;
        delete this._limits;
    }

    remove () {
        this._deactivate();

        stickies.some((sticky, index) => {
            if (sticky._node === this._node) {
                stickies.splice(index, 1);
                return true;
            }
        });

        this._removed = true;
    }
}

/*
 * 5. Stickyfill API
 */
const Stickyfill = {
    stickies,
    Sticky,

    forceSticky () {
        seppuku = false;
        init();

        this.refreshAll();
    },

    addOne (node) {
        // Check whether it’s a node
        if (!(node instanceof HTMLElement)) {
            // Maybe it’s a node list of some sort?
            // Take first node from the list then
            if (node.length && node[0]) node = node[0];
            else return;
        }

        // Check if Stickyfill is already applied to the node
        // and return existing sticky
        for (var i = 0; i < stickies.length; i++) {
            if (stickies[i]._node === node) return stickies[i];
        }

        // Create and return new sticky
        return new Sticky(node);
    },

    add (nodeList) {
        // If it’s a node make an array of one node
        if (nodeList instanceof HTMLElement) nodeList = [nodeList];
        // Check if the argument is an iterable of some sort
        if (!nodeList.length) return;

        // Add every element as a sticky and return an array of created Sticky instances
        const addedStickies = [];

        for (let i = 0; i < nodeList.length; i++) {
            const node = nodeList[i];

            // If it’s not an HTMLElement – create an empty element to preserve 1-to-1
            // correlation with input list
            if (!(node instanceof HTMLElement)) {
                addedStickies.push(void 0);
                continue;
            }

            // If Stickyfill is already applied to the node
            // add existing sticky
            if (stickies.some(sticky => {
                if (sticky._node === node) {
                    addedStickies.push(sticky);
                    return true;
                }
            })) continue;

            // Create and add new sticky
            addedStickies.push(new Sticky(node));
        }

        return addedStickies;
    },

    refreshAll () {
        stickies.forEach(sticky => sticky.refresh());
    },

    removeOne (node) {
        // Check whether it’s a node
        if (!(node instanceof HTMLElement)) {
            // Maybe it’s a node list of some sort?
            // Take first node from the list then
            if (node.length && node[0]) node = node[0];
            else return;
        }

        // Remove the stickies bound to the nodes in the list
        stickies.some(sticky => {
            if (sticky._node === node) {
                sticky.remove();
                return true;
            }
        });
    },

    remove (nodeList) {
        // If it’s a node make an array of one node
        if (nodeList instanceof HTMLElement) nodeList = [nodeList];
        // Check if the argument is an iterable of some sort
        if (!nodeList.length) return;

        // Remove the stickies bound to the nodes in the list
        for (let i = 0; i < nodeList.length; i++) {
            const node = nodeList[i];

            stickies.some(sticky => {
                if (sticky._node === node) {
                    sticky.remove();
                    return true;
                }
            });
        }
    },

    removeAll () {
        while (stickies.length) stickies[0].remove();
    }
};

/*
 * 6. Setup events (unless the polyfill was disabled)
 */
function init () {
    if (isInitialized) {
        return;
    }

    isInitialized = true;

    // Watch for scroll position changes and trigger recalc/refresh if needed
    function checkScroll () {
        if (window.pageXOffset != scroll.left) {
            scroll.top = window.pageYOffset;
            scroll.left = window.pageXOffset;

            Stickyfill.refreshAll();
        }
        else if (window.pageYOffset != scroll.top) {
            scroll.top = window.pageYOffset;
            scroll.left = window.pageXOffset;

            // recalc position for all stickies
            stickies.forEach(sticky => sticky._recalcPosition());
        }
    }

    checkScroll();
    window.addEventListener('scroll', checkScroll);

    // Watch for window resizes and device orientation changes and trigger refresh
    window.addEventListener('resize', Stickyfill.refreshAll);
    window.addEventListener('orientationchange', Stickyfill.refreshAll);

    //Fast dirty check for layout changes every 500ms
    let fastCheckTimer;

    function startFastCheckTimer () {
        fastCheckTimer = setInterval(function () {
            stickies.forEach(sticky => sticky._fastCheck());
        }, 500);
    }

    function stopFastCheckTimer () {
        clearInterval(fastCheckTimer);
    }

    let docHiddenKey;
    let visibilityChangeEventName;

    if ('hidden' in document) {
        docHiddenKey = 'hidden';
        visibilityChangeEventName = 'visibilitychange';
    }
    else if ('webkitHidden' in document) {
        docHiddenKey = 'webkitHidden';
        visibilityChangeEventName = 'webkitvisibilitychange';
    }

    if (visibilityChangeEventName) {
        if (!document[docHiddenKey]) startFastCheckTimer();

        document.addEventListener(visibilityChangeEventName, () => {
            if (document[docHiddenKey]) {
                stopFastCheckTimer();
            }
            else {
                startFastCheckTimer();
            }
        });
    }
    else startFastCheckTimer();
}

if (!seppuku) init();

/*
 * 7. Expose Stickyfill
 */
if (typeof module != 'undefined' && module.exports) {
    module.exports = Stickyfill;
}
else {
    this.Stickyfill = Stickyfill;
}
<|endoftext|>


<commit_before>import * as is from './is';
import Style from './style';
import { dash2camel } from './util';

// a dummy stylesheet object that doesn't need a reference to the core
// (useful for init)
let Stylesheet = function(){
  if( !(this instanceof Stylesheet) ){
    return new Stylesheet();
  }

  this.length = 0;
};

let sheetfn = Stylesheet.prototype;

sheetfn.instanceString = function(){
  return 'stylesheet';
};

// just store the selector to be parsed later
sheetfn.selector = function( selector ){
  let i = this.length++;

  this[ i ] = {
    selector: selector,
    properties: []
  };

  return this; // chaining
};

// just store the property to be parsed later
sheetfn.css = function( name, value ){
  let i = this.length - 1;

  if( is.string( name ) ){
    this[ i ].properties.push( {
      name: name,
      value: value
    } );
  } else if( is.plainObject( name ) ){
    let map = name;
    let propNames = Object.keys( map );

    for( let j = 0; j < propNames.length; j++ ){
      let key = propNames[ j ];
      let mapVal = map[ propNames ];

      if( mapVal == null ){ continue; }

      let prop = Style.properties[key] || Style.properties[dash2camel(key)];

      if( prop == null ){ continue; }

      let name = prop.name;
      let value = mapVal;

      this[ i ].properties.push( {
        name: name,
        value: value
      } );
    }
  }

  return this; // chaining
};

sheetfn.style = sheetfn.css;

// generate a real style object from the dummy stylesheet
sheetfn.generateStyle = function( cy ){
  let style = new Style( cy );

  return this.appendToStyle( style );
};

// append a dummy stylesheet object on a real style object
sheetfn.appendToStyle = function( style ){
  for( let i = 0; i < this.length; i++ ){
    let context = this[ i ];
    let selector = context.selector;
    let props = context.properties;

    style.selector( selector ); // apply selector

    for( let j = 0; j < props.length; j++ ){
      let prop = props[ j ];

      style.css( prop.name, prop.value ); // apply property
    }
  }

  return style;
};

export default Stylesheet;
<commit_msg>Fixes graph in debug page re. edge types and arrows for:  `Stylesheet.prototype.style()` iterates over `Object.keys(passedStyleJson)` rather than `Style.properties`.<commit_after>import * as is from './is';
import Style from './style';
import { dash2camel } from './util';

// a dummy stylesheet object that doesn't need a reference to the core
// (useful for init)
let Stylesheet = function(){
  if( !(this instanceof Stylesheet) ){
    return new Stylesheet();
  }

  this.length = 0;
};

let sheetfn = Stylesheet.prototype;

sheetfn.instanceString = function(){
  return 'stylesheet';
};

// just store the selector to be parsed later
sheetfn.selector = function( selector ){
  let i = this.length++;

  this[ i ] = {
    selector: selector,
    properties: []
  };

  return this; // chaining
};

// just store the property to be parsed later
sheetfn.css = function( name, value ){
  let i = this.length - 1;

  if( is.string( name ) ){
    this[ i ].properties.push( {
      name: name,
      value: value
    } );
  } else if( is.plainObject( name ) ){
    let map = name;
    let propNames = Object.keys( map );

    for( let j = 0; j < propNames.length; j++ ){
      let key = propNames[ j ];
      let mapVal = map[ key ];

      if( mapVal == null ){ continue; }

      let prop = Style.properties[key] || Style.properties[dash2camel(key)];

      if( prop == null ){ continue; }

      let name = prop.name;
      let value = mapVal;

      this[ i ].properties.push( {
        name: name,
        value: value
      } );
    }
  }

  return this; // chaining
};

sheetfn.style = sheetfn.css;

// generate a real style object from the dummy stylesheet
sheetfn.generateStyle = function( cy ){
  let style = new Style( cy );

  return this.appendToStyle( style );
};

// append a dummy stylesheet object on a real style object
sheetfn.appendToStyle = function( style ){
  for( let i = 0; i < this.length; i++ ){
    let context = this[ i ];
    let selector = context.selector;
    let props = context.properties;

    style.selector( selector ); // apply selector

    for( let j = 0; j < props.length; j++ ){
      let prop = props[ j ];

      style.css( prop.name, prop.value ); // apply property
    }
  }

  return style;
};

export default Stylesheet;
<|endoftext|>


<commit_before>var secrets = require("./app-config").secrets;
var taskmaster = {
  tasks: {},
  inPr: {},
  toAdd: [],
  add: function(repo, event, signature, body) {
    function signBlob(key, blob) {
      return (
        "sha1=" +
        require("crypto").createHmac("sha1", key).update(blob).digest("hex")
      );
    }
    if (!secrets || !secrets[repo]) {
      return;
    }
    if (event === "delete") {
      return taskmaster.remove(body);
    }
    if (event !== "pull_request" && event !== "push") {
      return;
    }
    if (
      !require("buffer-equal-constant-time")(
        new Buffer(signature),
        new Buffer(signBlob(secrets[repo], body))
      )
    ) {
      return;
    }
    taskmaster.toAdd.push([event, body]);
  },
  remove: function(body) {
    try {
      var data = JSON.parse(body);
      if (data.ref_type !== "branch") {
        return;
      }
      var debug = require("./if-debug");
      debug(
        "removing " + "repository/" + data.repository.full_name + "/" + data.ref
      );
      var fse = require("fs-extra");
      fse
        .remove("repository/" + data.repository.full_name + "/" + data.ref)
        .then(function() {
          debug(
            "Removed repository/" + data.repository.full_name + "/" + data.ref
          );
        })
        .catch(debug);
    } catch (exception) {
      console.log(exception);
    }
  },
  run: function() {
    var getNewPushes = function() {
      var toAdd = taskmaster.toAdd;
      var pushes = [];
      taskmaster.toAdd = [];
      for (var c = 0; c < toAdd.length; c++) {
        try {
          var data = JSON.parse(toAdd[c][1]);
          if (toAdd[c][0] === "pull_request") {
            var name = data.repository.full_name;
            if (data.action !== "closed") {
              require("./if-debug")(
                "pulling:" + name + "," + data.pull_request.head.ref
              );
              taskmaster.inPr[name] = taskmaster.inPr[name]
                ? taskmaster.inPr[name]
                : {};
              taskmaster.inPr[name][data.pull_request.head.ref] = true;
            } else {
              require("./if-debug")(
                "not pulling:" + name + "," + data.pull_request.head.ref
              );
              delete taskmaster.inPr[name][data.pull_request.head.ref];
            }
          } else {
            pushes.push(data);
          }
        } catch (e) {
          delete toAdd[c];
        }
      }
      return pushes;
    };
    var pushes = getNewPushes();
    for (var c = 0; c < pushes.length; c++) {
      var data = pushes[c];
      var name = data.repository.full_name;
      var branch = data.ref.split("/")[2];
      if (branch !== "master" && data.head_commit && data.head_commit.id) {
        taskmaster.tasks[name + "|" + branch] = data.head_commit.id;
        require("./gitstatus").pending(name, data.head_commit.id);
      }
    }
    var run = function() {
      for (var id in taskmaster.tasks) {
        if (
          taskmaster.inPr[id.split("|")[0]] &&
          taskmaster.inPr[id.split("|")[0]][id.split("|")[1]]
        ) {
          var commit = taskmaster.tasks[id];
          delete taskmaster.tasks[id];
          try {
            require("./if-debug")("formatting:" + id);
            require("./work")(id.split("|")[0], id.split("|")[1], commit);
            return;
          } catch (e) {
            console.log(e);
          }
        }
      }
    };
    run();
    require("timers").setTimeout(taskmaster.run, 5000);
  }
};
module.exports = taskmaster;
<commit_msg>Update taskmaster.js<commit_after>var secrets = require("./app-config").secrets;
var fs = require("fs-extra");
var taskmaster = {
  tasks: {},
  inPr: {},
  toAdd: [],
  add: function(repo, event, signature, body) {
    function signBlob(key, blob) {
      return (
        "sha1=" +
        require("crypto").createHmac("sha1", key).update(blob).digest("hex")
      );
    }
    if (!secrets || !secrets[repo]) {
      return;
    }
    if (event === "delete") {
      return taskmaster.remove(body);
    }
    if (event !== "pull_request" && event !== "push") {
      return;
    }
    if (
      !require("buffer-equal-constant-time")(
        new Buffer(signature),
        new Buffer(signBlob(secrets[repo], body))
      )
    ) {
      return;
    }
    taskmaster.toAdd.push([event, body]);
  },
  remove: function(body) {
    try {
      var data = JSON.parse(body);
      if (data.ref_type !== "branch") {
        return;
      }
      var debug = require("./if-debug");
      debug(
        "removing " + "repository/" + data.repository.full_name + "/" + data.ref
      );
      fs
        .remove("repository/" + data.repository.full_name + "/" + data.ref)
        .then(function() {
          debug(
            "Removed repository/" + data.repository.full_name + "/" + data.ref
          );
        })
        .catch(debug);
    } catch (exception) {
      console.log(exception);
    }
  },
  run: function() {
    var getNewPushes = function() {
      var toAdd = taskmaster.toAdd;
      var pushes = [];
      taskmaster.toAdd = [];
      for (var c = 0; c < toAdd.length; c++) {
        try {
          var data = JSON.parse(toAdd[c][1]);
          if (toAdd[c][0] === "pull_request") {
            var name = data.repository.full_name;
            if (data.action !== "closed") {
              require("./if-debug")(
                "pulling:" + name + "," + data.pull_request.head.ref
              );
              taskmaster.inPr[name] = taskmaster.inPr[name]
                ? taskmaster.inPr[name]
                : {};
              taskmaster.inPr[name][data.pull_request.head.ref] = true;
            } else {
              require("./if-debug")(
                "not pulling:" + name + "," + data.pull_request.head.ref
              );
              delete taskmaster.inPr[name][data.pull_request.head.ref];
            }
          } else {
            pushes.push(data);
          }
        } catch (e) {
          delete toAdd[c];
        }
      }
      return pushes;
    };
    var pushes = getNewPushes();
    for (var c = 0; c < pushes.length; c++) {
      var data = pushes[c];
      var name = data.repository.full_name;
      var branch = data.ref.split("/")[2];
      if (branch !== "master" && data.head_commit && data.head_commit.id) {
        taskmaster.tasks[name + "|" + branch] = data.head_commit.id;
        require("./gitstatus").pending(name, data.head_commit.id);
      }
    }
    var run = function() {
      for (var id in taskmaster.tasks) {
        if (
          taskmaster.inPr[id.split("|")[0]] &&
          taskmaster.inPr[id.split("|")[0]][id.split("|")[1]]
        ) {
          var commit = taskmaster.tasks[id];
          delete taskmaster.tasks[id];
          try {
            require("./if-debug")("formatting:" + id);
            require("./work")(id.split("|")[0], id.split("|")[1], commit);
            return;
          } catch (e) {
            console.log(e);
          }
        }
      }
    };
    run();
    require("timers").setTimeout(taskmaster.run, 5000);
  }
};
module.exports = taskmaster;
<|endoftext|>


<commit_before>'use strict';

/* https://github.com/angular/protractor/blob/master/docs/toc.md */

describe('my app', function() {

  browser.get('index.html');

  it('should automatically redirect to /view1 when location hash/fragment is empty', function() {
    expect(browser.getLocationAbsUrl()).toMatch("/view1");
  });

  describe('view1', function() {

    beforeEach(function() {
      browser.get('index.html#/view1');
    });

    it('should render view1 when user navigates to /view1', function() {
      expect(element.all(by.css('[ng-view] p')).first().getText()).
        toMatch(/partial for view 1/);
    });

  });

  describe('view2', function() {

    beforeEach(function() {
      browser.get('index.html#/view2');
    });

    it('should render view2 when user navigates to /view2', function() {
      expect(element.all(by.css('[ng-view] p')).first().getText()).
        toMatch(/partial for view 2/);
    });

  });
});
<commit_msg>Add one e2e test<commit_after>/* global describe, it, expect, beforeEach, afterEach, module, inject, browser, element, by */
'use strict';

/* https://github.com/angular/protractor/blob/master/docs/toc.md */

describe('my app', function() {

  browser.get('index.html');

  it('should automatically redirect to /view1 when location hash/fragment is empty', function() {
    expect(browser.getLocationAbsUrl()).toMatch("/view1");
  });

  describe('view1', function() {

    beforeEach(function() {
      browser.get('index.html#/view1');
    });

    it('should render view1 when user navigates to /view1', function() {
      expect(element.all(by.css('[ng-view] p')).first().getText()).
        toMatch(/partial for view 1/);
    });

  });

  describe('view2', function() {

    beforeEach(function() {
      browser.get('index.html#/view2');
    });

    it('should render view2 when user navigates to /view2', function() {
      expect(element.all(by.css('[ng-view] p')).first().getText()).
        toMatch(/partial for view 2/);
    });

    it('should fire View2Ctrl when user navigates to /view2', function() {
      expect(element.all(by.css('[ng-view] p:nth-child(2)')).first().getText()).
        toMatch(/hey this is ctrl2/);
    });
  });
});
<|endoftext|>


<commit_before>// Copyright 2014 Technical Machine, Inc. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

var usb = 'MOCK_USB' in process.env ? {} : require('usb');
var DFU = 'MOCK_USB' in process.env ? {} : require('../dfu/dfu');
var util = require('util');
var async = require('async');
var EventEmitter = require('events').EventEmitter;

var TESSEL_VID = 0x1d50;
var TESSEL_PID = 0x6097;

var REQ_INFO = 0x00;
var REQ_KILL = 0x10;
var REQ_STACK_TRACE = 0x11;
var REQ_WIFI = 0x20;
var REQ_CC = 0x21;

var VENDOR_REQ_OUT = usb.LIBUSB_REQUEST_TYPE_VENDOR | usb.LIBUSB_RECIPIENT_DEVICE | usb.LIBUSB_ENDPOINT_OUT;
var VENDOR_REQ_IN  = usb.LIBUSB_REQUEST_TYPE_VENDOR | usb.LIBUSB_RECIPIENT_DEVICE | usb.LIBUSB_ENDPOINT_IN;

var usb_debug = parseInt(process.env.TESSEL_USB_DEBUG, 10);
if (usb_debug) {
  console.log("USB debug level", usb_debug);
  usb.setDebugLevel(usb_debug);
}

// Common base support for bootloader and app mode
function TesselBase() {}
util.inherits(TesselBase, EventEmitter);

TesselBase.prototype.init = function init(next) {
  var self = this;
  try {
    this.usb.open();
  } catch (e) {
    if (e.message === 'LIBUSB_ERROR_ACCESS' && process.platform === 'linux') {
      console.error("Please run `sudo tessel install-drivers` to fix device permissions.\n(Error: could not open USB device.)")
    }
    return next(e)
  }

  this.usb.getStringDescriptor(this.usb.deviceDescriptor.iSerialNumber, function (error, data) {
    if (error) return next(error);
    self.serialNumber = data;
    next(null, self);
  })
}

// Wait for this device to reconnect in the specified mode
TesselBase.prototype.reFind = function reFind(desiredMode, next) {
  var retrycount = 16;
  function retry (error) {
    deviceBySerial(this.serialNumber, function(err, device) {
      if (err) return next(err);
      if (device && device.mode === desiredMode) {
        return next(null, device);
      } else if (--retrycount > 0) {
        return setTimeout(retry, 500);
      } else {
        var mode = device ? "In " + device.mode + " mode." : "Device not found.";
        return next("Timed out waiting to switch to " + desiredMode + " mode."  + msg);
      }
    });
  }
  setTimeout(retry, 1000);
}

// A Tessel in bootloader (DFU) mode
function TesselBoot(dev) {
  this.usb = dev;
  this.mode = 'boot';
}
util.inherits(TesselBoot, TesselBase);

TesselBoot.prototype.dnload = function(iface, image, next, statuscb) {
  var dfu = new DFU(this.usb, iface);
  dfu.claim(function (e) {
    if (e) return next(e);
    dfu.dnload(image, next, statuscb);
  });
}

TesselBoot.prototype.runRam = function runRam(image, next, statuscb) {
  this.dnload(1, image, next, statuscb);
}

TesselBoot.prototype.writeFlash = function writeFlash(image, next, statuscb) {
  this.dnload(0, image, next, statuscb);
}

TesselBoot.prototype.enterBootloader = function (next) {
  var self = this;
  // No-op so mode doesn't have to be checked
  setImmediate(function() { next(null, self); });
}

// A Tessel in normal app mode
function Tessel(dev) {
  this.usb = dev;
  this.mode = 'app';
}
util.inherits(Tessel, TesselBase);
exports.Tessel = Tessel;

Tessel.prototype.init = function init(next) {
  var self = this;
  this.logLevels = [];

  TesselBase.prototype.init.call(this, function() {
    // Fetch version info from the device
    self._info(function(err, info) {
      if (err) return next(err);
      self.version = info;
      next(null, self);
    });
  });
};

Tessel.prototype.claim = function claim(stop, next) {
  // Runs the claiming procedure exactly once, and calls next after it has completed
  if (this.claimed === 'claimed') {
    // Already claimed
    if (stop) {
      this.stop(next);
    } else {
      return setImmediate(next);
    }
  }

  this.initCommands();
  this.once('claimed', next);

  if (!this.claimed) {
    this.claimed = 'claiming';
    var self = this;
    self.intf = self.usb.interface(0);

    try {
      self.intf.claim();
    } catch (e) {
      if (e.message === 'LIBUSB_ERROR_BUSY') {
        e = "Device is in use by another process";
      }
      return next(e);
    }

    if (stop) {
      this.stop(step);
    } else {
      step();
    }

    function step() {
      // We use an alternate setting so it is automatically released if the program is killed
      self.intf.setAltSetting(1, function(error) {
        if (error) return next(error);
        self.log_ep = self.intf.endpoints[0];
        self.msg_in_ep = self.intf.endpoints[1];
        self.msg_out_ep = self.intf.endpoints[2];
        self.claimed = 'claimed';

        self.usb.timeout = 10000;

        self._receiveLogs();
        self._receiveMessages();

        self.emit('claimed');
      });
    }
  }
}

Tessel.prototype.close = function close (next) {
  if (this.closed) {
    return next && next();
  }
  this.closed = true;

  this.intf.release(true, function (err) {
    this.usb.close();
    this.emit('close');
    next && next();
  }.bind(this));
}

Tessel.prototype.listen = function listen(deprecated, levels) {
  this.logLevels = levels;
}

Tessel.prototype._receiveLogs = function _receiveLogs() {
  var self = this;
  self.log_ep.startStream(4, 4096);
  self.log_ep.on('data', function(data) {
    var pos = 0;
    while (pos < data.length) {
      if (data[pos] !== 1) { throw new Error("Expected STX at"+ pos +' ' + data[pos]) }
      var level = data[pos+1];

      for (var next=pos+2; next<data.length; next++) {
        if (data[next] === 1) {
          break;
        }
      }

      var str = data.toString('utf8', pos+2, next);

      if ((!self.logLevels && typeof self.logLevels != 'array') || self.logLevels.indexOf(level) != -1) {
        process.stderr.write(str + "\n");
      }

      self.emit('log', level, str);
      pos = next;
    }
  });
  self.log_ep.on('error', function(e) {
    console.error("Error reading USB log endpoint:", e);
    process.exit(-5);
  });
}

Tessel.prototype.postMessage = function postMessage(tag, buf, cb) {
  buf = buf || new Buffer(0);

  if (usb_debug) {
    console.log("USB TX: ", buf.length, tag.toString(16), buf);
  }

  var header = new Buffer(8);
  header.writeUInt32LE(buf.length, 0);
  header.writeUInt32LE(tag, 4);
  var data = Buffer.concat([header, buf]);

  var self = this;
  self.msg_out_ep.transferWithZLP(data, function(error) {
    if (error) {
      console.error("Error writing USB message endpoint", error);
      self.emit('error', error);
    }
    cb && cb(error);
  });
}

Tessel.prototype._receiveMessages = function _receiveMessages() {
  var self = this;

  var transferSize = 4096;
  self.msg_in_ep.startStream(2, transferSize);

  var buffers = [];
  self.msg_in_ep.on('data', function(data) {
    buffers.push(data);
    if (data.length < transferSize) {
      var b = Buffer.concat(buffers);
      if (b.length > 0) {
        var len = b.readUInt32LE(0);
        var tag = b.readUInt32LE(4);
        b = b.slice(8);

        if (usb_debug) {
          console.log("USB RX: ", len, tag.toString(16), data);
        }

        // Emit messages.
        self.emit('rawMessage', tag, b);
        self.emit('rawMessage:' + ('0000' + tag.toString(16)).slice(-4), b);
      }

      buffers = [];
    } else if (buffers.length * transferSize > 32 * 1024 * 1024) {
      // The message wouldn't fit in Tessel's memory. It probably didn't mean to send this...
      throw new Error("Malformed message (oversize): " + buffers[0].toString('hex', 0, 8))
    }
  });

  self.msg_in_ep.on('error', function(e) {
    console.error("Error reading USB message endpoint:", e);
    process.exit(-5);
  });
};

Tessel.prototype._info = function info(next) {
  this.usb.controlTransfer(VENDOR_REQ_IN, REQ_INFO, 0, 0, 512, function(error, data) {
    if (error) return next(error);
    next(null, JSON.parse(data.toString()));
  });
}

Tessel.prototype.stop = function stop(next) {
  this.usb.controlTransfer(VENDOR_REQ_OUT, REQ_KILL, 0, 0, new Buffer(0), next);
}

Tessel.prototype.debugstack = function stop(next) {
  this.usb.controlTransfer(VENDOR_REQ_IN, REQ_STACK_TRACE, 0, 0, 16, function(err, buf) {
    if (err) return callNext(err);

    var r = buf.readInt8(0);
    if (r != 0) return callNext(null, false);
    // otherwise, wait for the message
  });

  this.once('debug-stack', function (stack) {
    next(null, stack)
  })
}

Tessel.prototype.wifiIP = function (next) {
  this.usb.controlTransfer(VENDOR_REQ_IN, REQ_WIFI, 0, 0, 4, function(error, data) {
    var ip = data[0]+"."+data[1]+"."+data[2]+"."+data[3];
    if (error) return next(error);
    next(null, ip);
  });
}

Tessel.prototype.wifiVer = function (next) {
  this.usb.controlTransfer(VENDOR_REQ_IN, REQ_CC, 0, 0, 2, function(error, data) {
    var version = data[0]+"."+data[1];
    if (error) return next(error);
    next(null, version);
  });
}

exports.findTessel = function findTessel(opts, next) {
  if (opts.stop   === undefined) opts.stop = false;
  if (opts.serial === undefined) opts.serial = null;
  if (opts.claim  === undefined) opts.claim = true;
  if (opts.appMode  === undefined) opts.appMode = true;

  deviceBySerial(opts.serial, function (err, device) {
    if (err) return next(err);
    if (!device) {
      return next(opts.serial?"Device matching serial " + opts.serial + " not found.":"No devices found.", null);
    }

    // Bootloader can't currently switch to app mode without flashing something...
    if (opts.appMode && device.mode !== 'app') {
      return next("An update failed to complete. Press the reset button and try again", null);
    }

    if (opts.claim && device.mode === 'app') {
      device.claim(opts.stop, function(err) {
        if (err) return next(err);
        return next(null, device);
      });
    } else {
      return next(null, device);
    }
  });
}

function deviceBySerial(serial, next) {
  exports.listDevices(function (err, devices) {
    if (err) return next(err);
    for (var i=0; i<devices.length; i++) {
      if (!serial || serial === devices[i].serialNumber) {
        return next(null, devices[i])
      }
    }
    return next(null, null);
  });
}

exports.listDevices = function listDevices(next) {
  var devices = usb.getDeviceList().map(function(dev) {
    if ((dev.deviceDescriptor.idVendor == TESSEL_VID) && (dev.deviceDescriptor.idProduct == TESSEL_PID)) {
      if (dev.deviceDescriptor.bcdDevice >> 8 == 0) {
        return new TesselBoot(dev);
      } else {
        return new Tessel(dev);
      }
    }
  }).filter(function(x) {return x});

  async.each(devices, function(dev, cb) { dev.init(cb) }, function(err) { next(err, devices)} );
}
<commit_msg>Properly use serial number to find device when rebooting<commit_after>// Copyright 2014 Technical Machine, Inc. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

var usb = 'MOCK_USB' in process.env ? {} : require('usb');
var DFU = 'MOCK_USB' in process.env ? {} : require('../dfu/dfu');
var util = require('util');
var async = require('async');
var EventEmitter = require('events').EventEmitter;

var TESSEL_VID = 0x1d50;
var TESSEL_PID = 0x6097;

var REQ_INFO = 0x00;
var REQ_KILL = 0x10;
var REQ_STACK_TRACE = 0x11;
var REQ_WIFI = 0x20;
var REQ_CC = 0x21;

var VENDOR_REQ_OUT = usb.LIBUSB_REQUEST_TYPE_VENDOR | usb.LIBUSB_RECIPIENT_DEVICE | usb.LIBUSB_ENDPOINT_OUT;
var VENDOR_REQ_IN  = usb.LIBUSB_REQUEST_TYPE_VENDOR | usb.LIBUSB_RECIPIENT_DEVICE | usb.LIBUSB_ENDPOINT_IN;

var usb_debug = parseInt(process.env.TESSEL_USB_DEBUG, 10);
if (usb_debug) {
  console.log("USB debug level", usb_debug);
  usb.setDebugLevel(usb_debug);
}

// Common base support for bootloader and app mode
function TesselBase() {}
util.inherits(TesselBase, EventEmitter);

TesselBase.prototype.init = function init(next) {
  var self = this;
  try {
    this.usb.open();
  } catch (e) {
    if (e.message === 'LIBUSB_ERROR_ACCESS' && process.platform === 'linux') {
      console.error("Please run `sudo tessel install-drivers` to fix device permissions.\n(Error: could not open USB device.)")
    }
    return next(e)
  }

  this.usb.getStringDescriptor(this.usb.deviceDescriptor.iSerialNumber, function (error, data) {
    if (error) return next(error);
    self.serialNumber = data;
    next(null, self);
  })
}

// Wait for this device to reconnect in the specified mode
TesselBase.prototype.reFind = function reFind(desiredMode, next) {
  var self = this;
  var retrycount = 16;
  function retry (error) {
    deviceBySerial(self.serialNumber, function(err, device) {
      if (err) return next(err);
      if (device && device.mode === desiredMode) {
        return next(null, device);
      } else if (--retrycount > 0) {
        return setTimeout(retry, 500);
      } else {
        var mode = device ? "In " + device.mode + " mode." : "Device not found.";
        return next("Timed out waiting to switch to " + desiredMode + " mode."  + msg);
      }
    });
  }
  setTimeout(retry, 1000);
}

// A Tessel in bootloader (DFU) mode
function TesselBoot(dev) {
  this.usb = dev;
  this.mode = 'boot';
}
util.inherits(TesselBoot, TesselBase);

TesselBoot.prototype.dnload = function(iface, image, next, statuscb) {
  var dfu = new DFU(this.usb, iface);
  dfu.claim(function (e) {
    if (e) return next(e);
    dfu.dnload(image, next, statuscb);
  });
}

TesselBoot.prototype.runRam = function runRam(image, next, statuscb) {
  this.dnload(1, image, next, statuscb);
}

TesselBoot.prototype.writeFlash = function writeFlash(image, next, statuscb) {
  this.dnload(0, image, next, statuscb);
}

TesselBoot.prototype.enterBootloader = function (next) {
  var self = this;
  // No-op so mode doesn't have to be checked
  setImmediate(function() { next(null, self); });
}

// A Tessel in normal app mode
function Tessel(dev) {
  this.usb = dev;
  this.mode = 'app';
}
util.inherits(Tessel, TesselBase);
exports.Tessel = Tessel;

Tessel.prototype.init = function init(next) {
  var self = this;
  this.logLevels = [];

  TesselBase.prototype.init.call(this, function() {
    // Fetch version info from the device
    self._info(function(err, info) {
      if (err) return next(err);
      self.version = info;
      next(null, self);
    });
  });
};

Tessel.prototype.claim = function claim(stop, next) {
  // Runs the claiming procedure exactly once, and calls next after it has completed
  if (this.claimed === 'claimed') {
    // Already claimed
    if (stop) {
      this.stop(next);
    } else {
      return setImmediate(next);
    }
  }

  this.initCommands();
  this.once('claimed', next);

  if (!this.claimed) {
    this.claimed = 'claiming';
    var self = this;
    self.intf = self.usb.interface(0);

    try {
      self.intf.claim();
    } catch (e) {
      if (e.message === 'LIBUSB_ERROR_BUSY') {
        e = "Device is in use by another process";
      }
      return next(e);
    }

    if (stop) {
      this.stop(step);
    } else {
      step();
    }

    function step() {
      // We use an alternate setting so it is automatically released if the program is killed
      self.intf.setAltSetting(1, function(error) {
        if (error) return next(error);
        self.log_ep = self.intf.endpoints[0];
        self.msg_in_ep = self.intf.endpoints[1];
        self.msg_out_ep = self.intf.endpoints[2];
        self.claimed = 'claimed';

        self.usb.timeout = 10000;

        self._receiveLogs();
        self._receiveMessages();

        self.emit('claimed');
      });
    }
  }
}

Tessel.prototype.close = function close (next) {
  if (this.closed) {
    return next && next();
  }
  this.closed = true;

  this.intf.release(true, function (err) {
    this.usb.close();
    this.emit('close');
    next && next();
  }.bind(this));
}

Tessel.prototype.listen = function listen(deprecated, levels) {
  this.logLevels = levels;
}

Tessel.prototype._receiveLogs = function _receiveLogs() {
  var self = this;
  self.log_ep.startStream(4, 4096);
  self.log_ep.on('data', function(data) {
    var pos = 0;
    while (pos < data.length) {
      if (data[pos] !== 1) { throw new Error("Expected STX at"+ pos +' ' + data[pos]) }
      var level = data[pos+1];

      for (var next=pos+2; next<data.length; next++) {
        if (data[next] === 1) {
          break;
        }
      }

      var str = data.toString('utf8', pos+2, next);

      if ((!self.logLevels && typeof self.logLevels != 'array') || self.logLevels.indexOf(level) != -1) {
        process.stderr.write(str + "\n");
      }

      self.emit('log', level, str);
      pos = next;
    }
  });
  self.log_ep.on('error', function(e) {
    console.error("Error reading USB log endpoint:", e);
    process.exit(-5);
  });
}

Tessel.prototype.postMessage = function postMessage(tag, buf, cb) {
  buf = buf || new Buffer(0);

  if (usb_debug) {
    console.log("USB TX: ", buf.length, tag.toString(16), buf);
  }

  var header = new Buffer(8);
  header.writeUInt32LE(buf.length, 0);
  header.writeUInt32LE(tag, 4);
  var data = Buffer.concat([header, buf]);

  var self = this;
  self.msg_out_ep.transferWithZLP(data, function(error) {
    if (error) {
      console.error("Error writing USB message endpoint", error);
      self.emit('error', error);
    }
    cb && cb(error);
  });
}

Tessel.prototype._receiveMessages = function _receiveMessages() {
  var self = this;

  var transferSize = 4096;
  self.msg_in_ep.startStream(2, transferSize);

  var buffers = [];
  self.msg_in_ep.on('data', function(data) {
    buffers.push(data);
    if (data.length < transferSize) {
      var b = Buffer.concat(buffers);
      if (b.length > 0) {
        var len = b.readUInt32LE(0);
        var tag = b.readUInt32LE(4);
        b = b.slice(8);

        if (usb_debug) {
          console.log("USB RX: ", len, tag.toString(16), data);
        }

        // Emit messages.
        self.emit('rawMessage', tag, b);
        self.emit('rawMessage:' + ('0000' + tag.toString(16)).slice(-4), b);
      }

      buffers = [];
    } else if (buffers.length * transferSize > 32 * 1024 * 1024) {
      // The message wouldn't fit in Tessel's memory. It probably didn't mean to send this...
      throw new Error("Malformed message (oversize): " + buffers[0].toString('hex', 0, 8))
    }
  });

  self.msg_in_ep.on('error', function(e) {
    console.error("Error reading USB message endpoint:", e);
    process.exit(-5);
  });
};

Tessel.prototype._info = function info(next) {
  this.usb.controlTransfer(VENDOR_REQ_IN, REQ_INFO, 0, 0, 512, function(error, data) {
    if (error) return next(error);
    next(null, JSON.parse(data.toString()));
  });
}

Tessel.prototype.stop = function stop(next) {
  this.usb.controlTransfer(VENDOR_REQ_OUT, REQ_KILL, 0, 0, new Buffer(0), next);
}

Tessel.prototype.debugstack = function stop(next) {
  this.usb.controlTransfer(VENDOR_REQ_IN, REQ_STACK_TRACE, 0, 0, 16, function(err, buf) {
    if (err) return callNext(err);

    var r = buf.readInt8(0);
    if (r != 0) return callNext(null, false);
    // otherwise, wait for the message
  });

  this.once('debug-stack', function (stack) {
    next(null, stack)
  })
}

Tessel.prototype.wifiIP = function (next) {
  this.usb.controlTransfer(VENDOR_REQ_IN, REQ_WIFI, 0, 0, 4, function(error, data) {
    var ip = data[0]+"."+data[1]+"."+data[2]+"."+data[3];
    if (error) return next(error);
    next(null, ip);
  });
}

Tessel.prototype.wifiVer = function (next) {
  this.usb.controlTransfer(VENDOR_REQ_IN, REQ_CC, 0, 0, 2, function(error, data) {
    var version = data[0]+"."+data[1];
    if (error) return next(error);
    next(null, version);
  });
}

exports.findTessel = function findTessel(opts, next) {
  if (opts.stop   === undefined) opts.stop = false;
  if (opts.serial === undefined) opts.serial = null;
  if (opts.claim  === undefined) opts.claim = true;
  if (opts.appMode  === undefined) opts.appMode = true;

  deviceBySerial(opts.serial, function (err, device) {
    if (err) return next(err);
    if (!device) {
      return next(opts.serial?"Device matching serial " + opts.serial + " not found.":"No devices found.", null);
    }

    // Bootloader can't currently switch to app mode without flashing something...
    if (opts.appMode && device.mode !== 'app') {
      return next("An update failed to complete. Press the reset button and try again", null);
    }

    if (opts.claim && device.mode === 'app') {
      device.claim(opts.stop, function(err) {
        if (err) return next(err);
        return next(null, device);
      });
    } else {
      return next(null, device);
    }
  });
}

function deviceBySerial(serial, next) {
  exports.listDevices(function (err, devices) {
    if (err) return next(err);
    for (var i=0; i<devices.length; i++) {
      if (!serial || serial === devices[i].serialNumber) {
        return next(null, devices[i])
      }
    }
    return next(null, null);
  });
}

exports.listDevices = function listDevices(next) {
  var devices = usb.getDeviceList().map(function(dev) {
    if ((dev.deviceDescriptor.idVendor == TESSEL_VID) && (dev.deviceDescriptor.idProduct == TESSEL_PID)) {
      if (dev.deviceDescriptor.bcdDevice >> 8 == 0) {
        return new TesselBoot(dev);
      } else {
        return new Tessel(dev);
      }
    }
  }).filter(function(x) {return x});

  async.each(devices, function(dev, cb) { dev.init(cb) }, function(err) { next(err, devices)} );
}
<|endoftext|>


<commit_before>
// This file boots up Jasmine
//
import '6to5/polyfill'
import 'jasmine/jasmine.js'

var jasmineRequire = window.jasmineRequire = getJasmineRequireObj()
var jasmine = window.jasmine = jasmineRequire.core(jasmineRequire)
jasmineRequire.core(jasmineRequire)

var env = jasmine.getEnv()
var jasmineInterface = jasmineRequire.interface(jasmine, env)
Object.assign(window, jasmineInterface)

// Import the query string parser.
//
var queryString = new jasmine.QueryString({
  getWindowLocation() { return window.location }
})

// Report as pretty HTML
//
import 'jasmine/jasmine-html'
import 'jasmine/jasmine.css'
jasmineRequire.html(jasmine)
var htmlReporter = new jasmine.HtmlReporter({
  env: env,
  onRaiseExceptionsClick() {
    queryString.setParam('catch', !env.catchingExceptions())
  },
  getContainer() {
    return document.body
  },
  createElement() {
    return document.createElement.apply(document, arguments)
  },
  createTextNode() {
    return document.createTextNode.apply(document, arguments)
  },
  timer: new jasmine.Timer(),
})

// Catch exceptions based on queryString
//
var catchingExceptions = queryString.getParam('catch')
env.catchExceptions(
  typeof catchingExceptions === 'undefined' ?  true : catchingExceptions)

// Add those reporters!
//
env.addReporter(jasmineInterface.jsApiReporter)
env.addReporter(htmlReporter)
env.addReporter({
  jasmineDone() {
    setTimeout(function() {
      let specs = jsApiReporter.specs()
      let coverage = window.__coverage__ || null
      let json = JSON.stringify({ specs, coverage })
      let xh = new XMLHttpRequest()
      xh.open('POST', '/api/test', true)
      xh.setRequestHeader('Content-Type', 'application/json')
      xh.send(json)
    })
  }
})

var specFilter = new jasmine.HtmlSpecFilter({
  filterString() {
    return queryString.getParam('spec')
  }
})

env.specFilter = function(spec) {
  return specFilter.matches(spec.getFullName())
}

// Allow timing functions to be overridden.
// Certain browsers (Safari, IE 8, phantomjs) require this hack.
//
window.setTimeout = window.setTimeout
window.setInterval = window.setInterval
window.clearTimeout = window.clearTimeout
window.clearInterval = window.clearInterval

import 'val!./load.js'

htmlReporter.initialize()
env.execute()
<commit_msg>fix(test): fix test loading<commit_after>
// This file boots up Jasmine
//
import '6to5/polyfill'
import 'jasmine/jasmine.js'

var jasmineRequire = window.jasmineRequire = getJasmineRequireObj()
var jasmine = window.jasmine = jasmineRequire.core(jasmineRequire)
jasmineRequire.core(jasmineRequire)

var env = jasmine.getEnv()
var jasmineInterface = jasmineRequire.interface(jasmine, env)
Object.assign(window, jasmineInterface)

// Import the HTML reporter and QueryString library
//
import 'jasmine/jasmine-html'
import 'jasmine/jasmine.css'
jasmineRequire.html(jasmine)

// Import the query string parser
//
var queryString = new jasmine.QueryString({
  getWindowLocation() { return window.location }
})

// Report as pretty HTML
//
var htmlReporter = new jasmine.HtmlReporter({
  env: env,
  onRaiseExceptionsClick() {
    queryString.setParam('catch', !env.catchingExceptions())
  },
  getContainer() {
    return document.body
  },
  createElement() {
    return document.createElement.apply(document, arguments)
  },
  createTextNode() {
    return document.createTextNode.apply(document, arguments)
  },
  timer: new jasmine.Timer(),
})

// Catch exceptions based on queryString
//
var catchingExceptions = queryString.getParam('catch')
env.catchExceptions(
  typeof catchingExceptions === 'undefined' ?  true : catchingExceptions)

// Add those reporters!
//
env.addReporter(jasmineInterface.jsApiReporter)
env.addReporter(htmlReporter)
env.addReporter({
  jasmineDone() {
    setTimeout(function() {
      let specs = jsApiReporter.specs()
      let coverage = window.__coverage__ || null
      let json = JSON.stringify({ specs, coverage })
      let xh = new XMLHttpRequest()
      xh.open('POST', '/api/test', true)
      xh.setRequestHeader('Content-Type', 'application/json')
      xh.send(json)
    })
  }
})

var specFilter = new jasmine.HtmlSpecFilter({
  filterString() {
    return queryString.getParam('spec')
  }
})

env.specFilter = function(spec) {
  return specFilter.matches(spec.getFullName())
}

// Allow timing functions to be overridden.
// Certain browsers (Safari, IE 8, phantomjs) require this hack.
//
window.setTimeout = window.setTimeout
window.setInterval = window.setInterval
window.clearTimeout = window.clearTimeout
window.clearInterval = window.clearInterval

import 'val!./load.js'

htmlReporter.initialize()
env.execute()
<|endoftext|>


<commit_before>import {} from 'babel/register'
import { expect } from 'chai'
import DomPointer from '../index'
import { createElement } from './util'

const complies = (dp) => {
  expect(
      [...dp.refs.keys()]
  ).eql(
      [':0', ':0:0', ':0:0:0', ':0:0:1']
  )

  expect(dp.refs.get(':0')).eql(dp.el
          .firstChild
  )

  expect(dp.refs.get(':0:0')).eql(dp.el
          .firstChild
          .firstChild
  )

  expect(dp.refs.get(':0:0:0')).eql(dp.el
          .firstChild
          .firstChild
          .firstChild
  )

  expect(dp.refs.get(':0:0:1')).eql(dp.el
          .firstChild
          .firstChild
          .childNodes[1]
  )
}

describe('DomPointer', () => {
  const html = `

`
  const targetEl = document.getElementById('target')

  it('create()', () => {
    DomPointer.create(createElement(html))
  })

  it('fromHTML()', () => {
    DomPointer.fromHTML(html)
  })

  it('path()', () => {
    const dp = DomPointer.fromHTML(html)
    // gah when to do it?
    // normally if the element is empty you'll want to wait for all info first.
    // the elements
    dp.setElement(targetEl)
    dp.render()
    expect(dp.path(dp.refs.get(':0'))).eql(':0')
    expect(dp.path(dp.refs.get(':0:0'))).eql(':0:0')
    expect(dp.path(dp.refs.get(':0:0:0'))).eql(':0:0:0')
    expect(dp.path(dp.refs.get(':0:0:1'))).eql(':0:0:1')
  })

  it('paths()', () => {

    const dp = DomPointer.fromHTML(html)
    dp.setElement(targetEl)
    dp.render()

    const refs = [
      dp.refs.get(':0'),
      dp.refs.get(':0:0'),
      dp.refs.get(':0:0:0'),
      dp.refs.get(':0:0:1')
    ]

    expect(dp.paths(refs)).eql({
      ':0': refs[0],
      ':0:0': refs[1],
      ':0:0:0': refs[2],
      ':0:0:1': refs[3]
    })
  })

  it('setAttributes()', () => {
    const dp = DomPointer.fromHTML(html)
    dp.setElement(targetEl)
    dp.setAttributes([
      { path: ':0:0:0', op: 'remove', name: 'title' },
      { path: ':0:0:1', op: 'add', name: 'title', val: 'My Title' }
    ])
    dp.render()
    expect(dp.refs.get(':0:0:0').hasAttribute('title')).eql(false)
    expect(dp.refs.get(':0:0:1').getAttribute('title')).eql('My Title')
  })
})
<commit_msg>clean<commit_after>import {} from 'babel/register'
import { expect } from 'chai'
import DomPointer from '../index'
import { createElement } from './util'

const complies = (dp) => {
  expect(
      [...dp.refs.keys()]
  ).eql(
      [':0', ':0:0', ':0:0:0', ':0:0:1']
  )

  expect(dp.refs.get(':0')).eql(dp.el
          .firstChild
  )

  expect(dp.refs.get(':0:0')).eql(dp.el
          .firstChild
          .firstChild
  )

  expect(dp.refs.get(':0:0:0')).eql(dp.el
          .firstChild
          .firstChild
          .firstChild
  )

  expect(dp.refs.get(':0:0:1')).eql(dp.el
          .firstChild
          .firstChild
          .childNodes[1]
  )
}

describe('DomPointer', () => {
  const html = `

`
  const targetEl = document.getElementById('target')

  it('create()', () => {
    DomPointer.create(createElement(html))
  })

  it('fromHTML()', () => {
    DomPointer.fromHTML(html)
  })

  it('path()', () => {
    const dp = DomPointer.fromHTML(html)
    dp.setElement(targetEl)
    dp.render()
    expect(dp.path(dp.refs.get(':0'))).eql(':0')
    expect(dp.path(dp.refs.get(':0:0'))).eql(':0:0')
    expect(dp.path(dp.refs.get(':0:0:0'))).eql(':0:0:0')
    expect(dp.path(dp.refs.get(':0:0:1'))).eql(':0:0:1')
  })

  it('paths()', () => {

    const dp = DomPointer.fromHTML(html)
    dp.setElement(targetEl)
    dp.render()

    const refs = [
      dp.refs.get(':0'),
      dp.refs.get(':0:0'),
      dp.refs.get(':0:0:0'),
      dp.refs.get(':0:0:1')
    ]

    expect(dp.paths(refs)).eql({
      ':0': refs[0],
      ':0:0': refs[1],
      ':0:0:0': refs[2],
      ':0:0:1': refs[3]
    })
  })

  it('setAttributes()', () => {
    const dp = DomPointer.fromHTML(html)
    dp.setElement(targetEl)
    dp.setAttributes([
      { path: ':0:0:0', op: 'remove', name: 'title' },
      { path: ':0:0:1', op: 'add', name: 'title', val: 'My Title' }
    ])
    dp.render()
    expect(dp.refs.get(':0:0:0').hasAttribute('title')).eql(false)
    expect(dp.refs.get(':0:0:1').getAttribute('title')).eql('My Title')
  })
})
<|endoftext|>


<commit_before>/*global casper*/
/*jshint strict:false*/
/**
 * Special test server to test for HTTP status codes
 *
 */
var server = require('webserver').create();
var service = server.listen(8090, function (request, response) {
    var code = parseInt(/^\/(\d+)$/.exec(request.url)[1], 10);
    response.statusCode = code;
    response.write("");
    response.close();
});
var fs = require("fs");

casper.start();

// file protocol
casper.thenOpen('file://' + phantom.casperPath + '/tests/site/index.html', function() {
    this.test.assertHttpStatus(null, 'file:// protocol does not set a HTTP status');
});

// http protocol
var codes = [100, 101, 102, 118, 200, 201, 202, 203, 204, 205, 206, 207, 210,
         300, 301, 302, 303, 304, 305, 307, 310,
         400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413,
              414, 415, 416, 417, 418, 422, 423, 424, 425, 426, 449, 450,
         500, 501, 502, 503, 504, 505, 507, 509];

casper.each(codes, function(self, code) {
    if (code === 100) {
        // HTTP 100 is CONTINUE, so don't expect a terminated response
        return;
    }
    this.thenOpen('http://localhost:8090/' + code, function() {
        this.test.assertEquals(this.currentHTTPStatus, code);
        this.test.assertHttpStatus(code);
    });
});

casper.run(function() {
    server.close();
    this.test.done(109);
});
<commit_msg>migrated http_status tests to new testing format<commit_after>/*global casper*/
/*jshint strict:false*/
/**
 * Special test server to test for HTTP status codes
 *
 */
var fs = require('fs');
var utils = require('utils');
var server = require('webserver').create();
var service = server.listen(8090, function (request, response) {
    var code = parseInt(/^\/(\d+)$/.exec(request.url)[1], 10);
    response.statusCode = code;
    response.write("");
    response.close();
});

casper.test.begin("HTTP status code handling", 109, function(test) {
    casper.start();

    // file protocol
    casper.thenOpen('file://' + phantom.casperPath + '/tests/site/index.html', function() {
        this.test.assertHttpStatus(null, 'file:// protocol does not set a HTTP status');
    });

    // http protocol
    var codes = [100, 101, 102, 118, 200, 201, 202, 203, 204, 205, 206, 207, 210,
                 300, 301, 302, 303, 304, 305, 307, 310,
                 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413,
                      414, 415, 416, 417, 418, 422, 423, 424, 425, 426, 449, 450,
                 500, 501, 502, 503, 504, 505, 507, 509];

    casper.each(codes, function(self, code) {
        if (code === 100) {
            // HTTP 100 is CONTINUE, so don't expect a terminated response
            return;
        }
        this.thenOpen('http://localhost:8090/' + code, function() {
            this.test.assertEquals(this.currentHTTPStatus, code,
                utils.format('Status is stored in casper.currentHTTPStatus' , code));
            this.test.assertHttpStatus(code, utils.format('HTTP %d handled' , code));
        });
    });

    casper.run(function() {
        server.close();
        this.test.done();
    });
});
<|endoftext|>