<commit_before>//CEW

//isCalled toggles on and off with call of returnValues
var isCalled = false;

//CodeMirror Editor in textarea
var editor;

//Bool to determine if all questions have answers
var isCompleted;

//Stores answers, initialized to number of questions on test
var answers;

var numQuest;

function returnValues(val)
{
  //val - value of dropdown menu containing languages
  //result - updates textarea to be language specific
  var languageArgs;

  languageArgs = {
    lineNumbers: true,
    matchBrackets: true
  }

  //Assigns arguments to the language object.
  if (!isCalled)
  {
    if (val == "Python")
    {
      languageArgs["name"] = "python";
      languageArgs["version"] = 3;
      languageArgs["indentUnit"] = 4;
    }
    else if (val == "Java")
    {
      languageArgs["mode"] = "text/x-java";
    }
    else if (val == "C")
    {
      languageArgs["mode"] = "text/x-csrc";
    }
    else if (val == "C++")
    {
      languageArgs["mode"] = "text/x-c++src";
    }

    this.editor = CodeMirror.fromTextArea(
      document.getElementById('codingArea'),
      languageArgs);
    isCalled = true;
    //If the option is changed, deletes codemirror and initializes a new one
    //This took 1.5 hours to figure out. I nearly cried.
  }   else {

    this.editor.toTextArea();

    isCalled=false;

    returnValues(val);

  }

  return;
}
//CEW
//Originally stores first button, then changes as buttons are clicked.
var prevButt = document.getElementById("currentQuest");
//Index of Question. Used to reference into answers
var indexQuest;

//Makes a string variable because CodeMirror be trippin
var newText;

//Changes style of button
//TODO: Update textarea and store info.
function changeButtClass(that){

  prevButt =  document.getElementById("currentQuest");
  prevButt.removeAttribute("id");

  indexQuest = prevButt.textContent -1;

  //Saves answer to answers
  answers[indexQuest] = editor.getValue();

  //Updates current editor text
  editor.setValue(answers[that.textContent-1]);

  //Changes prevbutt color depending on whether or not text is in the textarea
  if (answers[prevButt.textContent-1] == ""){

    prevButt.setAttribute("class","btn btn-default");

  } else{

    prevButt.setAttribute("class","btn btn-default btn-warning");

  }

  //Updates look and id of buttons.
  that.setAttribute("class", "btn btn-default btn-success");
  that.setAttribute("id", "currentQuest");

}

//CEW
function submitSubmission(){
  //Updates last answer
  answers[document.getElementById("currentQuest").textContent-1] = editor.getValue();

  isCompleted = true;

  //result - Gets metadata and puts it into a JSON
  for (var i =0; i<answers.length;i++){
    if (answers[i] == ""){
      isCompleted = false;
    }
  }
  if (!isCompleted){
    if (!confirm("You have not completed all problems. Are you sure that you want to submit?")){
      return;
    }
  }
  var submitData;
  submitData = {
    //language: document.getElementById('languageSelect').value,
    time: Date(),
    problem: "1.1",
    submissions: answers
  };

}

//CEW
//Initializes editor to Python and makes all answers  = ""
function initialPython(){
  var urlDef = "/cgi-bin/CSAssess/controller/request.py";
  var token = getCookie("token");
  var dataDef = {"requestType":"getAssessment",
                  "session": token,
                  "name": "t0",
                  "user": "",
                  "section": "",
                  "course": "",
                  "question": 1
                 };
  var dataTypeDef = "json";
  //Gets assessment
  $.post(urlDef, dataDef, makeTheTestPage, dataTypeDef);

  numQuests = 5;
  answers = new Array(numQuests);

  createProgress();
  for (var i = 0; i<answers.length;i++){
    answers[i] = "";
  }
  languageArgs = {
    lineNumbers: true,
    matchBrackets: true,
    indentUnit: 4,
    version: 3,
    name: "Python"
  };
  this.editor = CodeMirror.fromTextArea(
      document.getElementById('codingArea'),
      languageArgs);
   isCalled = true;
}

//CEW
//creates the progress buttons
function createProgress(){
  for (var i=0;i<numQuests;i++){
    var btn = document.createElement("BUTTON");
    var questNum = document.createTextNode(i+1);
    if (i==0){
      btn.setAttribute("class","btn btn-default btn-success");
      btn.setAttribute("id","currentQuest");
    }else{
      btn.setAttribute("class","btn btn-default");
    }
    btn.setAttribute("onclick","changeButtClass(this)");
    btn.appendChild(questNum);
    document.getElementById("progress").appendChild(btn);
  }
}

//CEW
 function makeTheTestPage(data){
  console.log(data["assessmentList"]);
  console.log(data["session"]);
  console.log("WE MADE IT");
 }
<commit_msg>Comments<commit_after>//CEW

//isCalled toggles on and off with call of returnValues
var isCalled = false;

//CodeMirror Editor in textarea
var editor;

//Bool to determine if all questions have answers
var isCompleted;

//Stores answers, initialized to number of questions on test
var answers;

//Stores number question in assessment
var numQuest;

function returnValues(val)
{
  //val - value of dropdown menu containing languages
  //result - updates textarea to be language specific

  //Basic json of default editor
  var languageArgs;

  languageArgs = {
    lineNumbers: true,
    matchBrackets: true
  }

  //Assigns arguments to the language object depending on val
  if (!isCalled)
  {
    if (val == "Python")
    {
      languageArgs["name"] = "python";
      languageArgs["version"] = 3;
      languageArgs["indentUnit"] = 4;
    }
    else if (val == "Java")
    {
      languageArgs["mode"] = "text/x-java";
    }
    else if (val == "C")
    {
      languageArgs["mode"] = "text/x-csrc";
    }
    else if (val == "C++")
    {
      languageArgs["mode"] = "text/x-c++src";
    }

     //Creates a CodeMirror editor in place of TextArea
    this.editor = CodeMirror.fromTextArea(
      document.getElementById('codingArea'),
      languageArgs);

    //Toggles isCalled
    isCalled = true;

    //If the option is changed, deletes CodeMirror and calls this function again to initialize a new one
    //This took 1.5 hours to figure out. I nearly cried.
  }   else {

    this.editor.toTextArea();
    isCalled=false;
    returnValues(val);

  }

  return;
}

//CEW
//Originally stores first button, then changes as buttons are clicked.
//This is used to update the previous button after it is deactivated
var prevButt = document.getElementById("currentQuest");

//Index of Question. Used to reference into answers
var indexQuest;

//Makes a string variable because CodeMirror be trippin
var newText;

//Changes style of button to reflect state of code in question
//Orange: Code in question
//Green: Current Question
//Gray: No code in question
function changeButtClass(that){

  //Stores previous button and deletes its id to avoid conflicts
  prevButt =  document.getElementById("currentQuest");
  prevButt.removeAttribute("id");

  //Takes content of button and decrements 1 so it can assess answers
  indexQuest = prevButt.textContent -1;

  //Saves answer in textarea to answers
  answers[indexQuest] = editor.getValue();

  //Updates current editor text to answer of current question
  editor.setValue(answers[that.textContent-1]);

  //Changes prevbutt color depending on whether or not text is in the textarea
  if (answers[prevButt.textContent-1] == ""){

    prevButt.setAttribute("class","btn btn-default");

  } else{

    prevButt.setAttribute("class","btn btn-default btn-warning");

  }

  //Updates look and id of buttons.
  that.setAttribute("class", "btn btn-default btn-success");
  that.setAttribute("id", "currentQuest");

}

//CEW
//submits data to database
//TODO: Submit data to database
function submitSubmission(){

  //result - Gets metadata and puts it into a JSON

  //Updates last answer so it is in answers
  answers[document.getElementById("currentQuest").textContent-1] = editor.getValue();

  isCompleted = true;

  for (var i =0; i<answers.length;i++){
    if (answers[i] == ""){
      isCompleted = false;
    }
  }
  if (!isCompleted){
    if (!confirm("You have not completed all problems. Are you sure that you want to submit?")){
      return;
    }
  }
  var submitData;
  submitData = {
    //language: document.getElementById('languageSelect').value,
    time: Date(),
    problem: "1.1",
    submissions: answers
  };

}

//CEW
//Initializes editor to Python and makes all answers  = ""
function initialPython(){
  var urlDef = "/cgi-bin/CSAssess/controller/request.py";
  var token = getCookie("token");
  var dataDef = {"requestType":"getAssessment",
                  "session": token,
                  "name": "t0",
                  "user": "",
                  "section": "",
                  "course": "",
                  "question": 1
                 };
  var dataTypeDef = "json";
  //Gets assessment
  $.post(urlDef, dataDef, makeTheTestPage, dataTypeDef);

  numQuests = 5;
  answers = new Array(numQuests);

  createProgress();
  for (var i = 0; i<answers.length;i++){
    answers[i] = "";
  }
  languageArgs = {
    lineNumbers: true,
    matchBrackets: true,
    indentUnit: 4,
    version: 3,
    name: "Python"
  };
  this.editor = CodeMirror.fromTextArea(
      document.getElementById('codingArea'),
      languageArgs);
   isCalled = true;
}

//CEW
//creates the progress buttons
function createProgress(){
  for (var i=0;i<numQuests;i++){
    var btn = document.createElement("BUTTON");
    var questNum = document.createTextNode(i+1);
    if (i==0){
      btn.setAttribute("class","btn btn-default btn-success");
      btn.setAttribute("id","currentQuest");
    }else{
      btn.setAttribute("class","btn btn-default");
    }
    btn.setAttribute("onclick","changeButtClass(this)");
    btn.appendChild(questNum);
    document.getElementById("progress").appendChild(btn);
  }
}

//CEW
 function makeTheTestPage(data){
  console.log(data["assessmentList"]);
  console.log(data["session"]);
  console.log("WE MADE IT");
 }
<|endoftext|>


<commit_before>import {omitBy, isUndefined} from 'lodash'
import arrify from 'arrify'
import {createFallbackPrepare} from './fallbackPrepare'

const TITLE_CANDIDATES = ['title', 'name', 'label', 'heading', 'header', 'caption']
const DESCRIPTION_CANDIDATES = ['description', ...TITLE_CANDIDATES]

