<commit_before>import React, {
  Component,
  View,
  ScrollView,
} from 'react-native';

export default class InfiniteScrollView extends Component {
  constructor(props) {
    super(props);

    var fromIndex = props.fromIndex || Number.NEGATIVE_INFINITY;
    var toIndex = props.toIndex || Number.POSITIVE_INFINITY;

    var index = 0;
    if(this.props.index) index = Math.min(Math.max(this.props.index, fromIndex), toIndex);
    else index = Math.max(0, fromIndex);

    this._scrollView = null;
    this._offscreenPages = this.props.offScreenPages || 1;
    this._renderedRange = {};
    this.state = {
      index: index,
      fromIndex: fromIndex,
      toIndex: toIndex,
      size: {
        width: 0,
        height: 0,
      }
    }
  }
  shouldComponentUpdate(nextProps, nextState) {
    var range = this._pagesRange(nextState);
    return (
      nextState.size !== this.state.size ||
      range.to !== this._renderedRange.to || range.from !== this._renderedRange.from
    );
  }
  componentDidUpdate() {
    var scrollTo = {animated: false}
    if(this.props.horizontal) scrollTo.x = (this.state.index - this._renderedRange.from) * this.state.size.width;
    else scrollTo.y = (this.state.index - this._renderedRange.from) * this.state.size.height;
    this._scrollView.scrollTo(scrollTo);
  }
  render() {
    var pages = null;
    if(this.state.size.width > 0 && this.state.size.width > 0) {
      var range = this._pagesRange(this.state);
      pages = this._createPages(range);
    }
    return (
      <View style={this.props.style} onLayout={(event) => this._layoutChanged(event)}>
        <ScrollView
          style={{overflow: 'visible'}}
          ref={(scrollView) => { this._scrollView = scrollView; }}
          horizontal={this.props.horizontal}
          automaticallyAdjustContentInsets={false}
          showsHorizontalScrollIndicator={false}
          showsVerticalScrollIndicator={false}
          pagingEnabled={true}
          onMomentumScrollEnd={(e) => this._scrollEnded(e)}>
          {pages}
        </ScrollView>
      </View>
    );
  }
  _layoutChanged(event) {
    var {x, y, width, height} = event.nativeEvent.layout;

    this.setState({
      size: {
        width: width,
        height: height
      }
    });
  }
  _pagesRange(state) {
    var range = {};
    range.from = Math.max(state.index - this._offscreenPages, state.fromIndex);
    range.to = Math.min(range.from + 2 * this._offscreenPages, state.toIndex);
    range.from = Math.min(range.from, range.to - 2 * this._offscreenPages);
    return range;
  }
  _createPages(range) {
    var pages = [];
    for(i = range.from; i <= range.to; i++) {
      pages.push(this._renderPage(i));
    }
    this._renderedRange = range;
    return pages;
  }
  _renderPage(index) {
    return (
      <View style={{width: this.state.size.width, height: this.state.size.height}} key={index}>
        {this.props.renderPage(index)}
      </View>
    );
  }
  _scrollEnded(event) {
    var scrollIndex = Math.round(this.props.horizontal ? event.nativeEvent.contentOffset.x / this.state.size.width : event.nativeEvent.contentOffset.y / this.state.size.height);
    var index = this.state.index + scrollIndex - Math.min(this._offscreenPages, this.state.index - this.state.fromIndex) - Math.max(0, this._offscreenPages + this.state.index - this.state.toIndex);
    this.setState({index: index});
  }
}<commit_msg>Fixed issue with index, fromIndex and toIndex when set to 0.<commit_after>import React, {
  Component,
  View,
  ScrollView,
} from 'react-native';

export default class InfiniteScrollView extends Component {
  constructor(props) {
    super(props);

    var fromIndex = Number.NEGATIVE_INFINITY;
    if(props.fromIndex % 1 === 0) fromIndex = props.fromIndex;

    var toIndex = Number.POSITIVE_INFINITY;
    if(props.toIndex % 1 === 0) toIndex = props.toIndex;

    var index = 0;
    if(this.props.index % 1 === 0) index = Math.min(Math.max(this.props.index, fromIndex), toIndex);
    else index = Math.max(0, fromIndex);

    this._scrollView = null;
    this._offscreenPages = this.props.offScreenPages || 1;
    this._renderedRange = {};
    this.state = {
      index: index,
      fromIndex: fromIndex,
      toIndex: toIndex,
      size: {
        width: 0,
        height: 0,
      }
    }
  }
  shouldComponentUpdate(nextProps, nextState) {
    var range = this._pagesRange(nextState);
    return (
      nextState.size !== this.state.size ||
      range.to !== this._renderedRange.to || range.from !== this._renderedRange.from
    );
  }
  componentDidUpdate() {
    var scrollTo = {animated: false}
    if(this.props.horizontal) scrollTo.x = (this.state.index - this._renderedRange.from) * this.state.size.width;
    else scrollTo.y = (this.state.index - this._renderedRange.from) * this.state.size.height;
    this._scrollView.scrollTo(scrollTo);
  }
  render() {
    var pages = null;
    if(this.state.size.width > 0 && this.state.size.width > 0) {
      var range = this._pagesRange(this.state);
      pages = this._createPages(range);
    }
    return (
      <View style={this.props.style} onLayout={(event) => this._layoutChanged(event)}>
        <ScrollView
          style={{overflow: 'visible'}}
          ref={(scrollView) => { this._scrollView = scrollView; }}
          horizontal={this.props.horizontal}
          automaticallyAdjustContentInsets={false}
          showsHorizontalScrollIndicator={false}
          showsVerticalScrollIndicator={false}
          pagingEnabled={true}
          onMomentumScrollEnd={(e) => this._scrollEnded(e)}>
          {pages}
        </ScrollView>
      </View>
    );
  }
  _layoutChanged(event) {
    var {x, y, width, height} = event.nativeEvent.layout;

    this.setState({
      size: {
        width: width,
        height: height
      }
    });
  }
  _pagesRange(state) {
    var range = {};
    range.from = Math.max(state.index - this._offscreenPages, state.fromIndex);
    range.to = Math.min(range.from + 2 * this._offscreenPages, state.toIndex);
    range.from = Math.min(range.from, range.to - 2 * this._offscreenPages);
    return range;
  }
  _createPages(range) {
    var pages = [];
    for(i = range.from; i <= range.to; i++) {
      pages.push(this._renderPage(i));
    }
    this._renderedRange = range;
    return pages;
  }
  _renderPage(index) {
    return (
      <View style={{width: this.state.size.width, height: this.state.size.height}} key={index}>
        {this.props.renderPage(index)}
      </View>
    );
  }
  _scrollEnded(event) {
    var scrollIndex = Math.round(this.props.horizontal ? event.nativeEvent.contentOffset.x / this.state.size.width : event.nativeEvent.contentOffset.y / this.state.size.height);
    var index = this.state.index + scrollIndex - Math.min(this._offscreenPages, this.state.index - this.state.fromIndex) - Math.max(0, this._offscreenPages + this.state.index - this.state.toIndex);
    this.setState({index: index});
  }
}<|endoftext|>


<commit_before>import R from "ramda";
import Promise from "bluebird";
import chalk from "chalk";
import express from "express";
import fsPath from "path";
import webpack from "webpack";
import webpackConfig from "./webpack-config";
import webpackStats from "./webpack-stats";
import webpackDevServer from "./webpack-dev-server";
import specPaths from "./spec-paths";
import log from "./log";

const listenP = (app, port) => {
    return new Promise((resolve) => app.listen(port, () => resolve()));
  };

/**
 * Starts the UIHarness development server.
 * @param {Object} options
 *           --entry: Required. Path to the specs files (comma seperated if more than one).
 *                    If not present the server is not started.
 *                    Example: --entry ./src/specs
 *
 *           --port:  Optional. The port to start the server on.
 *                    Default: 3030
 *
 *           --babel: Optional. The babel "stage" to transpile using.
 *                    See: https://babeljs.io/docs/usage/experimental/
 *                    Default: 1
 *
 * @return {Promise}.
 */
export const start = (options = {}) => {
  return new Promise((resolve, reject) => {
    let buildStats, isStarted;

    // Extract options  default values.
    const ENV = process.env.NODE_ENV || "development";
    const PORT = options.port || 3030;
    const BABEL_STAGE = options.babel || 1;

    // Prepare the Webpack configuration.
    // const specs = specPaths(options.entry);
    console.log("TEMP add specs array");
    const specs = []; // TEMP
    const entry = R.flatten([
      fsPath.join(__dirname, "../client/entry.js"),
      specs
    ]);
    const config = webpackConfig({ entry });

    // Create the development server.
    const app = webpackDevServer(config);
    app.use("/", express.static(fsPath.resolve(__dirname, "../../public")));

    // Build JS to determine the file-size.
    const statsConfig = webpackConfig({
      entry,
      isProduction: true,
      minify: true
    });
    const gettingBuildStats = webpackStats(statsConfig, { production: true })
        .then(result => buildStats = result)
        .catch(err => {
            log.error("Failed to :", err);
            reject(err);
        });

    console.log("TODO", "Only build stats for built specs.");
    console.log("TODO", "Initiate the babel register if required");
    console.log("TODO", "Build the package for size details after starting the server (async)");

    // Start the server.
    log.info("");
    log.info(chalk.grey(`Starting (${ ENV })...`));
    const startingServer = listenP(app, PORT);

    // Finish up.
    Promise.all([startingServer, gettingBuildStats])
      .then(() => {

          // Server details.
          const packageJson = require(fsPath.resolve("./package.json"));
          log.info("");
          log.info(chalk.green("UIHarness:"));
          log.info(chalk.grey(" - module: "), packageJson.name, chalk.grey(`(v${ packageJson.version || "0.0.0" })`));
          log.info(chalk.grey(" - port:   "), PORT);
          log.info(chalk.grey(" - env:    "), ENV);
          log.info(chalk.grey(" - time:   "), buildStats.buildTime.secs, "secs");
          log.info(chalk.grey(" - size:   "), buildStats.size.display, chalk.grey("=>"), buildStats.zipped.display, chalk.grey("zipped"));

          // Specs.
          log.info(chalk.grey(" - specs:  "), specs[0] || chalk.magenta("None."));
          R.takeLast(specs.length - 1, specs).forEach(path => {
            log.info(chalk.grey("           "), path);
          });

          // Finish up.
          log.info("");
          resolve({});
      })
  });
};
<commit_msg>Factor out build-stats.<commit_after>import R from "ramda";
import Promise from "bluebird";
import chalk from "chalk";
import express from "express";
import fsPath from "path";
import webpack from "webpack";
import webpackConfig from "./webpack-config";
import webpackStats from "./webpack-stats";
import webpackDevServer from "./webpack-dev-server";
import specPaths from "./spec-paths";
import log from "./log";

const listenP = (app, port) => {
    return new Promise((resolve) => app.listen(port, () => resolve()));
  };

const calculateBuildStats = (entry) => {
  return new Promise((resolve, reject) => {
      const minify = false;
      const statsConfig = webpackConfig({
        entry,
        isProduction: true,
        minify
      });
      webpackStats(statsConfig, { production: true })
        .then(buildStats => {
            log.info(chalk.green("Build Stats:"));
            log.info(chalk.grey(" - minified: "), minify);
            log.info(chalk.grey(" - time:     "), buildStats.buildTime.secs, "secs");
            log.info(chalk.grey(" - size:     "), buildStats.size.display, chalk.grey("=>"), buildStats.zipped.display, chalk.grey("zipped"));
            console.log("");
            resolve(buildStats);
        })
        .catch(err => {
            log.error("Failed to :", err);
            reject(err);
        });
  });
};

/**
 * Starts the UIHarness development server.
 * @param {Object} options
 *           --entry: Required. Path to the specs files (comma seperated if more than one).
 *                    If not present the server is not started.
 *                    Example: --entry ./src/specs
 *
 *           --port:  Optional. The port to start the server on.
 *                    Default: 3030
 *
 *           --babel: Optional. The babel "stage" to transpile using.
 *                    See: https://babeljs.io/docs/usage/experimental/
 *                    Default: 1
 *
 * @return {Promise}.
 */
