<commit_before>mapkob = Object.create(null);

/**
 * Generic function to prepare input for consumption
 *
 * Type can be one of:
 *  - "newline delim": Take a string where sentences are delimited by newlines
 *  -
 *
 * @param {Object} data The input data
 * @param {String} type The type of input
 * @returns {Array} An array of strings, sentences delimited by undefined
 */
mapkob.prepareInput = function(data, type) {

  // newline delim
  var splitRe = new RegExp("([\n\r\.]+)")
  if (type === "newline delim") {
    var sentences = data.split(splitRe);
    var delimited = [];
    sentences.map(function(sentence, i) {
      delimited.push(sentence);
      if (i < sentences.length - 1) {
        delimited.push(undefined)
      }
    });

    return delimited.map(function(sentence) {
      return sentence === undefined ? [undefined] : sentence.split(" ");
    }).reduce(function(x,y) {return x.concat(y)})
  }
  return
}

/**
 * A Row mapkob row constructor
 *
 * @param {Object} input A simple object
 * @returns {Object} A maokob row
 */
mapkob.Row = function(input) {
  this.row = input;
  this.stateSpace = Object.keys(input);
  return this;
}

/**
 * Initializes a n x n zero matrix for the states
 *
 * @param {Array} stateSpace The state space
 * @returns {Object} A mapkob zero matrix
 */
mapkob.InitializeZeroMatrix = function(stateSpace) {
  var frequencyMatrix = {};
  var stateObject = {};

  stateSpace.map(function(word) {
    var stateObject = {};
    stateSpace.map(function(word) {stateObject[word] = 0;})
    frequencyMatrix[word] = stateObject;
  });

  this.stateSpace = stateSpace;
  this.matrix = frequencyMatrix;
  return this;
}

/**
 * A basic matrix serving as a parent
 *
 * returns {Object} A mapkob matrix object
 */
mapkob.Matrix = function() {
  this.matrix = {};
  this.stateSpace = [];
  this.type = "mapkob matrix";
  return this;
}

mapkob.SparseTransitionMatrix = function(words) {
  mapkob.Matrix.call(this);
  var uniqueWords = mapkob.unique(words.concat(undefined));
  this.stateSpace = uniqueWords;

  var matrix = {};
  uniqueWords.map(function(word) {matrix[word] = {};});
  words.map(function(word, i) {
    var nextWord = words[i + 1];

    if (matrix[word][nextWord] === undefined) {
      matrix[word][nextWord] = 1;
    } else {
      matrix[word][nextWord] += 1;
    }
  })
  this.matrix = matrix;
  this.type = "mapkob frequency matrix";
  return this;
}

/**
 * Returns a list of unique elements
 *
 * @param {Array} input The array of elements
 * @returns {Array} The deduped array
 */
mapkob.unique = function(input) {
  var output = [];
  input.map(function(element) {
    if (output.indexOf(element) === -1) {
      output.push(element)}});
  return output;
}

/**
 * Returns the row of a matrix
 *
 * @param {String} row The row by name to look up
 * @returns {Object} The row of the matrix
 */
mapkob.Matrix.prototype.getRow = function(row) {
  var row = new mapkob.Row(this.matrix[row]);
  return row;
}

// Let Special Matrix types inherit generic methods
mapkob.SparseTransitionMatrix.prototype = new mapkob.Matrix();

/**
 * Generates a sumulated Markov chain
 *
 * @returns {String} A Computer generated string
 */
mapkob.SparseTransitionMatrix.prototype.generateChain = function() {
  var stateI = Math.floor(Math.random() * this.stateSpace.length);
  var currentState = this.stateSpace[stateI];
  var output = [];

  while (currentState !== "undefined" && currentState !== undefined) {
    output.push(currentState);
    var currentRow = this.getRow(currentState);
    var rowSum = currentRow.stateSpace.map(function(state) {
      return currentRow.row[state];
    }).reduce(function(x, y) {return x + y});

    var probs = currentRow.stateSpace.map(function(state) {
      return currentRow.row[state] / rowSum;
    });

    var cumSums = probs.map(function(state, stateI) {
      var sum = 0;
      for (var i = 0; i <= stateI; i++) {
        sum += probs[i];
      }
      return sum;
    })

    var r = Math.random();
    for (var col in cumSums) {
      if (r <= cumSums[col] && (cumSums[col+1] === undefined || cumSums[col+1] > r)) {
        stateI = col;
        break;
      }
    }
    currentState = currentRow.stateSpace[stateI];
  }
  return output.join(" ");
}
<commit_msg>Split markov chain generation into Row methods<commit_after>mapkob = Object.create(null);

/**
 * Generic function to prepare input for consumption
 *
 * Type can be one of:
 *  - "newline delim": Take a string where sentences are delimited by newlines
 *  -
 *
 * @param {Object} data The input data
 * @param {String} type The type of input
 * @returns {Array} An array of strings, sentences delimited by undefined
 */
mapkob.prepareInput = function(data, type) {

  // newline delim
  var splitRe = new RegExp("([\n\r\.]+)")
  if (type === "newline delim") {
    var sentences = data.split(splitRe);
    var delimited = [];
    sentences.map(function(sentence, i) {
      delimited.push(sentence);
      if (i < sentences.length - 1) {
        delimited.push(undefined)
      }
    });

    return delimited.map(function(sentence) {
      return sentence === undefined ? [undefined] : sentence.split(" ");
    }).reduce(function(x,y) {return x.concat(y)})
  }
  return
}

/**
 * A Row mapkob row constructor
 *
 * @param {Object} input A simple object
 * @returns {Object} A maokob row
 */
mapkob.Row = function(input) {
  this.row = input;
  this.stateSpace = Object.keys(input);
  return this;
}

mapkob.TransitionMatrix = function(words) {
  var uniqueWords = mapkob.unique(words.concat(undefined));
  this.stateSpace = uniqueWords;

  var matrix = {};
  uniqueWords.map(function(word) {matrix[word] = {};});
  words.map(function(word, i) {
    var nextWord = words[i + 1];

    if (matrix[word][nextWord] === undefined) {
      matrix[word][nextWord] = 1;
    } else {
      matrix[word][nextWord] += 1;
    }
  })
  this.matrix = matrix;
  return this;
}

/**
 * Returns a list of unique elements
 *
 * @param {Array} input The array of elements
 * @returns {Array} The deduped array
 */
mapkob.unique = function(input) {
  var output = [];
  input.map(function(element) {
    if (output.indexOf(element) === -1) {
      output.push(element)}});
  return output;
}

/**
 * Returns the row of a matrix
 *
 * @param {String} row The row by name to look up
 * @returns {Object} The row of the matrix
 */
mapkob.TransitionMatrix.prototype.getRow = function(row) {
  var row = new mapkob.Row(this.matrix[row]);
  return row;
}

/**
 * Calculates the sum of the rows
 *
 * @returns {Number} The sum of the values
 */
mapkob.Row.prototype.sum = function() {
  return this.stateSpace.map(function(state) {
    return this.row[state];
  }, this).reduce(function(x, y) {
    return x + y;
  })
}

/**
 * Calculates relative frequencies of a row
 *
 * @returns {Object} A row
 */
mapkob.Row.prototype.probabilities = function() {
  var sum = this.sum();
  var probs = {};
  this.stateSpace.map(function(state) {probs[state] = this.row[state] / sum}, this);
  return new mapkob.Row(probs)
}

/**
 * A row with the cumulative sums
 *
 * @returns {Object} A row
 */
mapkob.Row.prototype.cumSum = function() {
  var sums = {};
  var sum = 0;
  this.stateSpace.map(function(state) {
    sum += this.row[state];
    sums[state] = sum;
  }, this);
  return new mapkob.Row(sums);
}

/**
 * Returns an array with the row's values
 *
 * @returns {Array} The rows values
 */
mapkob.Row.prototype.values = function() {
  return this.stateSpace.map(function(state) {
    return this.row[state]
  }, this);
}

/**
 * Picks the state with the largest CDF that is smaller or equal to p
 * Technically the first one where the next is larger or the array ends
 *
 * @returns {String} A state string
 */
mapkob.Row.prototype.pickState = function(p) {
  cdf = this.values();
  for (var col in cdf) {
    if (p <= cdf[col] && (cdf[col + 1] == undefined || cdf[col + 1] > p)) {
      return this.stateSpace[col];
    }
  }
}

/**
 * Generates a Markov chain
 *
 * @returns {String} A Computer generated string
 */
mapkob.TransitionMatrix.prototype.generateChain = function() {
  var stateI = Math.floor(Math.random() * this.stateSpace.length);
  var currentState = this.stateSpace[stateI];
  var output = [];

  while (currentState !== "undefined" && currentState !== undefined) {
    output.push(currentState);
    var cumSums = this.getRow(currentState).probabilities().cumSum();
    var r = Math.random();
    currentState = cumSums.pickState(r);
  }
  return output.join(" ");
}
<|endoftext|>


<commit_before>var mediaArchiveApp = angular.module('mediaArchiveApp', ['mediatypefilter']);

mediaArchiveApp.controller('StaticMediaArchiveCtrl', function ($scope, $http) {
  $scope.items = [];
  $scope.mediatypes = { audio: false, video: false};

  $scope.loadItems = function() {
    var httpRequest = $http({
      method: 'GET',
      url: '/wp-content/themes/lsecities-2012/assets/js/media-archive-app/media_archive_data.json'
    }).success(function(data, status) {
      $scope.audio_video_items = data.audio_video_items;
      $scope.articles = data.articles;
    });
  };

  $scope.loadItems();
});

mediaArchiveApp.controller('MediaArchiveCtrl', function ($scope, $http) {
  $scope.items = [];
  $scope.mediatypes = { audio: true, video: true };

  $scope.loadItems = function() {
    var avItemsRequest = $http({
      method: 'GET',
      url: '/search/audio_video_items'
    }).success(function(data, status) {
      $scope.audio_video_items = data.items;
    });

    var articleItemsRequest = $http({
      method: 'GET',
      url: '/search/articles'
    }).success(function(data, status) {
      $scope.articles = data.items;
    });
  };

  $scope.loadItems();
});

mediaArchiveApp.filter('mediatypefilter', function() {
  return function(items, mediatypes) {
    var filtered = [];

    console.log('in mediatypefilter');
    console.log(mediatypes);

    // If no specific media type has been selected, return everything
    if(mediatypes.audio == false && mediatypes.video == false) {
        return items;
    }

    // Otherwise, filter by media type
    angular.forEach(items, function(item) {
      if(mediatypes.audio == true && item.youtube_uri.length > 0){
        filtered.push(item);
      }
      else if(mediatypes.video == true && item.audio_uri.length > 0){
        filtered.push(item);
      }
    });

    return filtered;
  };
});
<commit_msg>fixup!dependency<commit_after>var mediaArchiveApp = angular.module('mediaArchiveApp');

mediaArchiveApp.controller('StaticMediaArchiveCtrl', function ($scope, $http) {
  $scope.items = [];
  $scope.mediatypes = { audio: false, video: false};

  $scope.loadItems = function() {
    var httpRequest = $http({
      method: 'GET',
      url: '/wp-content/themes/lsecities-2012/assets/js/media-archive-app/media_archive_data.json'
    }).success(function(data, status) {
      $scope.audio_video_items = data.audio_video_items;
      $scope.articles = data.articles;
    });
  };

  $scope.loadItems();
});

mediaArchiveApp.controller('MediaArchiveCtrl', ['mediatypefilter', function ($scope, $http) {
  $scope.items = [];
  $scope.mediatypes = { audio: true, video: true };

  $scope.loadItems = function() {
    var avItemsRequest = $http({
      method: 'GET',
      url: '/search/audio_video_items'
    }).success(function(data, status) {
      $scope.audio_video_items = data.items;
    });

    var articleItemsRequest = $http({
      method: 'GET',
      url: '/search/articles'
    }).success(function(data, status) {
      $scope.articles = data.items;
    });
  };

  $scope.loadItems();
}]);