function fieldHasReferenceTo(fieldDef, refType) {
  return arrify(fieldDef.to || []).some(memberTypeDef => memberTypeDef.type === refType)
}

function isImageAssetField(fieldDef) {
  return fieldHasReferenceTo(fieldDef, 'imageAsset')
}

function resolveImageAssetPath(typeDef) {
  const fields = typeDef.fields || []
  const imageAssetField = fields.find(isImageAssetField)
  if (imageAssetField) {
    return imageAssetField.name
  }
  const fieldWithImageAsset = fields.find(fieldDef => (fieldDef.fields || []).some(isImageAssetField))
  if (fieldWithImageAsset) {
    return `${fieldWithImageAsset.name}.asset`
  }
}

function isFileAssetField(fieldDef) {
  return fieldHasReferenceTo(fieldDef, 'fileAsset')
}

function resolveFileAssetPath(typeDef) {
  const fields = typeDef.fields || []
  const assetField = fields.find(isFileAssetField)
  if (assetField) {
    return assetField.name
  }
  const fieldWithFileAsset = fields.find(fieldDef => (fieldDef.fields || []).some(isFileAssetField))
  if (fieldWithFileAsset) {
    return `${fieldWithFileAsset.name}.asset`
  }
}

export default function guessPreviewFields(objectTypeDef) {

  const stringFieldNames = objectTypeDef.fields
    .filter(field => field.type === 'string')
    .map(field => field.name)

  // Check if we have fields with names that is listed in candidate fields
  let titleField = TITLE_CANDIDATES
    .find(candidate => stringFieldNames.includes(candidate))

  let descField = DESCRIPTION_CANDIDATES
    .find(candidate => candidate !== titleField && stringFieldNames.includes(candidate))

  if (!titleField) {
    // Pick first defined string field
    titleField = stringFieldNames[0]
    // Pick next as desc
    descField = stringFieldNames[1]
  }

  const imageAssetPath = resolveImageAssetPath(objectTypeDef)

  if (!titleField) {
    const fileAssetPath = resolveFileAssetPath(objectTypeDef)
    if (fileAssetPath) {
      titleField = `${fileAssetPath}.originalFilename`
    }
  }

  if (!titleField && !imageAssetPath) {
    // last resort, pick all fields and concat them
    const fieldNames = objectTypeDef.fields.map(field => field.name)
    const fieldMapping = fieldNames.reduce((acc, fieldName) => {
      acc[fieldName] = fieldName
      return acc
    }, {})

    return {
      select: fieldMapping,
      prepare: createFallbackPrepare(fieldNames)
    }
  }

  const select = omitBy({
    title: titleField,
    description: descField,
    imageUrl: imageAssetPath ? `${imageAssetPath}.url` : undefined
  }, isUndefined)

  return {
    select: select
  }

}
<commit_msg>[schema] Fix lint errors<commit_after>import {omitBy, isUndefined} from 'lodash'
import arrify from 'arrify'
import {createFallbackPrepare} from './fallbackPrepare'

const TITLE_CANDIDATES = ['title', 'name', 'label', 'heading', 'header', 'caption']
const DESCRIPTION_CANDIDATES = ['description', ...TITLE_CANDIDATES]

function fieldHasReferenceTo(fieldDef, refType) {
  return arrify(fieldDef.to || []).some(memberTypeDef => memberTypeDef.type === refType)
}

function isImageAssetField(fieldDef) {
  return fieldHasReferenceTo(fieldDef, 'imageAsset')
}

function resolveImageAssetPath(typeDef) {
  const fields = typeDef.fields || []
  const imageAssetField = fields.find(isImageAssetField)
  if (imageAssetField) {
    return imageAssetField.name
  }
  const fieldWithImageAsset = fields.find(fieldDef => (fieldDef.fields || []).some(isImageAssetField))

  return fieldWithImageAsset ? `${fieldWithImageAsset.name}.asset` : undefined
}

function isFileAssetField(fieldDef) {
  return fieldHasReferenceTo(fieldDef, 'fileAsset')
}

function resolveFileAssetPath(typeDef) {
  const fields = typeDef.fields || []
  const assetField = fields.find(isFileAssetField)
  if (assetField) {
    return assetField.name
  }
  const fieldWithFileAsset = fields.find(fieldDef => (fieldDef.fields || []).some(isFileAssetField))
  return fieldWithFileAsset ? `${fieldWithFileAsset.name}.asset` : undefined
}

export default function guessPreviewFields(objectTypeDef) {

  const stringFieldNames = objectTypeDef.fields
    .filter(field => field.type === 'string')
    .map(field => field.name)

  // Check if we have fields with names that is listed in candidate fields
  let titleField = TITLE_CANDIDATES
    .find(candidate => stringFieldNames.includes(candidate))

  let descField = DESCRIPTION_CANDIDATES
    .find(candidate => candidate !== titleField && stringFieldNames.includes(candidate))

  if (!titleField) {
    // Pick first defined string field
    titleField = stringFieldNames[0]
    // Pick next as desc
    descField = stringFieldNames[1]
  }

  const imageAssetPath = resolveImageAssetPath(objectTypeDef)

  if (!titleField) {
    const fileAssetPath = resolveFileAssetPath(objectTypeDef)
    if (fileAssetPath) {
      titleField = `${fileAssetPath}.originalFilename`
    }
  }

  if (!titleField && !imageAssetPath) {
    // last resort, pick all fields and concat them
    const fieldNames = objectTypeDef.fields.map(field => field.name)
    const fieldMapping = fieldNames.reduce((acc, fieldName) => {
      acc[fieldName] = fieldName
      return acc
    }, {})

    return {
      select: fieldMapping,
      prepare: createFallbackPrepare(fieldNames)
    }
  }

  const select = omitBy({
    title: titleField,
    description: descField,
    imageUrl: imageAssetPath ? `${imageAssetPath}.url` : undefined
  }, isUndefined)

  return {
    select: select
  }

}
<|endoftext|>


<commit_before>const path = require("path");
const webpack = require('webpack');
const WebpackBrowserPlugin = require('webpack-browser-plugin');

module.exports = {
    entry: [
        'webpack-dev-server/client?http://0.0.0.0:8888', // WebpackDevServer host and port
        'webpack/hot/only-dev-server', // "only" prevents reload on syntax errors
        "./entry.js"
    ],
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: "bundle.js",
        publicPath: 'build'
    },
    // resolve 指定可以被 require 的文件后缀。比如 Hello.jsx 这样的文件就可以直接用 require(./Hello) 引用。
    resolve: {
        extensions: ['', '.js', '.jsx']
    },
    module: {
        loaders: [
            // css 文件需要加载的loader
            // npm install style-loader css-loader --save
            {
                test: /\.css$/,
                loader: "style!css"
            },
            // react 需要加载的loader
            // babel 在下面配置
            // npm install babel-preset-es2015 babel-preset-react --save
            {
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_components)/, //这两种文件不编译
                loaders: ['react-hot', 'babel']
            },

            // **IMPORTANT** This is needed so that each bootstrap js file required by
            // bootstrap-webpack has access to the jQuery object
            {
                test: /bootstrap\/js\//,
                loader: 'imports?jQuery=jquery'
            },

            // Needed for the css-loader when [bootstrap-webpack](https://github.com/bline/bootstrap-webpack)
            // loads bootstrap's css.
            {
                test: /\.(woff|woff2)$/,
                loader: "url-loader?limit=10000&mimetype=application/font-woff"
            }, {
                test: /\.ttf$/,
                loader: "file-loader"
            }, {
                test: /\.eot$/,
                loader: "file-loader"
            }, {
                test: /\.svg$/,
                loader: "file-loader"
            }

        ]
    },
    devServer: {
        contentBase: __dirname, // 当前服务目录
        port: 8888,
        inline: true,
        historyApiFallback: true,
        stats: {
            colors: true
        },
        hot: true
    },
    babel: {
        presets: ['react', 'es2015']
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new WebpackBrowserPlugin({
            browser: 'Chrome'
        })
    ]
};<commit_msg>增加devtool设置<commit_after>const path = require("path");
const webpack = require('webpack');
const WebpackBrowserPlugin = require('webpack-browser-plugin');

module.exports = {
    entry: [
        'webpack-dev-server/client?http://0.0.0.0:8888', // WebpackDevServer host and port
        'webpack/hot/only-dev-server', // "only" prevents reload on syntax errors
        "./entry.js"
    ],
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: "bundle.js",
        publicPath: 'build'
    },
    // resolve 指定可以被 require 的文件后缀。比如 Hello.jsx 这样的文件就可以直接用 require(./Hello) 引用。
    resolve: {
        extensions: ['', '.js', '.jsx']
    },
    module: {
        loaders: [
            // css 文件需要加载的loader
            // npm install style-loader css-loader --save
            {
                test: /\.css$/,
                loader: "style!css"
            },
            // react 需要加载的loader
            // babel 在下面配置
            // npm install babel-preset-es2015 babel-preset-react --save
            {
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_components)/, //这两种文件不编译
                loaders: ['react-hot', 'babel']
            },

            // **IMPORTANT** This is needed so that each bootstrap js file required by
            // bootstrap-webpack has access to the jQuery object
            {
                test: /bootstrap\/js\//,
                loader: 'imports?jQuery=jquery'
            },

            // Needed for the css-loader when [bootstrap-webpack](https://github.com/bline/bootstrap-webpack)
            // loads bootstrap's css.
            {
                test: /\.(woff|woff2)$/,
                loader: "url-loader?limit=10000&mimetype=application/font-woff"
            }, {
                test: /\.ttf$/,
                loader: "file-loader"
            }, {
                test: /\.eot$/,
                loader: "file-loader"
            }, {
                test: /\.svg$/,
                loader: "file-loader"
            }

        ]
    },
    // chrome引入了source-map文件，标识es5代码对应的转码前的es6代码
    devtool: 'source-map',
    devServer: {
        contentBase: __dirname, // 当前服务目录
        port: 8888,
        inline: true,
        historyApiFallback: true,
        stats: {
            colors: true
        },
        hot: true
    },
    babel: {
        presets: ['react', 'es2015']
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new WebpackBrowserPlugin({
            browser: 'Chrome'
        })
    ]
};<|endoftext|>


<commit_before>var _ = require('lodash');
var fs = require('fs');
var babyparse = require('babyparse');
// var JSONStream = require('JSONStream');
// var es = require('event-stream');