export const start = (options = {}) => {
  return new Promise((resolve, reject) => {

    // Extract options  default values.
    const ENV = process.env.NODE_ENV || "development";
    const PORT = options.port || 3030;
    const BABEL_STAGE = options.babel || 1;

    // Prepare the Webpack configuration.
    // const specs = specPaths(options.entry);
    console.log("TEMP add specs array");
    const specs = []; // TEMP
    const entry = R.flatten([
      fsPath.join(__dirname, "../client/entry.js"),
      specs
    ]);
    const config = webpackConfig({ entry });

    // Create the development server.
    const app = webpackDevServer(config);
    app.use("/", express.static(fsPath.resolve(__dirname, "../../public")));

    console.log("TODO", "Only build stats for built specs.");
    console.log("TODO", "Initiate the babel register if required");

    // Start the server.
    log.info("");
    log.info(chalk.grey(`Starting (${ ENV })...`));
    const startingServer = listenP(app, PORT)
      .then(() => {
          // Server details.
          const packageJson = require(fsPath.resolve("./package.json"));
          log.info("");
          log.info(chalk.green("UIHarness:"));
          log.info(chalk.grey(" - module:   "), packageJson.name, chalk.grey(`(v${ packageJson.version || "0.0.0" })`));
          log.info(chalk.grey(" - port:     "), PORT);
          log.info(chalk.grey(" - env:      "), ENV);

          // Specs.
          log.info(chalk.grey(" - specs:    "), specs[0] || chalk.magenta("None."));
          R.takeLast(specs.length - 1, specs).forEach(path => {
            log.info(chalk.grey("             "), path);
          });

          // Finish up.
          log.info("");
          calculateBuildStats(entry).then(() => resolve({}));
      });
  });
};
<|endoftext|>


<commit_before>

window.onload = function(){

var board = $("#main-container"),
	firstClick = false,
	counter = 1;

	function createBoard(v){

	  	// Create 9 rows
	    for (var i = 0; i < v; i++){
	       row = document.createElement("div");
	       row.className = "row " + "row" + i;
	       row.setAttribute("data-row", i)
	       // Create cells
	       for(var j=0; j < v; j++){
	        cell = document.createElement("div");
	     	// token = document.createElement("div");
	        cell.className = "cell " + "cell" + j;
	        cell.setAttribute("data-cell", j)
	        // token.className = "token";
	        row.appendChild(cell);
	        // cell.appendChild(token);

	       }

	       board.append(row)
	    }
	    // Create the matrix - Our "back-end" logic that connects to the front-end grid we created above.
	    // We work with the matrix to deal wth the computations and conditional logic that allows our
	    // game to come alive.
	    matrix = new Array(9);
		for (var i = 0; i < matrix.length; i++) {
		matrix[i] = new Array(9);
		}

	} //createBoard END

createBoard(9)

	$( ".cell" ).click(function() {

		// alert($(this).attr('class') + $(this).parent().attr('class'))
		clickedRow = $(this).parent().attr('data-row')
		clickedCell = $(this).attr("data-cell")

		$(this).css("background", "rgb(45, 174, 45)") // change cell background

		if (firstClick === false) {

			matrix[clickedRow][clickedCell] = 1 // Set this square as start square
			firstClick = true;
			console.log(firstClick)
			matrix = placeMines(matrix)
			renderMines(matrix)
			renderClues(matrix)

		} // FirstClick check

	}) // End (.cell).click

	function placeMines(matrix) {

		// create 10 mines
		// Generate a random X and Y co-ord
		for (var i = 0; i < 10; i++) {

			var randomX = Math.round(Math.random() * 8),
				randomY = Math.round(Math.random() * 8);
			// check we dont place a mine in our start point
			while (matrix[randomX][randomY] === 1){
				randomX = Math.round(Math.random() * 8);
				randomY = Math.round(Math.random() * 8);
				console.log("stopped starting sq mine placement")
			}
			// check we dont place a mine on a spot that already has an existing mine
			while (matrix[randomX][randomY] === "mined"){
				randomX = Math.round(Math.random() * 8);
				randomY = Math.round(Math.random() * 8);
				console.log("stopped repeated mine placement")
			}

			// assign the mine to the matrix
			matrix[randomX][randomY] = "mined"

		};

		for (var x = 0; x < matrix.length; x++) {
			for (var y = 0; y < matrix[0].length; y++) {
				if (matrix[x][y] !== "mined") {matrix[x][y] = "free"}
		}}
		// Check that the random number wont place on the starting square, if so, roll again

			return matrix

	} // END placemines

	// Render the mines
	function renderMines(matrix){

		// Cycle the matrix looking for the mined spots
		for (var x = 0; x < matrix.length; x++) {
			for (var y = 0; y < matrix[0].length; y++) {
				if (matrix[x][y] === "mined") {

						// console.log("x is " + (x) + " y is " + (y))

						$(".row" + x).find(".cell" + y).css("background", "blue")

				}

			}

		}

	} // End RenderMines

	function renderClues(matrix){

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

				if (matrix[x][y] === "free") {
						counter = 1
						if (x !== 8 && matrix[x+1][y] === "mined") {
							$(".row" + x).find(".cell" + y).text(counter++)
						}

						if (x !== 8 && matrix[x+1][y+1] === "mined") {
							$(".row" + x).find(".cell" + y).text(counter++)
						}

						if (x !== 8 && matrix[x+1][y-1] === "mined") {
							$(".row" + x).find(".cell" + y).text(counter++)
						}

						if (matrix[x][y+1] === "mined") {
							$(".row" + x).find(".cell" + y).text(counter++)
						}

						if (matrix[x][y-1] === "mined") {
							$(".row" + x).find(".cell" + y).text(counter++)
						}

						if (x !== 0 && matrix[x-1][y-1] === "mined") {
							$(".row" + x).find(".cell" + y).text(counter++)
						}

						if (x !== 0 && matrix[x-1][y] === "mined") {
							$(".row" + x).find(".cell" + y).text(counter++)
						}

						if (x !== 0 && matrix[x-1][y+1] === "mined") {
							$(".row" + x).find(".cell" + y).text(counter++)
						}

				}
			}
		}
	}

} // End

<commit_msg>second commit - basic version<commit_after>

window.onload = function(){

var board = $("#main-container"),
	firstClick = false;

var minedSpot = {
	mined: true,
	clue: false,
	clicked: false,
	revealed: false
};

var freeSpot = {
	mined: false,
	clue: false,
	clicked: false,
	revealed: false
};

	function createBoard(v){

	  	// Create 9 rows
	    for (var i = 0; i < v; i++){
	       row = document.createElement("div");
	       row.className = "row " + "row" + i;
	       row.setAttribute("data-row", i)
	       // Create cells
	       for(var j=0; j < v; j++){
	        cell = document.createElement("div");
	     	// token = document.createElement("div");
	        cell.className = "cell " + "cell" + j;
	        cell.setAttribute("data-cell", j)
	        // token.className = "token";
	        row.appendChild(cell);
	        // cell.appendChild(token);

	       }

	       board.append(row)
	    }
	    // Create the matrix - Our "back-end" logic that connects to the front-end grid we created above.
	    // We work with the matrix to deal wth the computations and conditional logic that allows our
	    // game to come alive.
	    matrix = new Array(9);
		for (var i = 0; i < matrix.length; i++) {
		matrix[i] = new Array(9);
		}

	} //createBoard END

createBoard(9)

	$( ".cell" ).click(function() {

		// alert($(this).attr('class') + $(this).parent().attr('class'))
		clickedRow = parseInt($(this).parent().attr('data-row'))
		clickedCell = parseInt($(this).attr("data-cell"))

		$(this).css("background", "rgb(45, 174, 45)") // change cell background

		if (firstClick === false) {

			matrix[clickedRow][clickedCell] = Object.create(freeSpot) // Set this square as start square
			matrix[clickedRow][clickedCell]["clicked"] = true;
			firstClick = true;
			matrix = placeMines(matrix)
			renderMines(matrix)
			renderClues(matrix)
			revealSquares()

		} // FirstClick check

	}) // End (.cell).click

	function placeMines(matrix) {

		// create 10 mines
		// Generate a random X and Y co-ord
		for (var i = 0; i < 10; i++) {

			var randomX = Math.round(Math.random() * 8),
				randomY = Math.round(Math.random() * 8);
			// check we dont place a mine in our start point
		checkStartPlace()
		checkMinedPlace()

		function checkStartPlace(){
		for (var prop in matrix[randomX][randomY]){
			if (matrix[randomX][randomY].hasOwnProperty(prop)){

			while (matrix[randomX][randomY]["clicked"] === true){
				randomX = Math.round(Math.random() * 8);
				randomY = Math.round(Math.random() * 8);
				console.log("stopped starting sq mine placement")
				return

			}

			}
		}
	}
		function checkMinedPlace(){
		for (var prop in matrix[randomX][randomY]){
			if (matrix[randomX][randomY].hasOwnProperty(prop)){

		while (matrix[randomX][randomY]["mined"] === true){
				randomX = Math.round(Math.random() * 8);
				randomY = Math.round(Math.random() * 8);
				console.log("stopped repeated mine placement")
				return

			}
		}
	}
}
			// check we dont place a mine on a spot that already has an existing mine

			// assign the new mine object to the matrix
			matrix[randomX][randomY] = Object.create(minedSpot);

		};
		// fill the spaces that are free (not previously mined == undefined) with freeSpot objects
		for (var x = 0; x < matrix.length; x++) {
			for (var y = 0; y < matrix.length; y++) {
				if (matrix[x][y] === undefined) {matrix[x][y] = Object.create(freeSpot)}
		}}

			return matrix

	} // END placemines

	// Render the mines
	function renderMines(matrix){

		// Cycle the matrix looking for the mined spots and render
		for (var x = 0; x < matrix.length; x++) {
			for (var y = 0; y < matrix.length; y++) {
				if (matrix[x][y]["mined"] === true) {

						// console.log("x is " + (x) + " y is " + (y))
						$(".row" + x).find(".cell" + y).css("background", "blue")

				}

			}

		}
		return matrix
	} // End RenderMines

	// Logic for the clues
	function renderClues(matrix){

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

				if (matrix[x][y]["mined"] === false) {
						var counter = 1
						// Check down
						if (x !== 8 && matrix[x+1][y]["mined"] === true) {
							addNumberClue(x, y)
						}
						// check down right
						if (x !== 8 && y !== 8 && matrix[x+1][y+1]["mined"] === true) {
							addNumberClue(x, y)
						}
						// check down left
						if (x !== 8 && y !== 0 && matrix[x+1][y-1]["mined"] === true) {
							addNumberClue(x, y)
						}
						// check right
						if (y !== 8 && matrix[x][y+1]["mined"] === true) {
							addNumberClue(x, y)
						}
						// check left
						if (y !== 0 && matrix[x][y-1]["mined"] === true) {
							addNumberClue(x, y)
						}
						// check up left
						if (x !== 0 && y !== 0 && matrix[x-1][y-1]["mined"] === true) {
							addNumberClue(x, y)
						}
						// check up
						if (x !== 0 && matrix[x-1][y]["mined"] === true) {
							addNumberClue(x, y)
						}
						// check up right
						if (x !== 0 && y !== 8 && matrix[x-1][y+1]["mined"] === true) {
							addNumberClue(x, y)
						}

				}
			}
		}
		// Keeps a count of a clues surrounding mines and updates
		function addNumberClue(x, y){
			$(".row" + x).find(".cell" + y).text(counter++)
			matrix[x][y]["clue"] = true
			return counter
		}
		return matrix
	} // End RenderClues

	function revealSquares(){

		resetVars()
		floodFill(x, y)

		function floodFill(x, y){
			// reveal up
			if( x >= 0 && x <= 8 && y >= 0 && y <= 8 ){

				if (matrix[x][y]["mined"] === false && matrix[x][y]["revealed"] === false ){

					matrix[x][y]["revealed"] = true;
					$(".row" + x).find(".cell" + y).css("background", "red")
					floodFill(x - 1, y);
					floodFill(x + 1, y);
            		floodFill(x, y - 1);
            		floodFill(x, y + 1);
				} else {return}

			}

		}

		function checkClueSquare(x, y){

				if (matrix[x][y]["clue"] === true) {
				  $(".row" + x).find(".cell" + y).css("background", "red")

				}

				if(matrix[x][y]["mined"] === false && matrix[x][y]["clue"] === false) {
					$(".row" + x).find(".cell" + y).css("background", "red")

				}

				if(matrix[x][y]["mined"] === true) {

				}

			}

		function resetVars(){

			x = parseInt(clickedRow)
			y = parseInt(clickedCell)
			foundFullSquare = false
		}

	} // End revealSquares

} // End

<|endoftext|>


<commit_before>/* global app:true, io:false */

var socket;
var myname;
var block_id;
var pattern_array = [];
var pattern_string;