mediaArchiveApp.filter('mediatypefilter', function() {
  return function(items, mediatypes) {
    var filtered = [];

    console.log('in mediatypefilter');
    console.log(mediatypes);

    // If no specific media type has been selected, return everything
    if(mediatypes.audio == false && mediatypes.video == false) {
        return items;
    }

    // Otherwise, filter by media type
    angular.forEach(items, function(item) {
      if(mediatypes.audio == true && item.youtube_uri.length > 0){
        filtered.push(item);
      }
      else if(mediatypes.video == true && item.audio_uri.length > 0){
        filtered.push(item);
      }
    });

    return filtered;
  };
});
<|endoftext|>


<commit_before>module.exports.index = function(req, res) {
    var fs = require('fs'),
    cheerio = require('cheerio'),
    markers = [];

    var locations = {
        'Ringve Museum': {lat: 63.447417, lon: 10.454397},
        'Hospitalskirka': {lat: 63.430415, lon: 10.384338},
        'Ilen kirke': {lat: 63.429902, lon: 10.376173},
        'Modern Art Gallery': {lat: 63.433160, lon: 10.396279},
        'Leangen Idrettsanlegg': {lat: 63.426614, lon: 10.465094},
        'Voll gård': {lat: 63.410358, lon: 10.448298},
        'Trondheim Kunstmuseum, TKM Gråmølna': {lat: 63.435119, lon: 10.415345},
        'Nordenfjeldske Kunstindustrimuseum': {lat: 63.428663, lon: 10.396323},
        'Rica Nidelven': {lat: 63.435688, lon: 10.406365},
        'Galleri SG': {lat: 63.431089, lon: 10.402674},
        'verkstedhallen': {lat: 63.438353, lon: 10.422437},
        'Lademoen Kirke': {lat: 63.437077, lon: 10.430312},
        'Moskus': {lat: 63.433219, lon: 10.401193},
        'Trønderkjellern': {lat: 63.434457, lon: 10.401816},
        'Olavshallen': {lat: 63.433800, lon: 10.403286},
        'No 13': {lat: 63.431900, lon: 10.393050},
        'Nidarosdomen': {lat: 63.427029, lon: 10.395851},
        'Ila Brainnstasjon': {lat: 63.429577, lon: 10.369286},
        'Torvet': {lat: 63.430499, lon: 10.395100},
        'Vitensenteret i Trondheim': {lat: 63.430163, lon: 10.400807},
        'Byscenen': {lat: 63.430112, lon: 10.391656},
        'Vår Frue kirke': {lat: 63.430251, lon: 10.397562},
        'Dokkhuset Scene': {lat: 63.434337, lon: 10.411118},
        'Erkebispegården': {lat: 63.431334, lon: 10.395196},
        'Ravnkloa': {lat: 63.433882, lon: 10.392943},
        'Rockheim': {lat: 63.438751, lon: 10.401993},
        'Sverresborg Trøndelag Folkemuseum': {lat: 63.421408, lon: 10.356803},
        'Vitenskapsmuseet': {lat: 63.429107, lon: 10.386844},
        'Kulturbunker Dora': {lat: 63.439433,  lon: 10.421433},
        'Trondheim folkebibliotek': {lat: 63.439433, lon: 10.421433},
        'Trøndelag Teater': {lat: 63.429316, lon: 10.391333}
    };

    var months = {
        'januar': 1,
        'februar': 2,
        'mars': 3,
        'april': 4,
        'mai': 5,
        'juni': 6,
        'juli': 7,
        'august': 8,
        'september': 9,
        'oktober': 10,
        'november': 11,
        'desember': 12
    };

    function get_date(date_string) {
        var date_elements = date_string.split(" ");
        var day = date_elements[0];
        var month = months[date_elements[1]];
        var year = 2013;
        return year + '-' + month + '-' + day;
    };

    fs.readFile('./parser/examples/thismonth.html', 'utf-8', function (err, data) {
        var $ = cheerio.load(data);
        $('div.event').each(function (i, event) {
            var event_date = $(event).children('.event_date');
            var date = $(event_date).find('.eventDay').text();
            var time = $(event_date).find('.eventTime').text();
            var title = $(event).find('.event_text h1 a').text().trim();
            var location_raw = $(event).find('span a').first();
            var location = location_raw.text().trim();
            var category = $(location_raw).next().next().text().trim();
            var hit = locations[location];
            if (hit) {
                markers.push({
                    title: title,
                    location: location,
                    category: category,
                    date: get_date(date),
                    time: time,
                    lat: hit.lat,
                    lon: hit.lon
                });
            } else {
                console.log(location, "not found");
            }
        });
        return res.json(200, markers);
    });
};
<commit_msg>Fix lint error<commit_after>module.exports.index = function(req, res) {
    var fs = require('fs'),
    cheerio = require('cheerio'),
    markers = [];

    var locations = {
        'Ringve Museum': {lat: 63.447417, lon: 10.454397},
        'Hospitalskirka': {lat: 63.430415, lon: 10.384338},
        'Ilen kirke': {lat: 63.429902, lon: 10.376173},
        'Modern Art Gallery': {lat: 63.433160, lon: 10.396279},
        'Leangen Idrettsanlegg': {lat: 63.426614, lon: 10.465094},
        'Voll gård': {lat: 63.410358, lon: 10.448298},
        'Trondheim Kunstmuseum, TKM Gråmølna': {lat: 63.435119, lon: 10.415345},
        'Nordenfjeldske Kunstindustrimuseum': {lat: 63.428663, lon: 10.396323},
        'Rica Nidelven': {lat: 63.435688, lon: 10.406365},
        'Galleri SG': {lat: 63.431089, lon: 10.402674},
        'verkstedhallen': {lat: 63.438353, lon: 10.422437},
        'Lademoen Kirke': {lat: 63.437077, lon: 10.430312},
        'Moskus': {lat: 63.433219, lon: 10.401193},
        'Trønderkjellern': {lat: 63.434457, lon: 10.401816},
        'Olavshallen': {lat: 63.433800, lon: 10.403286},
        'No 13': {lat: 63.431900, lon: 10.393050},
        'Nidarosdomen': {lat: 63.427029, lon: 10.395851},
        'Ila Brainnstasjon': {lat: 63.429577, lon: 10.369286},
        'Torvet': {lat: 63.430499, lon: 10.395100},
        'Vitensenteret i Trondheim': {lat: 63.430163, lon: 10.400807},
        'Byscenen': {lat: 63.430112, lon: 10.391656},
        'Vår Frue kirke': {lat: 63.430251, lon: 10.397562},
        'Dokkhuset Scene': {lat: 63.434337, lon: 10.411118},
        'Erkebispegården': {lat: 63.431334, lon: 10.395196},
        'Ravnkloa': {lat: 63.433882, lon: 10.392943},
        'Rockheim': {lat: 63.438751, lon: 10.401993},
        'Sverresborg Trøndelag Folkemuseum': {lat: 63.421408, lon: 10.356803},
        'Vitenskapsmuseet': {lat: 63.429107, lon: 10.386844},
        'Kulturbunker Dora': {lat: 63.439433,  lon: 10.421433},
        'Trondheim folkebibliotek': {lat: 63.439433, lon: 10.421433},
        'Trøndelag Teater': {lat: 63.429316, lon: 10.391333}
    };

    var months = {
        'januar': 1,
        'februar': 2,
        'mars': 3,
        'april': 4,
        'mai': 5,
        'juni': 6,
        'juli': 7,
        'august': 8,
        'september': 9,
        'oktober': 10,
        'november': 11,
        'desember': 12
    };

    function get_date(date_string) {
        var date_elements = date_string.split(" ");
        var day = date_elements[0];
        var month = months[date_elements[1]];
        var year = 2013;
        return year + '-' + month + '-' + day;
    }

    fs.readFile('./parser/examples/thismonth.html', 'utf-8', function (err, data) {
        var $ = cheerio.load(data);
        $('div.event').each(function (i, event) {
            var event_date = $(event).children('.event_date');
            var date = $(event_date).find('.eventDay').text();
            var time = $(event_date).find('.eventTime').text();
            var title = $(event).find('.event_text h1 a').text().trim();
            var location_raw = $(event).find('span a').first();
            var location = location_raw.text().trim();
            var category = $(location_raw).next().next().text().trim();
            var hit = locations[location];
            if (hit) {
                markers.push({
                    title: title,
                    location: location,
                    category: category,
                    date: get_date(date),
                    time: time,
                    lat: hit.lat,
                    lon: hit.lon
                });
            } else {
                console.log(location, "not found");
            }
        });
        return res.json(200, markers);
    });
};
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var got = require('got');
var through2 = require('through2');
var split = require('split');
var changeCase = require('change-case');

var errorListUrl = 'http://src.chromium.org/svn/trunk/src/net/base/net_error_list.h';

var types = {
	0: 'system',
	100: 'connection',
	200: 'certificate',
	300: 'http',
	400: 'cache',
	500: 'unknown',
	600: 'ftp',
	700: 'certificate-manager',
	800: 'dns'
};

var sinkStream = through2(function (chunk, enc, next) {
	next();
});

var segmentsStream = (function () {
	var netErrorReg = /^NET_ERROR\(([A-Z_]+), ([0-9-]+)\)$/;
	var stream = through2.obj(function (line, enc, callback) {
		function next () {
			stream.push(line);
			return callback();
		}

		function inc () {
			stream.currentSegment += 1;
		}

		function addToSegment (line) {
			var seg = stream.segments[stream.currentSegment] || '';
			if (seg !== '') {
				seg += '\n';
			}

			seg += line;
			stream.segments[stream.currentSegment] = seg;
		}

		function prevSegment () {
			return stream.segments[stream.currentSegment - 1] || '';
		}

		if (/^\s*$/.test(line)) {
			inc();
			return next();
		}

		if (netErrorReg.test(line)) {
			inc();
			addToSegment(line)

			var matches = netErrorReg.exec(line);

			var errorCode = parseInt(matches[2], 10);
			var errorMessage = prevSegment();
			var errorName = changeCase.pascalCase(matches[1]);
			var errorType = types[Math.floor(Math.abs(errorCode) / 100) * 100];

			if (!(/Error$/.test(errorName))) {
				errorName += 'Error';
			}

			stream.errors.push({
				name: changeCase.pascalCase(errorName),
				code: errorCode,
				type: errorType,
				message: errorMessage
			});

		} else {
			line = line.replace(/^\/\/\s*/, '');
			addToSegment(line);
		}

		return next();

	});

	stream.errors = [];
	stream.currentSegment = 0;
	stream.segments = [];

	return stream;
})();

var lineCount = 0;

got(errorListUrl)
	.pipe(split())
	.pipe(segmentsStream)
	.pipe(sinkStream)
	.on('finish', function () {
		fs.writeFile(
			path.resolve('./errors.json'),
			JSON.stringify(segmentsStream.errors, null, '  '),
			{ encoding: 'utf-8' },
			function (err) {
				if (err) { throw err; }

				console.log('done');
			}
		);
	});
<commit_msg>Update error list headres file URL (thanks @cognitom)<commit_after>var fs = require('fs');
var path = require('path');
var got = require('got');
var through2 = require('through2');
var split = require('split');
var changeCase = require('change-case');

var errorListUrl = 'https://cs.chromium.org/codesearch/f/chromium/src/net/base/net_error_list.h';

var types = {
	0: 'system',
	100: 'connection',
	200: 'certificate',
	300: 'http',
	400: 'cache',
	500: 'unknown',
	600: 'ftp',
	700: 'certificate-manager',
	800: 'dns'
};

var sinkStream = through2(function (chunk, enc, next) {
	next();
});

var segmentsStream = (function () {
	var netErrorReg = /^NET_ERROR\(([A-Z_]+), ([0-9-]+)\)$/;
	var stream = through2.obj(function (line, enc, callback) {
		function next () {
			stream.push(line);
			return callback();
		}

		function inc () {
			stream.currentSegment += 1;
		}

		function addToSegment (line) {
			var seg = stream.segments[stream.currentSegment] || '';
			if (seg !== '') {
				seg += '\n';
			}

			seg += line;
			stream.segments[stream.currentSegment] = seg;
		}

		function prevSegment () {
			return stream.segments[stream.currentSegment - 1] || '';
		}

		if (/^\s*$/.test(line)) {
			inc();
			return next();
		}

		if (netErrorReg.test(line)) {
			inc();
			addToSegment(line)

			var matches = netErrorReg.exec(line);

			var errorCode = parseInt(matches[2], 10);
			var errorMessage = prevSegment();
			var errorName = changeCase.pascalCase(matches[1]);
			var errorType = types[Math.floor(Math.abs(errorCode) / 100) * 100];

			if (!(/Error$/.test(errorName))) {
				errorName += 'Error';
			}

			stream.errors.push({
				name: changeCase.pascalCase(errorName),
				code: errorCode,
				type: errorType,
				message: errorMessage
			});

		} else {
			line = line.replace(/^\/\/\s*/, '');
			addToSegment(line);
		}

		return next();

	});

	stream.errors = [];
	stream.currentSegment = 0;
	stream.segments = [];

	return stream;
})();