var getSimilarities = function(name) {
  return {
      'human-avg': require('./json/similarity-human.json'),
      'fc6':  require('./json/similarity-fc6-centroid.json'),
      'sketch_avg_full25k': require('./json/similarity-splitbyobject-sketch_average_full25k.json')
  };
};

var getCosts = function(name) {
  return require('./json/costs-' + name + '.json');
};

var getPossibleSketches = function(data) {
  return _.map(data, 'sketchLabel');
};

var getConditionLookup = function() {
  return require('../bdaInput/condition-lookup.json');
};

function _logsumexp(a) {
  var m = Math.max.apply(null, a);
  var sum = 0;
  for (var i = 0; i < a.length; ++i) {
    sum += (a[i] === -Infinity ? 0 : Math.exp(a[i] - m));
  }
  return m + Math.log(sum);
}

// P(target | sketch) = e^{scale * sim(t, s)} / (\sum_{i} e^{scale * sim(t, s)})
// => log(p) = scale * sim(target, sketch) - log(\sum_{i} e^{scale * sim(t, s)})
var getL0score = function(target, sketch, context, params, config) {
  var similarities = config.similarities[params.perception];
  var scores = [];
  for(var i=0; i<context.length; i++){
    var similarity = (similarities[context[i]][sketch]); // transform to range from 0 to 1
    scores.push(params.simScaling * similarity);
  }
  var similarity = (similarities[target][sketch]);
  return params.simScaling * similarity - _logsumexp(scores);
};

// Interpolates between the 'informativity' term of S0 and S1 based on pragWeight param
// Try remapping these to [0,1]...
var informativity = function(targetObj, sketch, context, params, config) {
  var sim = config.similarities[params.perception];
  var S0inf = (sim[targetObj][sketch]);// + 1.001) / 2;
   // console.log(S0inf);
  var S1inf = getL0score(targetObj, sketch, context, params, config); //Math.exp()
  // console.log(targetObj);
  // console.log(sketch);
  // console.log(S1inf);
  return ((1 - params.pragWeight) * S0inf + params.pragWeight * S1inf);
};

// note using logsumexp here isn't strictly necessary, because all the scores
// are *negative* (informativity is log(p of listener)) and there aren't
// enough terms for precision to matter...
var getSpeakerScore = function(trueSketch, targetObj, context, params, config) {
  var possibleSketches = config.possibleSketches;
  var costw = params.costWeight;
  var infw = params.infWeight;
  var scores = [];
  // note: could memoize this for moderate optimization...
  // (only needs to be computed once per context per param, not for every sketch)
  for(var i=0; i<possibleSketches.length; i++){
    var sketch = possibleSketches[i];
    var inf = informativity(targetObj, sketch, context, params, config);
    var cost = config.costs[sketch];
    if (isNaN(cost)) {
      console.log(targetObj,sketch,context);
      console.log(cost);
    }
    // console.log(cost);
    var utility = infw * inf - costw * cost; // independent informativity weight parameter
    scores.push( utility);//Math.log(Math.max(utility, Number.EPSILON)));
  }
  var trueUtility = (infw * informativity(targetObj, trueSketch, context, params, config)
		     - costw * config.costs[trueSketch]);
  //var roundedUtility = Math.max(trueUtility, Number.EPSILON);
  // console.log(_logsumexp(scores))
  //console.log(params.alpha * Math.log(roundedUtility))// - _logsumexp(scores));
  return  trueUtility - _logsumexp(scores); // softmax subtraction bc log space,
};

function readCSV(filename){
  return babyparse.parse(fs.readFileSync(filename, 'utf8'),
			 {header:true, skipEmptyLines:true}).data;
};

function writeCSV(jsonCSV, filename){
  fs.writeFileSync(filename, babyparse.unparse(jsonCSV) + '\n');
}

function appendCSV(jsonCSV, filename){
  fs.appendFileSync(filename, babyparse.unparse(jsonCSV) + '\n');
}

var paramSupportWriter = function(s, p, handle) {
  var sLst = _.toPairs(s);
  var l = sLst.length;
  for (var i = 0; i < l; i++) {
    fs.writeSync(handle, i + ',' + sLst[i].join(',')+','+p+'\n');
  }
};

var predictiveSupportWriter = function(s, filePrefix) {
  var dir = filePrefix.split('/').slice(0,3).join('/');
  if (!fs.existsSync(dir)){
      fs.mkdirSync(dir);
  }
  var predictiveFile = fs.openSync(filePrefix + "Predictives.csv", 'w');
  fs.writeSync(predictiveFile, ['index','game', "condition", 'trueSketch', "Target",
				"Distractor1", "Distractor2", "Distractor3",
				"coarseGrainedTrueSketch", "coarseGrainedPossibleSketch",
				"modelProb"] + '\n');

  var l = s.length;
  for (var i = 0; i < l; i++) {
    fs.writeSync(predictiveFile, s[i] + '\n');
  }

  fs.closeSync(predictiveFile);
};

// Note this is highly specific to a single type of erp
var bayesianErpWriter = function(erp, filePrefix) {
  var supp = erp.support();

  if(_.has(supp[0], 'params')) {
    var paramFile = fs.openSync(filePrefix + "Params.csv", 'w');
    fs.writeSync(paramFile, ["id", "perception", "pragmatics", "production",
			     "simScaling", "pragWeight","costWeight",
			     "logLikelihood", "posteriorProb"] + '\n');
  }

  supp.forEach(function(s) {
    if(_.has(s, 'params'))
      paramSupportWriter(s.params, erp.score(s), paramFile);
  });
  if(_.has(supp[0], 'params')) {
    fs.closeSync(paramFile);
  }
  console.log('writing complete.');
};

var getSubset = function(data, properties) {
  var matchProps = _.matches(properties);
  return _.filter(data, matchProps);
};

var locParse = function(filename) {
  return babyparse.parse(fs.readFileSync(filename, 'utf8'),
       {header: true,
        skipEmptyLines : true}).data;
};

module.exports = {
  getSimilarities, getPossibleSketches, getCosts, getSubset, getConditionLookup,
  predictiveSupportWriter,
  getL0score, getSpeakerScore,
  bayesianErpWriter, writeCSV, readCSV, locParse
};
<commit_msg>fix params indexing thing<commit_after>var _ = require('lodash');
var fs = require('fs');
var babyparse = require('babyparse');
// var JSONStream = require('JSONStream');
// var es = require('event-stream');

var getSimilarities = function(name) {
  return {
      'human-avg': require('./json/similarity-human.json'),
      'fc6':  require('./json/similarity-fc6-centroid.json'),
      'sketch_avg_full25k': require('./json/similarity-splitbyobject-sketch_average_full25k.json')
  };
};

var getCosts = function(name) {
  return require('./json/costs-' + name + '.json');
};

var getPossibleSketches = function(data) {
  return _.map(data, 'sketchLabel');
};

var getConditionLookup = function() {
  return require('../bdaInput/condition-lookup.json');
};

function _logsumexp(a) {
  var m = Math.max.apply(null, a);
  var sum = 0;
  for (var i = 0; i < a.length; ++i) {
    sum += (a[i] === -Infinity ? 0 : Math.exp(a[i] - m));
  }
  return m + Math.log(sum);
}

// P(target | sketch) = e^{scale * sim(t, s)} / (\sum_{i} e^{scale * sim(t, s)})
// => log(p) = scale * sim(target, sketch) - log(\sum_{i} e^{scale * sim(t, s)})
var getL0score = function(target, sketch, context, params, config) {
  var similarities = config.similarities[params.perception];
  var scores = [];
  for(var i=0; i<context.length; i++){
    var similarity = (similarities[context[i]][sketch]); // transform to range from 0 to 1
    scores.push(params.simScaling * similarity);
  }
  var similarity = (similarities[target][sketch]);
  return params.simScaling * similarity - _logsumexp(scores);
};

// Interpolates between the 'informativity' term of S0 and S1 based on pragWeight param
// Try remapping these to [0,1]...
var informativity = function(targetObj, sketch, context, params, config) {
  var sim = config.similarities[params.perception];
  var S0inf = (sim[targetObj][sketch]);// + 1.001) / 2;
   // console.log(S0inf);
  var S1inf = getL0score(targetObj, sketch, context, params, config); //Math.exp()
  // console.log(targetObj);
  // console.log(sketch);
  // console.log(S1inf);
  return ((1 - params.pragWeight) * S0inf + params.pragWeight * S1inf);
};

// note using logsumexp here isn't strictly necessary, because all the scores
// are *negative* (informativity is log(p of listener)) and there aren't
// enough terms for precision to matter...
var getSpeakerScore = function(trueSketch, targetObj, context, params, config) {
  var possibleSketches = config.possibleSketches;
  var costw = params.costWeight;
  var infw = params.infWeight;
  var scores = [];
  // note: could memoize this for moderate optimization...
  // (only needs to be computed once per context per param, not for every sketch)
  for(var i=0; i<possibleSketches.length; i++){
    var sketch = possibleSketches[i];
    var inf = informativity(targetObj, sketch, context, params, config);
    var cost = config.costs[sketch];
    if (isNaN(cost)) {
      console.log(targetObj,sketch,context);
      console.log(cost);
    }
    // console.log(cost);
    var utility = infw * inf - costw * cost; // independent informativity weight parameter
    scores.push( utility);//Math.log(Math.max(utility, Number.EPSILON)));
  }
  var trueUtility = (infw * informativity(targetObj, trueSketch, context, params, config)
		     - costw * config.costs[trueSketch]);
  //var roundedUtility = Math.max(trueUtility, Number.EPSILON);
  // console.log(_logsumexp(scores))
  //console.log(params.alpha * Math.log(roundedUtility))// - _logsumexp(scores));
  return  trueUtility - _logsumexp(scores); // softmax subtraction bc log space,
};

function readCSV(filename){
  return babyparse.parse(fs.readFileSync(filename, 'utf8'),
			 {header:true, skipEmptyLines:true}).data;
};

function writeCSV(jsonCSV, filename){
  fs.writeFileSync(filename, babyparse.unparse(jsonCSV) + '\n');
}

function appendCSV(jsonCSV, filename){
  fs.appendFileSync(filename, babyparse.unparse(jsonCSV) + '\n');
}