(function() {
  'use strict';

  /*socket = io.connect();
  socket.on('connect', function(){
  	socket.emit('/replay/#join');
  });

  socket.on('message', function (message) {
      console.log(message);
  });

  socket.on('disconnect', function() {
      console.log('>>> DB disconnected');
  });*/

  app = app || {};

  app.Reset = Backbone.Model.extend({
    defaults: {
      success: false,
      errors: [],
      errfor: {},
      blockid: undefined,
      confitm: ''
    },
    url: function(){
      return '/account/pattern/' + this.get('block_id') +'/';
    }
  });

  app.PatternView = Backbone.View.extend({
    el: '#pattern_menu',
    template: _.template( $('#tmpl-pattern_menu').html() ),
    events: {
      'click .btn-check': 'reqCheck',
      'click .btn-edit': 'reqEdit',
      'click .btn-submit': 'reqSubmit'
    },
    initialize: function() {
      //this.model = new app.Blocks();
      //this.listenTo(this.model, 'sync', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template);
    },
    reqCheck: function() {
      document.getElementById("btn_check").disabled = true;
      document.getElementById("btn_submit").disabled = false;
      document.getElementById("btn_edit").disabled = false;
      document.getElementById("pattern_input").disabled = true;
      var input = document.getElementById("pattern_input").value.split(/\n/);
      input = cleanArray(input);

      input.forEach(function(line){
	    var res = line.split(",");
	    var pattern = new Object();
	    pattern.id = res[0];
	    pattern.msec = res[1];
	    pattern.led = res[2];
	    pattern_array.push(pattern);
      });
      console.log(pattern_array);

      pattern_string = input.join("&&");
      console.log(pattern_string);

      drawVis(pattern_array);
    },
    reqEdit: function() {
      document.getElementById("btn_check").disabled = false;
      document.getElementById("btn_submit").disabled = true;
      document.getElementById("btn_edit").disabled = true;
      document.getElementById("pattern_input").disabled = false;
    },
    reqSubmit: function() {
      document.getElementById("btn_check").disabled = true;
      document.getElementById("btn_submit").disabled = true;
      document.getElementById("btn_edit").disabled = true;
      console.log("Submit");
    }
  });

  app.Router = Backbone.Router.extend({
    routes: {
      'account/pattern/': 'default',
      'account/pattern/load/:block/': 'load'
    },
    default: function(){
      console.log(" >>default view, nothing loaded");
    },
    load: function(block) {
      console.log(">> loading block "+block);
      block_id = block;
      var info_div = document.getElementById("info_box");
      var info_text = document.createElement("h6");
      var block_node = document.createTextNode("Pattern for [ block # "+block_id+" ]");
      var pattern_node = document.createTextNode(" -  [ pattern # "+" ]");
	info_text.appendChild(block_node);
	info_text.appendChild(pattern_node);
	info_div.appendChild(info_text);
      document.getElementById("btn_submit").disabled = true;
      document.getElementById("btn_edit").disabled = true;
      //socket.emit('/replay/#callblock', { targetBlock: block});
      setupVis();
    }
  });

  $(document).ready(function() {
    app.patternView = new app.PatternView();
    app.router = new app.Router();
    Backbone.history.start({ pushState: true });
  });
}());

function cleanArray(actual){
  var newArray = new Array();
  for(var i = 0; i<actual.length; i++){
      if (actual[i].length > 0){
        newArray.push(actual[i]);
    }
  }
  return newArray;
}

/////////////////////////////
// Canvas setup functions
/////////////////////////////

var svg_vis;
var margin = {top: 20, right: 20, bottom: 30, left: 60},
	width = 600 - margin.left - margin.right,
	height = 3600 - margin.top - margin.bottom;

function setupVis(){
    d3.select("#pattern_vis").selectAll("svg")
	.remove();

    svg_vis = d3.select("#pattern_vis").append("svg")
	.attr("width", width + margin.left + margin.right)
	.attr("height", height + margin.top + margin.bottom)
     .append("g")
	.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
}

function drawVis(data){
    var format = d3.time.format("%M:%S");
    var y = d3.time.scale()
	.domain([d3.time.minute.offset(new Date(0), 5), new Date(0)])
	.range([height, 0]);

    var color = d3.scale.category10();

    var yAxis = d3.svg.axis()
	.scale(y)
	.orient("left")
	.ticks(d3.time.seconds, 5)
	.tickFormat(format);

    svg_vis.append("g")
      .attr("class", "y axis")
      .call(yAxis);

    svg_vis.append("g")
        .attr("class", "grid")
        .attr("transform", "translate(1,0)")
        .call(make_y_axis()
            .tickSize(-width, 0, 0)
            .tickFormat(""));

    var pattern = svg_vis.selectAll('.plot')
	  .data(data)
      .enter().append("g")
	  .attr("class", "spot")
	  .attr("transform", function (d,i)
		{
			var dx = (d.msec-Math.floor(d.msec/1000)*1000)/2;
			var dy = y(d3.time.second.offset(new Date(0), Math.floor(d.msec/1000)))+1;
			return "translate(" + dx + ","+ dy + ")";
		});

      pattern.append('rect')
	  .attr('width', 48)
	  .attr('height', 10);

      pattern.append('text')
	  .attr('class', 'arrow-up')
	  .attr('font-family', 'FontAwesome')
	      .style('font-size', '150%' )
	      .attr("x",2)
	      .attr("y",10)
	      .text(function(d) { return '\uf0d8' })
	      .style("opacity", function(d) {
		  var array = d.led.split("^");
	          return parseFloat(array[0])
	      });

      pattern.append('text')
	  .attr('class', 'arrow-left')
	  .attr('font-family', 'FontAwesome')
	      .style('font-size', '150%' )
	      .style('color', 'white')
	      .attr("x",10)
	      .attr("y",10)
	      .text(function(d) { return '\uf0d9' })
	      .style("opacity", function(d) {
		  var array = d.led.split("^");
	          return parseFloat(array[1])
	      });

    function make_y_axis() {
	return d3.svg.axis()
	    .scale(y)
	    .orient("left")
	    .ticks(250)
    }
}

 /*   var frame = svg_data_vis.selectAll(".frame")
	    .data(d3data)
    .enter().append("g")
	    .attr("class", "block")
	    .attr("transform", function (d,i)
	    {
		    var dx = (i+1)%100*datavis_x_gap;
		    var dy = 20 + Math.floor((i+1)/100)*datavis_y_gap;
		    return "translate(" + dx + ","+ dy + ")";
	    });
	    //.on('mouseover', tip.show)
	    //.on('mouseout', tip.hide);

    frame.append("rect")
	    .attr("class", function (d,i)
	    {
		    var class_name;
		    if(i==current_frame){
		      class_name="current-frame";
		    }
		    else{
		      if (d.ledarray.length>0){
			    class_name="frame-with-led";
		      }else{
			    class_name="frame-no-led";
		      }

		    }
		    return class_name;
	    })
	    .attr("width", 8)
	    .attr("height", 8);*/
	    /*.attr("led", function (d){
		    if (d.ledarray.length>0){
			    return true;
		    }else{
			    return false
		    }
	    });*/
	    //.on('mouseover', tip.show)
	    //.on('mouseout', tip.hide)
	    //.on('click', mouseclick);
    /*frame.append("line")
	    .attr("class", function (d,i)
	    {
		    var class_name = "stroke-led";
		    return class_name;
	    })
	    .attr("x1", 4)
	    .attr("y1", 4)
	    .attr("x2", function (d){
	      if (d.ledarray.length>0) {
		var x2=0;

		d.ledarray.forEach(function(ele){
		  x2 = x2 + parseFloat(ele.arrow[1])*8 - parseFloat(ele.arrow[3])*8;
		});

		return 4 + x2/(d.ledarray.length)
	      }else{
		return 4
	      }
	    })
	    .attr("y2",function (d){
	      if (d.ledarray.length>0) {
		var y2=0;

		d.ledarray.forEach(function(ele){
		  y2 = y2 + parseFloat(ele.arrow[0])*8 - parseFloat(ele.arrow[2])*8;
		});

		return 4 + y2/(d.ledarray.length)
	      }else{
		return 4
	      }

	      return 4
	    });
	    */<commit_msg>pattern vis led<commit_after>/* global app:true, io:false */

var socket;
var myname;
var block_id;
var pattern_array = [];
var pattern_string;

(function() {
  'use strict';

  /*socket = io.connect();
  socket.on('connect', function(){
  	socket.emit('/replay/#join');
  });

  socket.on('message', function (message) {
      console.log(message);
  });

  socket.on('disconnect', function() {
      console.log('>>> DB disconnected');
  });*/

  app = app || {};

  app.Reset = Backbone.Model.extend({
    defaults: {
      success: false,
      errors: [],
      errfor: {},
      blockid: undefined,
      confitm: ''
    },
    url: function(){
      return '/account/pattern/' + this.get('block_id') +'/';
    }
  });

  app.PatternView = Backbone.View.extend({
    el: '#pattern_menu',
    template: _.template( $('#tmpl-pattern_menu').html() ),
    events: {
      'click .btn-check': 'reqCheck',
      'click .btn-edit': 'reqEdit',
      'click .btn-submit': 'reqSubmit'
    },
    initialize: function() {
      //this.model = new app.Blocks();
      //this.listenTo(this.model, 'sync', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template);
    },
    reqCheck: function() {
      document.getElementById("btn_check").disabled = true;
      document.getElementById("btn_submit").disabled = false;
      document.getElementById("btn_edit").disabled = false;
      document.getElementById("pattern_input").disabled = true;
      var input = document.getElementById("pattern_input").value.split(/\n/);
      input = cleanArray(input);

      input.forEach(function(line){
	    var res = line.split(",");
	    var pattern = new Object();
	    pattern.id = res[0];
	    pattern.msec = res[1];
	    pattern.led = res[2];
	    pattern_array.push(pattern);
      });
      console.log(pattern_array);

      pattern_string = input.join("&&");
      console.log(pattern_string);

      drawVis(pattern_array);
    },
    reqEdit: function() {
      document.getElementById("btn_check").disabled = false;
      document.getElementById("btn_submit").disabled = true;
      document.getElementById("btn_edit").disabled = true;
      document.getElementById("pattern_input").disabled = false;
    },
    reqSubmit: function() {
      document.getElementById("btn_check").disabled = true;
      document.getElementById("btn_submit").disabled = true;
      document.getElementById("btn_edit").disabled = true;
      console.log("Submit");
    }
  });

  app.Router = Backbone.Router.extend({
    routes: {
      'account/pattern/': 'default',
      'account/pattern/load/:block/': 'load'
    },
    default: function(){
      console.log(" >>default view, nothing loaded");
    },
    load: function(block) {
      console.log(">> loading block "+block);
      block_id = block;
      var info_div = document.getElementById("info_box");
      var info_text = document.createElement("h6");
      var block_node = document.createTextNode("Pattern for [ block # "+block_id+" ]");
      var pattern_node = document.createTextNode(" -  [ pattern # "+" ]");
	info_text.appendChild(block_node);
	info_text.appendChild(pattern_node);
	info_div.appendChild(info_text);
      document.getElementById("btn_submit").disabled = true;
      document.getElementById("btn_edit").disabled = true;
      //socket.emit('/replay/#callblock', { targetBlock: block});
      setupVis();
    }
  });

  $(document).ready(function() {
    app.patternView = new app.PatternView();
    app.router = new app.Router();
    Backbone.history.start({ pushState: true });
  });
}());

function cleanArray(actual){
  var newArray = new Array();
  for(var i = 0; i<actual.length; i++){
      if (actual[i].length > 0){
        newArray.push(actual[i]);
    }
  }
  return newArray;
}

/////////////////////////////
// Canvas setup functions
/////////////////////////////

var svg_vis;
var margin = {top: 20, right: 20, bottom: 30, left: 60},
	width = 600 - margin.left - margin.right,
	height = 3600 - margin.top - margin.bottom;

function setupVis(){
    d3.select("#pattern_vis").selectAll("svg")
	.remove();

    svg_vis = d3.select("#pattern_vis").append("svg")
	.attr("width", width + margin.left + margin.right)
	.attr("height", height + margin.top + margin.bottom)
     .append("g")
	.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
}