var lineCount = 0;

got(errorListUrl)
	.pipe(split())
	.pipe(segmentsStream)
	.pipe(sinkStream)
	.on('finish', function () {
		fs.writeFile(
			path.resolve('./errors.json'),
			JSON.stringify(segmentsStream.errors, null, '  '),
			{ encoding: 'utf-8' },
			function (err) {
				if (err) { throw err; }

				console.log('done');
			}
		);
	});
<|endoftext|>


<commit_before>var words = {
	plus : "",
	minus : "",
	multiplyBy: "",
	divideBy: ""
}

function getRelevantWords(word)
{
	var wordArray = Object.getOwnPropertyNames(words);
	var relevantWords = [];
	for(var i = 0; i < wordArray.length; i++)
	{
		if(wordArray[i].toLowerCase().substr(0, word.length) == word.toLowerCase())
		{
			relevantWords.push(wordArray[i]);
		}
	}
	return relevantWords;
}

function optionString(item, classText)
{
	var selectedString = "";

	if(classText != null && classText != undefined)
	{
		selectedString = classText;
	}

	return "
" + item + "
";
}

function fullOptionString(items)
{
	var result = "";

	for(var i = 0; i < items.length; i++)
	{
		if(i == 0){ result += optionString(items[i], selected) };
		else{	result += optionString(items[i]); }
	}
	return result;
}

function autoComplete()
{
	$("#math-words").removeClass("hidden");

	var typedText = $("textarea").val();

	var relevantWord =  typedText.split(' ').pop();

	$("#math-words").html( fullOptionString( getRelevantWords(relevantWord) ));
}

function SetCursorEnd(tID) {
    tID += "";
    $(tID).focus();
    var t = $(tID).val();
    if (t.length == 0) { return; }
    $(tID).val("");
    $(tID).val(t);
    $(tID).scrollTop($(tID)[0].scrollHeight);
}

function replaceText(replacementText)
{
	var typedText = $("textarea").val();
	var index = typedText.lastIndexOf(" ");
	if(index == null || index == undefined)	{
		index = 1;
	}
	var resultText = typedText.substr(0, index) + " " + replacementText;
	$("textarea").val(resultText);
	SetCursorEnd("#code-text");
}

$('body').on('click', '.ac-option', function() {
	replaceText($(this).text());
});

$('textarea').on( 'keydown', function( e ) {
    if( e.which == 9 ) {
    	e.preventDefault();
        console.log( e.target.href );

        replaceText($(".ac-option.selected").text());
    }
} );
<commit_msg>Update autocomplete.js<commit_after>var words = {
	plus : "",
	minus : "",
	multiplyBy: "",
	divideBy: ""
}

function getRelevantWords(word)
{
	var wordArray = Object.getOwnPropertyNames(words);
	var relevantWords = [];
	for(var i = 0; i < wordArray.length; i++)
	{
		if(wordArray[i].toLowerCase().substr(0, word.length) == word.toLowerCase())
		{
			relevantWords.push(wordArray[i]);
		}
	}
	return relevantWords;
}

function optionString(item, classText)
{
	var selectedString = "";

	if(classText != null && classText != undefined)
	{
		selectedString = classText;
	}

	return "
" + item + "
";
}

function fullOptionString(items)
{
	var result = "";

	for(var i = 0; i < items.length; i++)
	{
		if(i == 0){ result += optionString(items[i], selected) }
		else{	result += optionString(items[i]); }
	}
	return result;
}

function autoComplete()
{
	$("#math-words").removeClass("hidden");

	var typedText = $("textarea").val();

	var relevantWord =  typedText.split(' ').pop();

	$("#math-words").html( fullOptionString( getRelevantWords(relevantWord) ));
}

function SetCursorEnd(tID) {
    tID += "";
    $(tID).focus();
    var t = $(tID).val();
    if (t.length == 0) { return; }
    $(tID).val("");
    $(tID).val(t);
    $(tID).scrollTop($(tID)[0].scrollHeight);
}

function replaceText(replacementText)
{
	var typedText = $("textarea").val();
	var index = typedText.lastIndexOf(" ");
	if(index == null || index == undefined)	{
		index = 1;
	}
	var resultText = typedText.substr(0, index) + " " + replacementText;
	$("textarea").val(resultText);
	SetCursorEnd("#code-text");
}

$('body').on('click', '.ac-option', function() {
	replaceText($(this).text());
});

$('textarea').on( 'keydown', function( e ) {
    if( e.which == 9 ) {
    	e.preventDefault();
        console.log( e.target.href );

        replaceText($(".ac-option.selected").text());
    }
} );
<|endoftext|>


<commit_before>// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

'use strict';

var Amqp = require('azure-iot-device-amqp').Amqp;
// Uncomment one of these transports and then change it in fromConnectionString to test other transports
// var AmqpWs = require('azure-iot-device-amqp-ws').AmqpWs;
// var Http = require('azure-iot-device-http').Http;
// var Mqtt = require('azure-iot-device-mqtt').Mqtt;
var Client = require('azure-iot-device').Client;
var Message = require('azure-iot-device').Message;

// String containing Hostname, Device Id & Device Key in the following formats:
//  "HostName=<iothub_host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>"
var connectionString = '[IoT device connection string]';

// fromConnectionString must specify a transport constructor, coming from any transport package.
var client = Client.fromConnectionString(connectionString, Amqp);

var connectCallback = function (err) {
  if (err) {
    console.err('Could not connect: ' + err.message);
  } else {
    console.log('Client connected');
    client.on('message', function (msg) {
      console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);
      client.complete(msg, printResultFor('completed'));
      // reject and abandon follow the same pattern.
      // /!\ reject and abandon are not available with MQTT
    });

    // Create a message and send it to the IoT Hub every second
    var sendInterval = setInterval(function () {
      var windSpeed = 10 + (Math.random() * 4); // range: [10, 14]
      var data = JSON.stringify({ deviceId: 'myFirstDevice', windSpeed: windSpeed });
      var message = new Message(data);
      message.properties.add('myproperty', 'myvalue');
      console.log('Sending message: ' + message.getData());
      client.sendEvent(message, printResultFor('send'));
    }, 2000);

    client.on('error', function (err) {
      console.error(err.message);
    });

    client.on('disconnect', function () {
      clearInterval(sendInterval);
      client.removeAllListeners();
      client.connect(connectCallback);
    });
  }
};

client.open(connectCallback);

// Helper function to print results in the console
function printResultFor(op) {
  return function printResult(err, res) {
    if (err) console.log(op + ' error: ' + err.toString());
    if (res) console.log(op + ' status: ' + res.constructor.name);
  };
}
<commit_msg>Fix a typo of cosole.error<commit_after>// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

'use strict';

var Amqp = require('azure-iot-device-amqp').Amqp;
// Uncomment one of these transports and then change it in fromConnectionString to test other transports
// var AmqpWs = require('azure-iot-device-amqp-ws').AmqpWs;
// var Http = require('azure-iot-device-http').Http;
// var Mqtt = require('azure-iot-device-mqtt').Mqtt;
var Client = require('azure-iot-device').Client;
var Message = require('azure-iot-device').Message;

// String containing Hostname, Device Id & Device Key in the following formats:
//  "HostName=<iothub_host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>"
var connectionString = '[IoT device connection string]';

// fromConnectionString must specify a transport constructor, coming from any transport package.
var client = Client.fromConnectionString(connectionString, Amqp);

var connectCallback = function (err) {
  if (err) {
    console.error('Could not connect: ' + err.message);
  } else {
    console.log('Client connected');
    client.on('message', function (msg) {
      console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);
      client.complete(msg, printResultFor('completed'));
      // reject and abandon follow the same pattern.
      // /!\ reject and abandon are not available with MQTT
    });

    // Create a message and send it to the IoT Hub every second
    var sendInterval = setInterval(function () {
      var windSpeed = 10 + (Math.random() * 4); // range: [10, 14]
      var data = JSON.stringify({ deviceId: 'myFirstDevice', windSpeed: windSpeed });
      var message = new Message(data);
      message.properties.add('myproperty', 'myvalue');
      console.log('Sending message: ' + message.getData());
      client.sendEvent(message, printResultFor('send'));
    }, 2000);

    client.on('error', function (err) {
      console.error(err.message);
    });

    client.on('disconnect', function () {
      clearInterval(sendInterval);
      client.removeAllListeners();
      client.connect(connectCallback);
    });
  }
};

client.open(connectCallback);

// Helper function to print results in the console
function printResultFor(op) {
  return function printResult(err, res) {
    if (err) console.log(op + ' error: ' + err.toString());
    if (res) console.log(op + ' status: ' + res.constructor.name);
  };
}
<|endoftext|>


<commit_before>ON_THRESHOLD = 500;

sendRequest = function(uri, method, data, is_async) {
  var request = {
    url: uri,
    type: method,
    contentType: "application/json",
    accepts: "application/json",
    cache: false,
    dataType: 'json',
    async: is_async,
    data: JSON.stringify(data),
    error: function(jqXHR) {
      console.log("ajax error " + jqXHR.status);
    }
  };
  return $.ajax(request);
}

getLast = function(list) {
  return list[list.length - 1];
}

getData = function() {
  sendRequest("laundrydude/api/data", 'GET').done(function(data) {
    var chart_data = null;

    showHumidity(getLast(data['h']));
    showLight(getLast(data['l']));

    console.log('humid');
    humidity_chart_data = initChartData('Humidity', data['h']);
    humidity_chart.draw(humidity_chart_data, humidity_options);

    console.log('light');
    light_chart_data = initChartData('Light', data['l']);
    light_chart.draw(light_chart_data, light_options);
  })
}

showHumidity = function(humidity_data) {
  var humidity_value = null;

  if (humidity_data)
    humidity_value = humidity_data[1] + " %"

  showData(humidity_value, '#humidity');
}

showLight = function(light_data) {
  var on_state = null;

  if (light_data[1] > ON_THRESHOLD)
    on_state = ('ON');
  else
    on_state = ('OFF');

  showData(on_state, '#light');
}

showData = function(data, tag_id) {
  if (data)
    $(tag_id + "-value").text(data);
  else
    $(tag_id + "-value").text("No data");
}

formatTime = function(unix_timestamp) {
  var date = new Date(unix_timestamp*1000);

  var hours = "0" + date.getHours();
  var minutes = "0" + date.getMinutes();
  var seconds = "0" + date.getSeconds();

  //return hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
  return [date.getHours() % 24, date.getMinutes(), date.getSeconds()];
}

var humidity_chart = null;
var common_options = {
  legend: {
    position: 'none'
  },
  hAxis: {
    viewWindow: {
      min: [16, 15, 0,],
      max: [20,15,0]
    }
  }
};

var light_options = jQuery.extend(true, {}, common_options);
light_options.colors = ['#558B2F'];
light_options.vAxis = {
  viewWindow: {
      min: 0,
      max: 1000
  }
};

var humidity_options = jQuery.extend(true, {}, common_options);
humidity_options.colors = ['#0277BD'];
humidity_options.vAxis = {
  viewWindow: {
      min: 0,
      max: 100
  }
};

google.load('visualization', '1.1', {packages: ['corechart', 'line']});
google.setOnLoadCallback(drawBackgroundColor);

function initChartData(column_name, rows) {
  var chart_data = new google.visualization.DataTable();

  chart_data.addColumn('timeofday', 'Time of day');
  chart_data.addColumn('number', column_name);

  chart_data.addRows(rows);

  return chart_data;
}

function drawBackgroundColor() {
  humidity_chart = new google.visualization.LineChart(
    document.getElementById('humidity_chart_div'));
  light_chart = new google.visualization.LineChart(
    document.getElementById('light_chart_div'));

  getData();
  window.setInterval(getData, 5000);
}