var paramSupportWriter = function(i, s, p, handle) {
  var sLst = _.toPairs(s);
  var l = sLst.length;
  fs.writeSync(handle, i + ',' + sLst[0].join(',')+','+p+'\n');
};

var predictiveSupportWriter = function(s, filePrefix) {
  var dir = filePrefix.split('/').slice(0,3).join('/');
  if (!fs.existsSync(dir)){
      fs.mkdirSync(dir);
  }
  var predictiveFile = fs.openSync(filePrefix + "Predictives.csv", 'w');
  fs.writeSync(predictiveFile, ['index','game', "condition", 'trueSketch', "Target",
				"Distractor1", "Distractor2", "Distractor3",
				"coarseGrainedTrueSketch", "coarseGrainedPossibleSketch",
				"modelProb"] + '\n');

  var l = s.length;
  for (var i = 0; i < l; i++) {
    fs.writeSync(predictiveFile, s[i] + '\n');
  }

  fs.closeSync(predictiveFile);
};

// Note this is highly specific to a single type of erp
var bayesianErpWriter = function(erp, filePrefix) {
  var supp = erp.support();

  if(_.has(supp[0], 'params')) {
    var paramFile = fs.openSync(filePrefix + "Params.csv", 'w');
    fs.writeSync(paramFile, ["id", "perception", "pragmatics", "production",
			     "simScaling", "pragWeight","costWeight",
			     "logLikelihood", "posteriorProb"] + '\n');
  }

  supp.forEach(function(s, index) {
    if(_.has(s, 'params')) {
      paramSupportWriter(index, s.params, erp.score(s), paramFile);
    }
  });
    if(_.has(supp[0], 'params')) {
    fs.closeSync(paramFile);
  }
  console.log('writing complete.');
};

var getSubset = function(data, properties) {
  var matchProps = _.matches(properties);
  return _.filter(data, matchProps);
};

var locParse = function(filename) {
  return babyparse.parse(fs.readFileSync(filename, 'utf8'),
       {header: true,
        skipEmptyLines : true}).data;
};

module.exports = {
  getSimilarities, getPossibleSketches, getCosts, getSubset, getConditionLookup,
  predictiveSupportWriter,
  getL0score, getSpeakerScore,
  bayesianErpWriter, writeCSV, readCSV, locParse
};
<|endoftext|>


<commit_before>/**
 * Label Counter module.
 * @param d3 d3 module
 * @returns {{className: string}}
 * @constructor
 * @memberof svl
 */
function LabelCounter (d3) {
    var self = {className: 'LabelCounter'};

    var radius = 0.4, dR = radius / 2,
        svgWidth = 200, svgHeight = 120,
        margin = {top: 10, right: 10, bottom: 10, left: 0},
        padding = {left: 5, top: 15},
        width = 200 - margin.left - margin.right,
        height = 40 - margin.top - margin.bottom,
        colorScheme = svl.misc.getLabelColors(),
        imageWidth = 22, imageHeight = 22;

    // Prepare a group to store svg elements, and declare a text
    var dotPlots = {
      "CurbRamp": {
        id: "CurbRamp",
        description: "curb ramp",
        left: margin.left,
        top: margin.top,
        fillColor: colorScheme["CurbRamp"].fillStyle,
          imagePath: svl.rootDirectory + "/img/icons/Sidewalk/Icon_CurbRamp.png",
        count: 0,
        data: []
      },
      "NoCurbRamp": {
          id: "NoCurbRamp",
          description: "missing curb ramp",
          left: margin.left,
          top: (2 * margin.top) + margin.bottom + height,
          // top: 2 * margin.top + margin.bottom + height,
          fillColor: colorScheme["NoCurbRamp"].fillStyle,
          imagePath: svl.rootDirectory + "/img/icons/Sidewalk/Icon_NoCurbRamp.png",
          count: 0,
          data: []
      },
      "Obstacle": {
        id: "Obstacle",
        description: "obstacle",
        left: margin.left + (width/1.7),
        // top: 3 * margin.top + 2 * margin.bottom + 2 * height,
          top: (2 * margin.top) + margin.bottom + height,
        fillColor: colorScheme["Obstacle"].fillStyle,
          imagePath: svl.rootDirectory + "/img/icons/Sidewalk/Icon_Obstacle.png",
        count: 0,
        data: []
      },
      "SurfaceProblem": {
        id: "SurfaceProblem",
        description: "surface problem",
        left: margin.left,
        //top: 4 * margin.top + 3 * margin.bottom + 3 * height,
          top: (3 * margin.top) + (2 * margin.bottom) + (2 * height),
        fillColor: colorScheme["SurfaceProblem"].fillStyle,
          imagePath: svl.rootDirectory + "/img/icons/Sidewalk/Icon_SurfaceProblem.png",
        count: 0,
        data: []
      },
        "Other": {
            id: "Other",
            description: "other",
            left: margin.left + (width/1.7),
            top: (3 * margin.top) + (2 * margin.bottom) + (2 * height),
            fillColor: colorScheme["Other"].fillStyle,
            imagePath: svl.rootDirectory + "/img/icons/Sidewalk/Icon_Other.png",
            count: 0,
            data: []
        }
    };

    var keys = Object.keys(dotPlots);

    var x = d3.scale.linear()
              .domain([0, 20])
              .range([0, width]);

    var y = d3.scale.linear()
            .domain([0, 20])
            .range([height, 0]);

    var svg = d3.select('#label-counter')
                  .append('svg')
                  .attr('width', svgWidth)
                  .attr('height', svgHeight);

    var chart = svg.append('g')
                  .attr('width', svgWidth)
                  .attr('height', svgHeight)
                  .attr('class', 'chart')
                  .attr('transform', function () {
                     return 'translate(0,0)';
                  });

    for (var key in dotPlots) {
        dotPlots[key].g = chart.append('g')
                    .attr('transform', 'translate(' + dotPlots[key].left + ',' + dotPlots[key].top + ')')
                    .attr('width', width)
                    .attr('height', height)
                    .attr('class', 'main');

        dotPlots[key].label = dotPlots[key].g.selectAll("text.label")
            .data([0])
            .enter()
            .append("text")
            .text(function () {
                var ret = dotPlots[key].count + " " + dotPlots[key].description;
                ret += dotPlots[key].count > 1 ? "s" : "";
                return ret;
            })
            .style("font-size", "10px")
            .attr("class", "visible")
            .attr('transform', 'translate(0,' + imageHeight + ')');

        dotPlots[key].plot = dotPlots[key].g.append("g")
            .attr('transform', 'translate(' + (padding.left + imageWidth) + ',' + 0 + ')');

        dotPlots[key].g.append("image")
            .attr("xlink:href", dotPlots[key].imagePath)
            .attr("width", imageWidth)
            .attr("height", imageHeight)
            .attr('transform', 'translate(0,-15)');
      //dotPlots[key].countLabel = dotPlots[key].plot.selectAll("text.count-label")
      //  .data([0])
      //  .enter()
      //  .append("text")
      //  .style("font-size", "11px")
      //  .style("fill", "gray")
      //  .attr("class", "visible");
    }

    function countLabel(labelType) {
        return labelType in dotPlots ? dotPlots[key].count : null;
    }

    /**
     * Set label counts to 0
     */
    function reset () {
        for (var key in dotPlots) {
            set(key, 0);
        }
    }

    /**
     * Update the label count visualization.
     * @param key {string} Label type
     */
    function update(key) {
        // If a key is given, udpate the dot plot for that specific data.
        // Otherwise update all.
        if (key) {
          _update(key)
        } else {
          for (var key in dotPlots) {
            _update(key);
          }
        }

        // Actual update function
        function _update(key) {
            if (keys.indexOf(key) == -1) { key = "Other"; }

            var fiftyCircles = parseInt(dotPlots[key].count / 50),
              tenCircles = parseInt((dotPlots[key].count % 50) / 10),
              oneCircles = dotPlots[key].count % 10,
              count = fiftyCircles + tenCircles + oneCircles;

            /*
            the code of these three functions was being used so much I decided to seperately declare them
            the d3 calls look much cleaner now :)
            */
            function setCX(d, i){
              if (i < fiftyCircles && fiftyCircles != 0){
                return x(i * 4 * radius + dR);
              }
              else if (i < fiftyCircles + tenCircles && tenCircles != 0){
                return x(fiftyCircles * 4 * radius + dR) + x((i - fiftyCircles) * 2 * (radius + dR));
              }
              else{
                return x(fiftyCircles * 2 * radius + dR) + x(tenCircles * 1.9 * (radius + dR))+ x((i - tenCircles) * 2 * radius);
              }
            }

            function setCY(d, i){
              if (i < fiftyCircles && fiftyCircles != 0){
                return 0;
              }
              else if (i < fiftyCircles + tenCircles && tenCircles != 0){
                return x(dR);
              }
              else{
                return x(radius);
              }
            }

            function setR(d, i){
              if (i < fiftyCircles && fiftyCircles != 0){
                return x(2 * radius);
              }
              else if (i < fiftyCircles + tenCircles && tenCircles != 0){
                return x(radius + dR);
              }
              else{
                return x(radius);
              }
            }
            // Update the dot plot
            if (dotPlots[key].data.length >= count) {
              // Remove dots
              dotPlots[key].data = dotPlots[key].data.slice(0, count);

                dotPlots[key].plot.selectAll("circle")
                  .transition().duration(500)
                  .attr("r", setR)
                  .attr("cy", setCY)
                  .attr("cx", setCX);

                dotPlots[key].plot.selectAll("circle")
                  .data(dotPlots[key].data)
                  .exit()
                  .transition()
                  .duration(500)
                  .attr("cx", function () {
                    return 0;
                  })
                  .attr("r", 0)
                  .remove();
            } else {
              // Add dots
              var len = dotPlots[key].data.length;
              for (var i = 0; i < count - len; i++) {
                  dotPlots[key].data.push([len + i, 0, radius])
              }
              dotPlots[key].plot.selectAll("circle")
                .attr("r", setR)
                .attr("cy", setCY)
                .attr("cx", setCX)
                .data(dotPlots[key].data)
                .enter().append("circle")
                .attr("cx", x(0))
                .attr("cy", setCY)
                .attr("r", radius)
                .style("fill", dotPlots[key].fillColor)
                .transition().duration(1000)
                .attr("cx", setCX)
                .attr("cy", setCY)
                .attr("r", setR);
            }
            dotPlots[key].label.text(function () {
                var ret = dotPlots[key].count + " " + dotPlots[key].description;
                ret += dotPlots[key].count > 1 ? "s" : "";
                return ret;
            });
        }
    }

    /**
     * Decrement the label count
     * @param key {string} Label type
     */
    function decrement(key) {
        if (keys.indexOf(key) == -1) { key = "Other"; }
        if (key in dotPlots && dotPlots[key].count > 0) {
            dotPlots[key].count -= 1;
        }
        update(key);
    }

    /**
     * Increment the label count
     * @param key {string} Label type
     */
    function increment(key) {
        if (keys.indexOf(key) == -1) { key = "Other"; }
        if (key in dotPlots) {
            dotPlots[key].count += 1;
            update(key);
        }
    }

    /**
     * Set the number of label count
     * @param key {string} Label type
     * @param num {number} Label type count
     */
    function set(key, num) {
        dotPlots[key].count = num;
        update(key);
    }

    // Initialize
    update();
    self.countLabel = countLabel;
    self.increment = increment;
    self.decrement = decrement;
    self.set = set;
    self.reset = reset;
    return self;
}<commit_msg>Correct Label Count in Mission Complete Modal<commit_after>/**
 * Label Counter module.
 * @param d3 d3 module
 * @returns {{className: string}}
 * @constructor
 * @memberof svl
 */