function drawVis(data){
    var format = d3.time.format("%M:%S");
    var y = d3.time.scale()
	.domain([d3.time.minute.offset(new Date(0), 5), new Date(0)])
	.range([height, 0]);

    var color = d3.scale.category10();

    var yAxis = d3.svg.axis()
	.scale(y)
	.orient("left")
	.ticks(d3.time.seconds, 5)
	.tickFormat(format);

    svg_vis.append("g")
      .attr("class", "y axis")
      .call(yAxis);

    svg_vis.append("g")
        .attr("class", "grid")
        .attr("transform", "translate(1,0)")
        .call(make_y_axis()
            .tickSize(-width, 0, 0)
            .tickFormat(""));

    var pattern = svg_vis.selectAll('.plot')
	  .data(data)
      .enter().append("g")
	  .attr("class", "spot")
	  .attr("transform", function (d,i)
		{
			var dx = (d.msec-Math.floor(d.msec/1000)*1000)/2;
			var dy = y(d3.time.second.offset(new Date(0), Math.floor(d.msec/1000)))+1;
			return "translate(" + dx + ","+ dy + ")";
		});

      pattern.append('rect')
	  .attr('width', 48)
	  .attr('height', 10);

      pattern.append('text')
	  .attr('class', 'arrow-up')
	  .attr('font-family', 'FontAwesome')
	      .style('font-size', '150%' )
	      .attr("x",2)
	      .attr("y",10)
	      .text(function(d) { return '\uf0d8' })
	      .style("opacity", function(d) {
		  var array = d.led.split("^");
	          return parseFloat(array[0])
	      });

      pattern.append('text')
	  .attr('class', 'arrow-left')
	  .attr('font-family', 'FontAwesome')
	      .style('font-size', '150%' )
	      .attr("x",10)
	      .attr("y",10)
	      .text(function(d) { return '\uf0d9' })
	      .style('color', function(d) {
		  var array = d.led.split("^");
	          return "rgba(0, 0, 0, " + array[1] +")"
	      });

    function make_y_axis() {
	return d3.svg.axis()
	    .scale(y)
	    .orient("left")
	    .ticks(250)
    }
}

 /*   var frame = svg_data_vis.selectAll(".frame")
	    .data(d3data)
    .enter().append("g")
	    .attr("class", "block")
	    .attr("transform", function (d,i)
	    {
		    var dx = (i+1)%100*datavis_x_gap;
		    var dy = 20 + Math.floor((i+1)/100)*datavis_y_gap;
		    return "translate(" + dx + ","+ dy + ")";
	    });
	    //.on('mouseover', tip.show)
	    //.on('mouseout', tip.hide);

    frame.append("rect")
	    .attr("class", function (d,i)
	    {
		    var class_name;
		    if(i==current_frame){
		      class_name="current-frame";
		    }
		    else{
		      if (d.ledarray.length>0){
			    class_name="frame-with-led";
		      }else{
			    class_name="frame-no-led";
		      }

		    }
		    return class_name;
	    })
	    .attr("width", 8)
	    .attr("height", 8);*/
	    /*.attr("led", function (d){
		    if (d.ledarray.length>0){
			    return true;
		    }else{
			    return false
		    }
	    });*/
	    //.on('mouseover', tip.show)
	    //.on('mouseout', tip.hide)
	    //.on('click', mouseclick);
    /*frame.append("line")
	    .attr("class", function (d,i)
	    {
		    var class_name = "stroke-led";
		    return class_name;
	    })
	    .attr("x1", 4)
	    .attr("y1", 4)
	    .attr("x2", function (d){
	      if (d.ledarray.length>0) {
		var x2=0;

		d.ledarray.forEach(function(ele){
		  x2 = x2 + parseFloat(ele.arrow[1])*8 - parseFloat(ele.arrow[3])*8;
		});

		return 4 + x2/(d.ledarray.length)
	      }else{
		return 4
	      }
	    })
	    .attr("y2",function (d){
	      if (d.ledarray.length>0) {
		var y2=0;

		d.ledarray.forEach(function(ele){
		  y2 = y2 + parseFloat(ele.arrow[0])*8 - parseFloat(ele.arrow[2])*8;
		});

		return 4 + y2/(d.ledarray.length)
	      }else{
		return 4
	      }

	      return 4
	    });
	    */<|endoftext|>


<commit_before>import hook from './hook';
import { readFileSync } from 'fs';
import { dirname, sep, relative, resolve } from 'path';
import { get, removeQuotes } from './utility';
import assign from 'lodash.assign';
import identity from 'lodash.identity';
import pick from 'lodash.pick';
import postcss from 'postcss';

import ExtractImports from 'postcss-modules-extract-imports';
import LocalByDefault from 'postcss-modules-local-by-default';
import Scope from 'postcss-modules-scope';
import Parser from './parser';

// cache
let importNr = 0;
let tokensByFile = {};
// processing functions
let preProcess = identity;
let postProcess;
// defaults
let lazyResultOpts = {};
let plugins = [LocalByDefault, ExtractImports, Scope];
let rootDir = process.cwd();

/**
 * @param  {object}   opts
 * @param  {function} opts.createImportedName
 * @param  {function} opts.generateScopedName
 * @param  {function} opts.preprocessCss
 * @param  {function} opts.processCss
 * @param  {string}   opts.rootDir
 * @param  {string}   opts.to
 * @param  {array}    opts.use
 * @param  {array}    opts.extensions
 */
export default function setup(opts = {}) {
  // clearing cache
  importNr = 0;
  tokensByFile = {};

  preProcess = get('preprocessCss', null, 'function', opts) || identity;
  postProcess = get('processCss', null, 'function', opts) || null;
  rootDir = get('rootDir', ['root', 'd'], 'string', opts) || process.cwd();
  // https://github.com/postcss/postcss/blob/master/docs/api.md#processorprocesscss-opts
  lazyResultOpts = pick(opts, ['to']);

  const extraExtensions = get('extensions', null, 'array', opts);
  if (extraExtensions) {
    extraExtensions.forEach((extension) => {
      hook(filename => fetch(filename, filename), extension);
    });
  }

  const customPlugins = get('use', ['u'], 'array', opts);
  if (customPlugins) {
    return void (plugins = customPlugins);
  }

  plugins = [];

  const mode = get('mode', null, 'string', opts);
  plugins.push(mode
    ? new LocalByDefault({mode: opts.mode})
    : LocalByDefault);

  const createImportedName = get('createImportedName', null, 'function', opts);
  plugins.push(createImportedName
    ? new ExtractImports({createImportedName: opts.createImportedName})
    : ExtractImports);

  const generateScopedName = get('generateScopedName', null, 'function', opts);
  plugins.push(generateScopedName
    ? new Scope({generateScopedName: opts.generateScopedName})
    : Scope);
}

/**
 * @param  {string} _to    Absolute or relative path. Also can be path to the Node.JS module.
 * @param  {string} _from  Absolute path (relative to root).
 * @param  {string} _trace
 * @return {object}
 */
function fetch(_to, _from, _trace) {
  const trace = _trace || String.fromCharCode(importNr++);
  const newPath = removeQuotes(_to);
  // getting absolute path to the processing file
  const filename = /\w/.test(newPath[0])
    ? require.resolve(newPath)
    : resolve(dirname(_from), newPath);

  // checking cache
  let tokens = tokensByFile[filename];
  if (tokens) {
    return tokens;
  }

  const rootRelativePath = sep + relative(rootDir, filename);
  const CSSSource = preProcess(readFileSync(filename, 'utf8'));

  const lazyResult = postcss(plugins.concat(new Parser({ fetch, filename, trace })))
    .process(CSSSource, assign(lazyResultOpts, {from: rootRelativePath}));

  lazyResult.warnings().forEach(message => console.warn(message.text));

  tokens = lazyResult.root.tokens;
  // updating cache
  tokensByFile[filename] = tokens;

  if (postProcess) {
    postProcess(lazyResult.css);
  }

  return tokens;
}

hook(filename => fetch(filename, filename), '.css');
<commit_msg>warning<commit_after>import hook from './hook';
import { readFileSync } from 'fs';
import { dirname, sep, relative, resolve } from 'path';
import { get, removeQuotes } from './utility';
import assign from 'lodash.assign';
import identity from 'lodash.identity';
import pick from 'lodash.pick';
import postcss from 'postcss';

import ExtractImports from 'postcss-modules-extract-imports';
import LocalByDefault from 'postcss-modules-local-by-default';
import Scope from 'postcss-modules-scope';
import Parser from './parser';

// cache
let importNr = 0;
let tokensByFile = {};
// processing functions
let preProcess = identity;
let postProcess;
// defaults
let lazyResultOpts = {};
let plugins = [LocalByDefault, ExtractImports, Scope];
let rootDir = process.cwd();

/**
 * @param  {object}   opts
 * @param  {function} opts.createImportedName
 * @param  {function} opts.generateScopedName
 * @param  {function} opts.preprocessCss
 * @param  {function} opts.processCss
 * @param  {string}   opts.rootDir
 * @param  {string}   opts.to
 * @param  {array}    opts.use
 * @param  {array}    opts.extensions
 */
export default function setup(opts = {}) {
  // clearing cache
  importNr = 0;
  tokensByFile = {};

  preProcess = get('preprocessCss', null, 'function', opts) || identity;
  postProcess = get('processCss', null, 'function', opts) || null;
  rootDir = get('rootDir', ['root', 'd'], 'string', opts) || process.cwd();
  // https://github.com/postcss/postcss/blob/master/docs/api.md#processorprocesscss-opts
  lazyResultOpts = pick(opts, ['to']);

  const extraExtensions = get('extensions', null, 'array', opts);
  if (extraExtensions) {
    extraExtensions.forEach((extension) => {
      hook(filename => fetch(filename, filename), extension);
    });
  }

  // Warning. Options, which aren't affected by plugins, should be processed above.
  const customPlugins = get('use', ['u'], 'array', opts);
  if (customPlugins) {
    return void (plugins = customPlugins);
  }

  plugins = [];

  const mode = get('mode', null, 'string', opts);
  plugins.push(mode
    ? new LocalByDefault({mode: opts.mode})
    : LocalByDefault);

  const createImportedName = get('createImportedName', null, 'function', opts);
  plugins.push(createImportedName
    ? new ExtractImports({createImportedName: opts.createImportedName})
    : ExtractImports);

  const generateScopedName = get('generateScopedName', null, 'function', opts);
  plugins.push(generateScopedName
    ? new Scope({generateScopedName: opts.generateScopedName})
    : Scope);
}

/**
 * @param  {string} _to    Absolute or relative path. Also can be path to the Node.JS module.
 * @param  {string} _from  Absolute path (relative to root).
 * @param  {string} _trace
 * @return {object}
 */
function fetch(_to, _from, _trace) {
  const trace = _trace || String.fromCharCode(importNr++);
  const newPath = removeQuotes(_to);
  // getting absolute path to the processing file
  const filename = /\w/.test(newPath[0])
    ? require.resolve(newPath)
    : resolve(dirname(_from), newPath);

  // checking cache
  let tokens = tokensByFile[filename];
  if (tokens) {
    return tokens;
  }

  const rootRelativePath = sep + relative(rootDir, filename);
  const CSSSource = preProcess(readFileSync(filename, 'utf8'));

  const lazyResult = postcss(plugins.concat(new Parser({ fetch, filename, trace })))
    .process(CSSSource, assign(lazyResultOpts, {from: rootRelativePath}));

  lazyResult.warnings().forEach(message => console.warn(message.text));

  tokens = lazyResult.root.tokens;
  // updating cache
  tokensByFile[filename] = tokens;

  if (postProcess) {
    postProcess(lazyResult.css);
  }

  return tokens;
}

hook(filename => fetch(filename, filename), '.css');
<|endoftext|>


<commit_before>import fs from 'fs';
import path from 'path';
import moment from '@/config/moment';
import firebase from '@/config/firebase-admin';
import * as hbsTemplates from '@/config/handlebars';
import writefile from './writefile';
import Post from '@/models/Post';
import * as helpers from './helpers';
import { slugger } from '@/config/constants';

const cssInlineThreshold = 10; // KB
const logoURL = helpers.logoURL;
const database = firebase.database();
const publishedRef = database.ref('/published').orderByChild('created');

function inlineCSS(file) {
  if (!file.endsWith('.css')) return '';

  const filePath = path.resolve(process.cwd() + '/public' + file);
  const fileStats = fs.statSync(filePath);
  let html = '';

  if (fileStats.size / 1000.0 < cssInlineThreshold) {
    // Inline the file
    const fileContent = fs.readFileSync(filePath, 'utf8');
    html = `<style>${fileContent}</style>`;
  } else {
    html = `<link rel="stylesheet" href="${file}">`;
  }

  return html;
}