<commit_msg>[Web] Full day graphs.<commit_after>ON_THRESHOLD = 500;

sendRequest = function(uri, method, data, is_async) {
  var request = {
    url: uri,
    type: method,
    contentType: "application/json",
    accepts: "application/json",
    cache: false,
    dataType: 'json',
    async: is_async,
    data: JSON.stringify(data),
    error: function(jqXHR) {
      console.log("ajax error " + jqXHR.status);
    }
  };
  return $.ajax(request);
}

getLast = function(list) {
  return list[list.length - 1];
}

getData = function() {
  sendRequest("laundrydude/api/data", 'GET').done(function(data) {
    var chart_data = null;

    showHumidity(getLast(data['h']));
    showLight(getLast(data['l']));

    console.log('humid');
    humidity_chart_data = initChartData('Humidity', data['h']);
    humidity_chart.draw(humidity_chart_data, humidity_options);

    console.log('light');
    light_chart_data = initChartData('Light', data['l']);
    light_chart.draw(light_chart_data, light_options);
  })
}

showHumidity = function(humidity_data) {
  var humidity_value = null;

  if (humidity_data)
    humidity_value = humidity_data[1] + " %"

  showData(humidity_value, '#humidity');
}

showLight = function(light_data) {
  var on_state = null;

  if (light_data[1] > ON_THRESHOLD)
    on_state = ('ON');
  else
    on_state = ('OFF');

  showData(on_state, '#light');
}

showData = function(data, tag_id) {
  if (data)
    $(tag_id + "-value").text(data);
  else
    $(tag_id + "-value").text("No data");
}

formatTime = function(unix_timestamp) {
  var date = new Date(unix_timestamp*1000);

  var hours = "0" + date.getHours();
  var minutes = "0" + date.getMinutes();
  var seconds = "0" + date.getSeconds();

  //return hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
  return [date.getHours() % 24, date.getMinutes(), date.getSeconds()];
}

var humidity_chart = null;
var common_options = {
  legend: {
    position: 'none'
  },
  hAxis: {
    viewWindow: {
      min: [0, 0, 0,],
      max: [24,0,0]
    }
  }
};

var light_options = jQuery.extend(true, {}, common_options);
light_options.colors = ['#558B2F'];
light_options.vAxis = {
  viewWindow: {
      min: 0,
      max: 1000
  }
};

var humidity_options = jQuery.extend(true, {}, common_options);
humidity_options.colors = ['#0277BD'];
humidity_options.vAxis = {
  viewWindow: {
      min: 0,
      max: 100
  }
};

google.load('visualization', '1.1', {packages: ['corechart', 'line']});
google.setOnLoadCallback(drawBackgroundColor);

function initChartData(column_name, rows) {
  var chart_data = new google.visualization.DataTable();

  chart_data.addColumn('timeofday', 'Time of day');
  chart_data.addColumn('number', column_name);

  chart_data.addRows(rows);

  return chart_data;
}

function drawBackgroundColor() {
  humidity_chart = new google.visualization.LineChart(
    document.getElementById('humidity_chart_div'));
  light_chart = new google.visualization.LineChart(
    document.getElementById('light_chart_div'));

  getData();
  window.setInterval(getData, 5000);
}

<|endoftext|>


<commit_before>(function () {

  'use strict';

  module.exports = function () {

    // You can use normal require here, cucumber is NOT run in a Meteor context (by design)
    var url = require('url');
    var path = require('path');

    this.Given(/^I am a new user$/, function () {
      // no callbacks! DDP has been promisified so you can just return it
      return this.server.call('reset', []); // this.ddp is a connection to the mirror
    });

    this.Given(/^I am on route "([^"]*)"$/, function (relativePath, callback) {
      // WebdriverIO supports Promises/A+ out the box, so you can return that too
      this.browser. // this.browser is a pre-configured WebdriverIO + PhantomJS instance
        url(url.resolve(process.env.HOST, relativePath)). // process.env.HOST always points to the mirror
        call(callback);
    });

    this.Then(/^I should see the title "([^"]*)"$/, function (expectedTitle, callback) {
      // you can use chai-as-promised in step definitions also
      this.browser.
        waitForVisible('h1'). // WebdriverIO chain-able promise magic
        getTitle().should.become(expectedTitle).and.notify(callback);
    });

    this.When(/^I upload a new image$/, function (callback) {
      var filePath = path.join(__filename, '../../../files/face.png');
      this.browser
        //.chooseFile('#upload-file', '/home/netanel/Pictures/hospital.jpg')
        .click('#upload-file')
        .keys(filePath)
        .pause(1000)
        .call(callback);
    });

    this.Then(/^I should see the image in the table$/, function (callback) {
      this.browser
        .getText('table tr:first-child a')
        .should.eventually.equal('face.png').and.notify(callback);
    });

  };

})();
<commit_msg>Try to fix test<commit_after>(function () {

  'use strict';

  module.exports = function () {

    // You can use normal require here, cucumber is NOT run in a Meteor context (by design)
    var url = require('url');
    var path = require('path');

    this.Given(/^I am a new user$/, function () {
      // no callbacks! DDP has been promisified so you can just return it
      return this.server.call('reset', []); // this.ddp is a connection to the mirror
    });

    this.Given(/^I am on route "([^"]*)"$/, function (relativePath, callback) {
      // WebdriverIO supports Promises/A+ out the box, so you can return that too
      this.browser. // this.browser is a pre-configured WebdriverIO + PhantomJS instance
        url(url.resolve(process.env.HOST, relativePath)). // process.env.HOST always points to the mirror
        call(callback);
    });

    this.Then(/^I should see the title "([^"]*)"$/, function (expectedTitle, callback) {
      // you can use chai-as-promised in step definitions also
      this.browser.
        waitForVisible('h1'). // WebdriverIO chain-able promise magic
        getTitle().should.become(expectedTitle).and.notify(callback);
    });

    this.When(/^I upload a new image$/, function (callback) {
      var filePath = path.join(__filename, '../../../files/face.png');
      this.browser
        //.chooseFile('#upload-file', '/home/netanel/Pictures/hospital.jpg')
        .click('#upload-file')
        .keys(filePath)
        .pause(3000)
        .call(callback);
    });

    this.Then(/^I should see the image in the table$/, function (callback) {
      this.browser
        .getText('table tr:first-child a')
        .should.eventually.equal('face.png').and.notify(callback);
    });

  };

})();
<|endoftext|>


<commit_before>/* globals module, require */
'use strict';
const MergeTrees = require('broccoli-merge-trees');
const Funnel = require('broccoli-funnel');
const Rollup = require('broccoli-rollup');
const path = require('path');
const typescript = require('broccoli-typescript-compiler').typescript;
const buble = require('rollup-plugin-buble');
const fs = require('fs');

const SOURCE_MAPPING_DATA_URL = '//# sourceMap' + 'pingURL=data:application/json;base64,';

module.exports = function (app) {
  const src = new MergeTrees([
    new Funnel(path.dirname(require.resolve('@types/qunit/package')), {
      destDir: 'qunit',
      include: ['index.d.ts']
    }),
    new Funnel(__dirname + '/lib', {
      destDir: 'lib'
    }),
    new Funnel(__dirname + '/tests', {
      destDir: 'tests'
    })
  ]);

  const compiled = typescript(src, {
    throwOnError: process.env.EMBER_ENV === 'production',
    tsconfig: {
      compilerOptions: {
        baseUrl: '.',
        inlineSourceMap: true,
        inlineSources: true,
        module: 'es2015',
        moduleResolution: 'node',
        paths: {
          backburner: ['lib/index.ts']
        },
        strictNullChecks: true,
        target: 'es2015'
      },
      files: ['qunit/index.d.ts', 'lib/index.ts', 'tests/index.ts']
    }
  });

  const backburner = new Rollup(compiled, {
    rollup: {
      input: 'lib/index.js',
      output: {
        file: 'es6/backburner.js',
        format: 'es',
        sourcemap: true
      },
      format: 'es',
      plugins: [
        loadWithInlineMap()
      ]
    }
  });

  return new MergeTrees([
    backburner,
    new Rollup(compiled, {
      rollup: {
        input: 'lib/index.js',
        plugins: [
          loadWithInlineMap(),
          buble()
        ],
        output: [{
          file: 'named-amd/backburner.js',
          exports: 'named',
          format: 'amd',
          moduleId: 'backburner',
          sourcemap: true
        }, {
          file: 'backburner.js',
          format: 'cjs',
          sourcemap: true
        }]
      }
    }),
    new Rollup(compiled, {
      annotation: 'named-amd/tests.js',
      rollup: {
        input: 'tests/index.js',
        external: ['backburner'],
        plugins: [
          loadWithInlineMap(),
          buble()
        ],
        output: [{
          file: 'named-amd/tests.js',
          format: 'amd',
          moduleId: 'backburner-tests',
          sourcemap: true
        }]
      }
    }),
    new Funnel(path.dirname(require.resolve('qunitjs')), {
      annotation: 'tests/qunit.{js,css}',
      destDir: 'tests',
      files: ['qunit.css', 'qunit.js']
    }),
    new Funnel(path.dirname(require.resolve('loader.js')), {
      annotation: 'tests/loader.js',
      destDir: 'tests',
      files: ['loader.js']
    }),
    new Funnel(__dirname + '/tests', {
      destDir: 'tests',
      files: ['index.html']
    })
  ], {
    annotation: 'dist'
  });
};

function loadWithInlineMap() {
  return {
    load: function (id) {
      var code = fs.readFileSync(id, 'utf8');
      var result = {
        code: code,
        map: null
      };
      var index = code.lastIndexOf(SOURCE_MAPPING_DATA_URL);
      if (index === -1) {
        return result;
      }
      result.code = code.slice(0, index);
      result.map = parseSourceMap(code.slice(index + SOURCE_MAPPING_DATA_URL.length));
      result.file = id;
      console.log(id);
      console.log(result.map.sources);
      console.log(result.map.sourcesContent.map((c) => !!c));
      return result;
    }
  };
}

function parseSourceMap(base64) {
  return JSON.parse(new Buffer(base64, 'base64').toString('utf8'));
}
<commit_msg>Allow broccoli-typescript-compiler to resolve @types.<commit_after>/* globals module, require */
'use strict';
const MergeTrees = require('broccoli-merge-trees');
const Funnel = require('broccoli-funnel');
const Rollup = require('broccoli-rollup');
const path = require('path');
const typescript = require('broccoli-typescript-compiler').typescript;
const buble = require('rollup-plugin-buble');
const fs = require('fs');

const SOURCE_MAPPING_DATA_URL = '//# sourceMap' + 'pingURL=data:application/json;base64,';

module.exports = function (app) {
  const src = new MergeTrees([
    new Funnel(__dirname + '/lib', {
      destDir: 'lib'
    }),
    new Funnel(__dirname + '/tests', {
      destDir: 'tests'
    })
  ]);

  const compiled = typescript(src, {
    throwOnError: process.env.EMBER_ENV === 'production',
    tsconfig: {
      compilerOptions: {
        baseUrl: '.',
        inlineSourceMap: true,
        inlineSources: true,
        module: 'es2015',
        moduleResolution: 'node',
        paths: {
          backburner: ['lib/index.ts']
        },
        strictNullChecks: true,
        target: 'es2015'
      },
      files: ['qunit/index.d.ts', 'lib/index.ts', 'tests/index.ts']
    }
  });

  const backburner = new Rollup(compiled, {
    rollup: {
      input: 'lib/index.js',
      output: {
        file: 'es6/backburner.js',
        format: 'es',
        sourcemap: true
      },
      format: 'es',
      plugins: [
        loadWithInlineMap()
      ]
    }
  });

  return new MergeTrees([
    backburner,
    new Rollup(compiled, {
      rollup: {
        input: 'lib/index.js',
        plugins: [
          loadWithInlineMap(),
          buble()
        ],
        output: [{
          file: 'named-amd/backburner.js',
          exports: 'named',
          format: 'amd',
          moduleId: 'backburner',
          sourcemap: true
        }, {
          file: 'backburner.js',
          format: 'cjs',
          sourcemap: true
        }]
      }
    }),
    new Rollup(compiled, {
      annotation: 'named-amd/tests.js',
      rollup: {
        input: 'tests/index.js',
        external: ['backburner'],
        plugins: [
          loadWithInlineMap(),
          buble()
        ],
        output: [{
          file: 'named-amd/tests.js',
          format: 'amd',
          moduleId: 'backburner-tests',
          sourcemap: true
        }]
      }
    }),
    new Funnel(path.dirname(require.resolve('qunitjs')), {
      annotation: 'tests/qunit.{js,css}',
      destDir: 'tests',
      files: ['qunit.css', 'qunit.js']
    }),
    new Funnel(path.dirname(require.resolve('loader.js')), {
      annotation: 'tests/loader.js',
      destDir: 'tests',
      files: ['loader.js']
    }),
    new Funnel(__dirname + '/tests', {
      destDir: 'tests',
      files: ['index.html']
    })
  ], {
    annotation: 'dist'
  });
};