function LabelCounter (d3) {
    var self = {className: 'LabelCounter'};

    var radius = 0.4, dR = radius / 2,
        svgWidth = 200, svgHeight = 120,
        margin = {top: 10, right: 10, bottom: 10, left: 0},
        padding = {left: 5, top: 15},
        width = 200 - margin.left - margin.right,
        height = 40 - margin.top - margin.bottom,
        colorScheme = svl.misc.getLabelColors(),
        imageWidth = 22, imageHeight = 22;

    // Prepare a group to store svg elements, and declare a text
    var dotPlots = {
      "CurbRamp": {
        id: "CurbRamp",
        description: "curb ramp",
        left: margin.left,
        top: margin.top,
        fillColor: colorScheme["CurbRamp"].fillStyle,
          imagePath: svl.rootDirectory + "/img/icons/Sidewalk/Icon_CurbRamp.png",
        count: 0,
        data: []
      },
      "NoCurbRamp": {
          id: "NoCurbRamp",
          description: "missing curb ramp",
          left: margin.left,
          top: (2 * margin.top) + margin.bottom + height,
          // top: 2 * margin.top + margin.bottom + height,
          fillColor: colorScheme["NoCurbRamp"].fillStyle,
          imagePath: svl.rootDirectory + "/img/icons/Sidewalk/Icon_NoCurbRamp.png",
          count: 0,
          data: []
      },
      "Obstacle": {
        id: "Obstacle",
        description: "obstacle",
        left: margin.left + (width/1.7),
        // top: 3 * margin.top + 2 * margin.bottom + 2 * height,
          top: (2 * margin.top) + margin.bottom + height,
        fillColor: colorScheme["Obstacle"].fillStyle,
          imagePath: svl.rootDirectory + "/img/icons/Sidewalk/Icon_Obstacle.png",
        count: 0,
        data: []
      },
      "SurfaceProblem": {
        id: "SurfaceProblem",
        description: "surface problem",
        left: margin.left,
        //top: 4 * margin.top + 3 * margin.bottom + 3 * height,
          top: (3 * margin.top) + (2 * margin.bottom) + (2 * height),
        fillColor: colorScheme["SurfaceProblem"].fillStyle,
          imagePath: svl.rootDirectory + "/img/icons/Sidewalk/Icon_SurfaceProblem.png",
        count: 0,
        data: []
      },
        "Other": {
            id: "Other",
            description: "other",
            left: margin.left + (width/1.7),
            top: (3 * margin.top) + (2 * margin.bottom) + (2 * height),
            fillColor: colorScheme["Other"].fillStyle,
            imagePath: svl.rootDirectory + "/img/icons/Sidewalk/Icon_Other.png",
            count: 0,
            data: []
        }
    };

    var keys = Object.keys(dotPlots);

    var x = d3.scale.linear()
              .domain([0, 20])
              .range([0, width]);

    var y = d3.scale.linear()
            .domain([0, 20])
            .range([height, 0]);

    var svg = d3.select('#label-counter')
                  .append('svg')
                  .attr('width', svgWidth)
                  .attr('height', svgHeight);

    var chart = svg.append('g')
                  .attr('width', svgWidth)
                  .attr('height', svgHeight)
                  .attr('class', 'chart')
                  .attr('transform', function () {
                     return 'translate(0,0)';
                  });

    for (var key in dotPlots) {
        dotPlots[key].g = chart.append('g')
                    .attr('transform', 'translate(' + dotPlots[key].left + ',' + dotPlots[key].top + ')')
                    .attr('width', width)
                    .attr('height', height)
                    .attr('class', 'main');

        dotPlots[key].label = dotPlots[key].g.selectAll("text.label")
            .data([0])
            .enter()
            .append("text")
            .text(function () {
                var ret = dotPlots[key].count + " " + dotPlots[key].description;
                ret += dotPlots[key].count > 1 ? "s" : "";
                return ret;
            })
            .style("font-size", "10px")
            .attr("class", "visible")
            .attr('transform', 'translate(0,' + imageHeight + ')');

        dotPlots[key].plot = dotPlots[key].g.append("g")
            .attr('transform', 'translate(' + (padding.left + imageWidth) + ',' + 0 + ')');

        dotPlots[key].g.append("image")
            .attr("xlink:href", dotPlots[key].imagePath)
            .attr("width", imageWidth)
            .attr("height", imageHeight)
            .attr('transform', 'translate(0,-15)');
      //dotPlots[key].countLabel = dotPlots[key].plot.selectAll("text.count-label")
      //  .data([0])
      //  .enter()
      //  .append("text")
      //  .style("font-size", "11px")
      //  .style("fill", "gray")
      //  .attr("class", "visible");
    }

    function countLabel(labelType) {
        return labelType in dotPlots ? dotPlots[labelType].count : null;
    }

    /**
     * Set label counts to 0
     */
    function reset () {
        for (var key in dotPlots) {
            set(key, 0);
        }
    }

    /**
     * Update the label count visualization.
     * @param key {string} Label type
     */
    function update(key) {
        // If a key is given, udpate the dot plot for that specific data.
        // Otherwise update all.
        if (key) {
          _update(key)
        } else {
          for (var key in dotPlots) {
            _update(key);
          }
        }

        // Actual update function
        function _update(key) {
            if (keys.indexOf(key) == -1) { key = "Other"; }

            var fiftyCircles = parseInt(dotPlots[key].count / 50),
              tenCircles = parseInt((dotPlots[key].count % 50) / 10),
              oneCircles = dotPlots[key].count % 10,
              count = fiftyCircles + tenCircles + oneCircles;

            /*
            the code of these three functions was being used so much I decided to seperately declare them
            the d3 calls look much cleaner now :)
            */
            function setCX(d, i){
              if (i < fiftyCircles && fiftyCircles != 0){
                return x(i * 4 * radius + dR);
              }
              else if (i < fiftyCircles + tenCircles && tenCircles != 0){
                return x(fiftyCircles * 4 * radius + dR) + x((i - fiftyCircles) * 2 * (radius + dR));
              }
              else{
                return x(fiftyCircles * 2 * radius + dR) + x(tenCircles * 1.9 * (radius + dR))+ x((i - tenCircles) * 2 * radius);
              }
            }

            function setCY(d, i){
              if (i < fiftyCircles && fiftyCircles != 0){
                return 0;
              }
              else if (i < fiftyCircles + tenCircles && tenCircles != 0){
                return x(dR);
              }
              else{
                return x(radius);
              }
            }

            function setR(d, i){
              if (i < fiftyCircles && fiftyCircles != 0){
                return x(2 * radius);
              }
              else if (i < fiftyCircles + tenCircles && tenCircles != 0){
                return x(radius + dR);
              }
              else{
                return x(radius);
              }
            }
            // Update the dot plot
            if (dotPlots[key].data.length >= count) {
              // Remove dots
              dotPlots[key].data = dotPlots[key].data.slice(0, count);

                dotPlots[key].plot.selectAll("circle")
                  .transition().duration(500)
                  .attr("r", setR)
                  .attr("cy", setCY)
                  .attr("cx", setCX);

                dotPlots[key].plot.selectAll("circle")
                  .data(dotPlots[key].data)
                  .exit()
                  .transition()
                  .duration(500)
                  .attr("cx", function () {
                    return 0;
                  })
                  .attr("r", 0)
                  .remove();
            } else {
              // Add dots
              var len = dotPlots[key].data.length;
              for (var i = 0; i < count - len; i++) {
                  dotPlots[key].data.push([len + i, 0, radius])
              }
              dotPlots[key].plot.selectAll("circle")
                .attr("r", setR)
                .attr("cy", setCY)
                .attr("cx", setCX)
                .data(dotPlots[key].data)
                .enter().append("circle")
                .attr("cx", x(0))
                .attr("cy", setCY)
                .attr("r", radius)
                .style("fill", dotPlots[key].fillColor)
                .transition().duration(1000)
                .attr("cx", setCX)
                .attr("cy", setCY)
                .attr("r", setR);
            }
            dotPlots[key].label.text(function () {
                var ret = dotPlots[key].count + " " + dotPlots[key].description;
                ret += dotPlots[key].count > 1 ? "s" : "";
                return ret;
            });
        }
    }

    /**
     * Decrement the label count
     * @param key {string} Label type
     */
    function decrement(key) {
        if (keys.indexOf(key) == -1) { key = "Other"; }
        if (key in dotPlots && dotPlots[key].count > 0) {
            dotPlots[key].count -= 1;
        }
        update(key);
    }

    /**
     * Increment the label count
     * @param key {string} Label type
     */
    function increment(key) {
        if (keys.indexOf(key) == -1) { key = "Other"; }
        if (key in dotPlots) {
            dotPlots[key].count += 1;
            update(key);
        }
    }

    /**
     * Set the number of label count
     * @param key {string} Label type
     * @param num {number} Label type count
     */
    function set(key, num) {
        dotPlots[key].count = num;
        update(key);
    }

    // Initialize
    update();
    self.countLabel = countLabel;
    self.increment = increment;
    self.decrement = decrement;
    self.set = set;
    self.reset = reset;
    return self;
}<|endoftext|>