function webpackManifest() {
  const manifest = JSON.parse(fs.readFileSync('public/config/webpack.manifest.json', 'utf8'));
  Object.keys(manifest).map((entry) => {
    manifest[entry] = entry.endsWith('.css') ? inlineCSS(manifest[entry]) : manifest[entry];
  });

  return manifest;
}

export function buildGallery() {
  return new Promise((resolve) => {
    publishedRef.once('value', (snapshot) => {
      const val = snapshot.val();
      const postsArray = Object.keys(val).map(key => val[key]).reverse();
      const postsPerMonth = {};
      const filePath = 'public/gallery.html';

      postsArray.map((post) => {
        const createdDate = moment(post.created, 'DD.MM.YYYY');
        const month = createdDate.month();
        const year = createdDate.year();
        const monthName = `${moment.months(month)} ${year}`;
        if (!postsPerMonth[monthName]) postsPerMonth[monthName] = [];
        post.images.map(image => postsPerMonth[monthName].push(image));
      });

      const html = hbsTemplates.gallery({
        postsPerMonth,
        logoURL: logoURL(),
        webpack: webpackManifest(),
      });

      resolve(writefile(filePath, html));
    });
  });
}

/**
 * Build the index page
 * @returns {Promise} Promise resolved when the file is written to disk
 */
export function buildIndex() {
  return new Promise((resolve, reject) => {
    publishedRef.once('value', (snapshot) => {
      const val = snapshot.val();
      const filePath = 'public/index.html';
      if (!val) return reject(new Error('There are no posts to build an overview with.'));
      const posts = Object.keys(val).map(post => new Post(val[post])).reverse();
      const manifest = webpackManifest();
      const html = hbsTemplates.index({
        posts,
        logoURL: logoURL(),
        webpack: manifest,
      });
      writefile(filePath, html).then(resolve);
    });
  });
}

/**
 * Build a single post based on a post object
 * @param {Post} post - The current post
 * @param {Post} nextPost - Next post in line for the preview
 * @returns {Promise} Resolves when the file is written to disk
 */
export function buildPost(post, nextPost) {
  if (!post) throw new Error(`Post with id ${post} not found, can't touch this.`);

  const filePath = `public/posts/${slugger(post.title)}.html`;
  const html = hbsTemplates.post({
    post,
    nextPost,
    logoURL: logoURL(),
    webpack: webpackManifest(),
  });

  return writefile(filePath, html);
}

// Fetch post data from firebase and rebuild a single post
export function publish(id) {
  return new Promise((resolve) => {
    publishedRef.once('value', (snapshot) => {
      const value = snapshot.val();
      const posts = Object.keys(value).map(post => value[post]).reverse();
      let post = null;
      let nextPost = null;
      let lastPost = null;

      // Get current and next post
      for (let i = 0; i < posts.length; i += 1) {
        if (posts[i].id === id) {
          post = new Post(posts[i]);
          if (posts[i - 1]) nextPost = new Post(posts[i - 1]);
          if (posts[i + 1]) lastPost = new Post(posts[i + 1]);
        }
      }

      buildPost(post, nextPost)
        .then(() => {
          return lastPost ? buildPost(lastPost, post) : true;
        })
        .then(resolve);
    });
  });
}

export function publishAll() {
  const blogTasks = [];

  return new Promise((resolve, reject) => {
    publishedRef.once('value', (snapshot) => {
      const val = snapshot.val();
      if (!val) return new Error('There are no posts to build');
      const posts = Object.keys(val);

      for (let i = 0; i < posts.length; i += 1) {
        blogTasks.push(publish(posts[i]));
      }

      return Promise.all(blogTasks)
        .then(resolve)
        .catch(reject);
    });
  });
}

export function unpublish(id) {
  return new Promise((resolve, reject) => {
    database.ref(`/posts/${id}`)
      .once('value', (snapshot) => {
        const val = snapshot.val();
        if (!val) return new Error('This post is deleted or something');
        const post = new Post(val);
        const filepath = `public/posts/${slugger(post.title)}.html`;
        fs.unlink(filepath, (err) => {
          if (err && err.code === 'ENOENT') return resolve();
          if (err) reject(err);
          return resolve();
        });
      });
  });
}

// TODO: remove constant connection to firebase. listen only to
// http requests from the backend, this is much more efficient
publishedRef.on('child_added', (snapshot) => {
  const post = snapshot.val();
  publish(post.id).then(buildIndex).then(buildGallery);
});

publishedRef.on('child_removed', (snapshot) => {
  const post = snapshot.val();
  unpublish(post.id).then(buildIndex).then(buildGallery);
});

publishedRef.on('child_changed', (snapshot) => {
  const post = snapshot.val();
  publish(post.id).then(buildIndex).then(buildGallery);
});
<commit_msg>Don't reject building if there are no posts<commit_after>import fs from 'fs';
import path from 'path';
import moment from '@/config/moment';
import firebase from '@/config/firebase-admin';
import * as hbsTemplates from '@/config/handlebars';
import writefile from './writefile';
import Post from '@/models/Post';
import * as helpers from './helpers';
import { slugger } from '@/config/constants';

const cssInlineThreshold = 10; // KB
const logoURL = helpers.logoURL;
const database = firebase.database();
const publishedRef = database.ref('/published').orderByChild('created');

function inlineCSS(file) {
  if (!file.endsWith('.css')) return '';

  const filePath = path.resolve(process.cwd() + '/public' + file);
  const fileStats = fs.statSync(filePath);
  let html = '';

  if (fileStats.size / 1000.0 < cssInlineThreshold) {
    // Inline the file
    const fileContent = fs.readFileSync(filePath, 'utf8');
    html = `<style>${fileContent}</style>`;
  } else {
    html = `<link rel="stylesheet" href="${file}">`;
  }

  return html;
}

function webpackManifest() {
  const manifest = JSON.parse(fs.readFileSync('public/config/webpack.manifest.json', 'utf8'));
  Object.keys(manifest).map((entry) => {
    manifest[entry] = entry.endsWith('.css') ? inlineCSS(manifest[entry]) : manifest[entry];
  });

  return manifest;
}

export function buildGallery() {
  return new Promise((resolve) => {
    publishedRef.once('value', (snapshot) => {
      const val = snapshot.val();
      const postsArray = Object.keys(val).map(key => val[key]).reverse();
      const postsPerMonth = {};
      const filePath = 'public/gallery.html';

      postsArray.map((post) => {
        const createdDate = moment(post.created, 'DD.MM.YYYY');
        const month = createdDate.month();
        const year = createdDate.year();
        const monthName = `${moment.months(month)} ${year}`;
        if (!postsPerMonth[monthName]) postsPerMonth[monthName] = [];
        post.images.map(image => postsPerMonth[monthName].push(image));
      });

      const html = hbsTemplates.gallery({
        postsPerMonth,
        logoURL: logoURL(),
        webpack: webpackManifest(),
      });

      resolve(writefile(filePath, html));
    });
  });
}

/**
 * Build the index page
 * @returns {Promise} Promise resolved when the file is written to disk
 */
export function buildIndex() {
  return new Promise((resolve, reject) => {
    publishedRef.once('value', (snapshot) => {
      const val = snapshot.val();
      const filePath = 'public/index.html';
      const posts = Object.keys(val).map(post => new Post(val[post])).reverse();
      const manifest = webpackManifest();
      const html = hbsTemplates.index({
        posts,
        logoURL: logoURL(),
        webpack: manifest,
      });
      writefile(filePath, html).then(resolve);
    });
  });
}

/**
 * Build a single post based on a post object
 * @param {Post} post - The current post
 * @param {Post} nextPost - Next post in line for the preview
 * @returns {Promise} Resolves when the file is written to disk
 */
export function buildPost(post, nextPost) {
  if (!post) throw new Error(`Post with id ${post} not found, can't touch this.`);

  const filePath = `public/posts/${slugger(post.title)}.html`;
  const html = hbsTemplates.post({
    post,
    nextPost,
    logoURL: logoURL(),
    webpack: webpackManifest(),
  });

  return writefile(filePath, html);
}

// Fetch post data from firebase and rebuild a single post
export function publish(id) {
  return new Promise((resolve) => {
    publishedRef.once('value', (snapshot) => {
      const value = snapshot.val();
      const posts = Object.keys(value).map(post => value[post]).reverse();
      let post = null;
      let nextPost = null;
      let lastPost = null;

      // Get current and next post
      for (let i = 0; i < posts.length; i += 1) {
        if (posts[i].id === id) {
          post = new Post(posts[i]);
          if (posts[i - 1]) nextPost = new Post(posts[i - 1]);
          if (posts[i + 1]) lastPost = new Post(posts[i + 1]);
        }
      }

      buildPost(post, nextPost)
        .then(() => {
          return lastPost ? buildPost(lastPost, post) : true;
        })
        .then(resolve);
    });
  });
}

export function publishAll() {
  const blogTasks = [];

  return new Promise((resolve, reject) => {
    publishedRef.once('value', (snapshot) => {
      const val = snapshot.val();
      if (!val) return new Error('There are no posts to build');
      const posts = Object.keys(val);

      for (let i = 0; i < posts.length; i += 1) {
        blogTasks.push(publish(posts[i]));
      }

      return Promise.all(blogTasks)
        .then(resolve)
        .catch(reject);
    });
  });
}

export function unpublish(id) {
  return new Promise((resolve, reject) => {
    database.ref(`/posts/${id}`)
      .once('value', (snapshot) => {
        const val = snapshot.val();
        if (!val) return new Error('This post is deleted or something');
        const post = new Post(val);
        const filepath = `public/posts/${slugger(post.title)}.html`;
        fs.unlink(filepath, (err) => {
          if (err && err.code === 'ENOENT') return resolve();
          if (err) reject(err);
          return resolve();
        });
      });
  });
}

// TODO: remove constant connection to firebase. listen only to
// http requests from the backend, this is much more efficient
publishedRef.on('child_added', (snapshot) => {
  const post = snapshot.val();
  publish(post.id).then(buildIndex).then(buildGallery);
});

publishedRef.on('child_removed', (snapshot) => {
  const post = snapshot.val();
  unpublish(post.id).then(buildIndex).then(buildGallery);
});

publishedRef.on('child_changed', (snapshot) => {
  const post = snapshot.val();
  publish(post.id).then(buildIndex).then(buildGallery);
});
<|endoftext|>


<commit_before>/*
  * Cookies Kitchen
  * https://github.com/gobalo/Cookies-Kitchen
  *
  * Copyright 2014 Góbalo
  * Released under the MIT license
*/
var cookiesKitchen;