function loadWithInlineMap() {
  return {
    load: function (id) {
      var code = fs.readFileSync(id, 'utf8');
      var result = {
        code: code,
        map: null
      };
      var index = code.lastIndexOf(SOURCE_MAPPING_DATA_URL);
      if (index === -1) {
        return result;
      }
      result.code = code.slice(0, index);
      result.map = parseSourceMap(code.slice(index + SOURCE_MAPPING_DATA_URL.length));
      result.file = id;
      console.log(id);
      console.log(result.map.sources);
      console.log(result.map.sourcesContent.map((c) => !!c));
      return result;
    }
  };
}

function parseSourceMap(base64) {
  return JSON.parse(new Buffer(base64, 'base64').toString('utf8'));
}
<|endoftext|>


<commit_before>/**
 * CSS files to inject in order
 * (uses Grunt-style wildcard/glob/splat expressions)
 *
 * By default, Sails also supports LESS in development and production.
 * To use SASS/SCSS, Stylus, etc., edit the `sails-linker:devStyles` task
 * below for more options.  For this to work, you may need to install new
 * dependencies, e.g. `npm install grunt-contrib-sass`
 */
var cssFilesToInject = [
  'linker/**/*.css'
];

/**
 * Javascript files to inject in order
 * (uses Grunt-style wildcard/glob/splat expressions)
 *
 * To use client-side CoffeeScript, TypeScript, etc., edit the
 * `sails-linker:devJs` task below for more options.
 */

var jsFilesToInject = [

  // Below, as a demonstration, you'll see the built-in dependencies
  // linked in the proper order order

  // Bring in the socket.io client
  'linker/js/socket.io.js',

  // then beef it up with some convenience logic for talking to Sails.js
  'linker/js/sails.io.js',

  // A simpler boilerplate library for getting you up and running w/ an
  // automatic listener for incoming messages from Socket.io.
  'linker/js/app.js',

  // *->    put other dependencies here   <-*

  // All of the rest of your app scripts imported here
  'linker/**/*.js'
];

/**
 * Client-side HTML templates are injected using the sources below
 * The ordering of these templates shouldn't matter.
 * (uses Grunt-style wildcard/glob/splat expressions)
 *
 * By default, Sails uses JST templates and precompiles them into
 * functions for you.  If you want to use jade, handlebars, dust, etc.,
 * edit the relevant sections below.
 */

var templateFilesToInject = [
  'linker/**/*.html'
]

module.exports = {
  // Modify css file injection paths to use
  cssFilesToInject: cssFilesToInject.map(function(path) {
    return '.tmp/public/' + path;
  }),

  // Modify js file injection paths to use
  jsFilesToInject: jsFilesToInject.map(function(path) {
    return '.tmp/public/' + path;
  }),

  templateFilesToInject: templateFilesToInject.map(function(path) {
    return 'assets/' + path;
  })
};
<commit_msg>Updated injected files to not point to linker dir<commit_after>/**
 * CSS files to inject in order
 * (uses Grunt-style wildcard/glob/splat expressions)
 *
 * By default, Sails also supports LESS in development and production.
 * To use SASS/SCSS, Stylus, etc., edit the `sails-linker:devStyles` task
 * below for more options.  For this to work, you may need to install new
 * dependencies, e.g. `npm install grunt-contrib-sass`
 */
var cssFilesToInject = [
  'styles/**/*.css'
];

/**
 * Javascript files to inject in order
 * (uses Grunt-style wildcard/glob/splat expressions)
 *
 * To use client-side CoffeeScript, TypeScript, etc., edit the
 * `sails-linker:devJs` task below for more options.
 */

var jsFilesToInject = [

  // Below, as a demonstration, you'll see the built-in dependencies
  // linked in the proper order order

  // Bring in the socket.io client
  'js/socket.io.js',

  // then beef it up with some convenience logic for talking to Sails.js
  'js/sails.io.js',

  // A simpler boilerplate library for getting you up and running w/ an
  // automatic listener for incoming messages from Socket.io.
  'js/app.js',

  // *->    put other dependencies here   <-*

  // All of the rest of your app scripts imported here
  'js/**/*.js'
];

/**
 * Client-side HTML templates are injected using the sources below
 * The ordering of these templates shouldn't matter.
 * (uses Grunt-style wildcard/glob/splat expressions)
 *
 * By default, Sails uses JST templates and precompiles them into
 * functions for you.  If you want to use jade, handlebars, dust, etc.,
 * edit the relevant sections below.
 */

var templateFilesToInject = [
  'template/**/*.html'
]

module.exports = {
  // Modify css file injection paths to use
  cssFilesToInject: cssFilesToInject.map(function(path) {
    return '.tmp/public/' + path;
  }),

  // Modify js file injection paths to use
  jsFilesToInject: jsFilesToInject.map(function(path) {
    return '.tmp/public/' + path;
  }),

  templateFilesToInject: templateFilesToInject.map(function(path) {
    return 'assets/' + path;
  })
};
<|endoftext|>


<commit_before>/*
* jquery pager plugin
* 만든이: 정대규
* 일시: 2015.10.08
* 버전: 0.1
* lisence: MIT(공짜)
*/

$.fn.pagify = function(settings){
    var defaults = {
        current: 1 //현재 페이지 번호(text)
        , total: 0 //전체 건수
        , pager: 10 //web에서는 보통 pager를 10개로 노출한다.
        , combo: [10, 20, 30, 50] //콤보박스의 선택에 대한 부분은 추후 개발 예정임.
        , list: 20 //한 화면에 listing될 갯수를 지정.
        , showCombo: true//콤보박스의 선택에 대한 부분은 추후 개발 예정임.
        , showFirstEnd: true//처음/끝 버튼을 보일지 여부.
		, attr: "offset" //set custom attr name

        , first: function(min){ //'처음' 버튼
            return {[this.attr] : min - 1, "text": min};
        }
        , prev: function(num, min){ //'이전' 버튼
            var _prev = (num - 1) * this.pager - this.pager + 1;
            return _prev < min ? {[this.attr]: min - 1, "text": min} : {[this.attr]: _prev - 1, "text": _prev};
        }
        , from: function(num){ //'pager 시작' 번호
            return num === 1 ? 1 : num * this.pager - this.pager + 1;
        }
        , to: function(num){ //'pager 끝' 번호
            return num === 1 ? this.pager : num * this.pager;
        }
        , next: function(num, max){ //'다음' 버튼
            var _next = num * this.pager + 1;
            return _next > max ? {[this.attr]: max - 1, "text": max} : {[this.attr]: _next - 1, "text": _next};
        }
        , end: function(max){ //'끝' 버튼
            return {[this.attr]: max - 1, "text": max};
        }

        /*
        * 커스터마이징을 하는 가장 중요한 부분일 수 있음.
        * 원하는 형태로 아래 ui 부분을 수정해서 사용하면 됨.
        * 동적으로 그려진 객체가 되며, 클릭에 대한 이벤트는 플러그인 외부에서 처리하면 됨.
        */
        , ui: {
			style: function(idx){
				var _style = "text-decoration: none; font-size: 1.2em; pointer: cursor;";
				switch(idx){
					case 0:
						_style += " color: silver; padding: 0.3em;"
					break;
					case 1:
						_style += " color: gray; padding: 0.3em; font-weight: bold;"
					break;
					default:
						_style += " color: gray; font-weight: bold;"
					break;
				}
				return " style='" + _style + "'";
			}
			/* easy set buttons
            , first: function(num, text){ //'처음' 버튼
                return " ≪ \n";
            }
            , prev: function(num, text){ //'이전' 버튼
                return " ＜ \n";
            }
            , pager: function(num, text, isCurrent){ //'pager' 버튼 전체
                return "" + text + "\n";
            }
            , next: function(num, text){ //'다음' 버튼
                return " ＞ \n";
            }
            , end: function(num, text){ //'끝' 버튼
                return " ≫ \n";
            }
			*/
			/* default set buttons */
			, nav: function(type, num, text){
				var _type = "";
				switch(type){
					case "first":
						_type = "≪";
					break;
					case "prev":
						_type = "＜";
					break;
					case "next":
						_type = "＞";
					break;
					case "end":
						_type = "≫";
					break;
				}
                return " " + _type + " \n";
			}
        } //end: , ui: {
    } //end: var defaults = {

    /*
    * 플러그인의 실행부
    */
    $.extend(true, defaults, settings); //ui 부분을 위한 deep copy

    var listed = Math.ceil(defaults.total / defaults.list); //리스트화된 전체 건수
    var paged = Math.ceil(listed / defaults.pager); //pager 그룹의 건수
    var result = {};

    for(var i = 0; i <= paged; i++){
        var fromTo = [];
        var inPaged = false;

        /* pager fromTo를 먼저 구한다. */
        for(var j = defaults.from(i), num = j - 1; j <= defaults.to(i); j++, num++){
            if(j <= listed){
                if(j === defaults.current){
                    inPaged = true;
                }
                fromTo.push({[defaults.attr]: num, "text": j, "isCurrent": j === defaults.current});
            }
        } //end: for(var j = defaults.from(i), num = j - 1; j <= defaults.to(i); j++, num++){

        if(inPaged){ //보여줄 pager에 해당되면
            if(defaults.showFirstEnd && paged > 1 && defaults.current !== 1){ //'처음' 버튼 추가 여부
                result.first = defaults.first(1);
            }
            if(defaults.current > defaults.pager){ //'이전' 버튼 추가 여부
                result.prev = defaults.prev(i, 1);
            }
            result.fromTo = fromTo; //미리 구한 'pager fromTo' 추가
            if(defaults.next(i, listed).text < defaults.end(listed).text){ //'다음' 버튼 추가 여부
                result.next = defaults.next(i, listed);
            }
            if(defaults.showFirstEnd && paged > 1 && defaults.current !== listed){ //'끝' 버튼 추가 여부
                result.end = defaults.end(listed);
            }
        } //end: if(inPaged){
    } //end: for(var i = 0; i <= paged; i++){

    return this.each(function(){
        var tags = "";
        var _ui = defaults.ui;

        /*
        * 동적으로 그릴 tag 작성
        * '처음, 끝' 버튼은 추후 작성 예정
        */
        for(var i in result){
            var _result = result[i];
            if(i === "fromTo"){
                for(var j = 0; j < _result.length; j++){
                    tags += _ui.pager(_result[j][defaults.attr], _result[j].text, _result[j].isCurrent);
                }
            }else{
                //tags += _ui[i](_result[defaults.attr], _result.text); //easy set buttons
                tags += _ui.nav(i, _result[defaults.attr], _result.text); //default set buttons
			}
        } //end: for(var i in result){

		if(defaults.showCombo){
			tags += "<select style='font-size: 1em;'>\n";
			for(var i = 0, combo = defaults.combo; i < combo.length; i++){
				tags += "\t<option value='" + combo[i] + "'" + (defaults.list === combo[i] ? " selected='selected'" : "") + ">"
					+ combo[i]
				+ "</option>\n";
			}
			tags += "</select>\n";
		} //end: if(defaults.showCombo){

        $(this).html(tags); //해당 객체에 결과 그려넣기.
    }); //end: return this.each(function(){
} //end: $.fn.pagify = function(settings){
<commit_msg>error fix<commit_after>/*
* jquery pager plugin
* 만든이: 정대규
* 일시: 2015.10.08
* 버전: 0.1
* lisence: MIT(공짜)
*/