<commit_before>/*
	overthrow responsive sidescroller extension
	(c) 2013: Scott Jehl, Filament Group, Inc.
	MIT License
*/

(function( w, o ){

	if( !o || !"querySelector" in w.document ){
		return;
	}

	function sendEvent( elem, evt, args, ieID ){
		// TODO needs IE8 support
		if( document.createEvent ){
			var event = document.createEvent( "Event" );
			event.initEvent( evt, true, true );
			event.overthrow = args;
			elem.dispatchEvent( event );
		}
		else {
			w.document.documentElement[ieID][ evt ] = {
				e: evt,
				args: args
			};
			w.document.documentElement[ evt ]++;
		}
	}

	o.sidescroller = function( elems, options ){

		var scrolls = elems,
			evtPrefix = "overthrow",
			evtNext = evtPrefix + "-next",
			evtPrev = evtPrefix + "-prev",
			slideNum = 0,
			ieID = "overthrow" + (new Date().getTime()),
			snapScroll = options && options.snapScroll,
			rewind = options && options.rewind;

		for( var i = 0; i < scrolls.length; i++ ){

			var thisSideScroll = scrolls[ i ],
				thisScroll = scrolls[ i ].querySelector( ".overthrow" ),
				nextPrev = w.document.createElement( "div" ),
				handled;

			thisSideScroll.setAttribute( "tabindex", "0" );

			// oldIE will need some expando event props
			if( w.document.attachEvent ){
				// these are iterators to trigger a property mutate event in IE8
				w.document.documentElement[ evtPrev ] = 0;
				w.document.documentElement[ evtNext ] = 0;
				// these for for the event data when that property iterates
				w.document.documentElement[ ieID ] = {};
				w.document.documentElement[ ieID ][ evtPrev ] = {};
				w.document.documentElement[ ieID ][ evtNext ] = {};
				thisSideScroll.ieID = ieID;
			}

			nextPrev.className = "sidescroll-nextprev-links";

			nextPrev.innerHTML = "PreviousNext";

			function getActiveSlides( left ){
				var slides = thisScroll.querySelectorAll( "li" ),
					numSlides = slides.length,
					slidesWidth = thisScroll.offsetWidth,
					slideWidth = slides[ 0 ].offsetWidth,
					scrollLeft = left !== undefined ? left : thisScroll.scrollLeft,
					startSlide = Math.round( scrollLeft / slideWidth ),
					valid = true,
					ret = [];

				startSlide = Math.max( 0, startSlide );
				startSlide = Math.min( numSlides, startSlide );

				ret[ 0 ] = startSlide;
				for( var i = 1; i < numSlides; i++ ){
					if( startSlide + (i * slideWidth) < slidesWidth){
						ret.push( startSlide + i);
					}
					else{
						valid = false;
					}
				}
				slideNum = startSlide;
				return ret;
			}

			// expose the getactiveslides function on the overthrow element
			thisSideScroll.getActiveSlides = getActiveSlides;

			function handleClick( evt ){

				var e = evt || w.event;

				if( e.preventDefault ){
					e.preventDefault();
				}
				else{
					e.returnValue = false;
				}

				if( e.type === "keydown" || !handled ){
					handled = true;
					o.intercept();
					var slides = thisScroll.querySelectorAll( "li" ),
						target = e.target || e.srcElement,
						slidesWidth = thisScroll.offsetWidth,
						slideWidth = slides[ 0 ].offsetWidth,
						currScroll = thisScroll.scrollLeft,
						slideNum = Math.round( currScroll / slideWidth ),
						next = (e.type !== "keydown" && target.className.indexOf( "next" ) > -1) || e.keyCode === 39,
						newSlide = slideNum + ( next ? 1 : -1 ),
						newScroll = slideWidth * newSlide,
						scrollWidth = thisScroll.scrollWidth - slidesWidth;

					// if can't go left, go to end
					if( rewind ){

						if( newScroll < 0 ){
							newScroll = scrollWidth;
						}
						else if( newScroll > scrollWidth ){
							newScroll = 0;
						}
					}
					else {
						if( newScroll < 0 ){
							newScroll = 0;
						}
						else if( newScroll > scrollWidth ){
							newScroll = scrollWidth;
						}
					}

					var newActive = getActiveSlides( newScroll );

					if( newActive[ 0 ] !== slideNum ){

						o.toss( thisScroll, { left: newScroll } );

						sendEvent(
							thisSideScroll, // elem to receive event
							next ? evtNext : evtPrev, // evt name
							{
								active: newActive, // active slides
								originalEvent: e
							},
							ieID
						);
					}

					setTimeout( function(){ handled = false; }, 100 );
				}
			}

			function handleSnap( e ){
				o.intercept();
				var slideWidth = thisScroll.querySelector( "li" ).offsetWidth,
					currScroll = thisScroll.scrollLeft,
					newSlide = Math.round( currScroll / slideWidth ),
					newScroll = slideWidth * newSlide;

				o.toss( thisScroll, { left: newScroll, duration: 20 } );

				if( slideNum !== newSlide ){
					sendEvent(
						thisSideScroll, // elem to receive event
						newSlide > slideNum ? evtNext : evtPrev, // evt name
						{
							active: getActiveSlides( newScroll ), // active slides
							originalEvent: e
						},
						ieID
					);
					slideNum = newSlide;
				}
			}

			var debounce;
			function handleResize( e ){
				clearTimeout(debounce);
				debounce = setTimeout(function(){
					handleSnap( e );
				}, 100);
			}

			var debouncedos;
			function handleScroll( e ){
				clearTimeout(debouncedos);
				debouncedos = setTimeout(function(){
					handleSnap( e );
				}, 200);
			}

			function handleKey( e ){
				if( e.keyCode === 39 || e.keyCode === 37 ){
					handleClick( e );
				}
			}

			if( w.document.addEventListener ){
				nextPrev.addEventListener( "click", handleClick, false );
				nextPrev.addEventListener( "touchend", handleClick, false );
				w.addEventListener( "resize", handleResize, false );
				scrolls[ i ].addEventListener( "keydown", handleKey, false );
				if( snapScroll ){
					thisScroll.addEventListener( "scroll", handleScroll, false );
				}
			}
	 		else if( w.document.attachEvent ){
	 			nextPrev.attachEvent( "onclick", handleClick, false );
				w.attachEvent( "onresize", handleResize, false );
				scrolls[ i ].attachEvent( "onkeydown", handleKey, false );
				if( snapScroll ){
					thisScroll.attachEvent( "onscroll", handleScroll, false );
				}
	 		}

			thisSideScroll.insertBefore( nextPrev, thisScroll );

		}

	};

	o.sidescroller.onEvent = function( evt, elem, callback ){
		function cb( args ){
			var e = {
				type: evt,
				target: elem,
				overthrow: args
			};
			callback( e );
		}
		if( w.document.addEventListener ){
			elem.addEventListener( evt, cb );
		}
		else if( w.document.attachEvent ){
			w.document.documentElement.attachEvent( "onpropertychange", function( event ) {
				if( event.propertyName === evt ){
					cb( w.document.documentElement[ elem.ieID ][ evt ] );
				}
			});
		}
	};

}( this, this.overthrow ));<commit_msg>prevent re-initialization on a sidescroller<commit_after>/*
	overthrow responsive sidescroller extension
	(c) 2013: Scott Jehl, Filament Group, Inc.
	MIT License
*/

