<commit_before>var tabs = '';
var news = '';
var team = '';
var stats = '';
var gamelog = '';
var headshot = '';
var playerID = 0;
var teamID = 0;
var teamCity = '';
var teamName = '';
var baseURL = 'http://espn.com';

var callsMade = 0;
var numberOfCalls = 3;

items = [];
items[0] = [];
items[0]['a'] = '';
items[0]['h'] = '';
items[0]['s'] = 'ESPN';
items[0]['force_big_header'] = 1;
items[0]['f'] = 1;

function ddg_spice_espn(response) {

    var player = response.sports[0].leagues[0].athletes[0];
    var playerTeam = player.competitors[0].team;
    playerID = player.id;
    headshot = player.headshots.gamecast;
    teamID = playerTeam.id;
    teamCity = playerTeam.location;
    teamName = playerTeam.name;

    nrj("/js/spice/espn/basketball/nba/athletes/"
            + player.id + "/news/foo/ddg_spice_espn_news");
    nrj("/js/spice/espn/basketball/nba/teams/"
            + teamID + "/foo/bar/ddg_spice_espn_team");
    nrj("/js/spice/espn/basketball/nba/teams/"
            + teamID + "/events/dates/ddg_spice_espn_events");

    stats = player.stats;
    items[0]['u'] = baseURL + "/nba/player/_/id/" + playerID;
    items[0]['h'] = player.displayName + " - "
                  + playerTeam.location + " "
                  + playerTeam.name
                  + " (ESPN)";

    console.log(player);

    tabs = [ 'news', 'stats', 'team', 'gamelog' ];
    tabs = tabs.map(function(s, index, array) {
        return ''
            +  s.charAt(0).toUpperCase() + s.slice(1)
            +  '' + (index == array.length - 1 ? "" : " | ");
    }).join("");

    team = '
'
           + 'pretty pictures'
           + '
';

    playerStats = [ 'assists',
                    'athleteStatus',
                    'height',
                    'weight',
                    'dateOfBirth',
                    'blocks',
                    'defensiveRebounds',
                    'doubleDouble',
                    'ejections',
                    'fieldGoalsMade',
                    'fieldGoalsAttempted',
                    'fieldGoalPercentage',
                    'fouls',
                    'freeThrowsMade',
                    'freeThrowsAttempted',
                    'freeThrowPercentage',
                    'gamesStarted',
                    'minutes',
                    'offensiveRebounds',
                    'points',
                    'rebounds',
                    'steals',
                    'threePointersMade',
                    'threePointersAttempted',
                    'threePointPercentage',
                    'tripleDouble',
                    'turnovers',
                  ];

    function prepareStat(s, index, array) {
        display = s.replace(/([a-z\d](?=[A-Z])|[a-zA-Z](?=\d))/g, "$1 ");
        display = display.toLowerCase();
        display = '
'
                + display.charAt(0).toUpperCase() + display.slice(1)
                + ':	'
                + (player[s] ? player[s] : stats[s])
                + '
';
        return display;
    }

    playerStats = playerStats.map(prepareStat);
    var nestedStats = [ 'Birthplace', 'Position' ];
    [ player.birthPlace.city + ', ' + player.birthPlace.state,
      player.positions[0].name,
    ].map(function(s) {
        playerStats.unshift('
' + nestedStats.shift()
                          + ':	' + s + '
');
    });

    stats  = '
'
           + playerStats.join("")
           + '
';
}

function ddg_spice_espn_events(response) {
    var events = response.sports[0].leagues[0].events;
    console.log(events[85]);
    gamelog = '

'
            + '	Home		Away	'
            + '
';
    for (var i = events.length - 1; i > (events.length - 6); i--) {
        var competitors = events[i].competitions[0].competitors;
        var date = new Date(events[i].date);
        date.setMonth(date.getMonth()+1);
        var outcome = '';
        gamelog += '' + date.getUTCMonth() + '/' + date.getUTCDate() + '	';
        competitors.map(function(competitor, index, array) {
            teamDisplayName = competitor.team.location
                            + " " + competitor.team.name
            gamelog += '' + teamDisplayName + '	'
                    +  (index == 0 ? ' vs ' : '	');
            if (index == 1) {
                outcome = competitor.score > array[0].score;
                var win = 'W ';
                var loss = 'L ';
                gamelog += ''
                        +  ''
                        +  (competitor.team.id == teamID ?
                                (outcome ? win : loss)
                                + competitor.score
                                + '-' + array[0].score
                            : (outcome ? loss : win)
                                + array[0].score + '-'
                                + competitor.score)
                        +  '	';
            }
        });
        gamelog += '
';
    }
    gamelog += '

';
    ddg_spice_espn_bind();

}

function ddg_spice_espn_news(response) {
    console.log(response);
    headlines = response.headlines;

    news = '
'
         + '
';

    for (var i = 0; i < 3 && i < headlines.length; i++) {
        var article = headlines[i];
        news += '
' + article.headline + ''
             +  ' (' + article.source + ')
';
    }
    news += '
'
         +  '
';

    ddg_spice_espn_bind();
}

function ddg_spice_espn_team(response) {
    response = response.sports[0].leagues[0].teams[0];
    var record = response.record;
    var stats = response.stats;
    var roster = response.athletes;
    var logo = response.logos.large.href;
    var teamColor = response.color;
    var totalGames = record.wins + record.losses + record.ties;
    var winPercentage = Math.floor(record.wins / totalGames * 100);
    var lossPercentage = Math.floor(record.losses / totalGames * 100);
    var tiePercentage = 100 - winPercentage - lossPercentage;
    var season = record.season.year
               + " (" + record.season.description + " season)";
    console.log(response);
    team = '
'
         + ''
         + '<fieldset style="border-top:1px solid #'
         + teamColor + ';padding:10px 10px 20px 10px;width:67%;">'
         + '<legend> ' + season + ' </legend>'
         + '
 ' + record.wins + ' wins
'
         + '
 ' + record.losses + ' losses
'
         + (record.ties !== 0 ?
            '
 ' + record.ties + ' ties
'
            : "") + '</fieldset>'
         + '
'
         + 'Name	Position	No.	'
         + 'Age	HT	WT	'
         + roster.map(function(player) {
             return '
'
                    + '' + player.displayName + '	'
                    + '' + player.positions[0].name + '	'
                    + '' + player.jersey + '	'
                    + '' + player.age + '	'
                    + '' + player.height + '	'
                    + '' + player.weight + '	'
                    + '
';
         }).join("") + '
';
    team += '
';

    ddg_spice_espn_bind();
}

function ddg_spice_espn_bind() {
    if (++callsMade != numberOfCalls) return;

    items[0]['a'] = tabs
                  + news
                  + team
                  + stats
                  + gamelog;

	nra(items);

    var table = document.getElementById("espn_zci_stats");
    for (var i = 0; i < table.rows.length; i++) {
        if (i % 2 == 0) table.rows[i].className="tr_odd";
    }

    ids = [ "espn_zci_gamelog_link",
            "espn_zci_stats_link",
            "espn_zci_team_link",
            "espn_zci_news_link"
          ];

    var bgtabs = [];
    ids.map( function(id) {
        bgtabs.push(document.getElementById(id.replace("_link","")))
    });

    var current_link = document.getElementById("espn_zci_news_link");
    YAHOO.util.Dom.setStyle(current_link, "text-decoration", "underline");

    YAHOO.util.Event.addListener(ids, "click", function(e) {
        YAHOO.util.Dom.setStyle(current_link, "text-decoration", "none");
        current_link = this;
        YAHOO.util.Dom.setStyle(this, "text-decoration", "underline");
        var current_tab = this.id.replace("_link", "");
        bgtabs.map(function(i){i.style.display="none";});
        current_tab = document.getElementById(current_tab);
        current_tab.style.display = "block";

        moreAtLink = YAHOO.util.Dom.getElementsByClassName(
                        "zero_click_more_at_link", "a",
                        document.getElementById("zero_click_abstract")
                    )[0];

        switch (current_tab.id) {
            case "espn_zci_gamelog":
                moreAtLink.href = baseURL + "/nba/player/gamelog/_/id/"
                                + playerID;
                break;
            case "espn_zci_stats":
                moreAtLink.href = baseURL + "/nba/player/stats/_/id/"
                                + playerID;
                break;
            case "espn_zci_team":
                moreAtLink.href = baseURL + "/nba/team/_/name/"
                                + teamCity.toLowerCase().substr(0,3) + "/"
                                + teamName.toLowerCase().replace(" ", "-");
                break;
            default:
                moreAtLink.href = baseURL + "/nba/player/_/id/"
                                + playerID;
        }

        e.stopImmediatePropagation();
    });

    YAHOO.util.Event.addListener(ids, "mouseenter", function(e) {
        YAHOO.util.Dom.setStyle(this, 'text-decoration', 'underline');
    });

    YAHOO.util.Event.addListener(ids, "mouseleave", function(e) {
        if (this != current_link) {
            YAHOO.util.Dom.setStyle(this, 'text-decoration', 'none');
        }
    });
}
<commit_msg>prettified stat date of birth<commit_after>var tabs = '';
var news = '';
var team = '';
var stats = '';
var gamelog = '';
var headshot = '';
var playerID = 0;
var teamID = 0;
var teamCity = '';
var teamName = '';
var baseURL = 'http://espn.com';

var callsMade = 0;
var numberOfCalls = 3;

items = [];
items[0] = [];
items[0]['a'] = '';
items[0]['h'] = '';
items[0]['s'] = 'ESPN';
items[0]['force_big_header'] = 1;
items[0]['f'] = 1;

function ddg_spice_espn(response) {

    var player = response.sports[0].leagues[0].athletes[0];
    var playerTeam = player.competitors[0].team;
    playerID = player.id;
    headshot = player.headshots.gamecast;
    teamID = playerTeam.id;
    teamCity = playerTeam.location;
    teamName = playerTeam.name;

    nrj("/js/spice/espn/basketball/nba/athletes/"
            + player.id + "/news/foo/ddg_spice_espn_news");
    nrj("/js/spice/espn/basketball/nba/teams/"
            + teamID + "/foo/bar/ddg_spice_espn_team");
    nrj("/js/spice/espn/basketball/nba/teams/"
            + teamID + "/events/dates/ddg_spice_espn_events");

    stats = player.stats;
    items[0]['u'] = baseURL + "/nba/player/_/id/" + playerID;
    items[0]['h'] = player.displayName + " - "
                  + playerTeam.location + " "
                  + playerTeam.name
                  + " (ESPN)";

    console.log(player);

    tabs = [ 'news', 'stats', 'team', 'gamelog' ];
    tabs = tabs.map(function(s, index, array) {
        return ''
            +  s.charAt(0).toUpperCase() + s.slice(1)
            +  '' + (index == array.length - 1 ? "" : " | ");
    }).join("");

    team = '
'
           + 'pretty pictures'
           + '
';

    playerStats = [ 'assists',
                    'athleteStatus',
                    'height',
                    'weight',
                    'blocks',
                    'defensiveRebounds',
                    'doubleDouble',
                    'ejections',
                    'fieldGoalsMade',
                    'fieldGoalsAttempted',
                    'fieldGoalPercentage',
                    'fouls',
                    'freeThrowsMade',
                    'freeThrowsAttempted',
                    'freeThrowPercentage',
                    'gamesStarted',
                    'minutes',
                    'offensiveRebounds',
                    'points',
                    'rebounds',
                    'steals',
                    'threePointersMade',
                    'threePointersAttempted',
                    'threePointPercentage',
                    'tripleDouble',
                    'turnovers',
                  ];

    function prepareStat(s, index, array) {
        display = s.replace(/([a-z\d](?=[A-Z])|[a-zA-Z](?=\d))/g, "$1 ");
        display = display.toLowerCase();
        display = '
'
                + display.charAt(0).toUpperCase() + display.slice(1)
                + ':	'
                + (player[s] ? player[s] : stats[s])
                + '
';
        return display;
    }

    playerStats = playerStats.map(prepareStat);
    var nestedStats = ['Date of birth', 'Birthplace', 'Position' ];
    [ player.dateOfBirth.split("T")[0],
      player.birthPlace.city + ', ' + player.birthPlace.state,
      player.positions[0].name,
    ].map(function(s) {
        playerStats.unshift('
' + nestedStats.shift()
                          + ':	' + s + '
');
    });

    stats  = '
'
           + playerStats.join("")
           + '
';
}

function ddg_spice_espn_events(response) {
    var events = response.sports[0].leagues[0].events;
    console.log(events[85]);
    gamelog = '

'
            + '	Home		Away	'
            + '
';
    for (var i = events.length - 1; i > (events.length - 6); i--) {
        var competitors = events[i].competitions[0].competitors;
        var date = new Date(events[i].date);
        date.setMonth(date.getMonth()+1);
        var outcome = '';
        gamelog += '' + date.getUTCMonth() + '/' + date.getUTCDate() + '	';
        competitors.map(function(competitor, index, array) {
            teamDisplayName = competitor.team.location
                            + " " + competitor.team.name
            gamelog += '' + teamDisplayName + '	'
                    +  (index == 0 ? ' vs ' : '	');
            if (index == 1) {
                outcome = competitor.score > array[0].score;
                var win = 'W ';
                var loss = 'L ';
                gamelog += ''
                        +  ''
                        +  (competitor.team.id == teamID ?
                                (outcome ? win : loss)
                                + competitor.score
                                + '-' + array[0].score
                            : (outcome ? loss : win)
                                + array[0].score + '-'
                                + competitor.score)
                        +  '	';
            }
        });
        gamelog += '
';
    }
    gamelog += '

';
    ddg_spice_espn_bind();

}

function ddg_spice_espn_news(response) {
    console.log(response);
    headlines = response.headlines;

    news = '
'
         + '
';

    for (var i = 0; i < 3 && i < headlines.length; i++) {
        var article = headlines[i];
        news += '
' + article.headline + ''
             +  ' (' + article.source + ')
';
    }
    news += '
'
         +  '
';

    ddg_spice_espn_bind();
}

function ddg_spice_espn_team(response) {
    response = response.sports[0].leagues[0].teams[0];
    var record = response.record;
    var stats = response.stats;
    var roster = response.athletes;
    var logo = response.logos.large.href;
    var teamColor = response.color;
    var totalGames = record.wins + record.losses + record.ties;
    var winPercentage = Math.floor(record.wins / totalGames * 100);
    var lossPercentage = Math.floor(record.losses / totalGames * 100);
    var tiePercentage = 100 - winPercentage - lossPercentage;
    var season = record.season.year
               + " (" + record.season.description + " season)";
    console.log(response);
    team = '
'
         + ''
         + '<fieldset style="border-top:1px solid #'
         + teamColor + ';padding:10px 10px 20px 10px;width:67%;">'
         + '<legend> ' + season + ' </legend>'
         + '
 ' + record.wins + ' wins
'
         + '
 ' + record.losses + ' losses
'
         + (record.ties !== 0 ?
            '
 ' + record.ties + ' ties
'
            : "") + '</fieldset>'
         + '
'
         + 'Name	Position	No.	'
         + 'Age	HT	WT	'
         + roster.map(function(player) {
             return '
'
                    + '' + player.displayName + '	'
                    + '' + player.positions[0].name + '	'
                    + '' + player.jersey + '	'
                    + '' + player.age + '	'
                    + '' + player.height + '	'
                    + '' + player.weight + '	'
                    + '
';
         }).join("") + '
';
    team += '
';

    ddg_spice_espn_bind();
}

function ddg_spice_espn_bind() {
    if (++callsMade != numberOfCalls) return;

    items[0]['a'] = tabs
                  + news
                  + team
                  + stats
                  + gamelog;

	nra(items);

    var table = document.getElementById("espn_zci_stats");
    for (var i = 0; i < table.rows.length; i++) {
        if (i % 2 == 0) table.rows[i].className="tr_odd";
    }

    ids = [ "espn_zci_gamelog_link",
            "espn_zci_stats_link",
            "espn_zci_team_link",
            "espn_zci_news_link"
          ];

    var bgtabs = [];
    ids.map( function(id) {
        bgtabs.push(document.getElementById(id.replace("_link","")))
    });

    var current_link = document.getElementById("espn_zci_news_link");
    YAHOO.util.Dom.setStyle(current_link, "text-decoration", "underline");

    YAHOO.util.Event.addListener(ids, "click", function(e) {
        YAHOO.util.Dom.setStyle(current_link, "text-decoration", "none");
        current_link = this;
        YAHOO.util.Dom.setStyle(this, "text-decoration", "underline");
        var current_tab = this.id.replace("_link", "");
        bgtabs.map(function(i){i.style.display="none";});
        current_tab = document.getElementById(current_tab);
        current_tab.style.display = "block";

        moreAtLink = YAHOO.util.Dom.getElementsByClassName(
                        "zero_click_more_at_link", "a",
                        document.getElementById("zero_click_abstract")
                    )[0];

        switch (current_tab.id) {
            case "espn_zci_gamelog":
                moreAtLink.href = baseURL + "/nba/player/gamelog/_/id/"
                                + playerID;
                break;
            case "espn_zci_stats":
                moreAtLink.href = baseURL + "/nba/player/stats/_/id/"
                                + playerID;
                break;
            case "espn_zci_team":
                moreAtLink.href = baseURL + "/nba/team/_/name/"
                                + teamCity.toLowerCase().substr(0,3) + "/"
                                + teamName.toLowerCase().replace(" ", "-");
                break;
            default:
                moreAtLink.href = baseURL + "/nba/player/_/id/"
                                + playerID;
        }

        e.stopImmediatePropagation();
    });

    YAHOO.util.Event.addListener(ids, "mouseenter", function(e) {
        YAHOO.util.Dom.setStyle(this, 'text-decoration', 'underline');
    });

    YAHOO.util.Event.addListener(ids, "mouseleave", function(e) {
        if (this != current_link) {
            YAHOO.util.Dom.setStyle(this, 'text-decoration', 'none');
        }
    });
}
<|endoftext|>


<commit_before>/**
* directive.diPiece Module
*
* Description
*/
angular.module('directive.diPiece', [
    'service.GameManager',
    'resource.GameData'
])
.controller('PieceCtrl', [
    '$scope',
    'GameManager',
    'GameData',
function (
    $scope,
    GameManager,
    GameData
){
    var getX = _.memoize(function(x) {
           return x * GameData.gameBoard.pieceWidthInPixel + GameData.gameBoard.borderWidth;
        }),
        getY = _.memoize(function (y) {
            return y * GameData.gameBoard.pieceWidthInPixel;
        });

    function getPattern() {
        return GameManager.getCurrentPattern();
    }

    function getPiece() {
        return GameManager.getCurrentPiece();
    }

    function getPositionX () {
        return GameManager.getPositionX();
    }

    function getPositionY() {
        return GameManager.getPositionY();
    }

    $scope.pieces = _.range(16);

    // if sequence is match, then highlight the DOM ele
    $scope.checkPattern = function checkPattern(piece) {
        var res = _.find(getPattern(), function (p) {
            return piece === p;
        });
        return _.isNumber(res);
    };

    $scope.getClassForShape = function getClassForShape() {
        var pieceClass = '';
        switch(GameManager.getCurrentShape()) {
            case 0: pieceClass = 'dy-L';
                break;
            case 1: pieceClass = 'dy-O';
                break;
            case 2: pieceClass = 'dy-I';
                break;
            case 3: pieceClass = 'dy-T';
                break;
            case 4: pieceClass = 'dy-J';
                break;
            case 5: pieceClass = 'dy-S';
                break;
            case 6: pieceClass = 'dy-Z';
                break;
        }
        return pieceClass;
    };

    this.getLeft = function getLeft() {
        return getX(getPositionX());
    };

    this.getTop = function getTop() {
        return getY(getPositionY());
    };
}])
.directive('diPiece', [
function(
){
    var Piece = {};

    Piece.controller = 'PieceCtrl';

    Piece.templateUrl = 'directives/diPiece/diPiece.tpl.html';

    Piece.restrict = 'A';

    Piece.replace = true;

    Piece.scope = true;

    Piece.link = function link(scope, element, attrs, controller) {
        element.css('left', controller.getLeft() + 'px');
        scope.$on('GameOn', function () {
            var top = controller.getTop(),
                left = controller.getLeft();
            element.css('left', left + 'px');
            element.css('top', Math.round(top) + 'px');
        });
    };

    return Piece;
}]);<commit_msg>check game start before drawing<commit_after>/**
* directive.diPiece Module
*
* Description
*/
angular.module('directive.diPiece', [
    'service.GameManager',
    'resource.GameData'
])
.controller('PieceCtrl', [
    '$scope',
    'GameManager',
    'GameData',
function (
    $scope,
    GameManager,
    GameData
){
    var getX = _.memoize(function(x) {
           return x * GameData.gameBoard.pieceWidthInPixel + GameData.gameBoard.borderWidth;
        }),
        getY = _.memoize(function (y) {
            return y * GameData.gameBoard.pieceWidthInPixel;
        });

    function getPattern() {
        return GameManager.getCurrentPattern();
    }

    function getPiece() {
        return GameManager.getCurrentPiece();
    }

    function getPositionX () {
        return GameManager.getPositionX();
    }

    function getPositionY() {
        return GameManager.getPositionY();
    }

    $scope.pieces = _.range(16);

    // if sequence is match, then highlight the DOM ele
    $scope.checkPattern = function checkPattern(piece) {
        if (!GameManager.isGameStart()) {
            return;
        }
        var res = _.find(getPattern(), function (p) {
            return piece === p;
        });
        return _.isNumber(res);
    };

    $scope.getClassForShape = function getClassForShape() {
        if (!GameManager.isGameStart()) {
            return;
        }
        var pieceClass = '';
        switch(GameManager.getCurrentShape()) {
            case 0: pieceClass = 'dy-L';
                break;
            case 1: pieceClass = 'dy-O';
                break;
            case 2: pieceClass = 'dy-I';
                break;
            case 3: pieceClass = 'dy-T';
                break;
            case 4: pieceClass = 'dy-J';
                break;
            case 5: pieceClass = 'dy-S';
                break;
            case 6: pieceClass = 'dy-Z';
                break;
        }
        return pieceClass;
    };

    this.getLeft = function getLeft() {
        return getX(getPositionX());
    };

    this.getTop = function getTop() {
        return getY(getPositionY());
    };
}])
.directive('diPiece', [
function(
){
    var Piece = {};

    Piece.controller = 'PieceCtrl';

    Piece.templateUrl = 'directives/diPiece/diPiece.tpl.html';

    Piece.restrict = 'A';

    Piece.replace = true;

    Piece.scope = true;

    Piece.link = function link(scope, element, attrs, controller) {
        scope.$on('GameOn', function () {
            var top = controller.getTop(),
                left = controller.getLeft();
            element.css('left', left + 'px');
            element.css('top', Math.round(top) + 'px');
        });
    };

    return Piece;
}]);<|endoftext|>


<commit_before>var storybookCheck = require('./check');
var path = require('path');
var fs = require('fs');
var getPort = require('get-port');
var spawn = require('child_process').spawn;
var request = require('requestretry');
var jsdom = require('jsdom/lib/old-api.js');
var colors = require('colors/safe');
var template = require('lodash/template');

var baseUrl;
var previewCode;

exports.server = function(config, options, callback) {
  var storybookApp;
  var storybookVersion;
  if (!config || !config.storybookConfigDir) {
    return callback(new Error('Error: \'storybookConfigDir\' not found in config file.'));
  }
  if ([2, 3].indexOf(config.storybookVersion) > -1) {
    storybookApp = 'react';
    if (['react', 'vue', 'angular'].indexOf(config.storybookApp) > -1) {
      storybookApp = config.storybookApp;
    }
    storybookVersion = config.storybookVersion;
  } else {
    // check storybook module
    try {
      var pkg = storybookCheck();
      storybookApp = pkg.app;
      storybookVersion = pkg.version;
    } catch(ex) {
      return callback(ex);
    }
  }
  // find free port
  getPort().then(function (port) {
    // inject temp storybook config file to get storybook
    var configPath = path.resolve(process.cwd(), config.storybookConfigDir, 'config.js');
    if (!fs.existsSync(configPath)) {
      return callback(new Error('Storybook config file not found: ' + configPath));
    }
    var configBody = fs.readFileSync(configPath, 'utf8');
    var codeTemplate = fs.readFileSync(__dirname + '/templates/v' + storybookVersion + '.template', 'utf8');
    var code = template(codeTemplate)({ code: configBody, app: storybookApp });
    fs.writeFileSync(configPath, code, 'utf8');

    // start Storybook dev server
    var binPath = path.resolve(process.cwd(), 'node_modules/.bin');
    if (config.storybookBinPath) {
      binPath = config.storybookBinPath;
      console.log('Use custom storybook bin path: ' + binPath);
    }
    var bin = path.resolve(binPath, 'start-storybook');
    var isWin = false;
    if (/^win/.test(process.platform)) {
      isWin = true;
      bin += '.cmd';
    }
    var args = ['--port', port, '--config-dir', config.storybookConfigDir];
    if (config.storybookStaticDir) {
      args.push('--static-dir');
      args.push(config.storybookStaticDir);
    }
    console.log('\nStarting Storybook server...');
    console.log('>', 'start-storybook', args.join(' '), '\n\nPlease wait. Starting Storybook may take a minute...\n');
    var serverProcess = spawn(bin, args, {detached: !isWin});
    if (options && (options.debug || options.serverOnly)) {
      serverProcess.stdout.on('data', function(data) { console.log(data.toString('utf8').trim()); });
      serverProcess.stderr.on('data', function(data) { console.error(data.toString('utf8').trim()); });
    }

    // clean-up all child processes when this process is terminated
    process.on('exit', function() {
      if (fs.readFileSync(configPath, 'utf8') !== configBody) {
        fs.writeFileSync(configPath, configBody, 'utf8');
      }
      if (!isWin) {
        process.kill(-serverProcess.pid);
      }
    });
    process.on('SIGINT', function () {
      process.exit();
    });
    process.on('uncaughtException', function(err) {
      console.error(err);
      process.exit(1);
    });

    // wait for storybook server to be ready
    setTimeout(function() {
      baseUrl = 'http://localhost:' + port;
      request.get(baseUrl + '/static/preview.bundle.js', function(err, response, body) {
        if (err) return callback(err);
        if (response.statusCode != 200 || !body) {
          return callback(new Error('Error fetching preview bundle from storybook server'));
        }
        previewCode = body;
        try {
          // reset config file to original code
          fs.writeFileSync(configPath, configBody, 'utf8');
        } catch(ex) {
          return callback(ex);
        }
        callback(null, port);
      });
    }, 3*1000);
  }).catch(callback);
};

var getStorybook = function(window, tries, callback) {
  var storybookObj = null;
  var _storybook = window && window.__screener_storybook__;
  if (typeof _storybook === 'function') {
    var maxTries = 5;
    try {
      storybookObj = _storybook();
    } catch (ex) {
      return callback(ex);
    }
    if (tries < maxTries && (!storybookObj || (typeof storybookObj === 'object' && storybookObj.length === 0))) {
      setTimeout(function() {
        getStorybook(window, tries + 1, callback);
      }, 2*1000);
    } else {
      callback(null, storybookObj);
    }
  } else if (typeof _storybook === 'object') {
    callback(null, _storybook);
  }
};

exports.get = function(options, callback) {
  var setupCode = [
    fs.readFileSync(__dirname + '/polyfills/match-media.js', 'utf8'),
    fs.readFileSync(__dirname + '/polyfills/local-storage.js', 'utf8'),
    fs.readFileSync(__dirname + '/polyfills/event-source.js', 'utf8')
  ];
  var jsDomConfig = {
    html: '',
    src: setupCode.concat(previewCode),
    resourceLoader: function (resource, cb) {
      var pathname = resource.url.pathname;
      // fetch additional js files from storybook server
      if (/\.js$/.test(pathname)) {
        request.get(baseUrl + pathname, function(err, response, body) {
          if (err) return cb(err);
          if (response.statusCode === 200 && body) {
            cb(null, body);
          } else {
            resource.defaultFetch(cb);
          }
        });
      } else {
        resource.defaultFetch(cb);
      }
    },
    done: function (err, window) {
      if (err) return callback(err);
      getStorybook(window, 0, function (err, storybookObj) {
        if (err) return callback(err);
        if (!storybookObj) {
          console.error(colors.red('Error getting Storybook object'));
          if (options && options.debug) {
            console.error(colors.red('Please send debug output to support@screener.io'));
          } else {
            console.error(colors.red('Please re-run with --debug flag, and send debug output to support@screener.io'));
          }
          return callback(new Error('Storybook object not found'));
        }
        // jsdom window no longer needed. close it
        try { window.close(); } catch (ex) { /**/ }
        callback(null, storybookObj);
      });
    }
  };
  if (options && options.debug) {
    jsDomConfig.virtualConsole = jsdom.createVirtualConsole().sendTo(console);
  }
  // parse preview bundle js code and retrieve window object
  jsdom.env(jsDomConfig);
};
<commit_msg>enable pretendToBeVisual jsdom option<commit_after>var storybookCheck = require('./check');
var path = require('path');
var fs = require('fs');
var getPort = require('get-port');
var spawn = require('child_process').spawn;
var request = require('requestretry');
var jsdom = require('jsdom/lib/old-api.js');
var colors = require('colors/safe');
var template = require('lodash/template');

var baseUrl;
var previewCode;

exports.server = function(config, options, callback) {
  var storybookApp;
  var storybookVersion;
  if (!config || !config.storybookConfigDir) {
    return callback(new Error('Error: \'storybookConfigDir\' not found in config file.'));
  }
  if ([2, 3].indexOf(config.storybookVersion) > -1) {
    storybookApp = 'react';
    if (['react', 'vue', 'angular'].indexOf(config.storybookApp) > -1) {
      storybookApp = config.storybookApp;
    }
    storybookVersion = config.storybookVersion;
  } else {
    // check storybook module
    try {
      var pkg = storybookCheck();
      storybookApp = pkg.app;
      storybookVersion = pkg.version;
    } catch(ex) {
      return callback(ex);
    }
  }
  // find free port
  getPort().then(function (port) {
    // inject temp storybook config file to get storybook
    var configPath = path.resolve(process.cwd(), config.storybookConfigDir, 'config.js');
    if (!fs.existsSync(configPath)) {
      return callback(new Error('Storybook config file not found: ' + configPath));
    }
    var configBody = fs.readFileSync(configPath, 'utf8');
    var codeTemplate = fs.readFileSync(__dirname + '/templates/v' + storybookVersion + '.template', 'utf8');
    var code = template(codeTemplate)({ code: configBody, app: storybookApp });
    fs.writeFileSync(configPath, code, 'utf8');

    // start Storybook dev server
    var binPath = path.resolve(process.cwd(), 'node_modules/.bin');
    if (config.storybookBinPath) {
      binPath = config.storybookBinPath;
      console.log('Use custom storybook bin path: ' + binPath);
    }
    var bin = path.resolve(binPath, 'start-storybook');
    var isWin = false;
    if (/^win/.test(process.platform)) {
      isWin = true;
      bin += '.cmd';
    }
    var args = ['--port', port, '--config-dir', config.storybookConfigDir];
    if (config.storybookStaticDir) {
      args.push('--static-dir');
      args.push(config.storybookStaticDir);
    }
    console.log('\nStarting Storybook server...');
    console.log('>', 'start-storybook', args.join(' '), '\n\nPlease wait. Starting Storybook may take a minute...\n');
    var serverProcess = spawn(bin, args, {detached: !isWin});
    if (options && (options.debug || options.serverOnly)) {
      serverProcess.stdout.on('data', function(data) { console.log(data.toString('utf8').trim()); });
      serverProcess.stderr.on('data', function(data) { console.error(data.toString('utf8').trim()); });
    }

    // clean-up all child processes when this process is terminated
    process.on('exit', function() {
      if (fs.readFileSync(configPath, 'utf8') !== configBody) {
        fs.writeFileSync(configPath, configBody, 'utf8');
      }
      if (!isWin) {
        process.kill(-serverProcess.pid);
      }
    });
    process.on('SIGINT', function () {
      process.exit();
    });
    process.on('uncaughtException', function(err) {
      console.error(err);
      process.exit(1);
    });

    // wait for storybook server to be ready
    setTimeout(function() {
      baseUrl = 'http://localhost:' + port;
      request.get(baseUrl + '/static/preview.bundle.js', function(err, response, body) {
        if (err) return callback(err);
        if (response.statusCode != 200 || !body) {
          return callback(new Error('Error fetching preview bundle from storybook server'));
        }
        previewCode = body;
        try {
          // reset config file to original code
          fs.writeFileSync(configPath, configBody, 'utf8');
        } catch(ex) {
          return callback(ex);
        }
        callback(null, port);
      });
    }, 3*1000);
  }).catch(callback);
};

var getStorybook = function(window, tries, callback) {
  var storybookObj = null;
  var _storybook = window && window.__screener_storybook__;
  if (typeof _storybook === 'function') {
    var maxTries = 5;
    try {
      storybookObj = _storybook();
    } catch (ex) {
      return callback(ex);
    }
    if (tries < maxTries && (!storybookObj || (typeof storybookObj === 'object' && storybookObj.length === 0))) {
      setTimeout(function() {
        getStorybook(window, tries + 1, callback);
      }, 2*1000);
    } else {
      callback(null, storybookObj);
    }
  } else if (typeof _storybook === 'object') {
    callback(null, _storybook);
  }
};

exports.get = function(options, callback) {
  var setupCode = [
    fs.readFileSync(__dirname + '/polyfills/match-media.js', 'utf8'),
    fs.readFileSync(__dirname + '/polyfills/local-storage.js', 'utf8'),
    fs.readFileSync(__dirname + '/polyfills/event-source.js', 'utf8')
  ];
  var jsDomConfig = {
    html: '',
    src: setupCode.concat(previewCode),
    pretendToBeVisual: true,
    resourceLoader: function (resource, cb) {
      var pathname = resource.url.pathname;
      // fetch additional js files from storybook server
      if (/\.js$/.test(pathname)) {
        request.get(baseUrl + pathname, function(err, response, body) {
          if (err) return cb(err);
          if (response.statusCode === 200 && body) {
            cb(null, body);
          } else {
            resource.defaultFetch(cb);
          }
        });
      } else {
        resource.defaultFetch(cb);
      }
    },
    done: function (err, window) {
      if (err) return callback(err);
      getStorybook(window, 0, function (err, storybookObj) {
        if (err) return callback(err);
        if (!storybookObj) {
          console.error(colors.red('Error getting Storybook object'));
          if (options && options.debug) {
            console.error(colors.red('Please send debug output to support@screener.io'));
          } else {
            console.error(colors.red('Please re-run with --debug flag, and send debug output to support@screener.io'));
          }
          return callback(new Error('Storybook object not found'));
        }
        // jsdom window no longer needed. close it
        try { window.close(); } catch (ex) { /**/ }
        callback(null, storybookObj);
      });
    }
  };
  if (options && options.debug) {
    jsDomConfig.virtualConsole = jsdom.createVirtualConsole().sendTo(console);
  }
  // parse preview bundle js code and retrieve window object
  jsdom.env(jsDomConfig);
};
<|endoftext|>


<commit_before>import isRegexp from 'is-regexp'
import isObject from 'isobject'
import React from 'react'

// Chrome on my machine had performance issues
// with a number greater than 20 and when JSX handler disabled
const MAX_DEPTH = 20

function handlePrimitive(x) {
  const t = typeof x
  if (x === null || x === undefined || t === 'number' || t === 'boolean' || isRegexp(x)) {
    return String(x)
  }
  return null
}

function handleFunction(x) {
  if (typeof x === 'function') {
    return String(x).replace(/{[\s\S]*}/, '=> ...').replace(/.*\(/, '(')
  }
  return null
}

function handleString(x) {
  if (typeof x === 'string') {
    return `"${x}"`
  }
  return null
}

function handleDate(x) {
  if (x instanceof Date) {
    return `Date('${x.toISOString()}')`
  }
  return null
}

function handleArray(x, next, seen) {
  if (Array.isArray(x)) {
    if (x.length === 0) {
      return '[]'
    }
    seen.push(x)
    const result = `[${x.map(next).join(', ')}]`
    seen.pop()
    return result
  }
  return null
}

function wrapJsxProp(x) {
  return x[0] === '"' ? x : `{${x}}`
}

function wrapJsxChildren(x) {
  if (x[0] === '<') {
    return x
  }
  if (x[0] === '"') {
    return x.slice(1, x.length - 1)
  }
  return `{${x}}`
}

function handleJsx(x, next, seen, indent) {
  if (React.isValidElement(x)) {
    const lastIndent = indent === '' ? '' : indent.replace(/\s\s$/, '')
    const name = typeof x.type === 'string' ? x.type : (x.type.displayName || 'Unknown')
    const defaultProps = x.type && (typeof x.type.getDefaultProps === 'function')
      ? x.type.getDefaultProps()
      : {}
    const keys = Object.keys(x.props).filter(key => defaultProps[key] !== x.props[key])
    let props = ''
    let children = null
    if (keys.length > 0) {
      seen.push(x)
      const _keys = keys.filter(key => key !== 'children')
      if (_keys.length > 0) {
        const joint = indent === '' ? ' ' : indent
        props = _keys.map(key => {
          const val = x.props[key]
          return val === true ? key : `${key}=${wrapJsxProp(next(val))}`
        })
        props = `${joint}${props.join(joint)}${lastIndent}`
      }
      if (keys.indexOf('children') !== -1) {
        if (Array.isArray(x.props.children)) {
          children = x.props.children.map(c => wrapJsxChildren(next(c))).join(`${indent}`)
        } else {
          children = wrapJsxChildren(next(x.props.children))
        }
      }
      seen.pop()
    }
    const ending = children === null ? '/>' : `>${indent}${children}${lastIndent}</${name}>`
    return `<${name}${props}${ending}`
  }
  return null
}

function handleObject(x, next, seen, indent) {
  if (isObject(x)) {
    const keys = Object.keys(x)
    if (keys.length === 0) {
      return '{}'
    }
    seen.push(x)
    const joint = indent === '' ? ', ' : `,${indent}`
    const lastIndent = indent === '' ? '' : indent.replace(/\s\s$/, '')
    const body = keys.map(key => `${key}: ${next(x[key])}`).join(joint)
    const result = `{${indent}${body}${lastIndent}}`
    seen.pop()
    return result
  }
  return null
}

function handleUnknown() {
  return '__UnknownType'
}

const handlers = [
  handlePrimitive,
  handleFunction,
  handleString,
  handleDate,
  handleArray,
  handleJsx,
  handleObject,
  handleUnknown,
]

export default function stringify(_x, opts) {
  const seen = []
  function s(x, {indent = '\n  ', depthLim = 0, depth = 0} = {}) {
    if (depth > MAX_DEPTH) {
      return '__DepthLimit'
    }
    if (seen.indexOf(x) !== -1) {
      return '__Circular'
    }
    let i = 0
    let result
    const next = (__x) => s(__x, {indent: indent + '  ', depthLim: depthLim - 1, depth: depth + 1})
    do {
      result = handlers[i](x, next, seen, depthLim > 0 ? indent : '')
      i++
    } while (result === null)
    return result
  }
  return s(_x, opts)
}
<commit_msg>if displayName is not set, use function name as display name<commit_after>import isRegexp from 'is-regexp'
import isObject from 'isobject'
import React from 'react'

// Chrome on my machine had performance issues
// with a number greater than 20 and when JSX handler disabled
const MAX_DEPTH = 20

function handlePrimitive(x) {
  const t = typeof x
  if (x === null || x === undefined || t === 'number' || t === 'boolean' || isRegexp(x)) {
    return String(x)
  }
  return null
}

function handleFunction(x) {
  if (typeof x === 'function') {
    return String(x).replace(/{[\s\S]*}/, '=> ...').replace(/.*\(/, '(')
  }
  return null
}

function handleString(x) {
  if (typeof x === 'string') {
    return `"${x}"`
  }
  return null
}

function handleDate(x) {
  if (x instanceof Date) {
    return `Date('${x.toISOString()}')`
  }
  return null
}

function handleArray(x, next, seen) {
  if (Array.isArray(x)) {
    if (x.length === 0) {
      return '[]'
    }
    seen.push(x)
    const result = `[${x.map(next).join(', ')}]`
    seen.pop()
    return result
  }
  return null
}

function wrapJsxProp(x) {
  return x[0] === '"' ? x : `{${x}}`
}

function wrapJsxChildren(x) {
  if (x[0] === '<') {
    return x
  }
  if (x[0] === '"') {
    return x.slice(1, x.length - 1)
  }
  return `{${x}}`
}

function handleJsx(x, next, seen, indent) {
  if (React.isValidElement(x)) {
    const lastIndent = indent === '' ? '' : indent.replace(/\s\s$/, '')
    const name = typeof x.type === 'string' ? x.type : (x.type.displayName || x.type.name || 'Unknown')
    const defaultProps = x.type && (typeof x.type.getDefaultProps === 'function')
      ? x.type.getDefaultProps()
      : {}
    const keys = Object.keys(x.props).filter(key => defaultProps[key] !== x.props[key])
    let props = ''
    let children = null
    if (keys.length > 0) {
      seen.push(x)
      const _keys = keys.filter(key => key !== 'children')
      if (_keys.length > 0) {
        const joint = indent === '' ? ' ' : indent
        props = _keys.map(key => {
          const val = x.props[key]
          return val === true ? key : `${key}=${wrapJsxProp(next(val))}`
        })
        props = `${joint}${props.join(joint)}${lastIndent}`
      }
      if (keys.indexOf('children') !== -1) {
        if (Array.isArray(x.props.children)) {
          children = x.props.children.map(c => wrapJsxChildren(next(c))).join(`${indent}`)
        } else {
          children = wrapJsxChildren(next(x.props.children))
        }
      }
      seen.pop()
    }
    const ending = children === null ? '/>' : `>${indent}${children}${lastIndent}</${name}>`
    return `<${name}${props}${ending}`
  }
  return null
}

function handleObject(x, next, seen, indent) {
  if (isObject(x)) {
    const keys = Object.keys(x)
    if (keys.length === 0) {
      return '{}'
    }
    seen.push(x)
    const joint = indent === '' ? ', ' : `,${indent}`
    const lastIndent = indent === '' ? '' : indent.replace(/\s\s$/, '')
    const body = keys.map(key => `${key}: ${next(x[key])}`).join(joint)
    const result = `{${indent}${body}${lastIndent}}`
    seen.pop()
    return result
  }
  return null
}

function handleUnknown() {
  return '__UnknownType'
}

const handlers = [
  handlePrimitive,
  handleFunction,
  handleString,
  handleDate,
  handleArray,
  handleJsx,
  handleObject,
  handleUnknown,
]

export default function stringify(_x, opts) {
  const seen = []
  function s(x, {indent = '\n  ', depthLim = 0, depth = 0} = {}) {
    if (depth > MAX_DEPTH) {
      return '__DepthLimit'
    }
    if (seen.indexOf(x) !== -1) {
      return '__Circular'
    }
    let i = 0
    let result
    const next = (__x) => s(__x, {indent: indent + '  ', depthLim: depthLim - 1, depth: depth + 1})
    do {
      result = handlers[i](x, next, seen, depthLim > 0 ? indent : '')
      i++
    } while (result === null)
    return result
  }
  return s(_x, opts)
}
<|endoftext|>


<commit_before>var vector = require('./vector');

var Empty = function() {
    this.type = 'empty';
    this.tl_pher = null;
    this.br_pher = null;
};

var Wall = function(strength) {
    this.type = 'wall';
    this.strength = strength;
};

var Sugar = function(amount) {
    this.type = 'sugar';
    this.amount = amount;
};

var Home = function(team) {
    this.type = 'home';
    this.team = team;
    this.stored = 0;
};

var Ant = function(team, position, world) {
    this.world = world;
    this.team = team;
    this.position = position; // vector
    this.hasFood = false;
    this.isTrampled = false;
    this.direction = "left"; // chosen from "right", "up", "down"

    /* direction is a unit vector */
    this.move = function(direction) {
        var new_x, new_y, new_obj;

        if(direction === 'up') {
            new_x = this.position.x;
            new_y = this.position.y - 1;
        } else if(direction === 'down') {
            new_x = this.position.x;
            new_y = this.position.y + 1;
        } else if(direction === 'left') {
            new_x = this.position.x - 1;
            new_y = this.position.y;p
        } else if(direction === 'right') {
            new_x = this.position.x + 1;
            new_y = this.position.y;
        } else {
            console.log("ERROR: Ant.move() dosn't understand direction: " + direction);
            return false;
        }

        /* Bounds Checking */
        if(new_x >= world.map.width || new_x < 0
           || new_y >= world.map.height || new_y < 0) {
            return false;
        }

        new_obj = this.world.map.map[new_y][new_x];

        if(new_obj.type === 'empty' || new_obj.type === 'sugar') {
            this.position.x += direction.x;
            this.position.y += direction.y;

            if(new_obj.type == 'sugar' && this.hasFood === false){
                new_obj.amount--;
                this.hasFood = true;

                if(new_obj.amount === 0) {
                    world.map.map[new_y][new_x] = new Empty();
                }
            }
        } else {
            return false;
        }

        return true;
    };

    this.dig = function(direction) {
        var wall_x, wall_y, new_obj;
        if(direction === 'up') {
            wall_x = this.position.x;
            wall_y = this.position.y - 1;
        } else if(direction === 'down') {
            wall_x = this.position.x;
            wall_y = this.position.y + 1;
        } else if(direction === 'left') {
            wall_x = this.position.x - 1;
            wall_y = this.position.y;
        } else if(direction === 'right') {
            wall_x = this.position.x + 1;
            wall_y = this.position.y;
        } else {
            console.log("ERROR: Ant.dig() dosn't understand direction: " + direction);
            return false;
        }

        /* Bounds Checking */
        if(wall_x >= world.map.width || wall_x < 0
           || wall_y >= world.map.height || wall_y < 0) {
            return false;
        }

        new_obj = world.map.map[wall_y][wall_x];

        if(new_obj.type === 'wall') {
            new_obj.strength--;
        } else if(new_obj.type === 'home' && this.hasFood === true) {
            new_obj.stored++;
            this.hasFood = false;
        }

        if(new_obj.type === 'wall' && new_obj.strength === 0) {
            world.map.map[wall_y][wall_x] = new Empty();
            return true;
        }

        return false;
    };
};

function Map(width, height, sugars) {
    this.map = newMap(width, height, sugars);
    this.tl = new vector.Vec2(2, 2);
    this.br = new vector.Vec2(width-3, height-3);
    this.width = width;
    this.height = height;

    this.setPherAt = function (team, position, value ) {
        var cell = this.map[position.y][position.x];

        if (!cell.type == 'empty') {
            return false;
        }

        if(team === 'br') {
            cell.br_pher = value;
            cell.br_pher_seed = Math.random();
        } else if(team === 'tl') {
            cell.tl_pher = value;
            cell.tl_pher_seed = Math.random();
        } else {
            console.log("Weird input to Map.setPher()!\n");
            return false;
        }
        return true;
    };

    this.pherAt = function (team, position) {
        var cell = this.map[position.y][position.x];

        if (!cell.type == 'empty') {
            return null;
        }

        if(team === 'br') {
            return cell.br_pher;
        } else if(team === 'tl') {
            return cell.tl_pher;
        } else {
            console.log("Weird input to Map.pherAt()!\n");
            return null;
        }
    };
}

function newMap(width, height, sugars) {
    var i, j, k, x, y;

    if(height < 10) {
        height = 10;
    }
    if(width < 10) {
        width = 10;
    }

    var map = [];
    for (y = 0; y < height; y++) {
        map[y] = [];
    }

    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {
            map[y][x] = new Wall(5);
        }
    }

    for(k = 0; k < sugars/2; k++) {
        x = Math.floor(Math.random() * width);
        y = Math.floor(Math.random() * height);

        for(i = -1; i < 2; i++){
            for(j = -1; j < 2; j++){
                if(x+j >= 0 && x+j < width && y+i >= 0 && y+i < height){
                    map[y+i][x+j] = new Empty();
                }
                if(height-y-1+i >= 0 && height-y-1+i < height
                  && width-x-1+j >= 0 && width-x-1+j < width){
                    map[height-y-1+i][width-x-1+j] = new Empty();
                }
            }
        }

        for(i = -2; i < 3; i++){
            for(j = -2; j < 3; j++){
                if(x+j >= 0 && x+j < width && y+i >= 0 && y+i < height){
                    if(Math.random() < 0.7) {
                        map[y+i][x+j] = new Empty();
                    }
                }
                if(height-y-1+i >= 0 && height-y-1+i < height
                  && width-x-1+j >= 0 && width-x-1+j < width){
                    if(Math.random() < 0.7) {
                        map[height-y-1+i][width-x-1+j] = new Empty();
                    }
                }
            }
        }

        map[y][x] = new Sugar(20);
        map[height-y-1][width-x-1] = new Sugar(20);
    }

    for(i = 0; i < 5; i++) {
        for(j = 0; j < 5; j++) {
            map[i][j] = new Empty();
            map[height-i-1][width-j-1] = new Empty();
        }
    }

    map[2][2] = new Home("tl");
    map[height-3][width-3] = new Home("br");

    return map;
};

module.exports = {
    Empty: Empty,
    Wall: Wall,
    Sugar: Sugar,
    Home: Home,
    Ant: Ant,
    Map: Map
};
<commit_msg>fixed some jankyisms<commit_after>var vector = require('./vector');

var Empty = function() {
    this.type = 'empty';
    this.tl_pher = null;
    this.br_pher = null;
};

var Wall = function(strength) {
    this.type = 'wall';
    this.strength = strength;
};

var Sugar = function(amount) {
    this.type = 'sugar';
    this.amount = amount;
};

var Home = function(team) {
    this.type = 'home';
    this.team = team;
    this.stored = 0;
};

var Ant = function(team, position, world) {
    this.world = world;
    this.team = team;
    this.position = position; // vector
    this.hasFood = false;
    this.isTrampled = false;
    this.direction = "left"; // chosen from "right", "up", "down"

    /* direction is a unit vector */
    this.move = function(direct) {
        var new_x, new_y, new_obj;

        if(direct === 'up') {
            new_x = this.position.x;
            new_y = this.position.y - 1;
        } else if(direct === 'down') {
            new_x = this.position.x;
            new_y = this.position.y + 1;
        } else if(direct === 'left') {
            new_x = this.position.x - 1;
            new_y = this.position.y;p
        } else if(direct === 'right') {
            new_x = this.position.x + 1;
            new_y = this.position.y;
        } else {
            console.log("ERROR: Ant.move() dosn't understand direct: " + direct);
            return false;
        }

        this.direction = direct;

        /* Bounds Checking */
        if(new_x >= world.map.width || new_x < 0
           || new_y >= world.map.height || new_y < 0) {
            return false;
        }

        new_obj = this.world.map.map[new_y][new_x];

        if(new_obj.type === 'empty' || new_obj.type === 'sugar') {
            this.position.x = new_x;
            this.position.y = new_y;

            if(new_obj.type == 'sugar' && this.hasFood === false){
                new_obj.amount--;
                this.hasFood = true;

                if(new_obj.amount === 0) {
                    world.map.map[new_y][new_x] = new Empty();
                }
            }
        } else {
            return false;
        }

        return true;
    };

    this.dig = function(direction) {
        var wall_x, wall_y, new_obj;
        if(direction === 'up') {
            wall_x = this.position.x;
            wall_y = this.position.y - 1;
        } else if(direction === 'down') {
            wall_x = this.position.x;
            wall_y = this.position.y + 1;
        } else if(direction === 'left') {
            wall_x = this.position.x - 1;
            wall_y = this.position.y;
        } else if(direction === 'right') {
            wall_x = this.position.x + 1;
            wall_y = this.position.y;
        } else {
            console.log("ERROR: Ant.dig() dosn't understand direction: " + direction);
            return false;
        }

        /* Bounds Checking */
        if(wall_x >= world.map.width || wall_x < 0
           || wall_y >= world.map.height || wall_y < 0) {
            return false;
        }

        new_obj = world.map.map[wall_y][wall_x];

        if(new_obj.type === 'wall') {
            new_obj.strength--;
        } else if(new_obj.type === 'home' && this.hasFood === true) {
            new_obj.stored++;
            this.hasFood = false;
        }

        if(new_obj.type === 'wall' && new_obj.strength === 0) {
            world.map.map[wall_y][wall_x] = new Empty();
            return true;
        }

        return false;
    };
};

function Map(width, height, sugars) {
    this.map = newMap(width, height, sugars);
    this.tl = new vector.Vec2(2, 2);
    this.br = new vector.Vec2(width-3, height-3);
    this.width = width;
    this.height = height;

    this.getTLSugar = function(team) {
        if(team === 'tl') {
            return map[2][2].stored;
        } else {
            return map[width-2][height-2].stored;
        }
    }

    this.setPherAt = function (team, position, value ) {
        var cell = this.map[position.y][position.x];

        if (!cell.type == 'empty') {
            return false;
        }

        if(team === 'br') {
            cell.br_pher = value;
            cell.br_pher_seed = Math.random();
        } else if(team === 'tl') {
            cell.tl_pher = value;
            cell.tl_pher_seed = Math.random();
        } else {
            console.log("Weird input to Map.setPher()!\n");
            return false;
        }
        return true;
    };

    this.pherAt = function (team, position) {
        var cell = this.map[position.y][position.x];

        if (!cell.type == 'empty') {
            return null;
        }

        if(team === 'br') {
            return cell.br_pher;
        } else if(team === 'tl') {
            return cell.tl_pher;
        } else {
            console.log("Weird input to Map.pherAt()!\n");
            return null;
        }
    };
}

function newMap(width, height, sugars) {
    var i, j, k, x, y;

    if(height < 10) {
        height = 10;
    }
    if(width < 10) {
        width = 10;
    }

    var map = [];
    for (y = 0; y < height; y++) {
        map[y] = [];
    }

    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {
            map[y][x] = new Wall(5);
        }
    }

    for(k = 0; k < sugars/2; k++) {
        x = Math.floor(Math.random() * width);
        y = Math.floor(Math.random() * height);

        for(i = -1; i < 2; i++){
            for(j = -1; j < 2; j++){
                if(x+j >= 0 && x+j < width && y+i >= 0 && y+i < height){
                    map[y+i][x+j] = new Empty();
                }
                if(height-y-1+i >= 0 && height-y-1+i < height
                  && width-x-1+j >= 0 && width-x-1+j < width){
                    map[height-y-1+i][width-x-1+j] = new Empty();
                }
            }
        }

        for(i = -2; i < 3; i++){
            for(j = -2; j < 3; j++){
                if(x+j >= 0 && x+j < width && y+i >= 0 && y+i < height){
                    if(Math.random() < 0.7) {
                        map[y+i][x+j] = new Empty();
                    }
                }
                if(height-y-1+i >= 0 && height-y-1+i < height
                  && width-x-1+j >= 0 && width-x-1+j < width){
                    if(Math.random() < 0.7) {
                        map[height-y-1+i][width-x-1+j] = new Empty();
                    }
                }
            }
        }

        map[y][x] = new Sugar(20);
        map[height-y-1][width-x-1] = new Sugar(20);
    }

    for(i = 0; i < 5; i++) {
        for(j = 0; j < 5; j++) {
            map[i][j] = new Empty();
            map[height-i-1][width-j-1] = new Empty();
        }
    }

    map[2][2] = new Home("tl");
    map[height-3][width-3] = new Home("br");

    return map;
};

module.exports = {
    Empty: Empty,
    Wall: Wall,
    Sugar: Sugar,
    Home: Home,
    Ant: Ant,
    Map: Map
};
<|endoftext|>


<commit_before>'use strict'

const config = require('./config')
const bxservice = require('./bxservice')
const cmkservice = require('./cmkservice')
const bfnservice = require('./bfnservice')
const httpservice = require('./httpservice')
const ms_generator = require('./message_generator')

const LINENotifyToken_CryptoLover = process.env.LINENotifyToken_CryptoLover
const LINENotifyToken_OMSLover = process.env.LINENotifyToken_OMSLover
const LINENotifyToken_CryptoMoneyClub = process.env.LINENotifyToken_CryptoMoneyClub
const LINENotifyToken_CryptoInvester = process.env.LINENotifyToken_CryptoInvester
const LINENotifyToken_SunnDokk = process.env.LINENotifyToken_SunnDokk

const headers = {
  'User-Agent': 'AzukiChan/0.0.1',
  'Content-Type': 'application/x-www-form-urlencoded'
}

module.exports = {
  async publish () {
    try {
      const cmkdata = await cmkservice.getCoinPrice()
      const bxdata = await bxservice.getCoinPrice()
      const bfndata = await bfnservice.getCoinPrice()
      this.publishToCryptoMoneyClub(bxdata, cmkdata, bfndata)
      this.publishToOMSLover(bxdata, cmkdata)
      this.publishToCryptoLover(bxdata, cmkdata)
      this.publishToCryptoInvester(bxdata, cmkdata, bfndata)
      this.publishToSunnDokkWahh(bxdata, cmkdata, bfndata)

    } catch (err) {
      console.log(err)
    }
  },

  async publishToCryptoMoneyClub (bxdata, cmkdata, bfndata) {
    let message = ms_generator.cryptoMoneyClubMessage(bxdata, cmkdata, bfndata)
    const options = {
      'url': config.LINE_NOTIFY_API_ENDPOINT,
      'headers': headers,
      'auth': {
        'bearer': LINENotifyToken_CryptoMoneyClub
      },
      'form': {
        'message': message
      }
    }

    try {
      await httpservice.post(options)
    } catch (err) {
      console.log(err)
    }
  },

  async publishToOMSLover (bxdata, cmkdata) {
    let message = ms_generator.omsLoverMessage(bxdata, cmkdata)

    const options = {
      'url': config.LINE_NOTIFY_API_ENDPOINT,
      'headers': headers,
      'auth': {
        'bearer': LINENotifyToken_OMSLover
      },
      'form': {
        'message': message
      }
    }

    try {
      await httpservice.post(options)
    } catch (err) {
      console.log(err)
    }
  },

  async publishToCryptoLover (bxdata, cmkdata) {
    let message = ms_generator.cryptoLoverMessage(bxdata, cmkdata)

    const options = {
      'url': config.LINE_NOTIFY_API_ENDPOINT,
      'headers': headers,
      'auth': {
        'bearer': LINENotifyToken_CryptoLover
      },
      'form': {
        'message': message
      }
    }

    try {
      await httpservice.post(options)
    } catch (err) {
      console.log(err)
    }
  },

  async publishToCryptoInvester (bxdata, cmkdata, bfndata) {
    let message = ms_generator.cryptoInvesterMessage(bxdata, cmkdata, bfndata)

    const options = {
      'url': config.LINE_NOTIFY_API_ENDPOINT,
      'headers': headers,
      'auth': {
        'bearer': LINENotifyToken_CryptoInvester
      },
      'form': {
        'message': message
      }
    }

    try {
      await httpservice.post(options)
    } catch (err) {
      console.log(err)
    }
  },

  async publishToSunnDokkWahh (bxdata, cmkdata, bfndata) {
    let message = ms_generator.sunnDokkMessage(bxdata, cmkdata, bfndata)

    const options = {
      'url': config.LINE_NOTIFY_API_ENDPOINT,
      'headers': headers,
      'auth': {
        'bearer': LINENotifyToken_SunnDokk
      },
      'form': {
        'message': message
      }
    }

    try {
      await httpservice.post(options)
    } catch (err) {
      console.log(err)
    }
  }
}
<commit_msg>Unpublished some group<commit_after>'use strict'

const config = require('./config')
const bxservice = require('./bxservice')
const cmkservice = require('./cmkservice')
const bfnservice = require('./bfnservice')
const httpservice = require('./httpservice')
const ms_generator = require('./message_generator')

const LINENotifyToken_CryptoLover = process.env.LINENotifyToken_CryptoLover
const LINENotifyToken_OMSLover = process.env.LINENotifyToken_OMSLover
const LINENotifyToken_CryptoMoneyClub = process.env.LINENotifyToken_CryptoMoneyClub
const LINENotifyToken_CryptoInvester = process.env.LINENotifyToken_CryptoInvester
const LINENotifyToken_SunnDokk = process.env.LINENotifyToken_SunnDokk

const headers = {
  'User-Agent': 'AzukiChan/0.0.1',
  'Content-Type': 'application/x-www-form-urlencoded'
}

module.exports = {
  async publish () {
    try {
      const cmkdata = await cmkservice.getCoinPrice()
      const bxdata = await bxservice.getCoinPrice()
      const bfndata = await bfnservice.getCoinPrice()
      // this.publishToCryptoMoneyClub(bxdata, cmkdata, bfndata)
      this.publishToOMSLover(bxdata, cmkdata)
      this.publishToCryptoLover(bxdata, cmkdata)
      // this.publishToCryptoInvester(bxdata, cmkdata, bfndata)
      this.publishToSunnDokkWahh(bxdata, cmkdata, bfndata)

    } catch (err) {
      console.log(err)
    }
  },

  async publishToCryptoMoneyClub (bxdata, cmkdata, bfndata) {
    let message = ms_generator.cryptoMoneyClubMessage(bxdata, cmkdata, bfndata)
    const options = {
      'url': config.LINE_NOTIFY_API_ENDPOINT,
      'headers': headers,
      'auth': {
        'bearer': LINENotifyToken_CryptoMoneyClub
      },
      'form': {
        'message': message
      }
    }

    try {
      await httpservice.post(options)
    } catch (err) {
      console.log(err)
    }
  },

  async publishToOMSLover (bxdata, cmkdata) {
    let message = ms_generator.omsLoverMessage(bxdata, cmkdata)

    const options = {
      'url': config.LINE_NOTIFY_API_ENDPOINT,
      'headers': headers,
      'auth': {
        'bearer': LINENotifyToken_OMSLover
      },
      'form': {
        'message': message
      }
    }

    try {
      await httpservice.post(options)
    } catch (err) {
      console.log(err)
    }
  },

  async publishToCryptoLover (bxdata, cmkdata) {
    let message = ms_generator.cryptoLoverMessage(bxdata, cmkdata)

    const options = {
      'url': config.LINE_NOTIFY_API_ENDPOINT,
      'headers': headers,
      'auth': {
        'bearer': LINENotifyToken_CryptoLover
      },
      'form': {
        'message': message
      }
    }

    try {
      await httpservice.post(options)
    } catch (err) {
      console.log(err)
    }
  },

  async publishToCryptoInvester (bxdata, cmkdata, bfndata) {
    let message = ms_generator.cryptoInvesterMessage(bxdata, cmkdata, bfndata)

    const options = {
      'url': config.LINE_NOTIFY_API_ENDPOINT,
      'headers': headers,
      'auth': {
        'bearer': LINENotifyToken_CryptoInvester
      },
      'form': {
        'message': message
      }
    }

    try {
      await httpservice.post(options)
    } catch (err) {
      console.log(err)
    }
  },

  async publishToSunnDokkWahh (bxdata, cmkdata, bfndata) {
    let message = ms_generator.sunnDokkMessage(bxdata, cmkdata, bfndata)

    const options = {
      'url': config.LINE_NOTIFY_API_ENDPOINT,
      'headers': headers,
      'auth': {
        'bearer': LINENotifyToken_SunnDokk
      },
      'form': {
        'message': message
      }
    }

    try {
      await httpservice.post(options)
    } catch (err) {
      console.log(err)
    }
  }
}
<|endoftext|>


<commit_before>import update from 'immutability-helper';
import { createAction } from 'redux-actions';
import map from 'lodash/map';

export const EXECUTE_IMPORT = 'executeImportAction';

export function importItems (newItem, level, itemParent) {
  return function (dispatch, getState) {
    dispatch(executeImport(newItem, level, itemParent, getState()));
  };
}

export function executeImport (newItem, level, itemParent, currentState) {
  let importPhases = JSON.parse(JSON.stringify(currentState.selectedTOS.phases));
  let importActions = JSON.parse(JSON.stringify(currentState.selectedTOS.actions));
  let importRecords = JSON.parse(JSON.stringify(currentState.selectedTOS.records));

  switch (level) {
    case 'phase':
      let phaseIndexes = [];
      for (const key in importPhases) {
        if (importPhases.hasOwnProperty(key)) {
          phaseIndexes.push(importPhases[key].index);
        }
      }
      const newPhaseId = Math.random().toString(36).replace(/[^a-z]+/g, '');

      const newActions = {};
      const newRecords = {};
      if (importPhases[newItem].actions) {
        for (const childAction of importPhases[newItem].actions) {
          const newActionId = Math.random().toString(36).replace(/[^a-z]+/g, '');
          const newActionRecords = [];

          if (importActions[childAction].records) {
            for (const childRecord of importActions[childAction].records) {
              const newRecordId = Math.random().toString(36).replace(/[^a-z]+/g, '');
              const newRecord = Object.assign({}, importRecords[childRecord], { id: newRecordId }, { action: newActionId });
              newActionRecords.push(newRecordId);
              newRecords[newRecordId] = newRecord;
            }
          }

          const newAction = Object.assign({}, importActions[childAction], { id: newActionId }, { phase: newPhaseId }, { records: newActionRecords });
          newActions[newActionId] = newAction;
        }
      }
      const newPhaseIndex = phaseIndexes.length > 0 ? Math.max.apply(null, phaseIndexes) + 1 : 1;
      const newPhaseName = (importPhases[newItem].name || '') + ' (KOPIO)';
      const newPhase = Object.assign({}, importPhases[newItem], { id: newPhaseId }, { index: newPhaseIndex }, { name: newPhaseName }, { actions: map(newActions, (newAction) => newAction.id) }, { attributes: { TypeSpecifier: newPhaseName } });

      importPhases[newPhaseId] = newPhase;
      importActions = Object.assign({}, importActions, newActions);
      importRecords = Object.assign({}, importRecords, newRecords);
      break;
    case 'action':
      break;
    case 'record':
      break;
    default:
      return currentState;
  }

  return createAction(EXECUTE_IMPORT)({ level, importPhases, importActions, importRecords });
}

export const executeImportAction = (state, { payload }) => {
  return update(state, {
    phases: {
      $set: payload.importPhases
    },
    actions: {
      $set: payload.importActions
    },
    records: {
      $set: payload.importRecords
    }
  });
};
<commit_msg>Clean up<commit_after>import update from 'immutability-helper';
import { createAction } from 'redux-actions';
import map from 'lodash/map';

export const EXECUTE_IMPORT = 'executeImportAction';

export function importItems (newItem, level, itemParent) {
  return function (dispatch, getState) {
    dispatch(executeImport(newItem, level, itemParent, getState()));
  };
}

export function executeImport (newItem, level, itemParent, currentState) {
  let importPhases = JSON.parse(JSON.stringify(currentState.selectedTOS.phases));
  let importActions = JSON.parse(JSON.stringify(currentState.selectedTOS.actions));
  let importRecords = JSON.parse(JSON.stringify(currentState.selectedTOS.records));
  const newActions = {};
  const newRecords = {};

  switch (level) {
    case 'phase':
      let phaseIndexes = [];
      for (const key in importPhases) {
        if (importPhases.hasOwnProperty(key)) {
          phaseIndexes.push(importPhases[key].index);
        }
      }
      const newPhaseId = Math.random().toString(36).replace(/[^a-z]+/g, '');

      if (importPhases[newItem].actions) {
        for (const childAction of importPhases[newItem].actions) {
          const newActionId = Math.random().toString(36).replace(/[^a-z]+/g, '');
          const newActionRecords = [];

          if (importActions[childAction].records) {
            for (const childRecord of importActions[childAction].records) {
              const newRecordId = Math.random().toString(36).replace(/[^a-z]+/g, '');
              const newRecord = Object.assign({}, importRecords[childRecord], { id: newRecordId }, { action: newActionId });
              newActionRecords.push(newRecordId);
              newRecords[newRecordId] = newRecord;
            }
          }

          const newAction = Object.assign({}, importActions[childAction], { id: newActionId }, { phase: newPhaseId }, { records: newActionRecords });
          newActions[newActionId] = newAction;
        }
      }
      const newPhaseIndex = phaseIndexes.length > 0 ? Math.max.apply(null, phaseIndexes) + 1 : 1;
      const newPhaseName = (importPhases[newItem].name || '') + ' (KOPIO)';
      const newPhase = Object.assign({}, importPhases[newItem], { id: newPhaseId }, { index: newPhaseIndex }, { name: newPhaseName }, { actions: map(newActions, (newAction) => newAction.id) }, { attributes: { TypeSpecifier: newPhaseName } });

      importPhases[newPhaseId] = newPhase;
      importActions = Object.assign({}, importActions, newActions);
      importRecords = Object.assign({}, importRecords, newRecords);
      break;
    case 'action':
      break;
    case 'record':
      break;
    default:
      break;
  }

  return createAction(EXECUTE_IMPORT)({ importPhases, importActions, importRecords });
}

export const executeImportAction = (state, { payload }) => {
  return update(state, {
    phases: {
      $set: payload.importPhases
    },
    actions: {
      $set: payload.importActions
    },
    records: {
      $set: payload.importRecords
    }
  });
};
<|endoftext|>


<commit_before>define(
  ['apres', 'jquery'],
  function(apres, $) {
    var SauceConfigWidget = function(elem, params) {
      var params = apres.controller().params;

      function message(message, classes) {
        elem.find("div.alert").removeClass().addClass("alert " + classes).html(message).show();
      }

      function message_hide() {
        elem.find("div.alert").hide();
      }

      function load(url) {
        elem.find('.details').addClass('hide');
        elem.find('.alert').removeClass().addClass("alert alert-info").html("Loading ...");
        $.ajax({
          url: "/api/sauce",
          type: "GET",
          data: {url: url},
          dataType: "json",
          success: function (data, ts, xhr) {
            setBrowsers(data.results.sauce_browsers);
            elem.find('.sauce-username').val(data.results.sauce_username);
            elem.find('.sauce-access-key').val(data.results.sauce_access_key);
            elem.find('.details').show();
            message_hide();
          },
          error: function(xhr, ts, e) {
            if (xhr && xhr.responseText) {
                var data = $.parseJSON(xhr.responseText);
                message("Error loading Sauce config: " + data.errors[0], "alert-error");
            } else {
                message("Error loading Sauce config: " + e, "alert-error");
            }
          }

        });
      }

      function getBrowsers() {
        var checked = elem.find("input:checked");
        var sauceBrowsers = [];
        for (var i = 0; i < checked.length; i++) {
          var str = $(checked[i]).val();
          var parts = str.split('-');
          var platform = parts[0];
          var browser = parts[1];
          var browserVerson = parts[2] || '';
          sauceBrowsers.push({
            platform: platform,
            browserName: browser,
            version: browserVerson
          });
        }
        return sauceBrowsers;
      }

      function setBrowsers(sauceBrowsers) {
        for (var i = 0; i < sauceBrowsers.length; i++) {
          var o = sauceBrowsers[i];
          var searchValue = o.platform + "-" + o.browserName + "-" + o.version;
          elem.find("input[value='"+searchValue+"']").attr('checked', 'checked');
        }

      }

      this.events = {
        "click #sauce-save": function() {
          var sauce_browsers = getBrowsers();
          var sauce_username = elem.find(".sauce-username").val();
          var sauce_access_key = elem.find(".sauce-access-key").val();
          $.ajax("/api/sauce", {
                data: {
                  url:params.repo_url,
                  sauce_username:sauce_username,
                  sauce_access_key:sauce_access_key,
                  sauce_browsers: JSON.stringify(sauce_browsers)
                },
                error: function(xhr, ts, e) {
                  console.log(e);
                  message("Error saving sauce credentials.", "alert-error");
                },
                success: function(data, ts, xhr) {
                  message("Sauce credentials saved.", "alert-success");
                },
                type: "POST",
          });
        },
      };
      // There is a global "repo" object which is generated by the server
      var repo_url = apres.controller().params.repo_url;
      load(repo_url);

    };

    return SauceConfigWidget;
  }
);
<commit_msg>handle missing browsers<commit_after>define(
  ['apres', 'jquery'],
  function(apres, $) {
    var SauceConfigWidget = function(elem, params) {
      var params = apres.controller().params;

      function message(message, classes) {
        elem.find("div.alert").removeClass().addClass("alert " + classes).html(message).show();
      }

      function message_hide() {
        elem.find("div.alert").hide();
      }

      function load(url) {
        elem.find('.details').addClass('hide');
        elem.find('.alert').removeClass().addClass("alert alert-info").html("Loading ...");
        $.ajax({
          url: "/api/sauce",
          type: "GET",
          data: {url: url},
          dataType: "json",
          success: function (data, ts, xhr) {
            var browsers = data.results.sauce_browsers || [];
            setBrowsers(browsers);
            elem.find('.sauce-username').val(data.results.sauce_username);
            elem.find('.sauce-access-key').val(data.results.sauce_access_key);
            elem.find('.details').show();
            message_hide();
          },
          error: function(xhr, ts, e) {
            if (xhr && xhr.responseText) {
                var data = $.parseJSON(xhr.responseText);
                message("Error loading Sauce config: " + data.errors[0], "alert-error");
            } else {
                message("Error loading Sauce config: " + e, "alert-error");
            }
          }

        });
      }

      function getBrowsers() {
        var checked = elem.find("input:checked");
        var sauceBrowsers = [];
        for (var i = 0; i < checked.length; i++) {
          var str = $(checked[i]).val();
          var parts = str.split('-');
          var platform = parts[0];
          var browser = parts[1];
          var browserVerson = parts[2] || '';
          sauceBrowsers.push({
            platform: platform,
            browserName: browser,
            version: browserVerson
          });
        }
        return sauceBrowsers;
      }

      function setBrowsers(sauceBrowsers) {
        for (var i = 0; i < sauceBrowsers.length; i++) {
          var o = sauceBrowsers[i];
          var searchValue = o.platform + "-" + o.browserName + "-" + o.version;
          elem.find("input[value='"+searchValue+"']").attr('checked', 'checked');
        }

      }

      this.events = {
        "click #sauce-save": function() {
          var sauce_browsers = getBrowsers();
          var sauce_username = elem.find(".sauce-username").val();
          var sauce_access_key = elem.find(".sauce-access-key").val();
          $.ajax("/api/sauce", {
                data: {
                  url:params.repo_url,
                  sauce_username:sauce_username,
                  sauce_access_key:sauce_access_key,
                  sauce_browsers: JSON.stringify(sauce_browsers)
                },
                error: function(xhr, ts, e) {
                  console.log(e);
                  message("Error saving sauce credentials.", "alert-error");
                },
                success: function(data, ts, xhr) {
                  message("Sauce credentials saved.", "alert-success");
                },
                type: "POST",
          });
        },
      };
      // There is a global "repo" object which is generated by the server
      var repo_url = apres.controller().params.repo_url;
      load(repo_url);

    };

    return SauceConfigWidget;
  }
);
<|endoftext|>