$.fn.pagify = function(settings){
    var defaults = {
        current: 1 //현재 페이지 번호(text)
        , total: 0 //전체 건수
        , pager: 10 //web에서는 보통 pager를 10개로 노출한다.
        , combo: [10, 20, 30, 50] //콤보박스의 선택에 대한 부분은 추후 개발 예정임.
        , list: 20 //한 화면에 listing될 갯수를 지정.
        , showCombo: true//콤보박스의 선택에 대한 부분은 추후 개발 예정임.
        , showFirstEnd: true//처음/끝 버튼을 보일지 여부.
		, attr: "offset" //set custom attr name

        , first: function(min){ //'처음' 버튼
            return {[this.attr] : min - 1, "text": min};
        }
        , prev: function(num, min){ //'이전' 버튼
            var _prev = (num - 1) * this.pager - this.pager + 1;
            return _prev < min ? {[this.attr]: min - 1, "text": min} : {[this.attr]: _prev - 1, "text": _prev};
        }
        , from: function(num){ //'pager 시작' 번호
            return num === 1 ? 1 : num * this.pager - this.pager + 1;
        }
        , to: function(num){ //'pager 끝' 번호
            return num === 1 ? this.pager : num * this.pager;
        }
        , next: function(num, max){ //'다음' 버튼
            var _next = num * this.pager + 1;
            return _next > max ? {[this.attr]: max - 1, "text": max} : {[this.attr]: _next - 1, "text": _next};
        }
        , end: function(max){ //'끝' 버튼
            return {[this.attr]: max - 1, "text": max};
        }

        /*
        * 커스터마이징을 하는 가장 중요한 부분일 수 있음.
        * 원하는 형태로 아래 ui 부분을 수정해서 사용하면 됨.
        * 동적으로 그려진 객체가 되며, 클릭에 대한 이벤트는 플러그인 외부에서 처리하면 됨.
        */
        , ui: {
			style: function(idx){
				var _style = "text-decoration: none; font-size: 1.2em; pointer: cursor;";
				switch(idx){
					case 0:
						_style += " color: silver; padding: 0.3em;"
					break;
					case 1:
						_style += " color: gray; padding: 0.3em; font-weight: bold;"
					break;
					default:
						_style += " color: gray; font-weight: bold;"
					break;
				}
				return " style='" + _style + "'";
			} //end: style: function(idx){

			/* easy set buttons
            , first: function(num, text){ //'처음' 버튼
                return " ≪ \n";
            }
            , prev: function(num, text){ //'이전' 버튼
                return " ＜ \n";
            }
            , next: function(num, text){ //'다음' 버튼
                return " ＞ \n";
            }
            , end: function(num, text){ //'끝' 버튼
                return " ≫ \n";
            }
			*/

			/* default set buttons */
			, nav: function(type, num, text){
				var _type = "";
				switch(type){
					case "first":
						_type = "≪";
					break;
					case "prev":
						_type = "＜";
					break;
					case "next":
						_type = "＞";
					break;
					case "end":
						_type = "≫";
					break;
				}
                return " " + _type + " \n";
			} //end: , nav: function(type, num, text){

            , pager: function(num, text, isCurrent){ //'pager' 버튼 전체
                return "" + text + "\n";
            }
        } //end: , ui: {
    } //end: var defaults = {

    /*
    * 플러그인의 실행부
    */
    $.extend(true, defaults, settings); //ui 부분을 위한 deep copy

    var listed = Math.ceil(defaults.total / defaults.list); //리스트화된 전체 건수
    var paged = Math.ceil(listed / defaults.pager); //pager 그룹의 건수
    var result = {};

    for(var i = 0; i <= paged; i++){
        var fromTo = [];
        var inPaged = false;

        /* pager fromTo를 먼저 구한다. */
        for(var j = defaults.from(i), num = j - 1; j <= defaults.to(i); j++, num++){
            if(j <= listed){
                if(j === defaults.current){
                    inPaged = true;
                }
                fromTo.push({[defaults.attr]: num, "text": j, "isCurrent": j === defaults.current});
            }
        } //end: for(var j = defaults.from(i), num = j - 1; j <= defaults.to(i); j++, num++){

        if(inPaged){ //보여줄 pager에 해당되면
            if(defaults.showFirstEnd && paged > 1 && defaults.current !== 1){ //'처음' 버튼 추가 여부
                result.first = defaults.first(1);
            }
            if(defaults.current > defaults.pager){ //'이전' 버튼 추가 여부
                result.prev = defaults.prev(i, 1);
            }
            result.fromTo = fromTo; //미리 구한 'pager fromTo' 추가
            if(defaults.next(i, listed).text < defaults.end(listed).text){ //'다음' 버튼 추가 여부
                result.next = defaults.next(i, listed);
            }
            if(defaults.showFirstEnd && paged > 1 && defaults.current !== listed){ //'끝' 버튼 추가 여부
                result.end = defaults.end(listed);
            }
        } //end: if(inPaged){
    } //end: for(var i = 0; i <= paged; i++){

    return this.each(function(){
        var tags = "";
        var _ui = defaults.ui;

        /*
        * 동적으로 그릴 tag 작성
        * '처음, 끝' 버튼은 추후 작성 예정
        */
        for(var i in result){
            var _result = result[i];
            if(i === "fromTo"){
                for(var j = 0; j < _result.length; j++){
                    tags += _ui.pager(_result[j][defaults.attr], _result[j].text, _result[j].isCurrent);
                }
            }else{
                //tags += _ui[i](_result[defaults.attr], _result.text); //easy set buttons
                tags += _ui.nav(i, _result[defaults.attr], _result.text); //default set buttons
			}
        } //end: for(var i in result){

		if(defaults.showCombo){
			tags += "<select style='font-size: 1em;'>\n";
			for(var i = 0, combo = defaults.combo; i < combo.length; i++){
				tags += "\t<option value='" + combo[i] + "'" + (defaults.list === combo[i] ? " selected='selected'" : "") + ">"
					+ combo[i]
				+ "</option>\n";
			}
			tags += "</select>\n";
		} //end: if(defaults.showCombo){

        $(this).html(tags); //해당 객체에 결과 그려넣기.
    }); //end: return this.each(function(){
} //end: $.fn.pagify = function(settings){
<|endoftext|>


<commit_before>import angularProvider from './ng/angular';
import updates from './updates';
import manualReload from './util/manual-reload';
import fromPairs from 'lodash/fromPairs';

let
  templatePathPrefix =
  '<!-- File path (added by ng-hot-reload plugin): ',
  templatePathSuffix = ' -->';

function decorateTemplateRequest(moduleName = 'ng') {
  const savedFilePaths = new Map();
  /**
   * Extracts the actual file path from the template and saves the
   * link betwen the relative url and the actual path in computer.
   * @param {string} path Relative path/url where the component attempts
   *      load the template from.
   * @param {string} file Template file.
   * @return {boolean} True if the function was able to extract the
   *      original path from the template.
   */
  function setFilePath(path, file) {
    const match = matchFilePath(file);
    if (!match) {
      return false;
    } else {
      savedFilePaths.set(match.filePath, path);
      return true;
    }
  }

  // Initialized when the app first runs
  let templateUpdates, $templateCache;
  const angular = angularProvider();

  // Override the $templateCache service so we can react to template changes
  angular.module(moduleName).config(['$provide', function($provide) {
    $provide.decorator('$templateRequest', ['$delegate', '$templateCache', '$q',
    function($delegate, _$templateCache_, $q) {
      $templateCache = _$templateCache_;

      function ngHotReloadRequestTemplate(tpl, ...rest) {
        const result = $delegate.call(this, tpl, ...rest);
        result.then(template => {
          setFilePath(tpl, template);
        });
        return result;
      }

      // Proxy all the properties of the original $templateRequest service,
      // namely, `totalPendingRequests`.
      const proxyProperties = Object.keys($delegate).map(key => [key, {
        get: function() {
          return $delegate[key];
        },
        set: function(value) {
          return ($delegate[key] = value);
        },
      }]);
      Object.defineProperties(
        ngHotReloadRequestTemplate,
        fromPairs(proxyProperties));

      return ngHotReloadRequestTemplate;
    }]);
  }]);

  angular.module(moduleName).run(['$rootScope', function($rootScope) {
    templateUpdates = updates($rootScope, moduleName, 'template');
  }]);

  return {
    update(filePath) {
      if (templateUpdates && savedFilePaths.has(filePath)) {
        const key = savedFilePaths.get(filePath);
        $templateCache.remove(key);
        templateUpdates.update(key);
      } else {
        const msg = templateUpdates ?
          `Template ${filePath} hasn't been used yet.`
          : 'App was not initialized yet.';
        manualReload(msg);
      }
    },
    getTemplateCache: () => $templateCache,
  };
}

function matchFilePath(file) {
  const filePathStart = file.indexOf(templatePathPrefix);
  if (filePathStart === -1) {
    return null;
  }
  const filePathEnd = file.indexOf(templatePathSuffix, filePathStart) ||
    file.length;

  const filePath = file.substring(
    filePathStart + templatePathPrefix.length, filePathEnd);

  return {
    filePath,
    filePathStart,
    filePathEnd,
  };
}

export const getTemplatePathPrefix = () => templatePathPrefix;
export const getTemplatePathSuffix = () => templatePathSuffix;
export const setTemplatePathPrefix = prefix => templatePathPrefix = prefix;
export const setTemplatePathSuffix = suffix => templatePathSuffix = suffix;
export { decorateTemplateRequest };
<commit_msg>Minor fix to an outdated/incorrect comment<commit_after>import angularProvider from './ng/angular';
import updates from './updates';
import manualReload from './util/manual-reload';
import fromPairs from 'lodash/fromPairs';

let
  templatePathPrefix =
  '<!-- File path (added by ng-hot-reload plugin): ',
  templatePathSuffix = ' -->';

function decorateTemplateRequest(moduleName = 'ng') {
  const savedFilePaths = new Map();
  /**
   * Extracts the actual file path from the template and saves the
   * link betwen the relative url and the actual path in computer.
   * @param {string} path Relative path/url where the component attempts
   *      load the template from.
   * @param {string} file Template file.
   * @return {boolean} True if the function was able to extract the
   *      original path from the template.
   */
  function setFilePath(path, file) {
    const match = matchFilePath(file);
    if (!match) {
      return false;
    } else {
      savedFilePaths.set(match.filePath, path);
      return true;
    }
  }

  // Initialized when the app first runs
  let templateUpdates, $templateCache;
  const angular = angularProvider();

  // Override the $templateRequest service so we can react to template changes
  angular.module(moduleName).config(['$provide', function($provide) {
    $provide.decorator('$templateRequest', ['$delegate', '$templateCache', '$q',
    function($delegate, _$templateCache_, $q) {
      $templateCache = _$templateCache_;

      function ngHotReloadRequestTemplate(tpl, ...rest) {
        const result = $delegate.call(this, tpl, ...rest);
        result.then(template => {
          setFilePath(tpl, template);
        });
        return result;
      }

      // Proxy all the properties of the original $templateRequest service,
      // namely, `totalPendingRequests`.
      const proxyProperties = Object.keys($delegate).map(key => [key, {
        get: function() {
          return $delegate[key];
        },
        set: function(value) {
          return ($delegate[key] = value);
        },
      }]);
      Object.defineProperties(
        ngHotReloadRequestTemplate,
        fromPairs(proxyProperties));

      return ngHotReloadRequestTemplate;
    }]);
  }]);

  angular.module(moduleName).run(['$rootScope', function($rootScope) {
    templateUpdates = updates($rootScope, moduleName, 'template');
  }]);

  return {
    update(filePath) {
      if (templateUpdates && savedFilePaths.has(filePath)) {
        const key = savedFilePaths.get(filePath);
        $templateCache.remove(key);
        templateUpdates.update(key);
      } else {
        const msg = templateUpdates ?
          `Template ${filePath} hasn't been used yet.`
          : 'App was not initialized yet.';
        manualReload(msg);
      }
    },
    getTemplateCache: () => $templateCache,
  };
}

function matchFilePath(file) {
  const filePathStart = file.indexOf(templatePathPrefix);
  if (filePathStart === -1) {
    return null;
  }
  const filePathEnd = file.indexOf(templatePathSuffix, filePathStart) ||
    file.length;

  const filePath = file.substring(
    filePathStart + templatePathPrefix.length, filePathEnd);

  return {
    filePath,
    filePathStart,
    filePathEnd,
  };
}