(function( w, o ){

	if( !o || !"querySelector" in w.document ){
		return;
	}

	function sendEvent( elem, evt, args, ieID ){
		// TODO needs IE8 support
		if( document.createEvent ){
			var event = document.createEvent( "Event" );
			event.initEvent( evt, true, true );
			event.overthrow = args;
			elem.dispatchEvent( event );
		}
		else {
			w.document.documentElement[ieID][ evt ] = {
				e: evt,
				args: args
			};
			w.document.documentElement[ evt ]++;
		}
	}

	o.sidescroller = function( elems, options ){

		var scrolls = elems,
			evtPrefix = "overthrow",
			evtNext = evtPrefix + "-next",
			evtPrev = evtPrefix + "-prev",
			snapScroll = options && options.snapScroll,
			rewind = options && options.rewind;

		for( var i = 0; i < scrolls.length; i++ ){

			(function(){

				var thisSideScroll = scrolls[ i ],
					thisScroll = scrolls[ i ].querySelector( ".overthrow" ),
					nextPrev = w.document.createElement( "div" ),
					slideNum = 0,
					ieID = "overthrow" + (new Date().getTime()),
					handled;

				// prevent re-init
				if( thisSideScroll.initialized ){
					return;
				}
				thisSideScroll.initialized = true;

				thisSideScroll.setAttribute( "tabindex", "0" );

				// oldIE will need some expando event props
				if( w.document.attachEvent ){
					// these are iterators to trigger a property mutate event in IE8
					w.document.documentElement[ evtPrev ] = 0;
					w.document.documentElement[ evtNext ] = 0;
					// these for for the event data when that property iterates
					w.document.documentElement[ ieID ] = {};
					w.document.documentElement[ ieID ][ evtPrev ] = {};
					w.document.documentElement[ ieID ][ evtNext ] = {};
					thisSideScroll.ieID = ieID;
				}

				nextPrev.className = "sidescroll-nextprev-links";

				nextPrev.innerHTML = "PreviousNext";

				function getActiveSlides( left ){
					var slides = thisScroll.querySelectorAll( "li" ),
						numSlides = slides.length,
						slidesWidth = thisScroll.offsetWidth,
						slideWidth = slides[ 0 ].offsetWidth,
						scrollLeft = left !== undefined ? left : thisScroll.scrollLeft,
						startSlide = Math.round( scrollLeft / slideWidth ),
						valid = true,
						ret = [];

					startSlide = Math.max( 0, startSlide );
					startSlide = Math.min( numSlides, startSlide );

					ret[ 0 ] = startSlide;
					for( var i = 1; i < numSlides; i++ ){
						if( startSlide + (i * slideWidth) < slidesWidth){
							ret.push( startSlide + i);
						}
						else{
							valid = false;
						}
					}
					slideNum = startSlide;
					return ret;
				}

				// expose the getactiveslides function on the overthrow element
				thisSideScroll.getActiveSlides = getActiveSlides;

				function handleClick( evt ){

					var e = evt || w.event;

					if( e.preventDefault ){
						e.preventDefault();
					}
					else{
						e.returnValue = false;
					}

					if( e.type === "keydown" || !handled ){
						handled = true;
						o.intercept();
						var slides = thisScroll.querySelectorAll( "li" ),
							target = e.target || e.srcElement,
							slidesWidth = thisScroll.offsetWidth,
							slideWidth = slides[ 0 ].offsetWidth,
							currScroll = thisScroll.scrollLeft,
							slideNum = Math.round( currScroll / slideWidth ),
							next = (e.type !== "keydown" && target.className.indexOf( "next" ) > -1) || e.keyCode === 39,
							newSlide = slideNum + ( next ? 1 : -1 ),
							newScroll = slideWidth * newSlide,
							scrollWidth = thisScroll.scrollWidth - slidesWidth;

						// if can't go left, go to end
						if( rewind ){

							if( newScroll < 0 ){
								newScroll = scrollWidth;
							}
							else if( newScroll > scrollWidth ){
								newScroll = 0;
							}
						}
						else {
							if( newScroll < 0 ){
								newScroll = 0;
							}
							else if( newScroll > scrollWidth ){
								newScroll = scrollWidth;
							}
						}

						var newActive = getActiveSlides( newScroll );

						if( newActive[ 0 ] !== slideNum ){

							o.toss( thisScroll, { left: newScroll } );

							sendEvent(
								thisSideScroll, // elem to receive event
								next ? evtNext : evtPrev, // evt name
								{
									active: newActive, // active slides
									originalEvent: e
								},
								ieID
							);
						}

						setTimeout( function(){ handled = false; }, 100 );
					}
				}

				function handleSnap( e ){
					o.intercept();
					var slideWidth = thisScroll.querySelector( "li" ).offsetWidth,
						currScroll = thisScroll.scrollLeft,
						newSlide = Math.round( currScroll / slideWidth ),
						newScroll = slideWidth * newSlide;

					o.toss( thisScroll, { left: newScroll, duration: 20 } );

					if( slideNum !== newSlide ){
						sendEvent(
							thisSideScroll, // elem to receive event
							newSlide > slideNum ? evtNext : evtPrev, // evt name
							{
								active: getActiveSlides( newScroll ), // active slides
								originalEvent: e
							},
							ieID
						);
						slideNum = newSlide;
					}
				}

				var debounce;
				function handleResize( e ){
					clearTimeout(debounce);
					debounce = setTimeout(function(){
						handleSnap( e );
					}, 100);
				}

				var debouncedos;
				function handleScroll( e ){
					clearTimeout(debouncedos);
					debouncedos = setTimeout(function(){
						handleSnap( e );
					}, 200);
				}

				function handleKey( e ){
					if( e.keyCode === 39 || e.keyCode === 37 ){
						handleClick( e );
					}
				}

				if( w.document.addEventListener ){
					nextPrev.addEventListener( "click", handleClick, false );
					nextPrev.addEventListener( "touchend", handleClick, false );
					w.addEventListener( "resize", handleResize, false );
					scrolls[ i ].addEventListener( "keydown", handleKey, false );
					if( snapScroll ){
						thisScroll.addEventListener( "scroll", handleScroll, false );
					}
				}
		 		else if( w.document.attachEvent ){
		 			nextPrev.attachEvent( "onclick", handleClick, false );
					w.attachEvent( "onresize", handleResize, false );
					scrolls[ i ].attachEvent( "onkeydown", handleKey, false );
					if( snapScroll ){
						thisScroll.attachEvent( "onscroll", handleScroll, false );
					}
		 		}

				thisSideScroll.insertBefore( nextPrev, thisScroll );

			}());

		}

	};

	o.sidescroller.onEvent = function( evt, elem, callback ){
		function cb( args ){
			var e = {
				type: evt,
				target: elem,
				overthrow: args
			};
			callback( e );
		}
		if( w.document.addEventListener ){
			elem.addEventListener( evt, cb );
		}
		else if( w.document.attachEvent ){
			w.document.documentElement.attachEvent( "onpropertychange", function( event ) {
				if( event.propertyName === evt ){
					cb( w.document.documentElement[ elem.ieID ][ evt ] );
				}
			});
		}
	};

}( this, this.overthrow ));<|endoftext|>


<commit_before>'use strict';

angular.module('nearby').controller('NearbyController', ['$scope', 'Breweries', 'geolocation', '$stateParams', 'uiGmapLogger', '$anchorScroll', '$location', 'usSpinnerService',
	function($scope, Breweries, geolocation, $stateParams, uiGmapLogger, $anchorScroll, $location, usSpinnerService) {

    // enable logging of google map info and error
    uiGmapLogger.doLog = true;

    // this array would be used to fetch data from brewerydb factory
    $scope.breweries = [];

    // an object to story user's current coordinate,
    $scope.coords = {};

    // pushing breweries data from $http request and place markers
    var handleSuccess = function(data, status){
      $scope.breweries = data.data;
      placeMarker();

      // stop the spinner
      usSpinnerService.stop('spinner-1');
    };

    // function to access users geolocation coordinates
    geolocation.getLocation().then(function(data){
      // get user coordinates
      $scope.coords = {lat:data.coords.latitude, long:data.coords.longitude};

      // set to san francisco by Default for Victor
      //$scope.coords = {lat:37.7833, long:-122.4167};

      // initialise the Google map
      $scope.map = { center: { latitude: $scope.coords.lat, longitude: $scope.coords.long }, zoom: 12};

      // allow scroll to zoom
      $scope.windowOptions = {
         visible: true
      };

      // add maker for current location
      curLocationMarker();

      // get Breweries data from factory
      Breweries.getData($scope.coords).success(handleSuccess);

    });

    // marker for current coordinate
    var curLocationMarker = function(){
      $scope.marker = {
        id: 'curLoc',
        coords: {
          latitude: $scope.coords.lat,
          longitude: $scope.coords.long,
        },
        options: {
          animation: 'DROP'
        }
      };
    };

    $scope.windowOptions = {
      visible: true
    };

    $scope.onClick = function() {
      $scope.windowOptions.visible = !$scope.windowOptions.visible;
    };

    $scope.closeClick = function() {
      $scope.windowOptions.visible = false;
    };

    $scope.title = 'You are here!';

    $scope.clickEventsObject = {
      mouseover: function(marker, e, model)  {
        model.mouseOver();
      },
      mouseout: function(marker, e, model)  {
        model.mouseOut();
      }
    };

    // an array to store all breweries marker
    $scope.allMarkers = [];

    // create markers for all breweries
    var createMarker = function (i, lat, lng, name, breweryId) {
      var ret = {
        id: i,
        breweryId: breweryId,
        latitude: lat,
        longitude: lng,
        title: name,
        icon: '/modules/nearby/images/beer-icon.png',
        show: false
      };
      ret.onClick = function() {
        ret.show = !ret.show;
      };
      ret.mouseOver = function(){
        ret.show = !ret.show;
        $scope.gotoAnchor(breweryId);
      };
      ret.mouseOut = function(){
        ret.show = !ret.show;
      };

      return ret;
    };

    // a function to place all breweries markers
    var placeMarker = function(){

      var markers = [];
      for (var i = 0; i < $scope.breweries.length; i++) {
        var lat = $scope.breweries[i].latitude;
        var lng = $scope.breweries[i].longitude;
        var name = $scope.breweries[i].brewery.name;
        var breweryId = $scope.breweries[i].brewery.id;

        markers.push(createMarker(i, lat, lng, name, breweryId));
      }

      $scope.allMarkers = markers;
    };

    $scope.gotoAnchor = function(x) {
      var newHash = 'anchor' + x;
      if ($location.hash() !== newHash) {
        // set the $location.hash to `newHash` and
        // $anchorScroll will automatically scroll to it
        $location.hash('anchor' + x);
      } else {
        // call $anchorScroll() explicitly,
        // since $location.hash hasn't changed
        $anchorScroll();
      }
    };
  }
]);

angular.module('nearby').run(['$anchorScroll', function($anchorScroll) {
  $anchorScroll.yOffset = 50;   // always scroll by 50 extra pixels
}]);
<commit_msg>add condition to handle no breweries data<commit_after>'use strict';