;(function($, window, document, undefined){

window.console = window.console!==null ? window.console : { log: function() {}, info: function() {} };

cookiesKitchen = {
	//Kitchen stuff
	settings	: {
		apiUrl : 'http://gobalo.es/kwsn/api/cookiesKitchen',
		cookieName : 'eatMe',
		cookieVal  : 'soGood',
		cookieTime : 100
	},
	html : {
		$advice	: null,
		$content: null,
		$bg		: null,
		$close	: null
	},
	tryCount	: 3,
	cookie		: document.cookie,
	lastEvent	: null,

	//Available styles (bg is not an option)
	styles : {
		//Block background
		"bg": "#cookies-alert-bg{top:0;left:0;background:black;opacity:0.7;z-index:999;position:fixed;width:100%;height:100%}",
		//Selectable styles
		"1"	: "#cookies-alert{top:0;left:0;position:fixed;z-index:999999;padding: 10px 0px;width: 100%;background-color:#CA303C;border-bottom:solid 1px #a72731;box-shadow: 0px 0px 2px #a72731;}#cookies-alert p{width: 100%;text-align: center;font-family:'Open Sans',sans-serif,Arial;font-size:14px;margin: 0;color: #fff;}#cookies-alert p a{color:#fff}#cookies-alert #close{font-weight:900;text-shadow: 1px 1px 2px #bbb;cursor:pointer;position:fixed;right: 20px;}",
		"2"	: "#cookies-alert{bottom:10px;right:20px;position:fixed;z-index:999999;padding:8px 0px;width:400px;background-color:#CA303C;border-radius:4px;}#cookies-alert p{font-family:'Open Sans',sans-serif,Arial;font-size:13px;margin: 0px 20px 0 20px;text-align:justify;color:#fff;}#cookies-alert p a{color:#fff}#cookies-alert #close{cursor:pointer;float:right;text-decoration:underline}",
		"3" : "#cookies-alert{bottom:0;left:0;position:fixed;z-index:999999;padding: 10px 0px;width: 100%;background-color:#FF4844;border-bottom:solid 1px #a72731;box-shadow: 0px 0px 2px #a72731;}#cookies-alert p{width: 100%;text-align: center;font-family:'Open Sans',sans-serif,Arial;font-size:14px;margin: 0;color: #fff;}#cookies-alert p a{color:#fff}#cookies-alert #close{font-weight:900;text-shadow: 1px 1px 2px #bbb;cursor:pointer;position:fixed;right: 20px;}"
	},

	/*
	 * Initialize script
	 */
	init : function(){
		console.log("Cookies-Kitchen: https://github.com/gobalo/Cookies-Kitchen");
		console.log("Calentando el horno...");

		var self = this,
			scripts	= document.getElementsByTagName('script'),
			thisTag	= scripts[scripts.length-1],
			$thisTag = null;

		//Set current cookie
		this.cookie = document.cookie;

		//Get this script html tag
		$(scripts).each(function(){
			if( this.id==='cookiesKitchen' && $(this).data("name")!==undefined ){
				window.a=this;
				thisTag = this;
				$thisTag = $(this);
			}
		});

		if( $thisTag===null ){
			//$thisTag = $('

');
		}

		//Set settings
		this.settings.ext		= $thisTag.attr('data-extension') || '';
		this.settings.domain	= document.domain + '_' + this.settings.ext;
		this.settings.name		= $thisTag.attr('data-name') || this.settings.domain;
		this.settings.url		= $thisTag.attr('data-url');
		this.settings.animation	= $thisTag.attr('data-animation');
		this.settings.block		= $thisTag.attr('data-block')==='true' ? true : false;
		this.settings.style		= $thisTag.attr('data-style') || 1;

		if( !this.getCookie(this.settings.cookieName) ){

			this.showAlert();

			$.ajax({
				url			: this.settings.apiUrl,
				dataType	: "jsonp",
				data : {
					cFn		: "cookiesKitchen.cookMe",
					domain	: this.settings.domain
				},
				timeout : 3000,
				error : function(){
					if( arguments[1]==="timeout" ){
						self.cookMe();
					}
				}
			});
		}
	},

	/**
	 * @param string name - Cookie name
	 * @param string val - Cookie value
	 * @param int time - Cookie expire time
	 */
	setCookie : function(name, val, time){
		var exdate = new Date();
		exdate.setDate(exdate.getDate() + time);
		val = encodeURIComponent(val) + ( (time===null) ? '' : '; expires=' + exdate.toUTCString() );
		document.cookie = name + '=' + val;
		this.cookie = document.cookie;
	},

	/**
	 * @param string name - Cookie name
	 * @return string - Returns the value of the requested cookie, null if not found
	 */
	getCookie : function(name){
		var cookieValue	= this.cookie,
			init = cookieValue.indexOf(' ' + name + '=');

		if( init===-1 ){
			init = cookieValue.indexOf(name + '=');
		}
		if( init===-1 ){
			cookieValue = null;
		}else{
			init = cookieValue.indexOf('=', init) + 1;
			var end = cookieValue.indexOf(';', init);

			if( end===-1 ){
				end = cookieValue.length;
			}
			cookieValue = decodeURIComponent(cookieValue.substring(init, end));
		}
		return cookieValue;
	},

	/**
	 * @param string name - Cookie name
	 * @param string val - Cookie value
	 * @return boolean - Returns if a cookie exist with requested name and value
	 */
	checkCookie : function(name, val){
		var re = new RegExp(name + '=' + val + '(;*)', 'g');
		return this.cookie.match(re);
	},

	/*
	 * Shows cookies advice
	 */
	showAlert : function(){

		if( !this.html.$advice && !this.html.$bg ){

			this.html.$bg	= $('

').hide();
			this.html.$advice = $('

').hide();

			//Construct html advice
			var privacy	= this.settings.url!=='' ? 'Política de Cookies' : 'Política de Cookies';

			switch( this.settings.style ){
				case "1":
					this.html.$close = $('X');
					this.html.$content= $('
' +
							'' + this.settings.name + ' utiliza cookies propias y de terceros para mejorar ' +
							'tu experiencia de navegación y realizar tareas de análisis. Si continúas navegando consideramos ' +
							'que aceptas el uso de cookies.
Por favor, revisa nuestra ' + privacy + '.' +
						'
');
					break;
				case '2':
					this.html.$close = $('Cerrar');
					this.html.$content= $('
' +
							'' + this.settings.name + ' utiliza cookies propias y de terceros para mejorar ' +
							'tu experiencia de navegación y realizar tareas de análisis. Si continúas navegando consideramos ' +
							'que aceptas el uso de cookies.
Por favor, revisa nuestra ' + privacy + '.' +
						'
');
					break;
				case '3':
					this.html.$close = $('Aceptar');
					this.html.$content= $('
El sitio web de ' +
							'' + this.settings.name + ' hace uso de cookies propias y de terceros para ' +
							'ofrecerte un mejor servicio. Por favor, revisa nuestra ' + privacy + '.' +
						'
');
				default:
					this.html.$close = $('X');
					this.html.$content= $('
' +
							'' + this.settings.name + ' utiliza cookies propias y de terceros para mejorar ' +
							'tu experiencia de navegación y realizar tareas de análisis. Si continúas navegando consideramos ' +
							'que aceptas el uso de cookies.
Por favor, revisa nuestra ' + privacy + '.' +
						'
');
			}

			this.html.$close.hide();

			this.html.$close.click(function(){
				cookiesKitchen.hideAlert();
			});

			//Append htm advice
			this.html.$advice.append('').append( this.html.$content.append( this.html.$close ) );

			$('body').prepend( this.html.$advice ).prepend( this.html.$bg );

			$(document).trigger('cooking-cookie');
			this.lastEvent = 'cooking-cookie';
		}

		if(this.settings.block){
			this.html.$bg.fadeIn();
		}

		switch(this.settings.animation){
			case 'slide':
				this.html.$advice.slideDown();
				break;
			case 'fade':
				this.html.$advice.fadeIn();
				break;
			default:
				this.html.$advice.fadeIn();
		}

		this.html.$close.fadeIn();
	},

	/*
	 * Hides cookies advice
	 */
	hideAlert : function(){
		$(document).trigger('burning-cookie');
		this.lastEvent = 'burning-cookie';

		this.html.$close.fadeOut();

		switch(cookiesKitchen.settings.animation){
			case 'slide':
				this.html.$advice.slideUp();
				break;
			case 'fade':
				this.html.$advice.fadeOut();
				break;
			default:
				this.html.$advice.fadeOut();
		}

		if( cookiesKitchen.settings.block ){
			this.html.$bg.fadeOut();
		}

		cookiesKitchen.makeMeBurn();
	},

	/**
	 * @desc PUBLIC - Checks if the advice have been closed before by the user (stored in session),
	 * if true hides alert and set the cookie on the browser
	 * 0 => User never have closed the advice (cookie)
	 * 1 => User have closed the advice (cokkie)
	 * @param object payload - CookiesKitchen API returned object
	*/
	cookMe : function(payload){

		if( payload===undefined ){
			payload = {
				burnedCookies : '0'
			};
		}

		if( payload.burnedCookies!=='0' ){
			cookiesKitchen.hideAlert();

			if( !cookiesKitchen.getCookie(cookiesKitchen.settings.cookieName) && cookiesKitchen.checkCookie(cookiesKitchen.settings.cookieName, cookiesKitchen.settings.cookieVal) ){
				cookiesKitchen.setCookie(cookiesKitchen.settings.cookieName, cookiesKitchen.settings.cookieVal, cookiesKitchen.settings.cookieTime);
			}
		}else{

			cookiesKitchen.showAlert();

		}
	},

	/**
	 * @desc PUBLIC - Tells the API that user have closed the advice, and store it (session)
	 * @param object payload - CookiesKitchen API returned object
	 * 0 => User never have closed the advice (session)
	 * 1 => User have closed the advice (sesison)
	*/
	makeMeBurn : function(payload){

		if( payload===undefined ){
			payload = {
				burnedCookies : '0'
			};
		}

		cookiesKitchen.setCookie(cookiesKitchen.settings.cookieName, cookiesKitchen.settings.cookieVal, cookiesKitchen.settings.cookieTime);

		if( payload.burnedCookies==='0' && this.tryCount>0 ){
			$.ajax({
				url			: this.settings.apiUrl,
				dataType	: "jsonp",
				data : {
					cFn		: "cookiesKitchen.makeMeBurn",
					domain	: cookiesKitchen.settings.domain
				},
				complete:function(){
					cookiesKitchen.tryCount--;
				}
			});
		}
	}
};

cookiesKitchen.init();

})(jQuery||window._$, window, document);
<commit_msg>Editted style 3 close button<commit_after>/*
  * Cookies Kitchen
  * https://github.com/gobalo/Cookies-Kitchen
  *
  * Copyright 2014 Góbalo
  * Released under the MIT license
*/
var cookiesKitchen;

;(function($, window, document, undefined){

window.console = window.console!==null ? window.console : { log: function() {}, info: function() {} };

cookiesKitchen = {
	//Kitchen stuff
	settings	: {
		apiUrl : 'http://gobalo.es/kwsn/api/cookiesKitchen',
		cookieName : 'eatMe',
		cookieVal  : 'soGood',
		cookieTime : 100
	},
	html : {
		$advice	: null,
		$content: null,
		$bg		: null,
		$close	: null
	},
	tryCount	: 3,
	cookie		: document.cookie,
	lastEvent	: null,

	//Available styles (bg is not an option)
	styles : {
		//Block background
		"bg": "#cookies-alert-bg{top:0;left:0;background:black;opacity:0.7;z-index:999;position:fixed;width:100%;height:100%}",
		//Selectable styles
		"1"	: "#cookies-alert{top:0;left:0;position:fixed;z-index:999999;padding: 10px 0px;width: 100%;background-color:#CA303C;border-bottom:solid 1px #a72731;box-shadow: 0px 0px 2px #a72731;}#cookies-alert p{width: 100%;text-align: center;font-family:'Open Sans',sans-serif,Arial;font-size:14px;margin: 0;color: #fff;}#cookies-alert p a{color:#fff}#cookies-alert #close{font-weight:900;text-shadow: 1px 1px 2px #bbb;cursor:pointer;position:fixed;right: 20px;}",
		"2"	: "#cookies-alert{bottom:10px;right:20px;position:fixed;z-index:999999;padding:8px 0px;width:400px;background-color:#CA303C;border-radius:4px;}#cookies-alert p{font-family:'Open Sans',sans-serif,Arial;font-size:13px;margin: 0px 20px 0 20px;text-align:justify;color:#fff;}#cookies-alert p a{color:#fff}#cookies-alert #close{cursor:pointer;float:right;text-decoration:underline}",
		"3" : "#cookies-alert{bottom:0;left:0;position:fixed;z-index:999999;padding: 10px 0px;width: 100%;background-color:#FF4844;border-bottom:solid 1px #a72731;box-shadow: 0px 0px 2px #a72731;}#cookies-alert p{width: 100%;text-align: center;font-family:'Open Sans',sans-serif,Arial;font-size:14px;margin: 0;color: #fff;}#cookies-alert p a{color:#fff}#cookies-alert #close{font-weight:900;text-shadow: 1px 1px 2px #bbb;cursor:pointer;position:fixed;right: 20px;}"
	},

	/*
	 * Initialize script
	 */
	init : function(){
		console.log("Cookies-Kitchen: https://github.com/gobalo/Cookies-Kitchen");
		console.log("Calentando el horno...");

		var self = this,
			scripts	= document.getElementsByTagName('script'),
			thisTag	= scripts[scripts.length-1],
			$thisTag = null;

		//Set current cookie
		this.cookie = document.cookie;

		//Get this script html tag
		$(scripts).each(function(){
			if( this.id==='cookiesKitchen' && $(this).data("name")!==undefined ){
				window.a=this;
				thisTag = this;
				$thisTag = $(this);
			}
		});

		if( $thisTag===null ){
			//$thisTag = $('

');
		}

		//Set settings
		this.settings.ext		= $thisTag.attr('data-extension') || '';
		this.settings.domain	= document.domain + '_' + this.settings.ext;
		this.settings.name		= $thisTag.attr('data-name') || this.settings.domain;
		this.settings.url		= $thisTag.attr('data-url');
		this.settings.animation	= $thisTag.attr('data-animation');
		this.settings.block		= $thisTag.attr('data-block')==='true' ? true : false;
		this.settings.style		= $thisTag.attr('data-style') || 1;

		if( !this.getCookie(this.settings.cookieName) ){

			this.showAlert();

			$.ajax({
				url			: this.settings.apiUrl,
				dataType	: "jsonp",
				data : {
					cFn		: "cookiesKitchen.cookMe",
					domain	: this.settings.domain
				},
				timeout : 3000,
				error : function(){
					if( arguments[1]==="timeout" ){
						self.cookMe();
					}
				}
			});
		}
	},

	/**
	 * @param string name - Cookie name
	 * @param string val - Cookie value
	 * @param int time - Cookie expire time
	 */
	setCookie : function(name, val, time){
		var exdate = new Date();
		exdate.setDate(exdate.getDate() + time);
		val = encodeURIComponent(val) + ( (time===null) ? '' : '; expires=' + exdate.toUTCString() );
		document.cookie = name + '=' + val;
		this.cookie = document.cookie;
	},

	/**
	 * @param string name - Cookie name
	 * @return string - Returns the value of the requested cookie, null if not found
	 */
	getCookie : function(name){
		var cookieValue	= this.cookie,
			init = cookieValue.indexOf(' ' + name + '=');

		if( init===-1 ){
			init = cookieValue.indexOf(name + '=');
		}
		if( init===-1 ){
			cookieValue = null;
		}else{
			init = cookieValue.indexOf('=', init) + 1;
			var end = cookieValue.indexOf(';', init);

			if( end===-1 ){
				end = cookieValue.length;
			}
			cookieValue = decodeURIComponent(cookieValue.substring(init, end));
		}
		return cookieValue;
	},

	/**
	 * @param string name - Cookie name
	 * @param string val - Cookie value
	 * @return boolean - Returns if a cookie exist with requested name and value
	 */
	checkCookie : function(name, val){
		var re = new RegExp(name + '=' + val + '(;*)', 'g');
		return this.cookie.match(re);
	},

	/*
	 * Shows cookies advice
	 */
	showAlert : function(){

		if( !this.html.$advice && !this.html.$bg ){

			this.html.$bg	= $('

').hide();
			this.html.$advice = $('

').hide();

			//Construct html advice
			var privacy	= this.settings.url!=='' ? 'Política de Cookies' : 'Política de Cookies';

			switch( this.settings.style ){
				case "1":
					var privacy	= this.settings.url!=='' ? 'Política de Cookies' : 'Política de Cookies';
					this.html.$close = $('X');
					this.html.$content= $('
' +
							'' + this.settings.name + ' utiliza cookies propias y de terceros para mejorar ' +
							'tu experiencia de navegación y realizar tareas de análisis. Si continúas navegando consideramos ' +
							'que aceptas el uso de cookies.
Por favor, revisa nuestra ' + privacy + '.' +
						'
');
					break;
				case '2':
					var privacy	= this.settings.url!=='' ? 'Política de Cookies' : 'Política de Cookies';
					this.html.$close = $('Cerrar');
					this.html.$content= $('
' +
							'' + this.settings.name + ' utiliza cookies propias y de terceros para mejorar ' +
							'tu experiencia de navegación y realizar tareas de análisis. Si continúas navegando consideramos ' +
							'que aceptas el uso de cookies.
Por favor, revisa nuestra ' + privacy + '.' +
						'
');
					break;
				case '3':
					var privacy	= this.settings.url!=='' ? 'Más información' : 'Más información';
					this.html.$close = $('Aceptar');
					this.html.$content= $('
El sitio web de ' +
							'' + this.settings.name + ' hace uso de cookies propias y de terceros para ' +
							'ofrecerte un mejor servicio. [' + privacy + ']' +
						'
');
				default:
					var privacy	= this.settings.url!=='' ? 'Política de Cookies' : 'Política de Cookies';
					this.html.$close = $('X');
					this.html.$content= $('
' +
							'' + this.settings.name + ' utiliza cookies propias y de terceros para mejorar ' +
							'tu experiencia de navegación y realizar tareas de análisis. Si continúas navegando consideramos ' +
							'que aceptas el uso de cookies.
Por favor, revisa nuestra ' + privacy + '.' +
						'
');
			}

			this.html.$close.hide();

			this.html.$close.click(function(){
				cookiesKitchen.hideAlert();
			});

			//Append htm advice
			this.html.$advice.append('').append( this.html.$content.append( this.html.$close ) );

			$('body').prepend( this.html.$advice ).prepend( this.html.$bg );

			$(document).trigger('cooking-cookie');
			this.lastEvent = 'cooking-cookie';
		}

		if(this.settings.block){
			this.html.$bg.fadeIn();
		}

		switch(this.settings.animation){
			case 'slide':
				this.html.$advice.slideDown();
				break;
			case 'fade':
				this.html.$advice.fadeIn();
				break;
			default:
				this.html.$advice.fadeIn();
		}

		this.html.$close.fadeIn();
	},

	/*
	 * Hides cookies advice
	 */
	hideAlert : function(){
		$(document).trigger('burning-cookie');
		this.lastEvent = 'burning-cookie';

		this.html.$close.fadeOut();

		switch(cookiesKitchen.settings.animation){
			case 'slide':
				this.html.$advice.slideUp();
				break;
			case 'fade':
				this.html.$advice.fadeOut();
				break;
			default:
				this.html.$advice.fadeOut();
		}

		if( cookiesKitchen.settings.block ){
			this.html.$bg.fadeOut();
		}

		cookiesKitchen.makeMeBurn();
	},

	/**
	 * @desc PUBLIC - Checks if the advice have been closed before by the user (stored in session),
	 * if true hides alert and set the cookie on the browser
	 * 0 => User never have closed the advice (cookie)
	 * 1 => User have closed the advice (cokkie)
	 * @param object payload - CookiesKitchen API returned object
	*/
	cookMe : function(payload){

		if( payload===undefined ){
			payload = {
				burnedCookies : '0'
			};
		}

		if( payload.burnedCookies!=='0' ){
			cookiesKitchen.hideAlert();

			if( !cookiesKitchen.getCookie(cookiesKitchen.settings.cookieName) && cookiesKitchen.checkCookie(cookiesKitchen.settings.cookieName, cookiesKitchen.settings.cookieVal) ){
				cookiesKitchen.setCookie(cookiesKitchen.settings.cookieName, cookiesKitchen.settings.cookieVal, cookiesKitchen.settings.cookieTime);
			}
		}else{

			cookiesKitchen.showAlert();

		}
	},

	/**
	 * @desc PUBLIC - Tells the API that user have closed the advice, and store it (session)
	 * @param object payload - CookiesKitchen API returned object
	 * 0 => User never have closed the advice (session)
	 * 1 => User have closed the advice (sesison)
	*/
	makeMeBurn : function(payload){

		if( payload===undefined ){
			payload = {
				burnedCookies : '0'
			};
		}

		cookiesKitchen.setCookie(cookiesKitchen.settings.cookieName, cookiesKitchen.settings.cookieVal, cookiesKitchen.settings.cookieTime);

		if( payload.burnedCookies==='0' && this.tryCount>0 ){
			$.ajax({
				url			: this.settings.apiUrl,
				dataType	: "jsonp",
				data : {
					cFn		: "cookiesKitchen.makeMeBurn",
					domain	: cookiesKitchen.settings.domain
				},
				complete:function(){
					cookiesKitchen.tryCount--;
				}
			});
		}
	}
};

cookiesKitchen.init();

})(jQuery||window._$, window, document);
<|endoftext|>


<commit_before>/**
 * ===================================================================
 * main js
 *
 * -------------------------------------------------------------------
 */

(function($) {

	"use strict";

	/*---------------------------------------------------- */
	/* Preloader
	------------------------------------------------------ */
   $(window).load(function() {

      // will first fade out the loading animation
    	$("#loader").fadeOut("slow", function(){

        // will fade out the whole DIV that covers the website.
        $("#preloader").delay(300).fadeOut("slow");

      });

  	})

  	/*---------------------------------------------------- */
  	/* FitText Settings
  	------------------------------------------------------ */
  	setTimeout(function() {

   	$('#intro h1').fitText(1, { minFontSize: '42px', maxFontSize: '84px' });

  	}, 100);

	/*---------------------------------------------------- */
	/* FitVids
	------------------------------------------------------ */
  	$(".fluid-video-wrapper").fitVids();

	/*---------------------------------------------------- */
	/* Owl Carousel
	------------------------------------------------------ */
	$("#owl-slider").owlCarousel({
        navigation: false,
        pagination: true,
        itemsCustom : [
	        [0, 1],
	        [700, 2],
	        [960, 3]
	     ],
        navigationText: false
    });

	/*----------------------------------------------------- */
	/* Alert Boxes
  	------------------------------------------------------- */
	$('.alert-box').on('click', '.close', function() {
	  $(this).parent().fadeOut(500);
	});

	/*----------------------------------------------------- */
	/* Stat Counter
  	------------------------------------------------------- */
   var statSection = $("#stats"),
       stats = $(".stat-count");

   statSection.waypoint({

   	handler: function(direction) {

      	if (direction === "down") {

			   stats.each(function () {
				   var $this = $(this);

				   $({ Counter: 0 }).animate({ Counter: $this.text() }, {
				   	duration: 4000,
				   	easing: 'swing',
				   	step: function (curValue) {
				      	$this.text(Math.ceil(curValue));
				    	}
				  	});
				});

       	}

       	// trigger once only
       	this.destroy();

		},

		offset: "90%"

	});

	/*---------------------------------------------------- */
	/*	Masonry
	------------------------------------------------------ */
	var containerProjects = $('#folio-wrapper');

	containerProjects.imagesLoaded( function() {

		containerProjects.masonry( {
		  	itemSelector: '.folio-item',
		  	resize: true
		});

	});

	/*----------------------------------------------------*/
	/*	Modal Popup
	------------------------------------------------------*/
   $('.item-wrap a').magnificPopup({

      type:'inline',
      fixedContentPos: false,
      removalDelay: 300,
      showCloseBtn: false,
      mainClass: 'mfp-fade'

   });

   $(document).on('click', '.popup-modal-dismiss', function (e) {
   	e.preventDefault();
   	$.magnificPopup.close();
   });

	/*-----------------------------------------------------*/
  	/* Navigation Menu
   ------------------------------------------------------ */
   var toggleButton = $('.menu-toggle'),
       nav = $('.main-navigation');

   // toggle button
   toggleButton.on('click', function(e) {

		e.preventDefault();
		toggleButton.toggleClass('is-clicked');
		nav.slideToggle();

	});

   // nav items
  	nav.find('li a').on("click", function() {

   	// update the toggle button
   	toggleButton.toggleClass('is-clicked');
   	// fadeout the navigation panel
   	nav.fadeOut();

  	});

   /*---------------------------------------------------- */
  	/* Highlight the current section in the navigation bar
  	------------------------------------------------------ */
	var sections = $("section"),
	navigation_links = $("#main-nav-wrap li a");

	sections.waypoint( {

       handler: function(direction) {

		   var active_section;

			active_section = $('section#' + this.element.id);

			if (direction === "up") active_section = active_section.prev();

			var active_link = $('#main-nav-wrap a[href="#' + active_section.attr("id") + '"]');

         navigation_links.parent().removeClass("current");
			active_link.parent().addClass("current");

		},

		offset: '25%'
	});

	/*---------------------------------------------------- */
  	/* Smooth Scrolling
  	------------------------------------------------------ */
  	$('.smoothscroll').on('click', function (e) {

	 	e.preventDefault();

   	var target = this.hash,
    	$target = $(target);

    	$('html, body').stop().animate({
       	'scrollTop': $target.offset().top
      }, 800, 'swing', function () {
      	window.location.hash = target;
      });

  	});

   /*---------------------------------------------------- */
	/*  Placeholder Plugin Settings
	------------------------------------------------------ */
	$('input, textarea, select').placeholder()

  /*---------------------------------------------------- */
	/*	contact form
	------------------------------------------------------ */

	/* local validation */
	$('#contactForm').validate({

		/* submit via ajax */
		submitHandler: function(form) {

			var sLoader = $('#submit-loader');

			$.ajax({

		      type: "POST",
		      url: "inc/sendEmail.php",
		      data: $(form).serialize(),
		      beforeSend: function() {

		      	sLoader.fadeIn();

		      },
		      success: function(msg) {

	            // Message was sent
	            if (msg == 'OK') {
	            	sLoader.fadeOut();
	               $('#message-warning').hide();
	               $('#contactForm').fadeOut();
	               $('#message-success').fadeIn();
	            }
	            // There was an error
	            else {
	            	sLoader.fadeOut();
	               $('#message-warning').html(msg);
		            $('#message-warning').fadeIn();
	            }

		      },
		      error: function() {

		      	sLoader.fadeOut();
		      	$('#message-warning').html("Something went wrong. Please try again.");
		         $('#message-warning').fadeIn();

		      }

	      });
  		}

	});

 	/*----------------------------------------------------- */
  	/* Back to top
   ------------------------------------------------------- */
	var pxShow = 300; // height on which the button will show
	var fadeInTime = 400; // how slow/fast you want the button to show
	var fadeOutTime = 400; // how slow/fast you want the button to hide
	var scrollSpeed = 300; // how slow/fast you want the button to scroll to top. can be a value, 'slow', 'normal' or 'fast'

   // Show or hide the sticky footer button
	jQuery(window).scroll(function() {

		if (!( $("#header-search").hasClass('is-visible'))) {

			if (jQuery(window).scrollTop() >= pxShow) {
				jQuery("#go-top").fadeIn(fadeInTime);
			} else {
				jQuery("#go-top").fadeOut(fadeOutTime);
			}

		}

	});

})(jQuery);
<commit_msg>re-adds files<commit_after>/**
 * ===================================================================
 * main js
 *
 * -------------------------------------------------------------------
 */

(function($) {

	"use strict";

	/*---------------------------------------------------- */
	/* Preloader
	------------------------------------------------------ */
   $(window).load(function() {

      // will first fade out the loading animation
    	$("#loader").fadeOut("slow", function(){

        // will fade out the whole DIV that covers the website.
        $("#preloader").delay(300).fadeOut("slow");

      });

  	})

  	/*---------------------------------------------------- */
  	/* FitText Settings
  	------------------------------------------------------ */
  	setTimeout(function() {

   	$('#intro h1').fitText(1, { minFontSize: '42px', maxFontSize: '84px' });

  	}, 100);

	/*---------------------------------------------------- */
	/* FitVids
	------------------------------------------------------ */
  	$(".fluid-video-wrapper").fitVids();

	/*---------------------------------------------------- */
	/* Owl Carousel
	------------------------------------------------------ */
	$("#owl-slider").owlCarousel({
        navigation: false,
        pagination: true,
        itemsCustom : [
	        [0, 1],
	        [700, 2],
	        [960, 3]
	     ],
        navigationText: false
    });

	/*----------------------------------------------------- */
	/* Alert Boxes
  	------------------------------------------------------- */
	$('.alert-box').on('click', '.close', function() {
	  $(this).parent().fadeOut(500);
	});

	/*----------------------------------------------------- */
	/* Stat Counter
  	------------------------------------------------------- */
   var statSection = $("#stats"),
       stats = $(".stat-count");

   statSection.waypoint({

   	handler: function(direction) {

      	if (direction === "down") {

			   stats.each(function () {
				   var $this = $(this);

				   $({ Counter: 0 }).animate({ Counter: $this.text() }, {
				   	duration: 4000,
				   	easing: 'swing',
				   	step: function (curValue) {
				      	$this.text(Math.ceil(curValue));
				    	}
				  	});
				});

       	}

       	// trigger once only
       	this.destroy();

		},

		offset: "90%"

	});

	/*---------------------------------------------------- */
	/*	Masonry
	------------------------------------------------------ */
	var containerProjects = $('#folio-wrapper');

	containerProjects.imagesLoaded( function() {

		containerProjects.masonry( {
		  	itemSelector: '.folio-item',
		  	resize: true
		});

	});

	/*----------------------------------------------------*/
	/*	Modal Popup
	------------------------------------------------------*/
   $('.item-wrap a').magnificPopup({

      type:'inline',
      fixedContentPos: false,
      removalDelay: 300,
      showCloseBtn: false,
      mainClass: 'mfp-fade'

   });

   $(document).on('click', '.popup-modal-dismiss', function (e) {
   	e.preventDefault();
   	$.magnificPopup.close();
   });

	/*-----------------------------------------------------*/
  	/* Navigation Menu
   ------------------------------------------------------ */
   var toggleButton = $('.menu-toggle'),
       nav = $('.main-navigation');

   // toggle button
   toggleButton.on('click', function(e) {

		e.preventDefault();
		toggleButton.toggleClass('is-clicked');
		nav.slideToggle();

	});

   // nav items
  	nav.find('li a').on("click", function() {

   	// update the toggle button
   	toggleButton.toggleClass('is-clicked');
   	// fadeout the navigation panel
   	nav.fadeOut();

  	});

   /*---------------------------------------------------- */
  	/* Highlight the current section in the navigation bar
  	------------------------------------------------------ */
	var sections = $("section"),
	navigation_links = $("#main-nav-wrap li a");

	sections.waypoint( {

       handler: function(direction) {

		   var active_section;

			active_section = $('section#' + this.element.id);

			if (direction === "up") active_section = active_section.prev();

			var active_link = $('#main-nav-wrap a[href="#' + active_section.attr("id") + '"]');

         navigation_links.parent().removeClass("current");
			active_link.parent().addClass("current");

		},

		offset: '25%'
	});

	/*---------------------------------------------------- */
  	/* Smooth Scrolling
  	------------------------------------------------------ */
  	$('.smoothscroll').on('click', function (e) {

	 	e.preventDefault();

   	var target = this.hash,
    	$target = $(target);

    	$('html, body').stop().animate({
       	'scrollTop': $target.offset().top
      }, 800, 'swing', function () {
      	window.location.hash = target;
      });

  	});

   /*---------------------------------------------------- */
	/*  Placeholder Plugin Settings
	------------------------------------------------------ */
	$('input, textarea, select').placeholder()

  	/*---------------------------------------------------- */
	/*	contact form
	------------------------------------------------------ */

	/* local validation */
	$('#contactForm').validate({

		/* submit via ajax */
		submitHandler: function(form) {

			var sLoader = $('#submit-loader');

			$.ajax({

		      type: "POST",
		      url: "inc/sendEmail.php",
		      data: $(form).serialize(),
		      beforeSend: function() {

		      	sLoader.fadeIn();

		      },
		      success: function(msg) {

	            // Message was sent
	            if (msg == 'OK') {
	            	sLoader.fadeOut();
	               $('#message-warning').hide();
	               $('#contactForm').fadeOut();
	               $('#message-success').fadeIn();
	            }
	            // There was an error
	            else {
	            	sLoader.fadeOut();
	               $('#message-warning').html(msg);
		            $('#message-warning').fadeIn();
	            }

		      },
		      error: function() {

		      	sLoader.fadeOut();
		      	$('#message-warning').html("Something went wrong. Please try again.");
		         $('#message-warning').fadeIn();

		      }

	      });
  		}

	});

 	/*----------------------------------------------------- */
  	/* Back to top
   ------------------------------------------------------- */
	var pxShow = 300; // height on which the button will show
	var fadeInTime = 400; // how slow/fast you want the button to show
	var fadeOutTime = 400; // how slow/fast you want the button to hide
	var scrollSpeed = 300; // how slow/fast you want the button to scroll to top. can be a value, 'slow', 'normal' or 'fast'

   // Show or hide the sticky footer button
	jQuery(window).scroll(function() {

		if (!( $("#header-search").hasClass('is-visible'))) {

			if (jQuery(window).scrollTop() >= pxShow) {
				jQuery("#go-top").fadeIn(fadeInTime);
			} else {
				jQuery("#go-top").fadeOut(fadeOutTime);
			}

		}

	});

})(jQuery);
<|endoftext|>


<commit_before>import Money from './money'
import Map from './helpers/map'

/** Class representing a Wallet. */
export default class Wallet {

  /**
  * Create a new Wallet object.
  * @param {Map} amount - A key/value Map with currency/value
  */
  constructor(amount = new Map()) {
    this.amount = amount
  }

  /**
  * Returns a new Wallet with initial money
  * @param {Money []} arrayOfMoney - An array of money
  * @return {Wallet}
  */
  static init = (...arrayOfMoney) =>
    arrayOfMoney.reduce((wallet, money) => wallet.add(money), new Wallet())

  /**
  * Returns an amount by currency.
  * @param {string} currency - A money currency
  * @return {number}
  */
  getAmount = currency => this.amount.get(currency) || 0

  /**
  * Returns a new Wallet with added Money.
  * @param {Money} money - The money that will be added.
  * @return {Wallet}
  */
  add = (money) => {
    const currency = money.currency
    const current = this.getAmount(currency)
    return new Wallet(this.amount.set(currency, money.add(current).getValue()))
  }

  /**
  * Returns a new Wallet with subtracted Money.
  * @param {Money} money - The money that will be subtracted.
  * @return {Wallet}
  */
  subtract = (money) => {
    const currency = money.currency
    const current = Money.init(this.getAmount(currency))
    return new Wallet(this.amount.set(currency, current.subtract(money).getValue()))
  }

  convertCurrency = (from, to, exchangeRate) => {
    const fromAmount = Money.init(this.getAmount(from), { currency: from })
    const converted = fromAmount.multiplyBy(exchangeRate).getValue()
    return new Wallet(this.amount.set(from, 0).set(to, converted))
  }
}

export { Money }
export * from './display'
export * from './currency'
<commit_msg>add comments to convertCurrency<commit_after>import Money from './money'
import Map from './helpers/map'

/** Class representing a Wallet. */
export default class Wallet {

  /**
  * Create a new Wallet object.
  * @param {Map} amount - A key/value Map with currency/value
  */
  constructor(amount = new Map()) {
    this.amount = amount
  }

  /**
  * Returns a new Wallet with initial money
  * @param {Money []} arrayOfMoney - An array of money
  * @return {Wallet}
  */
  static init = (...arrayOfMoney) =>
    arrayOfMoney.reduce((wallet, money) => wallet.add(money), new Wallet())

  /**
  * Returns an amount by currency.
  * @param {string} currency - A money currency
  * @return {number}
  */
  getAmount = currency => this.amount.get(currency) || 0

  /**
  * Returns a new Wallet with added Money.
  * @param {Money} money - The money that will be added.
  * @return {Wallet}
  */
  add = (money) => {
    const currency = money.currency
    const current = this.getAmount(currency)
    return new Wallet(this.amount.set(currency, money.add(current).getValue()))
  }

  /**
  * Returns a new Wallet with subtracted Money.
  * @param {Money} money - The money that will be subtracted.
  * @return {Wallet}
  */
  subtract = (money) => {
    const currency = money.currency
    const current = Money.init(this.getAmount(currency))
    return new Wallet(this.amount.set(currency, current.subtract(money).getValue()))
  }

  /**
   * Convert money with currency {from} in currency {true} using {exchangeRate}
   * @param {currency} from
   * @param {currency} to
   * @param {number} exchangeRate
   * @return {Wallet}
   */
  convertCurrency = (from, to, exchangeRate) => {
    const fromAmount = Money.init(this.getAmount(from), { currency: from })
    const converted = fromAmount.multiplyBy(exchangeRate).getValue()
    return new Wallet(this.amount.set(from, 0).set(to, converted))
  }
}

export { Money }
export * from './display'
export * from './currency'
<|endoftext|>


<commit_before>//Link logic goes there
var mod = {};
module.exports = mod;

mod.loop = function(room) {
    //
};
<commit_msg>restore link transfer logic<commit_after>//Link logic goes there
var mod = {};
module.exports = mod;

mod.loop = function(room) {
    const inputLinks = [];
    const outputLinks = [];

    const fullAndNotCooldown = function(link) {
        return link.energy===link.energyCapacity && link.cooldown===0;
    };
    for(const link of room.links) {
        if(link.memory.marked) {
            if(link.memory.source) {
                if(fullAndNotCooldown(link)) inputLinks.push(link);
            }
            else if(link.energy===0) outputLinks.push(link);
        } else {
            let marked = false;
            if(link.pos.findInRange(room.controller, 2).length > 0) {
                link.memory.controller = true;
                marked = true;
            }
            const spawnsAndExtensions = room.cachedFind(FIND_MY_STRUCTURES).filter(s => s.structureType===STRUCTURE_SPAWN || s.structureType===STRUCTURE_EXTENSION);
            if(link.pos.findInRange(spawnsAndExtensions, 2).length > 0) {
                link.memory.center = true;
                marked = true;
            }

            if(!marked) link.memory.source = true;
            link.memory.marked = true;
        }
    }

    for(const input of inputLinks) {
        if(outputLinks.length > 0) {
            input.transferEnergy(outputLinks.pop());
        }
    }
};
<|endoftext|>