export const getTemplatePathPrefix = () => templatePathPrefix;
export const getTemplatePathSuffix = () => templatePathSuffix;
export const setTemplatePathPrefix = prefix => templatePathPrefix = prefix;
export const setTemplatePathSuffix = suffix => templatePathSuffix = suffix;
export { decorateTemplateRequest };
<|endoftext|>


<commit_before>/**
 * modules/analytics data store: tags.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import invariant from 'invariant';

/**
 * Internal dependencies
 */
import API from 'googlesitekit-api';
import Data from 'googlesitekit-data';
import { getExistingTag } from 'assets/js/util';
import { STORE_NAME } from './index';

const { getRegistry } = Data.commonActions;

// Actions
const FETCH_EXISTING_TAG = 'FETCH_EXISTING_TAG';
const FETCH_TAG_PERMISSION = 'FETCH_TAG_PERMISSION';
const RECEIVE_EXISTING_TAG = 'RECEIVE_EXISTING_TAG';
const RECEIVE_EXISTING_TAG_FAILED = 'RECEIVE_EXISTING_TAG_FAILED';
const RECEIVE_TAG_PERMISSION = 'RECEIVE_TAG_PERMISSION';
const RECEIVE_TAG_PERMISSION_FAILED = 'RECEIVE_TAG_PERMISSION_FAILED';

export const INITIAL_STATE = {
	existingTag: undefined,
	isFetchingExistingTag: false,
	isFetchingTagPermission: {},
	tagPermissions: undefined,
};

export const actions = {
	fetchExistingTag() {
		return {
			payload: {},
			type: FETCH_EXISTING_TAG,
		};
	},

	fetchTagPermission( { propertyID, accountID = '' } ) {
		invariant( propertyID, 'propertyID is required.' );

		return {
			payload: { propertyID, accountID },
			type: FETCH_TAG_PERMISSION,
		};
	},

	receiveExistingTag( existingTag ) {
		invariant( existingTag, 'existingTag is required.' );

		return {
			payload: { existingTag },
			type: RECEIVE_EXISTING_TAG,
		};
	},

	receiveExistingTagFailed( error ) {
		invariant( error, 'error is required.' );

		return {
			payload: { error },
			type: RECEIVE_EXISTING_TAG_FAILED,
		};
	},

	receiveTagPermission( { propertyID, accountID, permission } ) {
		invariant( propertyID, 'propertyID is required.' );
		invariant( permission !== undefined, 'permission cannot be undefined.' );

		return {
			payload: { propertyID, accountID, permission },
			type: RECEIVE_TAG_PERMISSION,
		};
	},

	receiveTagPermissionFailed( { propertyID, accountID, error } ) {
		invariant( propertyID, 'propertyID is required.' );
		invariant( error, 'error is required.' );

		return {
			payload: { accountID, error, propertyID },
			type: RECEIVE_TAG_PERMISSION_FAILED,
		};
	},
};

export const controls = {
	[ FETCH_EXISTING_TAG ]: () => {
		// TODO: Replace this with data from `core/site` selectors and
		// an implementation contained inside the store
		// once https://github.com/google/site-kit-wp/issues/1000 is
		// implemented.
		// TODO: Test this in the future. The underlying implementation is
		// currently quite nested and difficult to straightforwardly test.
		return getExistingTag( 'analytics' );
	},
	[ FETCH_TAG_PERMISSION ]: ( { payload: { propertyID, accountID } } ) => {
		return API.get( 'modules', 'analytics', 'tag-permission', { propertyID, accountID } );
	},
};

export const reducer = ( state, { type, payload } ) => {
	switch ( type ) {
		case FETCH_EXISTING_TAG: {
			return {
				...state,
				isFetchingExistingTag: true,
			};
		}

		case FETCH_TAG_PERMISSION: {
			const { propertyID } = payload;

			return {
				...state,
				isFetchingTagPermission: {
					...state.isFetchingTagPermission,
					[ propertyID ]: true,
				},
			};
		}

		case RECEIVE_EXISTING_TAG: {
			const { existingTag } = payload;

			return {
				...state,
				existingTag,
				isFetchingExistingTag: false,
			};
		}

		case RECEIVE_EXISTING_TAG_FAILED: {
			const { error } = payload;

			return {
				...state,
				error,
				isFetchingExistingTag: false,
			};
		}

		case RECEIVE_TAG_PERMISSION: {
			const { propertyID, accountID, permission } = payload;

			return {
				...state,
				isFetchingTagPermission: {
					...state.isFetchingTagPermission,
					[ propertyID ]: false,
				},
				tagPermissions: {
					...state.tagPermissions || {},
					[ propertyID ]: { accountID, permission },
				},
			};
		}

		case RECEIVE_TAG_PERMISSION_FAILED: {
			const { propertyID, error } = payload;

			return {
				...state,
				error,
				isFetchingTagPermission: {
					...state.isFetchingTagPermission,
					[ propertyID ]: false,
				},
			};
		}

		default: {
			return { ...state };
		}
	}
};

export const resolvers = {
	*hasExistingTag() {
		const registry = yield getRegistry();
		yield registry.select( STORE_NAME ).getExistingTag();
	},

	*hasTagPermission( propertyID, accountID = '' ) {
		const registry = yield getRegistry();
		yield registry.select( STORE_NAME ).getTagPermission( propertyID, accountID );
	},

	*getExistingTag() {
		try {
			const registry = yield actions.getRegistry();
			const existingTag = yield actions.fetchExistingTag( 'analytics' );
			yield actions.receiveExistingTag( existingTag );

			// Invalidate this resolver so it will run again.
			yield registry.getActions().invalidateResolutionForStoreSelector( 'getExistingTag' );

			return;
		} catch ( err ) {
			// TODO: Implement an error handler store or some kind of centralized
			// place for error dispatch...
			return actions.receiveExistingTagFailed( err );
		}
	},

	*getTagPermission( propertyID, accountID = '' ) {
		try {
			const response = yield actions.fetchTagPermission( { propertyID, accountID } );

			if ( propertyID !== response.propertyID ) {
				throw {
					code: 'google_analytics_existing_tag_permission',
				};
			}

			yield actions.receiveTagPermission( {
				accountID: response.accountID,
				propertyID,
				permission: true,
			} );

			return;
		} catch ( error ) {
			// This error code indicates the current user doesn't have access to this
			// tag and shouldn't dispatch an error action.
			if ( error.code === 'google_analytics_existing_tag_permission' ) {
				yield actions.receiveTagPermission( { propertyID, accountID, permission: false } );
				return;
			}

			// TODO: Implement an error handler store or some kind of centralized
			// place for error dispatch...
			return actions.receiveTagPermissionFailed( { accountID, error, propertyID } );
		}
	},
};

export const selectors = {
	/**
	 * Check to see if an existing tag is available on the site.
	 *
	 * @since n.e.x.t
	 *
	 * @param {Object} state Data store's state.
	 * @return {?boolean} True if a tag exists, false if not; undefined if not loaded.
	 */
	hasExistingTag( state ) {
		const existingTag = selectors.getExistingTag( state );
		return existingTag !== undefined ? !! existingTag : undefined;
	},

	/**
	 * Get an existing tag on the site, if present.
	 *
	 * Returns an object with the shape when successful:
	 * ```
	 * {
	 *   accountID = null,
	 *   propertyID = null,
	 * }
	 * ```
	 *
	 * @since n.e.x.t
	 *
	 * @param {Object} state Data store's state.
	 * @return {?Object} Site connection info.
	 */
	getExistingTag( state ) {
		const { existingTag } = state;

		return existingTag;
	},

	/**
	 * Checks whether the user has access to an existing Google Analytics tag / property.
	 *
	 * This can be an existing tag found on the site, or any Google Analytics property.
	 * If the account ID is known, it should be specified as well.
	 *
	 * Returns `undefined` if the permission check has not yet loaded.
	 *
	 * @since n.e.x.t
	 *
	 * @param {Object} state      Data store's state.
	 * @param {string} propertyID The Analytics Property ID to check permissions for.
	 * @param {string} accountID  Optional. The Analytics Account ID the property belongs to, if known.
	 * @return {?boolean} True if the user has access, false if not; `undefined` if not loaded.
	 */
	hasTagPermission( state, propertyID, accountID = '' ) {
		const response = selectors.getTagPermission( state, propertyID, accountID );
		return response !== undefined ? response.permission : undefined;
	},

	/**
	 * Checks permissions for an existing Google Analytics tag / property.
	 *
	 * This can be an existing tag found on the site, or any Google Analytics property.
	 * If the account ID is known, it should be specified as well.
	 *
	 * Returns `undefined` if the permission check has not yet loaded.
	 *
	 * @since n.e.x.t
	 *
	 * @param {Object} state      Data store's state.
	 * @param {string} propertyID The Analytics Property ID to check permissions for.
	 * @param {string} accountID  Optional. The Analytics Account ID the property belongs to, if known.
	 * @return {?Object} Object with string `accountID` and boolean `permission` properties; `undefined` if not loaded.
	 */
	getTagPermission( state, propertyID, accountID = '' ) { // eslint-disable-line no-unused-vars
		invariant( propertyID, 'propertyID is required.' );

		const { tagPermissions } = state;

		if ( 'undefined' === typeof tagPermissions || 'undefined' === typeof tagPermissions[ propertyID ] ) {
			return undefined;
		}

		return tagPermissions[ propertyID ];
	},
};

export default {
	INITIAL_STATE,
	actions,
	controls,
	reducer,
	resolvers,
	selectors,
};
<commit_msg>Refactor has*Tag selectors as registry selectors.<commit_after>/**
 * modules/analytics data store: tags.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import invariant from 'invariant';

/**
 * Internal dependencies
 */
import API from 'googlesitekit-api';
import { createRegistrySelector } from 'googlesitekit-data';
import { getExistingTag } from 'assets/js/util';
import { STORE_NAME } from './index';

// Actions
const FETCH_EXISTING_TAG = 'FETCH_EXISTING_TAG';
const FETCH_TAG_PERMISSION = 'FETCH_TAG_PERMISSION';
const RECEIVE_EXISTING_TAG = 'RECEIVE_EXISTING_TAG';
const RECEIVE_EXISTING_TAG_FAILED = 'RECEIVE_EXISTING_TAG_FAILED';
const RECEIVE_TAG_PERMISSION = 'RECEIVE_TAG_PERMISSION';
const RECEIVE_TAG_PERMISSION_FAILED = 'RECEIVE_TAG_PERMISSION_FAILED';

export const INITIAL_STATE = {
	existingTag: undefined,
	isFetchingExistingTag: false,
	isFetchingTagPermission: {},
	tagPermissions: undefined,
};

export const actions = {
	fetchExistingTag() {
		return {
			payload: {},
			type: FETCH_EXISTING_TAG,
		};
	},

	fetchTagPermission( { propertyID, accountID = '' } ) {
		invariant( propertyID, 'propertyID is required.' );

		return {
			payload: { propertyID, accountID },
			type: FETCH_TAG_PERMISSION,
		};
	},

	receiveExistingTag( existingTag ) {
		invariant( existingTag, 'existingTag is required.' );

		return {
			payload: { existingTag },
			type: RECEIVE_EXISTING_TAG,
		};
	},

	receiveExistingTagFailed( error ) {
		invariant( error, 'error is required.' );

		return {
			payload: { error },
			type: RECEIVE_EXISTING_TAG_FAILED,
		};
	},

	receiveTagPermission( { propertyID, accountID, permission } ) {
		invariant( propertyID, 'propertyID is required.' );
		invariant( permission !== undefined, 'permission cannot be undefined.' );

		return {
			payload: { propertyID, accountID, permission },
			type: RECEIVE_TAG_PERMISSION,
		};
	},

	receiveTagPermissionFailed( { propertyID, accountID, error } ) {
		invariant( propertyID, 'propertyID is required.' );
		invariant( error, 'error is required.' );

		return {
			payload: { accountID, error, propertyID },
			type: RECEIVE_TAG_PERMISSION_FAILED,
		};
	},
};