angular.module('nearby').controller('NearbyController', ['$scope', 'Breweries', 'geolocation', '$stateParams', 'uiGmapLogger', '$anchorScroll', '$location', 'usSpinnerService',
	function($scope, Breweries, geolocation, $stateParams, uiGmapLogger, $anchorScroll, $location, usSpinnerService) {

    // enable logging of google map info and error
    uiGmapLogger.doLog = true;

    // this array would be used to fetch data from brewerydb factory
    $scope.breweries = [];

    // an object to story user's current coordinate,
    $scope.coords = {};

    // pushing breweries data from $http request and place markers
    var handleSuccess = function(data, status){

      if (data.data){

        console.log(data.data)

        $scope.breweries = data.data;

        placeMarker();

      } else {

        $scope.breweries = [{
          brewery: {
            name: 'Sorry',
            description: 'No breweries nearby'
          }
        }]

      }

      // stop the spinner
      usSpinnerService.stop('spinner-1');
    };

    // function to access users geolocation coordinates
    geolocation.getLocation().then(function(data){
      // get user coordinates
      $scope.coords = {lat:data.coords.latitude, long:data.coords.longitude};

      // set to san francisco by Default for Victor
      // $scope.coords = {lat:37.7833, long:-122.4167};

      // initialise the Google map
      $scope.map = { center: { latitude: $scope.coords.lat, longitude: $scope.coords.long }, zoom: 12};

      // allow scroll to zoom
      $scope.windowOptions = {
         visible: true
      };

      // add maker for current location
      curLocationMarker();

      // get Breweries data from factory
      Breweries.getData($scope.coords).success(handleSuccess);

    });

    // marker for current coordinate
    var curLocationMarker = function(){
      $scope.marker = {
        id: 'curLoc',
        coords: {
          latitude: $scope.coords.lat,
          longitude: $scope.coords.long,
        },
        options: {
          animation: 'DROP'
        }
      };
    };

    $scope.windowOptions = {
      visible: true
    };

    $scope.onClick = function() {
      $scope.windowOptions.visible = !$scope.windowOptions.visible;
    };

    $scope.closeClick = function() {
      $scope.windowOptions.visible = false;
    };

    $scope.title = 'You are here!';

    $scope.clickEventsObject = {
      mouseover: function(marker, e, model)  {
        model.mouseOver();
      },
      mouseout: function(marker, e, model)  {
        model.mouseOut();
      }
    };

    // an array to store all breweries marker
    $scope.allMarkers = [];

    // create markers for all breweries
    var createMarker = function (i, lat, lng, name, breweryId) {
      var ret = {
        id: i,
        breweryId: breweryId,
        latitude: lat,
        longitude: lng,
        title: name,
        icon: '/modules/nearby/images/beer-icon.png',
        show: false
      };
      ret.onClick = function() {
        ret.show = !ret.show;
      };
      ret.mouseOver = function(){
        ret.show = !ret.show;
        $scope.gotoAnchor(breweryId);
      };
      ret.mouseOut = function(){
        ret.show = !ret.show;
      };

      return ret;
    };

    // a function to place all breweries markers
    var placeMarker = function(){

      var markers = [];
      for (var i = 0; i < $scope.breweries.length; i++) {
        var lat = $scope.breweries[i].latitude;
        var lng = $scope.breweries[i].longitude;
        var name = $scope.breweries[i].brewery.name;
        var breweryId = $scope.breweries[i].brewery.id;

        markers.push(createMarker(i, lat, lng, name, breweryId));
      }

      $scope.allMarkers = markers;
    };

    $scope.gotoAnchor = function(x) {
      var newHash = 'anchor' + x;
      if ($location.hash() !== newHash) {
        // set the $location.hash to `newHash` and
        // $anchorScroll will automatically scroll to it
        $location.hash('anchor' + x);
      } else {
        // call $anchorScroll() explicitly,
        // since $location.hash hasn't changed
        $anchorScroll();
      }
    };
  }
]);

angular.module('nearby').run(['$anchorScroll', function($anchorScroll) {
  $anchorScroll.yOffset = 50;   // always scroll by 50 extra pixels
}]);
<|endoftext|>


<commit_before>module.exports = {
    adapt: function() {
        var url = require('url');
        var httpc = require('http');
        var https = require('https');

        global.window = {};

        window.setTimeout = setTimeout;
        window.clearTimeout = clearTimeout;

        window.console = console;
        window.console.debug = window.console.log;

        // Fields shared by all XMLHttpRequest instances.
        var _agentc = new httpc.Agent({
            keepAlive: true
        });
        var _agents = new https.Agent({
            keepAlive: true
        });
        var _cookieStore = {};

        function _secure(uri) {
            return /^https/i.test(uri.protocol);
        }

        // Bare minimum XMLHttpRequest implementation that works with CometD.
        window.XMLHttpRequest = function() {
            var _config;
            var _request;

            this.status = 0;
            this.statusText = '';
            this.readyState = window.XMLHttpRequest.UNSENT;
            this.responseText = '';

            this.open = function(method, uri) {
                _config = url.parse(uri);
                _config.method = method;
                _config.agent = _secure(_config) ? _agents : _agentc;
                _config.headers = {};
                this.readyState = window.XMLHttpRequest.OPENED;
            };

            this.setRequestHeader = function(name, value) {
                _config.headers[name] = value;
            };

            this.send = function(data) {
                var cookieStore = this.context && this.context.cookieStore;
                if (!cookieStore) {
                    cookieStore = _cookieStore;
                }
                var list = cookieStore[_config.hostname];
                if (list) {
                    var cookies = '';
                    for (var i = 0; i < list.length; ++i) {
                        if (i > 0) {
                            cookies += '; ';
                        }
                        cookies += list[i];
                    }
                    if (cookies) {
                        _config.headers['Cookie'] = cookies;
                    }
                }

                var self = this;
                var http = _secure(_config) ? https : httpc;
                _request = http.request(_config, function(response) {
                    var success = false;
                    self.status = response.statusCode;
                    self.statusText = response.statusMessage;
                    self.readyState = window.XMLHttpRequest.HEADERS_RECEIVED;
                    var headers = response.headers;
                    for (var name in headers) {
                        if (headers.hasOwnProperty(name)) {
                            if (/^set-cookie$/i.test(name)) {
                                var header = headers[name];
                                for (var i = 0; i < header.length; ++i) {
                                    var whole = header[i];
                                    var parts = whole.split(';');
                                    var cookie = parts[0];

                                    var host = _config.hostname;
                                    var list = cookieStore[host];
                                    if (list === undefined) {
                                        cookieStore[host] = list = [];
                                    }
                                    list.push(cookie);
                                }
                            }
                        }
                    }
                    response.on('data', function(chunk) {
                        self.readyState = window.XMLHttpRequest.LOADING;
                        self.responseText += chunk;
                    });
                    response.on('end', function() {
                        success = true;
                        self.readyState = window.XMLHttpRequest.DONE;
                        if (self.onload) {
                            self.onload();
                        }
                    });
                    response.on('close', function() {
                        if (!success) {
                            self.readyState = window.XMLHttpRequest.DONE;
                            if (self.onerror) {
                                self.onerror();
                            }
                        }
                    });
                });
                ['abort', 'aborted', 'error'].forEach(function(event) {
                    _request.on(event, function(x) {
                        self.readyState = window.XMLHttpRequest.DONE;
                        if (self.onerror) {
                            self.onerror(x);
                        }
                    });
                });
                if (data) {
                    _request.write(data);
                }
                _request.end();
            };

            this.abort = function() {
                if (_request) {
                    _request.abort();
                }
            };

            this._config = function() {
                return _config;
            };
        };
        window.XMLHttpRequest.UNSENT = 0;
        window.XMLHttpRequest.OPENED = 1;
        window.XMLHttpRequest.HEADERS_RECEIVED = 2;
        window.XMLHttpRequest.LOADING = 3;
        window.XMLHttpRequest.DONE = 4;
    }
};
<commit_msg>Fixes #8 - Report error messages in XHR.statusText.<commit_after>module.exports = {
    adapt: function() {
        var url = require('url');
        var httpc = require('http');
        var https = require('https');

        global.window = {};

        window.setTimeout = setTimeout;
        window.clearTimeout = clearTimeout;

        window.console = console;
        window.console.debug = window.console.log;

        // Fields shared by all XMLHttpRequest instances.
        var _agentc = new httpc.Agent({
            keepAlive: true
        });
        var _agents = new https.Agent({
            keepAlive: true
        });
        var _cookieStore = {};

        function _secure(uri) {
            return /^https/i.test(uri.protocol);
        }

        // Bare minimum XMLHttpRequest implementation that works with CometD.
        window.XMLHttpRequest = function() {
            var _config;
            var _request;

            this.status = 0;
            this.statusText = '';
            this.readyState = window.XMLHttpRequest.UNSENT;
            this.responseText = '';

            this.open = function(method, uri) {
                _config = url.parse(uri);
                _config.method = method;
                _config.agent = _secure(_config) ? _agents : _agentc;
                _config.headers = {};
                this.readyState = window.XMLHttpRequest.OPENED;
            };

            this.setRequestHeader = function(name, value) {
                _config.headers[name] = value;
            };

            this.send = function(data) {
                var cookieStore = this.context && this.context.cookieStore;
                if (!cookieStore) {
                    cookieStore = _cookieStore;
                }
                var list = cookieStore[_config.hostname];
                if (list) {
                    var cookies = '';
                    for (var i = 0; i < list.length; ++i) {
                        if (i > 0) {
                            cookies += '; ';
                        }
                        cookies += list[i];
                    }
                    if (cookies) {
                        _config.headers['Cookie'] = cookies;
                    }
                }

                var self = this;
                var http = _secure(_config) ? https : httpc;
                _request = http.request(_config, function(response) {
                    var success = false;
                    self.status = response.statusCode;
                    self.statusText = response.statusMessage;
                    self.readyState = window.XMLHttpRequest.HEADERS_RECEIVED;
                    var headers = response.headers;
                    for (var name in headers) {
                        if (headers.hasOwnProperty(name)) {
                            if (/^set-cookie$/i.test(name)) {
                                var header = headers[name];
                                for (var i = 0; i < header.length; ++i) {
                                    var whole = header[i];
                                    var parts = whole.split(';');
                                    var cookie = parts[0];

                                    var host = _config.hostname;
                                    var list = cookieStore[host];
                                    if (list === undefined) {
                                        cookieStore[host] = list = [];
                                    }
                                    list.push(cookie);
                                }
                            }
                        }
                    }
                    response.on('data', function(chunk) {
                        self.readyState = window.XMLHttpRequest.LOADING;
                        self.responseText += chunk;
                    });
                    response.on('end', function() {
                        success = true;
                        self.readyState = window.XMLHttpRequest.DONE;
                        if (self.onload) {
                            self.onload();
                        }
                    });
                    response.on('close', function() {
                        if (!success) {
                            self.readyState = window.XMLHttpRequest.DONE;
                            if (self.onerror) {
                                self.onerror();
                            }
                        }
                    });
                });
                ['abort', 'aborted', 'error'].forEach(function(event) {
                    _request.on(event, function(x) {
                        self.readyState = window.XMLHttpRequest.DONE;
                        var error = x.message;
                        if (error) {
                            self.statusText = error;
                        }
                        if (self.onerror) {
                            self.onerror(x);
                        }
                    });
                });
                if (data) {
                    _request.write(data);
                }
                _request.end();
            };

            this.abort = function() {
                if (_request) {
                    _request.abort();
                }
            };

            this._config = function() {
                return _config;
            };
        };
        window.XMLHttpRequest.UNSENT = 0;
        window.XMLHttpRequest.OPENED = 1;
        window.XMLHttpRequest.HEADERS_RECEIVED = 2;
        window.XMLHttpRequest.LOADING = 3;
        window.XMLHttpRequest.DONE = 4;
    }
};
<|endoftext|>