export const controls = {
	[ FETCH_EXISTING_TAG ]: () => {
		// TODO: Replace this with data from `core/site` selectors and
		// an implementation contained inside the store
		// once https://github.com/google/site-kit-wp/issues/1000 is
		// implemented.
		// TODO: Test this in the future. The underlying implementation is
		// currently quite nested and difficult to straightforwardly test.
		return getExistingTag( 'analytics' );
	},
	[ FETCH_TAG_PERMISSION ]: ( { payload: { propertyID, accountID } } ) => {
		return API.get( 'modules', 'analytics', 'tag-permission', { propertyID, accountID } );
	},
};

export const reducer = ( state, { type, payload } ) => {
	switch ( type ) {
		case FETCH_EXISTING_TAG: {
			return {
				...state,
				isFetchingExistingTag: true,
			};
		}

		case FETCH_TAG_PERMISSION: {
			const { propertyID } = payload;

			return {
				...state,
				isFetchingTagPermission: {
					...state.isFetchingTagPermission,
					[ propertyID ]: true,
				},
			};
		}

		case RECEIVE_EXISTING_TAG: {
			const { existingTag } = payload;

			return {
				...state,
				existingTag,
				isFetchingExistingTag: false,
			};
		}

		case RECEIVE_EXISTING_TAG_FAILED: {
			const { error } = payload;

			return {
				...state,
				error,
				isFetchingExistingTag: false,
			};
		}

		case RECEIVE_TAG_PERMISSION: {
			const { propertyID, accountID, permission } = payload;

			return {
				...state,
				isFetchingTagPermission: {
					...state.isFetchingTagPermission,
					[ propertyID ]: false,
				},
				tagPermissions: {
					...state.tagPermissions || {},
					[ propertyID ]: { accountID, permission },
				},
			};
		}

		case RECEIVE_TAG_PERMISSION_FAILED: {
			const { propertyID, error } = payload;

			return {
				...state,
				error,
				isFetchingTagPermission: {
					...state.isFetchingTagPermission,
					[ propertyID ]: false,
				},
			};
		}

		default: {
			return { ...state };
		}
	}
};

export const resolvers = {
	*getExistingTag() {
		try {
			const registry = yield actions.getRegistry();
			const existingTag = yield actions.fetchExistingTag( 'analytics' );
			yield actions.receiveExistingTag( existingTag );

			// Invalidate this resolver so it will run again.
			yield registry.getActions().invalidateResolutionForStoreSelector( 'getExistingTag' );

			return;
		} catch ( err ) {
			// TODO: Implement an error handler store or some kind of centralized
			// place for error dispatch...
			return actions.receiveExistingTagFailed( err );
		}
	},

	*getTagPermission( propertyID, accountID = '' ) {
		try {
			const response = yield actions.fetchTagPermission( { propertyID, accountID } );

			if ( propertyID !== response.propertyID ) {
				throw {
					code: 'google_analytics_existing_tag_permission',
				};
			}

			yield actions.receiveTagPermission( {
				accountID: response.accountID,
				propertyID,
				permission: true,
			} );

			return;
		} catch ( error ) {
			// This error code indicates the current user doesn't have access to this
			// tag and shouldn't dispatch an error action.
			if ( error.code === 'google_analytics_existing_tag_permission' ) {
				yield actions.receiveTagPermission( { propertyID, accountID, permission: false } );
				return;
			}

			// TODO: Implement an error handler store or some kind of centralized
			// place for error dispatch...
			return actions.receiveTagPermissionFailed( { accountID, error, propertyID } );
		}
	},
};

export const selectors = {
	/**
	 * Check to see if an existing tag is available on the site.
	 *
	 * @since n.e.x.t
	 *
	 * @param {Object} state Data store's state.
	 * @return {?boolean} True if a tag exists, false if not; undefined if not loaded.
	 */
	hasExistingTag: createRegistrySelector( ( select ) => () => {
		const existingTag = select( STORE_NAME ).getExistingTag();

		return existingTag !== undefined ? !! existingTag : undefined;
	} ),

	/**
	 * Get an existing tag on the site, if present.
	 *
	 * Returns an object with the shape when successful:
	 * ```
	 * {
	 *   accountID = null,
	 *   propertyID = null,
	 * }
	 * ```
	 *
	 * @since n.e.x.t
	 *
	 * @param {Object} state Data store's state.
	 * @return {?Object} Site connection info.
	 */
	getExistingTag( state ) {
		const { existingTag } = state;

		return existingTag;
	},

	/**
	 * Checks whether the user has access to an existing Google Analytics tag / property.
	 *
	 * This can be an existing tag found on the site, or any Google Analytics property.
	 * If the account ID is known, it should be specified as well.
	 *
	 * Returns `undefined` if the permission check has not yet loaded.
	 *
	 * @since n.e.x.t
	 *
	 * @param {Object} state      Data store's state.
	 * @param {string} propertyID The Analytics Property ID to check permissions for.
	 * @param {string} accountID  Optional. The Analytics Account ID the property belongs to, if known.
	 * @return {?boolean} True if the user has access, false if not; `undefined` if not loaded.
	 */
	hasTagPermission: createRegistrySelector( ( select ) => ( state, propertyID, accountID = '' ) => {
		const { permission } = select( STORE_NAME ).getTagPermission( state, propertyID, accountID ) || {};

		return permission;
	} ),

	/**
	 * Checks permissions for an existing Google Analytics tag / property.
	 *
	 * This can be an existing tag found on the site, or any Google Analytics property.
	 * If the account ID is known, it should be specified as well.
	 *
	 * Returns `undefined` if the permission check has not yet loaded.
	 *
	 * @since n.e.x.t
	 *
	 * @param {Object} state      Data store's state.
	 * @param {string} propertyID The Analytics Property ID to check permissions for.
	 * @param {string} accountID  Optional. The Analytics Account ID the property belongs to, if known.
	 * @return {?Object} Object with string `accountID` and boolean `permission` properties; `undefined` if not loaded.
	 */
	getTagPermission( state, propertyID, accountID = '' ) { // eslint-disable-line no-unused-vars
		invariant( propertyID, 'propertyID is required.' );

		const { tagPermissions } = state;

		if ( 'undefined' === typeof tagPermissions || 'undefined' === typeof tagPermissions[ propertyID ] ) {
			return undefined;
		}

		return tagPermissions[ propertyID ];
	},
};

export default {
	INITIAL_STATE,
	actions,
	controls,
	reducer,
	resolvers,
	selectors,
};
<|endoftext|>


<commit_before>export const feed = `

type RootQuery {
  _id: String
  created: String
  username: String
  entry: String
  status: String
  due: String
  type: String
  description: String
  uuid: String
  project: String
  context: String
  super: String
  workflow: String
  firstfield: String
  secondfield: String
}

type MetaQuery {
  count: String
  subtotal: String
  errors: [String]!
  return: [RootQuery]
}

type MetaMutate {
  collection: String
  op: String
  selector: String
  count: String
  in: String
  out: String
  mutator: String
  errors: [String]!
  return: [RootQuery]
}

type Query {
  query(collection: String="tmpmutation", selector: String, limit: Int=0, skip: Int=0, duebefore: String, dueafter: String, uuid: String): MetaQuery
  user(id: String!): User
}

type Mutation {
  mutate(collection: String, op: String, selector: String, mutator: String): MetaMutate
}

`;

export default feed
<commit_msg>this causes a lexer error in graphql but it's possible to bypass<commit_after>export const feed = `

type RootQuery {
  _id: String
  @context: String
  @type: String
  @id: String
  created: String
  username: String
  entry: String
  status: String
  due: String
  type: String
  description: String
  uuid: String
  project: String
  context: String
  super: String
  workflow: String
  firstfield: String
  secondfield: String
}

type MetaQuery {
  count: String
  subtotal: String
  errors: [String]!
  return: [RootQuery]
}

type MetaMutate {
  collection: String
  op: String
  selector: String
  count: String
  in: String
  out: String
  mutator: String
  errors: [String]!
  return: [RootQuery]
}

type Query {
  query(collection: String="tmpmutation", selector: String, limit: Int=0, skip: Int=0, duebefore: String, dueafter: String, uuid: String): MetaQuery
  user(id: String!): User
}

type Mutation {
  mutate(collection: String, op: String, selector: String, mutator: String): MetaMutate
}

`;

export default feed
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import Button from 'material-ui/Button';
import TextField from 'material-ui/TextField';
import Dialog, { DialogActions, DialogContent, DialogTitle } from 'material-ui/Dialog';

const SchoolAddDialog = ({ open, onClose }) => (
  <Dialog open={open} onClose={onClose} aria-labelledby="school-add-dialog">
    <DialogTitle id="school-add-dialog">Adicione uma escola</DialogTitle>
    <DialogContent>
      <TextField autoFocus margin="dense" label="Nome" fullWidth />
      <TextField margin="dense" label="Email" type="email" fullWidth />
      <TextField margin="dense" label="Telefone" fullWidth />
      <TextField margin="dense" label="Coordenador pedagógico" fullWidth />
      <TextField margin="dense" label="Diretor" fullWidth />
    </DialogContent>
    <DialogActions>
      <Button onClick={onClose} color="primary">
        Cancelar
      </Button>
      <Button onClick={onClose} color="primary">
        Adicionar
      </Button>
    </DialogActions>
  </Dialog>
);

SchoolAddDialog.propTypes = {
  onClose: PropTypes.func.isRequired,
  open: PropTypes.bool.isRequired,
};

export default SchoolAddDialog;
<commit_msg>Add graphql mutation to dialog for adding schools<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import Button from 'material-ui/Button';
import TextField from 'material-ui/TextField';
import Dialog, { DialogActions, DialogContent, DialogTitle } from 'material-ui/Dialog';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';

const SchoolAddDialog = ({ open, onClose, handleAddSchool }) => (
  <Dialog open={open} onClose={onClose} aria-labelledby="school-add-dialog">
    <DialogTitle id="school-add-dialog">Adicione uma escola</DialogTitle>
    <form onSubmit={handleAddSchool}>
      <DialogContent>
        <TextField name="name" autoFocus margin="dense" label="Nome" fullWidth />
        <TextField name="email" margin="dense" label="Email" type="email" fullWidth />
        <TextField name="phone" margin="dense" label="Telefone" fullWidth />
        <TextField
          name="pedagogicalCoordinator"
          margin="dense"
          label="Coordenador pedagógico"
          fullWidth
        />
        <TextField name="director" margin="dense" label="Diretor" fullWidth />
      </DialogContent>
      <DialogActions>
        <Button onClick={onClose} color="primary">
          Cancelar
        </Button>
        <Button type="submit" color="primary">
          Adicionar
        </Button>
      </DialogActions>
    </form>
  </Dialog>
);

SchoolAddDialog.propTypes = {
  handleAddSchool: PropTypes.func.isRequired,
  onClose: PropTypes.func.isRequired,
  open: PropTypes.bool.isRequired,
};

export const newSchoolMutation = gql`
  mutation newSchoolMutation(
    $name: String!
    $email: String!
    $phone: String
    $pedagogicalCoordinator: String
    $director: String
    $city: String!
    $address: String
  ) {
    createSchool(
      name: $name
      email: $email
      phone: $phone
      pedagogicalCoordinator: $pedagogicalCoordinator
      director: $director
      city: $city
      address: $address
    ) {
      id
      name
      email
      phone
      city {
        name
      }
    }
  }
`;

export default graphql(newSchoolMutation, {
  // Use an unambiguous name for use in the `props` section below
  name: 'newSchool',
  // Apollo's way of injecting new props which are passed to the component
  props: ({ newSchool, ownProps: { onClose } }) => ({
    // `handleAddSchool` is the name of the prop passed to the component
    handleAddSchool: event => {
      /* global FormData */
      const data = new FormData(event.target);
      console.log(data);

      event.preventDefault();
      event.stopPropagation();

      newSchool({
        variables: {
          name: data.get('name'),
          email: data.get('email'),
          phone: data.get('phone'),
          pedagogicalCoordinator: data.get('pedagogicalCoordinator'),
          director: data.get('director'),
          city: 'Barra do Bugres',
          address: data.get('address'),
        },
      })
        .then(({ data: { createSchool: { id, name, email, phone, city } } }) => {
          // This is React's SyntheticEvent wrapper, we can't use 'event.target'
          // event.target.reset();
          onClose();
        })
        .catch(error => {
          // Something went wrong, such as incorrect password, or no network
          // available, etc.
          console.error(error);
        });
    },
  }),
})(SchoolAddDialog);
<|endoftext|>