<commit_before>if (typeof (require) != 'undefined') {
	var loader = require('../../node_modules/Butterfly-js/dist/butterfly.min.js').loader;
}

/**
 * Entry point of the game, contains some part of the game engine and deals with
 * the different entities
 */
loader.executeModule('main',
'B', 'Canvas', 'Entities', 'Physics', 'Utils', 'data',
function (B, canvas, Entities, Physics, Utils, data) {
	var ball,
		paddle,
		bricks = [],
		// position of the mouse in the canvas, taking in account the scroll
		// and position of the canvas in the page
		mouseX,
		mouseY,
		fps = 30,
		urlParams = Utils.getUrlParams(window.location.search);

	const DEBUG = urlParams.debug || NO_DEBUG;

	B.on(window, 'load', function () {
		// Init the view
		canvas.init(document.getElementById('game-canvas'));
		setInterval(updateAll, 1000 / fps);

		loadResources(function () {
			// Init the ball
			ball = new Entities.Ball(canvas.width() / 2, 3 * canvas.height() / 4, BALL_RADIUS, BALL_SPEED_X, BALL_SPEED_Y);
			// Position of the ball in the grid
			ball.setGridCoordinates(BRICK_SPACE_WIDTH, BRICK_SPACE_HEIGHT);
			// Init the paddle at the middle of the game view, 100px above the bottom
			paddle = new Entities.Paddle(
				(canvas.width() - PADDLE_WIDTH) / 2, canvas.height() - 100,
				PADDLE_WIDTH,
				PADDLE_THICKNESS
			);
		});

	});

	/* Events */
	// Event to execute when the player wins
	B.Events.on('win', null, function () {
		resetBricks(bricks);
		ball.reset();
	});

	// Event to execute when the player loses
	B.Events.on('lost', null, function () {
		resetBricks(bricks);
	});

	// Event to execute when the mouse move
	B.Events.on('mouse-moved', null, function (mX, mY) {
		mouseX = mX;
		mouseY = mY;
		// @TODO move that in the paddle logic
		if (mouseX > PADDLE_WIDTH / 2 && mouseX < canvas.width() - PADDLE_WIDTH / 2) {
			paddle.updatePosition(
				Math.min(
					Math.max(
						0,
						mouseX - PADDLE_WIDTH / 2
					),
					canvas.width() - PADDLE_WIDTH / 2
				)
			);
		}

		if (DEBUG) {
			ball.x = mouseX;
			ball.y = mouseY;
			ball.speedX = BALL_SPEED_X;
			ball.speedY = BALL_SPEED_Y * -1;
		}
	});
	/* End of Events */

	function loadResources (loadedCallback) {
		var r, loaded = 0;

		if (!data.resources) {
			loadedCallback();
			return;
		}

		for (r = 0; r < data.resources.length; r++) {
			data.resources[r].resource = new Image();
			data.resources[r].resource.onload = function () {
				if (++loaded == data.resources.length) {
					loadedCallback();
				}
			};
			data.resources[r].resource.src = data.resources[r].url;
		}
	}

	/*
	 * Create the bricks, The whole game is a grid and bricks are on the grid
	 * The bricks are organised on a rectangle of the grid started at the
	 * position (BRICK_GRID_START_COL, BRICK_GRID_START_COL) and ends at the
	 * position (BRICK_GRID_COL, BRICK_GRID_ROW)
	 * Each brick is an instance of the class Entities.Brick
	 */
	var col, row;
	for (row = BRICK_GRID_START_ROW; row < BRICK_GRID_ROW; row++ ) {
		for (col = BRICK_GRID_START_COL; col < BRICK_GRID_COL; col++ ) {
			bricks.push(new Entities.Brick(
				// 5 is the initial left margin
				BRICK_SPACE_WIDTH * col,
				BRICK_SPACE_HEIGHT * row,
				BRICK_WIDTH,
				BRICK_HEIGHT,
				// @TODO remove destructable field
				true, Entities.Brick.STATE_ACTIVE
			));
		}
	}

	// Set the number of remaining bricks to destroy
	var remainingBricks = BRICKS_NUMBER;

	// @TODO put that somewhere
	// Reset the bricks to the original state (all active)
	function resetBricks (bricks) {
		for (var b = 0; b < BRICKS_NUMBER; b++) {
			bricks[b].reset();
		}
	}

	/**
	 * Method to convert a pair of coordinates to the index of the cell in the
	 * grid the coordinates are in
	 */
	colRowToGridIndex = function (col, row) {
		return col - BRICK_GRID_START_COL +
			(BRICK_GRID_COL - BRICK_GRID_START_COL) * (row - BRICK_GRID_START_ROW);
	};

	/**
	 * Method to update the game state and the objects's position
	 */
	function moveAll () {
		// Update the ball position
		ball.updatePosition();
		ball.setGridCoordinates(BRICK_SPACE_WIDTH, BRICK_SPACE_HEIGHT);

		/* Ball and edges collision*/
		var wallBounded = Physics.sphereBounceAgainstInnerRectangle(ball, {x: 0, y: 0, w: canvas.width(), h: canvas.height()});
		if (wallBounded == 'down') {
			ball.reset();
			console.log('fire lost');
			B.Events.fire('lost');
		}
		/* End of Ball and edges collision*/

		/* Ball and active brick collision */
		var brick,
			brickSide,
			brickTopBot;

		brick = bricks[colRowToGridIndex(
			ball.gridCellCol,
			ball.gridCellRow
		)];

		// if the ball is on an active brick
		if (BRICK_GRID_START_COL <= ball.gridCellCol && ball.gridCellCol < BRICK_GRID_COL
			&& BRICK_GRID_START_COL <= ball.gridCellRow && ball.gridCellRow < BRICK_GRID_ROW
			&& brick.state == Entities.Brick.STATE_ACTIVE
		) {
			// brick next to the current one, according to ball's old position
			brickSide = bricks[colRowToGridIndex(ball.oldGridCellCol, ball.gridCellRow)];
			brickSide = brickSide && brickSide.state == Entities.Brick.STATE_ACTIVE && brickSide || undefined;

			// brick under or above to the current one, according to ball's old position
			brickTopBot = bricks[colRowToGridIndex(ball.gridCellCol, ball.oldGridCellRow)];
			brickTopBot = brickTopBot && brickTopBot.state == Entities.Brick.STATE_ACTIVE && brickTopBot || undefined;

			Physics.sphereBounceAgainstGridRectangle(ball, brick, brickSide, brickTopBot);

			brick.state = Entities.Brick.STATE_INACTIVE;
			remainingBricks--;

			if (remainingBricks == 0) {
				console.log('win');
				B.Events.fire('win');
				return;
			}
		}
		/* End of Ball and active brick collision */

		/* Ball and paddle collision */
		// if the ball is colliding with the paddle
		if (Physics.sphereCollidesWithRectangle(ball, paddle)) {
			Physics.sphereBounceAgainstRectangle(ball, paddle);
		}
		/* Ball and paddle collision */
	}

	/**
	 * Method to execute on each frame to update the game state and the
	 * objects's position and then redraw the canvas
	 */
	function updateAll () {
		moveAll();
		canvas.drawAll([ball, paddle, bricks]);

		if (DEBUG) {
			canvas.drawText('(' +
				Math.floor(mouseX / BRICK_SPACE_WIDTH) + ', ' +
				Math.floor(mouseY / BRICK_SPACE_HEIGHT) + ', ' +
				colRowToGridIndex(Math.floor(mouseX / BRICK_SPACE_WIDTH), Math.floor(mouseY / BRICK_SPACE_HEIGHT)) + ')', mouseX, mouseY, 'white');

			canvas.line([ball.x, ball.y], [ball.x + ball.speedX * 30, ball.y + ball.speedY * 30]);
		}
	}
});
<commit_msg>interval started after the resources<commit_after>if (typeof (require) != 'undefined') {
	var loader = require('../../node_modules/Butterfly-js/dist/butterfly.min.js').loader;
}

/**
 * Entry point of the game, contains some part of the game engine and deals with
 * the different entities
 */
loader.executeModule('main',
'B', 'Canvas', 'Entities', 'Physics', 'Utils', 'data',
function (B, canvas, Entities, Physics, Utils, data) {
	var ball,
		paddle,
		bricks = [],
		// position of the mouse in the canvas, taking in account the scroll
		// and position of the canvas in the page
		mouseX,
		mouseY,
		fps = 30,
		urlParams = Utils.getUrlParams(window.location.search);

	const DEBUG = urlParams.debug || NO_DEBUG;

	B.on(window, 'load', function () {
		// Init the view
		canvas.init(document.getElementById('game-canvas'));

		loadResources(function () {
			setInterval(updateAll, 1000 / fps);
			// Init the ball
			ball = new Entities.Ball(canvas.width() / 2, 3 * canvas.height() / 4, BALL_RADIUS, BALL_SPEED_X, BALL_SPEED_Y);
			// Position of the ball in the grid
			ball.setGridCoordinates(BRICK_SPACE_WIDTH, BRICK_SPACE_HEIGHT);
			// Init the paddle at the middle of the game view, 100px above the bottom
			paddle = new Entities.Paddle(
				(canvas.width() - PADDLE_WIDTH) / 2, canvas.height() - 100,
				PADDLE_WIDTH,
				PADDLE_THICKNESS
			);
		});

	});

	/* Events */
	// Event to execute when the player wins
	B.Events.on('win', null, function () {
		resetBricks(bricks);
		ball.reset();
	});

	// Event to execute when the player loses
	B.Events.on('lost', null, function () {
		resetBricks(bricks);
	});

	// Event to execute when the mouse move
	B.Events.on('mouse-moved', null, function (mX, mY) {
		mouseX = mX;
		mouseY = mY;
		// @TODO move that in the paddle logic
		if (mouseX > PADDLE_WIDTH / 2 && mouseX < canvas.width() - PADDLE_WIDTH / 2) {
			paddle.updatePosition(
				Math.min(
					Math.max(
						0,
						mouseX - PADDLE_WIDTH / 2
					),
					canvas.width() - PADDLE_WIDTH / 2
				)
			);
		}

		if (DEBUG) {
			ball.x = mouseX;
			ball.y = mouseY;
			ball.speedX = BALL_SPEED_X;
			ball.speedY = BALL_SPEED_Y * -1;
		}
	});
	/* End of Events */

	function loadResources (loadedCallback) {
		var r, loaded = 0;

		if (!data.resources) {
			loadedCallback();
			return;
		}

		for (r = 0; r < data.resources.length; r++) {
			data.resources[r].resource = new Image();
			data.resources[r].resource.onload = function () {
				if (++loaded == data.resources.length) {
					loadedCallback();
				}
			};
			data.resources[r].resource.src = data.resources[r].url;
		}
	}

	/*
	 * Create the bricks, The whole game is a grid and bricks are on the grid
	 * The bricks are organised on a rectangle of the grid started at the
	 * position (BRICK_GRID_START_COL, BRICK_GRID_START_COL) and ends at the
	 * position (BRICK_GRID_COL, BRICK_GRID_ROW)
	 * Each brick is an instance of the class Entities.Brick
	 */
	var col, row;
	for (row = BRICK_GRID_START_ROW; row < BRICK_GRID_ROW; row++ ) {
		for (col = BRICK_GRID_START_COL; col < BRICK_GRID_COL; col++ ) {
			bricks.push(new Entities.Brick(
				// 5 is the initial left margin
				BRICK_SPACE_WIDTH * col,
				BRICK_SPACE_HEIGHT * row,
				BRICK_WIDTH,
				BRICK_HEIGHT,
				// @TODO remove destructable field
				true, Entities.Brick.STATE_ACTIVE
			));
		}
	}

	// Set the number of remaining bricks to destroy
	var remainingBricks = BRICKS_NUMBER;

	// @TODO put that somewhere
	// Reset the bricks to the original state (all active)
	function resetBricks (bricks) {
		for (var b = 0; b < BRICKS_NUMBER; b++) {
			bricks[b].reset();
		}
	}

	/**
	 * Method to convert a pair of coordinates to the index of the cell in the
	 * grid the coordinates are in
	 */
	colRowToGridIndex = function (col, row) {
		return col - BRICK_GRID_START_COL +
			(BRICK_GRID_COL - BRICK_GRID_START_COL) * (row - BRICK_GRID_START_ROW);
	};

	/**
	 * Method to update the game state and the objects's position
	 */
	function moveAll () {
		// Update the ball position
		ball.updatePosition();
		ball.setGridCoordinates(BRICK_SPACE_WIDTH, BRICK_SPACE_HEIGHT);

		/* Ball and edges collision*/
		var wallBounded = Physics.sphereBounceAgainstInnerRectangle(ball, {x: 0, y: 0, w: canvas.width(), h: canvas.height()});
		if (wallBounded == 'down') {
			ball.reset();
			console.log('fire lost');
			B.Events.fire('lost');
		}
		/* End of Ball and edges collision*/

		/* Ball and active brick collision */
		var brick,
			brickSide,
			brickTopBot;

		brick = bricks[colRowToGridIndex(
			ball.gridCellCol,
			ball.gridCellRow
		)];

		// if the ball is on an active brick
		if (BRICK_GRID_START_COL <= ball.gridCellCol && ball.gridCellCol < BRICK_GRID_COL
			&& BRICK_GRID_START_COL <= ball.gridCellRow && ball.gridCellRow < BRICK_GRID_ROW
			&& brick.state == Entities.Brick.STATE_ACTIVE
		) {
			// brick next to the current one, according to ball's old position
			brickSide = bricks[colRowToGridIndex(ball.oldGridCellCol, ball.gridCellRow)];
			brickSide = brickSide && brickSide.state == Entities.Brick.STATE_ACTIVE && brickSide || undefined;

			// brick under or above to the current one, according to ball's old position
			brickTopBot = bricks[colRowToGridIndex(ball.gridCellCol, ball.oldGridCellRow)];
			brickTopBot = brickTopBot && brickTopBot.state == Entities.Brick.STATE_ACTIVE && brickTopBot || undefined;

			Physics.sphereBounceAgainstGridRectangle(ball, brick, brickSide, brickTopBot);

			brick.state = Entities.Brick.STATE_INACTIVE;
			remainingBricks--;

			if (remainingBricks == 0) {
				console.log('win');
				B.Events.fire('win');
				return;
			}
		}
		/* End of Ball and active brick collision */

		/* Ball and paddle collision */
		// if the ball is colliding with the paddle
		if (Physics.sphereCollidesWithRectangle(ball, paddle)) {
			Physics.sphereBounceAgainstRectangle(ball, paddle);
		}
		/* Ball and paddle collision */
	}

	/**
	 * Method to execute on each frame to update the game state and the
	 * objects's position and then redraw the canvas
	 */
	function updateAll () {
		moveAll();
		canvas.drawAll([ball, paddle, bricks]);

		if (DEBUG) {
			canvas.drawText('(' +
				Math.floor(mouseX / BRICK_SPACE_WIDTH) + ', ' +
				Math.floor(mouseY / BRICK_SPACE_HEIGHT) + ', ' +
				colRowToGridIndex(Math.floor(mouseX / BRICK_SPACE_WIDTH), Math.floor(mouseY / BRICK_SPACE_HEIGHT)) + ')', mouseX, mouseY, 'white');

			canvas.line([ball.x, ball.y], [ball.x + ball.speedX * 30, ball.y + ball.speedY * 30]);
		}
	}
});
<|endoftext|>


<commit_before>import Collection from "./collection";
import { OriginIterator, Curator } from "./iterator/index";
import { FilterIterator } from "./iterator/object";

class ObjectIterator extends OriginIterator {
  constructor(object) {
    super(object, ObjectIterator);
    this.keys = Object.keys(object);
    this.reset();
  }

  static default() {
    return {};
  }

  static add(object, key, value) {
    // eslint-disable-next-line no-param-reassign
    object[key] = value;
  }

  next() {
    if (this.index === this.keys.length) {
      return { done: true };
    }
    const key = this.keys[this.index];
    this.index += 1;
    return { done: false, key, value: this.coll[key] };
  }

  reset() {
    this.index = 0;
  }
}

export default class KasenObject extends Collection {
  static __iterator(object) {
    return new ObjectIterator(object);
  }

  static map(object, func) {
    const result = {};
    const keys = Object.keys(object);
    const len = keys.length;
    for (let i = 0; i < len; i += 1) {
      const key = keys[i];
      result[key] = func(object[key], key);
    }
    return result;
  }

  filter(func) {
    return super.filter(FilterIterator, func);
  }

  pick(keys) {
    const func = (_value, key) => keys.some(k => k === key);
    return super.filter(FilterIterator, func);
  }

  set(key, value) {
    const curate = iter => {
      const object = ObjectIterator.curate(iter);
      ObjectIterator.add(object, key, value);
      return object;
    };
    return super.set(Curator, curate);
  }

  // TODO?: flip()

  static reduce(object, func, init) {
    const keys = Object.keys(object);
    let acc = init;
    if (init === undefined) {
      if (!keys.length) {
        throw new TypeError("Reduce of empty object with no initial value");
      }
      acc = object[keys.pop()];
    }
    for (let i = 0, len = keys.length; i < len; i += 1) {
      const key = keys[i];
      acc = func(acc, object[key], key);
    }
    return acc;
  }
}
<commit_msg>Just fix coding style<commit_after>import Collection from "./collection";
import { OriginIterator, Curator } from "./iterator/index";
import { FilterIterator } from "./iterator/object";

class ObjectIterator extends OriginIterator {
  constructor(object) {
    super(object, ObjectIterator);
    this.keys = Object.keys(object);
    this.reset();
  }

  static default() {
    return {};
  }

  static add(object, key, value) {
    // eslint-disable-next-line no-param-reassign
    object[key] = value;
  }

  next() {
    if (this.index === this.keys.length) {
      return { done: true };
    }
    const key = this.keys[this.index];
    this.index += 1;
    return { done: false, key, value: this.coll[key] };
  }

  reset() {
    this.index = 0;
  }
}

export default class KasenObject extends Collection {
  static __iterator(object) {
    return new ObjectIterator(object);
  }

  static map(object, func) {
    const result = {};
    const keys = Object.keys(object);
    for (let i = 0, len = keys.length; i < len; i += 1) {
      const key = keys[i];
      result[key] = func(object[key], key);
    }
    return result;
  }

  filter(func) {
    return super.filter(FilterIterator, func);
  }

  pick(keys) {
    const func = (_value, key) => keys.some(k => k === key);
    return super.filter(FilterIterator, func);
  }

  set(key, value) {
    const curate = iter => {
      const object = ObjectIterator.curate(iter);
      ObjectIterator.add(object, key, value);
      return object;
    };
    return super.set(Curator, curate);
  }

  // TODO?: flip()

  static reduce(object, func, init) {
    const keys = Object.keys(object);
    let acc = init;
    if (init === undefined) {
      if (!keys.length) {
        throw new TypeError("Reduce of empty object with no initial value");
      }
      acc = object[keys.pop()];
    }
    for (let i = 0, len = keys.length; i < len; i += 1) {
      const key = keys[i];
      acc = func(acc, object[key], key);
    }
    return acc;
  }
}
<|endoftext|>


<commit_before>var util = require('util')
var thunky = require('thunky')
var Readable = require('readable-stream').Readable

var Cursor = function (getCursor) {
  Readable.call(this, {objectMode: true, highWaterMark: 0})

  this._opts = {}

  var self = this
  this._get = thunky(function (cb) {
    getCursor(function (err, cursor) {
      if (err) { return cb(err) }

      // Apply all opts
      for (var key in self._opts) {
        if (self._opts.hasOwnProperty(key)) {
          cursor = cursor[key].call(cursor, self._opts[key])
        }
      }

      cb(null, cursor)
    })
  })
}

util.inherits(Cursor, Readable)

Cursor.prototype.next = function (cb) {
  this._get(function (err, cursor) {
    if (err) return cb(err)
    cursor.next(cb)
  })

  return this
}

Cursor.prototype.rewind = function (cb) {
  this._get(function (err, cursor) {
    if (err) return cb(err)
    cursor.rewind(cb)
  })

  return this
}

Cursor.prototype.toArray = function (cb) {
  var array = []
  var self = this

  var loop = function () {
    self.next(function (err, obj) {
      if (err) return cb(err)
      if (!obj) return cb(null, array)
      array.push(obj)
      loop()
    })
  }

  loop()
}

Cursor.prototype.map = function (mapfn, cb) {
  var array = []
  var self = this

  var loop = function () {
    self.next(function (err, obj) {
      if (err) return cb(err)
      if (!obj) return cb(null, array)
      array.push(mapfn(obj))
      loop()
    })
  }

  loop()
}

Cursor.prototype.forEach = function (fn) {
  var self = this

  var loop = function () {
    self.next(function (err, obj) {
      if (err) return fn(err)
      fn(err, obj)

      if (!obj) return
      loop()
    })
  }

  loop()
}

Cursor.prototype.limit = function (n, cb) {
  this._opts.limit = n
  if (cb) return this.toArray(cb)
  return this
}

Cursor.prototype.skip = function (n, cb) {
  this._opts.skip = n
  if (cb) return this.toArray(cb)
  return this
}

Cursor.prototype.batchSize = function (n, cb) {
  this._opts.batchSize = n
  if (cb) return this.toArray(cb)
  return this
}

Cursor.prototype.sort = function (sortObj, cb) {
  this._opts.sort = sortObj
  if (cb) return this.toArray(cb)
  return this
}

Cursor.prototype.count = function (cb) {
  var self = this

  this._get(function(err, cursor) {
    if (err) { return cb(err) }
    cursor.count(true, self.opts, cb)
  })
}

Cursor.prototype.size = function (cb) {
  var self = this

  this._get(function(err, cursor) {
    if (err) { return cb(err) }
    cursor.count(false, self.opts, cb)
  })
}

Cursor.prototype.explain = function (cb) {
  this._get(function (err, cursor) {
    cursor.explain(cb)
  })
}

Cursor.prototype.destroy = function () {
  var self = this
  this._get(function (err, cursor) {
    if (err) return self.emit('error', err)
    if (cursor.kill) cursor.kill()
  })
}

Cursor.prototype._read = function () {
  var self = this
  this.next(function (err, data) {
    if (err) return self.emit('error', err)
    self.push(data)
  })
}

module.exports = Cursor
<commit_msg>Implement cursor destroy/close<commit_after>var util = require('util')
var thunky = require('thunky')
var Readable = require('readable-stream').Readable

var Cursor = function (getCursor) {
  Readable.call(this, {objectMode: true, highWaterMark: 0})

  this._opts = {}

  var self = this
  this._get = thunky(function (cb) {
    getCursor(function (err, cursor) {
      if (err) { return cb(err) }

      // Apply all opts
      for (var key in self._opts) {
        if (self._opts.hasOwnProperty(key)) {
          cursor = cursor[key].call(cursor, self._opts[key])
        }
      }

      cb(null, cursor)
    })
  })
}

util.inherits(Cursor, Readable)

Cursor.prototype.next = function (cb) {
  this._get(function (err, cursor) {
    if (err) return cb(err)
    cursor.next(cb)
  })

  return this
}

Cursor.prototype.rewind = function (cb) {
  this._get(function (err, cursor) {
    if (err) return cb(err)
    cursor.rewind(cb)
  })

  return this
}

Cursor.prototype.toArray = function (cb) {
  var array = []
  var self = this

  var loop = function () {
    self.next(function (err, obj) {
      if (err) return cb(err)
      if (!obj) return cb(null, array)
      array.push(obj)
      loop()
    })
  }

  loop()
}

Cursor.prototype.map = function (mapfn, cb) {
  var array = []
  var self = this

  var loop = function () {
    self.next(function (err, obj) {
      if (err) return cb(err)
      if (!obj) return cb(null, array)
      array.push(mapfn(obj))
      loop()
    })
  }

  loop()
}

Cursor.prototype.forEach = function (fn) {
  var self = this

  var loop = function () {
    self.next(function (err, obj) {
      if (err) return fn(err)
      fn(err, obj)

      if (!obj) return
      loop()
    })
  }

  loop()
}

Cursor.prototype.limit = function (n, cb) {
  this._opts.limit = n
  if (cb) return this.toArray(cb)
  return this
}

Cursor.prototype.skip = function (n, cb) {
  this._opts.skip = n
  if (cb) return this.toArray(cb)
  return this
}

Cursor.prototype.batchSize = function (n, cb) {
  this._opts.batchSize = n
  if (cb) return this.toArray(cb)
  return this
}

Cursor.prototype.sort = function (sortObj, cb) {
  this._opts.sort = sortObj
  if (cb) return this.toArray(cb)
  return this
}

Cursor.prototype.count = function (cb) {
  var self = this

  this._get(function(err, cursor) {
    if (err) { return cb(err) }
    cursor.count(true, self.opts, cb)
  })
}

Cursor.prototype.size = function (cb) {
  var self = this

  this._get(function(err, cursor) {
    if (err) { return cb(err) }
    cursor.count(false, self.opts, cb)
  })
}

Cursor.prototype.explain = function (cb) {
  this._get(function (err, cursor) {
    cursor.explain(cb)
  })
}

Cursor.prototype.destroy = function () {
  var self = this
  this._get(function (err, cursor) {
    if (err) return self.emit('error', err)
    if (cursor.close) cursor.close(function(err) {
      if (err) { self.emit('error', err) }
    })
  })
}

Cursor.prototype._read = function () {
  var self = this
  this.next(function (err, data) {
    if (err) return self.emit('error', err)
    self.push(data)
  })
}

module.exports = Cursor
<|endoftext|>


<commit_before>Handlebars.registerHelper('department_code', function (id) {
  return new Handlebars.SafeString(Yacs.models.departments.store.id[id].code);
});

Handlebars.registerHelper('course_credits', function (c) {
  var outString = '';
  // render "credit(s)" properly
  if (c.min_credits != c.max_credits) {
    outString = c.min_credits + '-' + c.max_credits + ' credits';
  }
  else {
    outString = c.max_credits + ' credit' + (c.max_credits == 1 ? '' : 's');
  }
  return new Handlebars.SafeString(outString);
});

Handlebars.registerHelper('join', function (arr) {
  return new Handlebars.SafeString(arr.join(', '));
});

Handlebars.registerHelper('seats_available', function (s) {
  var remaining = s.seats - s.seats_taken;
  return new Handlebars.SafeString(remaining);
});

Handlebars.registerHelper('closed_status', function (s) {
  return new Handlebars.SafeString(s.seats > 0 && s.seats_taken >= s.seats ? 'closed' : '');
});

Handlebars.registerHelper('day_name', function (n) {
  return new Handlebars.SafeString(['Sun', 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat'][n]);
});

Handlebars.registerHelper('time_range', function (start, end) {
  return new Handlebars.SafeString([start, end].map(function (time) {
    var hour = Math.floor(time / 100);
    var ampm = hour > 12 ? 'p' : 'a';
    hour = hour > 12 ? hour - 12 : hour == 0 ? 12 : hour;
    var minutes = time % 100;
    minutes = minutes > 9 ? minutes : minutes == 0 ? '' : '0' + minutes;
    return hour + (minutes ? ':' + minutes : '') + ampm;
  }).join('-'));
});
<commit_msg>Fixed noon display PM with >=<commit_after>Handlebars.registerHelper('department_code', function (id) {
  return new Handlebars.SafeString(Yacs.models.departments.store.id[id].code);
});

Handlebars.registerHelper('course_credits', function (c) {
  var outString = '';
  // render "credit(s)" properly
  if (c.min_credits != c.max_credits) {
    outString = c.min_credits + '-' + c.max_credits + ' credits';
  }
  else {
    outString = c.max_credits + ' credit' + (c.max_credits == 1 ? '' : 's');
  }
  return new Handlebars.SafeString(outString);
});

Handlebars.registerHelper('join', function (arr) {
  return new Handlebars.SafeString(arr.join(', '));
});

Handlebars.registerHelper('seats_available', function (s) {
  var remaining = s.seats - s.seats_taken;
  return new Handlebars.SafeString(remaining);
});

Handlebars.registerHelper('closed_status', function (s) {
  return new Handlebars.SafeString(s.seats > 0 && s.seats_taken >= s.seats ? 'closed' : '');
});

Handlebars.registerHelper('day_name', function (n) {
  return new Handlebars.SafeString(['Sun', 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat'][n]);
});

Handlebars.registerHelper('time_range', function (start, end) {
  return new Handlebars.SafeString([start, end].map(function (time) {
    var hour = Math.floor(time / 100);
    var ampm = hour >= 12 ? 'p' : 'a';
    hour = hour > 12 ? hour - 12 : hour == 0 ? 12 : hour;
    var minutes = time % 100;
    minutes = minutes > 9 ? minutes : minutes == 0 ? '' : '0' + minutes;
    return hour + (minutes ? ':' + minutes : '') + ampm;
  }).join('-'));
});
<|endoftext|>


<commit_before>define('imcms-link-validator-rest-api', ["imcms-rest-api"], function (rest) {
    let url = '/links';
    let api = new rest.API(url);

    api.search = function (queryObj) {
        return rest.ajax.call({url: url, type: 'GET', json: true}, queryObj);
    };

    return api;
});<commit_msg>IMCMS-334 New design to super admin page: link validator tab - Rename<commit_after>define('imcms-link-validator-rest-api', ["imcms-rest-api"], function (rest) {
    let url = '/links';
    let api = new rest.API(url);

    api.validate = function (filterObj) {
        return rest.ajax.call({url: url, type: 'GET', json: true}, filterObj);
    };

    return api;
});<|endoftext|>


<commit_before>'use strict'
exports.inject = require('./origin')
exports.properties = {
  $ (val, event) {
    var pattern = parsePattern(val)
    var emitter = this.subscribe(pattern, onSubscribe)
    var child = this.ChildConstructor.prototype
    var on = child._on
    if (on) {
      let ref = on.reference
      if (ref) {
        let attach = ref.attach
        if (attach) {
          let pattern = emitter.pattern
          let set = {}
          attach.each(function (property, key) {
            let pattern = property[2][1]
            pattern.setKey('_ignore', true)
            set[key] = pattern
          })
          attachChildSub(pattern, set)
        }
      }
    }
    if (!this.$origin) {
      this.setKey('$origin', {}, event)
    }
    emitter.run(event)
  }
}

function parsePattern (val) {
  if (typeof val === 'string') {
    val = val
      .replace(/\.\.\.\//gi, '$upward.')
      .replace(/\.\.\//gi, 'parent.')

    let firstChar = val[0]
    if (firstChar !== '.') {
      let firstKey = val.substring(0, 6)
      if (firstKey !== 'parent' && firstKey !== '$upward') {
        val = '$upward.' + val
      }
    } else {
      val = val.substring(2)
    }
    let keys = val.split('.')
    let value = true
    for (let i = keys.length - 1; i >= 0; i--) {
      let key = keys[i]
      val = {}
      val[key] = value
      value = val
    }
  }
  return val
}

function onSubscribe (data, event) {
  var target = resolve(this)
  if (target._input !== null) {
    // console.log(data.length, data[0].origin.path.join('.'),'-->',target.path.join('.'))
    target.$origin.set(data[0].origin) //event needed
  }
}

function resolve (target) {
  var _contextLevel = target._contextLevel
  if (_contextLevel) {
    let path = []
    while (_contextLevel) {
      path.push(target.key)
      target = target.parent
      _contextLevel--
    }
    for (let i = path.length - 1; i >= 0; i--) {
      target = target[path[i]]
    }
  }
  return target
}

function attachChildSub (pattern, set) {
  for (let i in pattern) {
    if (i[0] !== '_' && i !== 'key') {
      let property = pattern[i]
      if (property._input) {
        property.setKey('_childSub', {})
        for (let i in set) {
          property._childSub.setKey(i, set[i])
        }
      }
      attachChildSub(property, set)
    }
  }
}
<commit_msg>removed log<commit_after>'use strict'
exports.inject = require('./origin')
exports.properties = {
  $ (val, event) {
    var pattern = parsePattern(val)
    var emitter = this.subscribe(pattern, onSubscribe)
    var child = this.ChildConstructor.prototype
    var on = child._on
    if (on) {
      let ref = on.reference
      if (ref) {
        let attach = ref.attach
        if (attach) {
          let pattern = emitter.pattern
          let set = {}
          attach.each(function (property, key) {
            let pattern = property[2][1]
            pattern.setKey('_ignore', true)
            set[key] = pattern
          })
          attachChildSub(pattern, set)
        }
      }
    }
    if (!this.$origin) {
      this.setKey('$origin', {}, event)
    }
    emitter.run(event)
  }
}

function parsePattern (val) {
  if (typeof val === 'string') {
    val = val
      .replace(/\.\.\.\//gi, '$upward.')
      .replace(/\.\.\//gi, 'parent.')

    let firstChar = val[0]
    if (firstChar !== '.') {
      let firstKey = val.substring(0, 6)
      if (firstKey !== 'parent' && firstKey !== '$upward') {
        val = '$upward.' + val
      }
    } else {
      val = val.substring(2)
    }
    let keys = val.split('.')
    let value = true
    for (let i = keys.length - 1; i >= 0; i--) {
      let key = keys[i]
      val = {}
      val[key] = value
      value = val
    }
  }
  return val
}

function onSubscribe (data, event) {
  var target = resolve(this)
  if (target._input !== null) {
    target.$origin.set(data[0].origin) //event needed
  }
}

function resolve (target) {
  var _contextLevel = target._contextLevel
  if (_contextLevel) {
    let path = []
    while (_contextLevel) {
      path.push(target.key)
      target = target.parent
      _contextLevel--
    }
    for (let i = path.length - 1; i >= 0; i--) {
      target = target[path[i]]
    }
  }
  return target
}

function attachChildSub (pattern, set) {
  for (let i in pattern) {
    if (i[0] !== '_' && i !== 'key') {
      let property = pattern[i]
      if (property._input) {
        property.setKey('_childSub', {})
        for (let i in set) {
          property._childSub.setKey(i, set[i])
        }
      }
      attachChildSub(property, set)
    }
  }
}
<|endoftext|>


<commit_before>/*global define */
/*jslint white:true,global:true*/
/*
 * MonoBus
 * One bus to rule them all...
 *
 * The idea is to have a single message bus which allows natural and transparent
 * partitioning.
 *
 * A single message bus is easier to debug, and should make more abstract bus
 * mechanisms easier to create.
 *
 * But a single bus by itself exposes too much, provides no privacy or protection
 * for otherwise private channels.
 *
 *
 *
 */
define([
    'uuid',
    'bluebird'
], function (Uuid, Promise) {
    'use strict';
    var instanceId = 0;
    function newInstance() {
        instanceId += 1;
        return instanceId;
    }

    function factory(config) {
        var api,
            config = config || {},
            listenerRegistry = {},
            sendQueue = [],
            requestMap = [],
            interval = 0,
            timer,
            instanceId = newInstance(),
            channels = {},
            doLogMessages = false,
            strictMode = config.strict;

        // CHANNELS

        /*
         * Channels are the top level method for distributing messages. Many
         * message producers and consumers will communicate solely over a channel.
         *
         * Channels are implemented as property of envelopes and addresses.
         */

        function makeChannel(spec) {
            if (channels[spec.name]) {
                throw new Error('A channel with name "' + spec.name + '" already exists');
            }
            if (!spec.description) {
                if (strictMode) {
                    throw new Error('Channel description is required');
                } else {
                    console.warn('Channel created without description');
                }
            }
            console.log('MAKING CHANNEL', spec);
            channels[spec.name] = {
                name: spec.name,
                description: spec.description,
                created: new Date(),
                messageCount: 0,
                listeners: [],
                keyListeners: {},
                testListeners: []
            };
            return channels[spec.name];
        }

        function ensureChannel(name) {
            if (!channels[name]) {
                console.warn('Channel implicitly created', name);
                makeChannel({name: name});
            }
            return channels[name];
        }

        function getChannel(name) {
            var channel = channels[name];
            if (!channel) {
                throw new Error('Channel with name "' + name + '" does not exist');
            }
            return channel;
        }

        function removeChannel(name) {
            delete channels[name];
        }

        // LISTENING

        function letListenerHandle(item, handle) {
            try {
                handle(item.message, item.envelope);
            } catch (ex) {
                console.error('Bus handle failure', ex);
            }
        }

        function processKeyListeners(channel, item) {
            var listeners = channel.keyListeners[item.envelope.key],
                handled = false;
            if (!listeners) {
                return;
            }
            listeners.forEach(function (listener) {
                handled = true;
                if (doLogMessages) {
                    console.log('PROCESSING KEY LISTENER', channel, item);
                }
                letListenerHandle(item, listener.handle);
            });
            return handled;
        }

        function testListener(item, tester) {
            try {
                return tester(item.message, item.envelope);
            } catch (ex) {
                console.error('Bus test failure', ex);
                return false;
            }
        }

        /*
         * Listening registers a function which when true given a message,
         * invokes the receiving function.
         *
         * Update: for more efficient routing, it is now possible to
         * specify a listen key which is used as an absolute address for
         * messages. The key may be a string or an object. Objects are converted
         * to a hash of sorts and then used as strings.
         *
         * Also, each listener now gets a unique id to allow unsubscription.
         *
         */
        function encodeKey(tryKey) {
            if (typeof tryKey === 'object') {
                return JSON.stringify(tryKey);
            }
            return tryKey;
        }

        function listen(spec) {
            var id = new Uuid(4).format(),
                key,
                listener = {
                    spec: spec,
                    id: id,
                    created: new Date()
                },
            channelName = spec.channel || 'default',
                channel = ensureChannel(channelName);
            if (spec.key) {
                key = encodeKey(spec.key);
                if (!channel.keyListeners[key]) {
                    channel.keyListeners[key] = [];
                }
                listener.handle = spec.handle;
                listener.key = key;

                channel.keyListeners[key].push(listener);
            } else if (spec.test) {
                listener.test = spec.test;
                listener.handle = spec.handle;
                channel.testListeners.push(listener);
            } else {
                console.warn('listen: nothing to listen on (test or key)');
            }

            return id;
        }

        // PROCESSING ENGINE

        function processTestListeners(channel, item) {
            var handled = false;
            channel.testListeners.forEach(function (listener) {
                if (doLogMessages) {
                    console.log('PROCESSING TEST LISTENER?', channel, item);
                }
                if (testListener(item, listener.test)) {
                    handled = true;
                    console.log('PROCESSING TEST LISTENER!', channel, item);
                    letListenerHandle(item, listener.handle);
                }
            });
            return handled;
        }
        function processPending() {
            var processingQueue = sendQueue;
            sendQueue = [];
            processingQueue.forEach(function (item) {
                var channel = getChannel(item.envelope.channel),
                    handled;

                if (item.envelope.key) {
                    if (doLogMessages) {
                        console.log('PROCESSING KEY', channel, item);
                    }
                    handled = processKeyListeners(channel, item);
                } else {
                    if (doLogMessages) {
                        console.log('PROCESSING TEST', channel, item);
                    }
                    handled = processTestListeners(channel, item);
                }
                if (!handled) {
                    console.warn('No listeners handled message', item, channel);
                }
            });
        }
        /*
         *
         * running the bus queue is as
         */
        function run() {
            if (timer) {
                return;
            }
            timer = window.setTimeout(function () {
                timer = null;
                try {
                    processPending();
                } catch (ex) {
                    console.error('Bus processing error', ex);
                }
            }, interval);
        }

        // SENDING

        /*
         * sending places a message into the queue (bus).
         *
         * The optional address can be used to route the message to some
         * some specific key or other strategy not yet thunk up.
         */
        function send(message, address) {
            // support simple message sending ...
            address = address || {};

            var envelope = {
                created: new Date(),
                id: new Uuid(4).format(),
                address: address
            };

            if (address) {
                if (address.key) {
                    envelope.key = encodeKey(address.key);
                }
            }

            envelope.channel = address.channel || 'default';

            if (doLogMessages) {
                console.log('SEND', message, envelope);
            }
            sendQueue.push({
                message: message,
                envelope: envelope
            });
            run();
        }

        /*
         *
         * Respond sets up a special listener, which when it matches,
         * will put a return value into the bus as a new message targeted
         * at the requestId
         *
         */
        function respond(spec) {
            var originalHandle = spec.handle;
            function newHandle(message, envelope) {
                try {
                    var responseMessage = originalHandle(message);
                    send(responseMessage, {
                        key: {requestId: envelope.address.requestId}
                    });
                } catch (ex) {
                    console.error('Error handling in respond', ex);
                }
            }
            spec.handle = newHandle;
            listen(spec);
        }

        /*
         * Request supports request/response style messaging.
         * It accomplishes this by using a special store for messages -
         * pending requests - which is a map of all request messages.
         */
        function request(message, address) {
            return new Promise(function (resolve, reject) {
                var requestId = new Uuid(4).format();

                // when this listener with a key set to the request id
                // is called, it will resolve the promise, and it is
                // configured to be removed from the listeners once it
                // is run, as well as to invoke the error handler upon
                // timeout. (TODO)
                listen({
                    key: {requestId: requestId},
                    once: true,
                    timeout: address.timeout || 10000,
                    handle: function (responseMessage) {
                        resolve(responseMessage);
                    }
                });

                // NB - respond understands requestId in the envelope.
                if (!address) {
                    address = {};
                }
                address.requestId = requestId;
                send(message, address);
            });
        }

        // convenience strategies.
        function on(type, handler, channel) {
            // listen({
            //     test: function (message) {
            //         return (message.type === type);
            //     },
            //     handle: handler
            // });
            listen({
                channel: channel,
                key: JSON.stringify({type: type}),
                handle: handler
            });
        }

        function emit(type, message) {
            if (message === undefined) {
                message = {};
            }
            send(message, {
                key: {type: type}
            });
        }

        function logMessages(doLog) {
            if (doLog) {
                doLogMessages = true;
            } else {
                doLogMessages = false;
            }
        }

        // CHANNEL BUS

        /*
         * Creates and returns a mini bus wrapper around a single channel.
         * Allows usage of the main bus but within a scope limited to the
         * specific channel. The main bus is available through a method.
         */
        function makeChannelBus(name, description) {
            var channelName = name || new Uuid(4).format(),
                channelSpec = {
                    name: channelName,
                    description: description
                };

            makeChannel(channelSpec);

            function on(type, handler) {
                return listen({
                    channel: channelName,
                    key: {type: type},
                    handle: handler
                });
            }

            function emit(type, message) {
                if (message === undefined) {
                    message = {};
                }
                return send(message, {
                    channel: channelName,
                    key: {type: type}
                });
            }

            function channelSend(message, address) {
                address = address || {};
                address.channel = channelName;
                return send(message, address);
            }

            function channelListen(spec) {
                spec.channel = channelName;
                return listen(spec);
            }

            function channelRequest(message, address) {
                address = address || {};
                address.channel = channelName;
                return request(message, address);
            }

            function channelRespond(spec) {
                spec.channel = channelName;
                return respond(spec);
            }

            function bus() {
                return api;
            }

            function stop() {
                removeChannel(channelName);
            }

            return {
                on: on,
                emit: emit,
                bus: bus,
                listen: channelListen,
                send: channelSend,
                respond: channelRespond,
                request: channelRequest,
                stop: stop
            };
        }

        // MANAGEMENT

        // MAIN
        makeChannel({name: 'default', description: 'The Default Channel'});

        // API
        api = {
            listen: listen,
            send: send,
            respond: respond,
            request: request,
            on: on,
            emit: emit,
            makeChannelBus: makeChannelBus,
            makeChannel: makeChannel,
            removeChannel: removeChannel,
            logMessages: logMessages
        };

        return api;
    }

    return {
        make: function (config) {
            return factory(config);
        }
    };
});<commit_msg>add persistent messages and listener removal<commit_after>/*global define */
/*jslint white:true,global:true*/
/*
 * MonoBus
 * One bus to rule them all...
 *
 * The idea is to have a single message bus which allows natural and transparent
 * partitioning.
 *
 * A single message bus is easier to debug, and should make more abstract bus
 * mechanisms easier to create.
 *
 * But a single bus by itself exposes too much, provides no privacy or protection
 * for otherwise private channels.
 *
 *
 *
 */
define([
    'uuid',
    'bluebird',
    './unodep'
], function (Uuid, Promise, utils) {
    'use strict';
    var instanceId = 0;
    function newInstance() {
        instanceId += 1;
        return instanceId;
    }

    function factory(config) {
        var api,
            config = config || {},
            listenerRegistry = {},
            transientMessages = [],
            requestMap = [],
            interval = 0,
            timer,
            instanceId = newInstance(),
            channels = {},
            doLogMessages = false,
            strictMode = config.strict;

        // CHANNELS

        /*
         * Channels are the top level method for distributing messages. Many
         * message producers and consumers will communicate solely over a channel.
         *
         * Channels are implemented as property of envelopes and addresses.
         */

        function makeChannel(spec) {
            if (channels[spec.name]) {
                throw new Error('A channel with name "' + spec.name + '" already exists');
            }
            if (!spec.description) {
                if (strictMode) {
                    throw new Error('Channel description is required');
                } else {
                    console.warn('Channel created without description');
                }
            }
            channels[spec.name] = {
                name: spec.name,
                description: spec.description,
                created: new Date(),
                messageCount: 0,
                listeners: [],
                keyListeners: {},
                testListeners: [],
                persistentMessages: {}
            };
            return channels[spec.name];
        }

        function ensureChannel(name) {
            if (!channels[name]) {
                console.warn('Channel implicitly created', name);
                makeChannel({name: name});
            }
            return channels[name];
        }

        function getChannel(name) {
            var channel = channels[name];
            if (!channel) {
                throw new Error('Channel with name "' + name + '" does not exist');
            }
            return channel;
        }

        function removeChannel(name) {
            delete channels[name];
        }

        // LISTENING

        function letListenerHandle(item, handle) {
            try {
                handle(item.message, item.envelope);
            } catch (ex) {
                console.error('Bus handle failure', ex);
                console.error(ex.message);
            }
        }

        function processKeyListeners(channel, item) {
            var listeners = channel.keyListeners[item.envelope.key],
                handled = false;
            if (!listeners) {
                return;
            }
            listeners.forEach(function (listener) {
                handled = true;
                if (doLogMessages) {
                    console.log('PROCESSING KEY LISTENER', channel, item);
                }
                letListenerHandle(item, listener.handle);
            });
            return handled;
        }

        function testListener(item, tester) {
            try {
                return tester(item.message, item.envelope);
            } catch (ex) {
                console.error('Bus test failure', ex);
                return false;
            }
        }

        /*
         * Listening registers a function which when true given a message,
         * invokes the receiving function.
         *
         * Update: for more efficient routing, it is now possible to
         * specify a listen key which is used as an absolute address for
         * messages. The key may be a string or an object. Objects are converted
         * to a hash of sorts and then used as strings.
         *
         * Also, each listener now gets a unique id to allow unsubscription.
         *
         */
        function encodeKey(tryKey) {
            if (typeof tryKey === 'object') {
                return JSON.stringify(tryKey);
            }
            return tryKey;
        }

        /*
         * basically takes care of sorting the keys before encoding.
         * TODO: actually do that.
         */
        function encodeObject(tryObject) {
            return JSON.stringify(tryObject);
        }

        function canonicalizeChannelName(channelName, defaultName) {
            if (!channelName) {
                return defaultName || 'default';
            }
            if (typeof channelName === 'object') {
                return encodeObject(channelName);
            }
            if (typeof channelName === 'string') {
                return channelName;
            }
            return String(channelName);
        }

        function listen(spec) {
            var id = new Uuid(4).format(),
                key,
                channelName = canonicalizeChannelName(spec.channel),
                channel = ensureChannel(channelName),
                listener = {
                    spec: spec,
                    id: id,
                    created: new Date(),
                    channelName: channelName
                };

            if (spec.key) {
                key = encodeKey(spec.key);
                if (!channel.keyListeners[key]) {
                    channel.keyListeners[key] = [];
                }
                listener.handle = spec.handle;
                listener.key = key;

                channel.keyListeners[key].push(listener);

                // If it matches a persistent message, we need to trigger the
                // persistent message to emit a message.
                maybeSendPersistentMessages(channel, key);

                // Just trigger a queue run in case there are any persistent
                // messages.
                run();
            } else if (spec.test) {
                listener.test = spec.test;
                listener.handle = spec.handle;
                channel.testListeners.push(listener);
            } else {
                console.warn('listen: nothing to listen on (test or key)');
            }

            listenerRegistry[id] = listener;
            return id;
        }

        function removeListener(id) {
            var listenerToRemove = listenerRegistry[id],
                channel, listeners, newListeners;
            if (!listenerToRemove) {
                return;
            }
            channel = getChannel(listenerToRemove.channelName);
            if (!channel) {
                return;
            }
            if (listenerToRemove.key) {
                listeners = channel.keyListeners[listenerToRemove.key];
                if (!listeners) {
                    return;
                }
                channel.keyListeners[listenerToRemove.key] = listeners.filter(function (listener) {
                    return (listener.id !== listenerToRemove.id);
                });
            } else if (listenerToRemove.test) {
                listeners = channel.testListeners;
                if (!listeners) {
                    return;
                }
                channel.testListeners = listeners.filter(function (listener) {
                    return (listener.id !== listenerToRemove.id);
                });
            }
        }

        // PROCESSING ENGINE

        function processTestListeners(channel, item) {
            var handled = false;
            channel.testListeners.forEach(function (listener) {
                if (doLogMessages) {
                    console.log('PROCESSING TEST LISTENER?', channel, item);
                }
                if (testListener(item, listener.test)) {
                    handled = true;
                    if (doLogMessages) {
                        console.log('PROCESSING TEST LISTENER!', channel, item);
                    }
                    letListenerHandle(item, listener.handle);
                }
            });
            return handled;
        }

        function processQueueItem(item) {
            var channel = getChannel(item.envelope.channel),
                handled;

            if (item.envelope.key) {
                if (doLogMessages) {
                    console.log('PROCESSING KEY', channel, item);
                }
                handled = processKeyListeners(channel, item);
            } else {
                if (doLogMessages) {
                    console.log('PROCESSING TEST', channel, item);
                }
                handled = processTestListeners(channel, item);
            }
            if (!handled) {
                console.warn('No listeners handled message', item, channel);
            }
        }

        function processQueues() {
            var processingQueue = transientMessages;
            transientMessages = [];

            processingQueue.forEach(function (item) {
                try {
                    processQueueItem(item);
                } catch (ex) {
                    console.error('ERROR processing queue item', ex);
                }
            });

        }
        /*
         *
         * running the bus queue is as
         */
        function run() {
            if (timer) {
                return;
            }
            timer = window.setTimeout(function () {
                timer = null;
                try {
                    processQueues();
                } catch (ex) {
                    console.error('Bus processing error', ex);
                }
            }, interval);
        }

        // SENDING

        function setPersistentMessage(message, envelope) {
            var channel = ensureChannel(envelope.channel),
                key = envelope.key,
                existingMessage;
            if (!key) {
                throw new Error('Persistent messages require a key');
            }

            existingMessage = channel.persistentMessages[key];
            if (existingMessage) {
                if (utils.isEqual(existingMessage.message, message)) {
                    return;
                }
            }

            channel.persistentMessages[key] = {
                message: message,
                envelope: envelope
            };
            transientMessages.push({
                message: message,
                envelope: envelope
            });
            run();
        }

        function maybeSendPersistentMessages(channel, key) {
            var persistentMessage = channel.persistentMessages[key];
            if (!persistentMessage) {
                return;
            }
            transientMessages.push({
                message: persistentMessage.message,
                envelope: persistentMessage.envelope
            });
            run();
        }

        /*
         * sending places a message into the queue (bus).
         *
         * The optional address can be used to route the message to some
         * some specific key or other strategy not yet thunk up.
         */
        function send(message, address) {
            // support simple message sending ...
            address = address || {};

            var envelope = {
                created: new Date(),
                id: new Uuid(4).format(),
                address: address
            };

            if (address.key) {
                envelope.key = encodeKey(address.key);
            }

            envelope.channel = canonicalizeChannelName(address.channel);

            if (doLogMessages) {
                console.log('SEND', message, envelope);
            }

            transientMessages.push({
                message: message,
                envelope: envelope
            });
            run();
        }

        function set(message, address) {
            // support simple message sending ...
            address = address || {};

            var envelope = {
                created: new Date(),
                id: new Uuid(4).format(),
                address: address
            };

            if (!address.key) {
                throw new Error('Setting a persistent message requires a key');
            }

            envelope.key = encodeKey(address.key);
            envelope.channel = canonicalizeChannelName(address.channel);

            if (doLogMessages) {
                console.log('SET', message, envelope);
            }

            // Persistent messages are stored on a map by 'key' per channel.
            setPersistentMessage(message, envelope);
        }

        /*
         *
         * Respond sets up a special listener, which when it matches,
         * will put a return value into the bus as a new message targeted
         * at the requestId
         *
         */
        function respond(spec) {
            var originalHandle = spec.handle;
            function newHandle(message, envelope) {
                try {
                    var responseMessage = originalHandle(message);
                    send(responseMessage, {
                        key: {requestId: envelope.address.requestId}
                    });
                } catch (ex) {
                    console.error('Error handling in respond', ex);
                }
            }
            spec.handle = newHandle;
            listen(spec);
        }

        /*
         * Request supports request/response style messaging.
         * It accomplishes this by using a special store for messages -
         * pending requests - which is a map of all request messages.
         */
        function request(message, address) {
            return new Promise(function (resolve, reject) {
                var requestId = new Uuid(4).format();

                // when this listener with a key set to the request id
                // is called, it will resolve the promise, and it is
                // configured to be removed from the listeners once it
                // is run, as well as to invoke the error handler upon
                // timeout. (TODO)
                listen({
                    key: {requestId: requestId},
                    once: true,
                    timeout: address.timeout || 10000,
                    handle: function (responseMessage) {
                        resolve(responseMessage);
                    }
                });

                // NB - respond understands requestId in the envelope.
                if (!address) {
                    address = {};
                }
                address.requestId = requestId;
                send(message, address);
            });
        }

        // convenience strategies.
        function on(type, handler, channel) {
            // listen({
            //     test: function (message) {
            //         return (message.type === type);
            //     },
            //     handle: handler
            // });
            listen({
                channel: channel,
                key: JSON.stringify({type: type}),
                handle: handler
            });
        }

        function emit(type, message) {
            if (message === undefined) {
                message = {};
            }
            send(message, {
                key: {type: type}
            });
        }

        function logMessages(doLog) {
            if (doLog) {
                doLogMessages = true;
            } else {
                doLogMessages = false;
            }
        }

        // CHANNEL BUS

        /*
         * Creates and returns a mini bus wrapper around a single channel.
         * Allows usage of the main bus but within a scope limited to the
         * specific channel. The main bus is available through a method.
         */
        function makeChannelBus(name, description) {
            var channelName = canonicalizeChannelName(name, new Uuid(4).format()),
                channelSpec = {
                    name: channelName,
                    description: description
                };

            makeChannel(channelSpec);

            function on(type, handler) {
                return listen({
                    channel: channelName,
                    key: {type: type},
                    handle: handler
                });
            }

            function emit(type, message) {
                if (message === undefined) {
                    message = {};
                }
                return send(message, {
                    channel: channelName,
                    key: {type: type}
                });
            }

            function channelSend(message, address) {
                address = address || {};
                address.channel = channelName;
                return send(message, address);
            }

            function channelSet(message, address) {
                address = address || {};
                address.channel = channelName;
                return set(message, address);
            }

            function channelListen(spec) {
                spec.channel = channelName;
                return listen(spec);
            }

            function channelRequest(message, address) {
                address = address || {};
                address.channel = channelName;
                return request(message, address);
            }

            function channelRespond(spec) {
                spec.channel = channelName;
                return respond(spec);
            }

            function bus() {
                return api;
            }

            function stop() {
                removeChannel(channelName);
            }

            return {
                on: on,
                emit: emit,
                set: set,
                bus: bus,
                listen: channelListen,
                send: channelSend,
                respond: channelRespond,
                request: channelRequest,
                stop: stop
            };
        }

        // MANAGEMENT

        // MAIN
        makeChannel({name: 'default', description: 'The Default Channel'});

        // API
        api = {
            listen: listen,
            send: send,
            respond: respond,
            request: request,
            on: on,
            emit: emit,
            set: set,
            makeChannelBus: makeChannelBus,
            makeChannel: makeChannel,
            removeChannel: removeChannel,
            logMessages: logMessages,
            removeListener: removeListener
        };

        return api;
    }

    return {
        make: function (config) {
            return factory(config);
        }
    };
});<|endoftext|>


<commit_before>var ACTIVE_LOCALE = window.ACTIVE_LOCALE;
if (ACTIVE_LOCALE !== 'en') {
  require('moment/locale/' + ACTIVE_LOCALE);
}
var Locale = require('../../locale/index');
var Polyglot = require('node-polyglot');
var polyglot = new Polyglot({
  locale: ACTIVE_LOCALE, // Needed for pluralize behaviour
  phrases: Locale[ACTIVE_LOCALE]
});
window._t = polyglot.t.bind(polyglot);

var $ = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
var deepInsights = require('cartodb-deep-insights.js');
var ConfigModel = require('./data/config-model');
var EditorMapView = require('./editor/editor-map-view');
var MapDefinitionModel = require('./data/map-definition-model');
var AnalysisDefinitionNodesCollection = require('./data/analysis-definition-nodes-collection');
var AnalysisDefinitionsCollection = require('./data/analysis-definitions-collection');
var LayerDefinitionsCollection = require('./data/layer-definitions-collection');
var WidgetDefinitionsCollection = require('./data/widget-definitions-collection');
var VisDefinitionModel = require('./data/vis-definition-model');
var createEditorMenuTabPane = require('./components/tab-pane/create-editor-menu-tab-pane');
var editorPaneTemplate = require('./editor/editor-pane.tpl');
var editorPaneIconItemTemplate = require('./editor/editor-pane-icon.tpl');
var ModalsServiceModel = require('./components/modals/modals-service-model');
var AnalysesService = require('./editor/layers/layer-content-views/analyses/analyses-service.js');
var OnboardingsServiceModel = require('./components/onboardings/onboardings-service-model');
var BuilderOnboardingLauncher = require('./components/onboardings/builder/launcher');
var viewFactory = require('./components/view-factory');
var UserModel = require('./data/user-model');
var UserNotifications = require('./data/user-notifications');
var EditorModel = require('./data/editor-model');
var UserActions = require('./data/user-actions');
var ImporterManager = require('./components/background-importer/background-importer');
var BackgroundPollingModel = require('./data/editor-background-polling-model');
var StyleManager = require('./editor/style/style-manager');
var DeepInsightsIntegrations = require('./deep-insights-integrations');
var EditFeatureOverlay = require('./deep-insights-integration/edit-feature-overlay');
var Notifier = require('./components/notifier/notifier');
var MetricsTracker = require('./components/metrics/metrics-tracker');
var FeedbackButtonView = require('./editor/feedback/feedback-button-view');
var SettingsOptions = require('./data/map-settings');
var SettingsView = require('./editor/editor-settings-view');
var OverlaysCollection = require('./data/overlays-definition-collection');
var MapcapsCollection = require('./data/mapcaps-collection');
var PrivacyCollection = require('./components/modals/publish/privacy-collection');
var CreatePrivacyOptions = require('./components/modals/publish/create-privacy-options');
var UserGroupFetcher = require('./data/users-group-fetcher');
var State = require('./data/state-definition-model');
var LegendDefinitionsCollection = require('./data/legends/legend-definitions-collection');
var LegendsState = require('./data/legends/legends-state');
var LegendFactory = require('./editor/layers/layer-content-views/legend/legend-factory');
var EditorVisualizationWarningView = require('./components/modals/editor-visualization-warning/editor-visualization-warning-view');
var MapModeModel = require('./map-mode-model');
var BuilderActivatedNotification = require('./components/onboardings/builder-activated/builder-activated-notification-view');
var NodeGeometryTracker = require('./node-geometry-tracker');
var WidgetsService = require('./editor/widgets/widgets-service');
var DataServicesApiCheck = require('./editor/layers/layer-content-views/analyses/analyses-quota/analyses-quota-info');
var AppNotifications = require('./app-notifications');

// JSON data passed from entry point (editor/visualizations/show.html):
var vizJSON = window.vizJSON;
var stateJSON = window.stateJSON;
var userData = window.userData;
var frontendConfig = window.frontendConfig;
var visualizationData = window.visualizationData;
var layersData = window.layersData;
var analysesData = window.analysesData;
var builderNotifications = window.builderNotifications;
var dashboardNotifications = window.dashboardNotifications;
var mapcapsData = window.mapcapsData;
var overlaysData = window.overlaysData;
var basemaps = window.basemaps;
var mapzenApiKey = window.mapzenApiKey;

var configModel = new ConfigModel(
  _.defaults(
    {
      base_url: userData.base_url,
      api_key: userData.api_key
    },
    frontendConfig
  )
);

DataServicesApiCheck.get(configModel).fetch();

var onboardingNotification = new UserNotifications(builderNotifications, {
  key: 'builder',
  configModel: configModel
});

var userModel = new UserModel(userData, {
  configModel: configModel
});

var editorModel = new EditorModel();

var visDefinitionModel = new VisDefinitionModel(visualizationData, {
  configModel: configModel
});
var modals = new ModalsServiceModel();
var onboardings = new OnboardingsServiceModel();
onboardings.editorModel = editorModel;

UserGroupFetcher.track({
  userModel: userModel,
  configModel: configModel,
  acl: visDefinitionModel.getPermissionModel().acl
});

var stateDefModel = new State({
  json: stateJSON
}, {
  visDefinitionModel: visDefinitionModel
});

var mapId = visualizationData.map_id;

var analysisDefinitionNodesCollection = new AnalysisDefinitionNodesCollection(null, {
  userModel: userModel,
  configModel: configModel,
  relatedTableData: visualizationData.related_tables
});

var layerDefinitionsCollection = new LayerDefinitionsCollection(null, {
  configModel: configModel,
  userModel: userModel,
  analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
  mapId: mapId,
  stateDefinitionModel: stateDefModel
});

var analysisDefinitionsCollection = new AnalysisDefinitionsCollection(analysesData, {
  configModel: configModel,
  analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
  layerDefinitionsCollection: layerDefinitionsCollection,
  vizId: visDefinitionModel.id
});

layerDefinitionsCollection.resetByLayersData(layersData);

// Track geometry changes over any node definition model
NodeGeometryTracker.track({
  analysisDefinitionsCollection: analysisDefinitionsCollection,
  analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
  layerDefinitionsCollection: layerDefinitionsCollection
});

var widgetDefinitionsCollection = new WidgetDefinitionsCollection(null, {
  configModel: configModel,
  mapId: mapId,
  layerDefinitionsCollection: layerDefinitionsCollection,
  analysisDefinitionNodesCollection: analysisDefinitionNodesCollection
});

vizJSON.widgets.forEach(function (d) {
  widgetDefinitionsCollection.add(d);
});

var legendDefinitionsCollection = new LegendDefinitionsCollection(null, {
  configModel: configModel,
  layerDefinitionsCollection: layerDefinitionsCollection,
  vizId: visDefinitionModel.id
});
legendDefinitionsCollection.resetByData(vizJSON);
LegendFactory.init(legendDefinitionsCollection);
LegendsState.init(layerDefinitionsCollection, legendDefinitionsCollection);

Notifier.init({
  editorModel: editorModel,
  visDefinitionModel: visDefinitionModel
});

AppNotifications.init();

MetricsTracker.init({
  userId: userModel.get('id'),
  visId: visDefinitionModel.get('id'),
  configModel: configModel
});

BuilderOnboardingLauncher.init({
  onboardings: onboardings,
  userModel: userModel,
  editorModel: editorModel,
  onboardingNotification: onboardingNotification
});

AnalysesService.init({
  onboardings: onboardings,
  layerDefinitionsCollection: layerDefinitionsCollection,
  modals: modals,
  userModel: userModel,
  configModel: configModel
});

var userActions = UserActions({
  userModel: userModel,
  analysisDefinitionsCollection: analysisDefinitionsCollection,
  analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
  layerDefinitionsCollection: layerDefinitionsCollection,
  widgetDefinitionsCollection: widgetDefinitionsCollection
});

var privacyOptions = CreatePrivacyOptions(visDefinitionModel, userModel);
var privacyCollection = new PrivacyCollection(privacyOptions);

var mapcapsCollection = new MapcapsCollection(mapcapsData, {
  visDefinitionModel: visDefinitionModel
});

var backgroundPollingModel = new BackgroundPollingModel({
  importsPolling: false
}, {
  configModel: configModel,
  userModel: userModel,
  userActions: userActions
});

ImporterManager.init({
  pollingModel: backgroundPollingModel,
  createVis: false,
  userModel: userModel,
  configModel: configModel,
  modals: modals
});

var mapDefModel = new MapDefinitionModel(
  _.extend(
    vizJSON,
    {
      id: visualizationData.map_id
    }
  ),
  {
    parse: true,
    configModel: configModel,
    userModel: userModel,
    layerDefinitionsCollection: layerDefinitionsCollection
  }
);

var overlaysCollection = new OverlaysCollection(overlaysData, {
  configModel: configModel,
  visId: visDefinitionModel.id
});

var mapModeModel = new MapModeModel();

WidgetsService.init({
  analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
  editorModel: editorModel,
  layerDefinitionsCollection: layerDefinitionsCollection,
  modals: modals,
  userActions: userActions,
  widgetDefinitionsCollection: widgetDefinitionsCollection
});

var mapCreation = function () {
  BuilderOnboardingLauncher.launch();

  if (!configModel.get('cartodb_com_hosted')) {
    if (userModel.get('actions').builder_enabled && userModel.get('show_builder_activated_message') &&
        _.isEmpty(dashboardNotifications)) {
      var builderActivatedNotification = new UserNotifications(dashboardNotifications, {
        key: 'dashboard',
        configModel: configModel
      });

      var builderActivatedNotificationView = new BuilderActivatedNotification({
        builderActivatedNotification: builderActivatedNotification
      });

      $('.js-editor').addClass('Editor--topBar');
      builderActivatedNotificationView.bind('clean', function () {
        $('.js-editor').removeClass('Editor--topBar');
      }, this);
    }
  }

  deepInsights.createDashboard('#dashboard', vizJSON, {
    apiKey: configModel.get('api_key'),
    no_cdn: false,
    cartodb_logo: false,
    renderMenu: false,
    show_empty_infowindow_fields: true,
    showLimitErrors: true,
    state: stateJSON,
    interactiveFeatures: true,
    layerSelectorEnabled: false,
    mapzenApiKey: mapzenApiKey,
    vector: false // disable vector rendering
  }, function (error, dashboard) {
    if (error) {
      console.error('Dashboard has some errors:\n', error);
    }

    var vis = dashboard.getMap();
    var dashboardView = dashboard.getView();

    dashboardView.listenTo(editorModel, 'change:edition', function (m) {
      dashboardView.$el.toggleClass('is-dark', m.isEditing());
    });

    var styleManager = new StyleManager(layerDefinitionsCollection, vis.map, configModel);

    var editFeatureOverlay = new EditFeatureOverlay({
      map: vis.map,
      mapModeModel: mapModeModel,
      modals: modals
    });
    editFeatureOverlay.hide();
    vis.addCustomOverlay(editFeatureOverlay);

    var deepInsightsIntegrations = new DeepInsightsIntegrations({
      onboardings: onboardings,
      userModel: userModel,
      deepInsightsDashboard: dashboard,
      analysisDefinitionsCollection: analysisDefinitionsCollection,
      analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
      layerDefinitionsCollection: layerDefinitionsCollection,
      legendDefinitionsCollection: legendDefinitionsCollection,
      widgetDefinitionsCollection: widgetDefinitionsCollection,
      overlayDefinitionsCollection: overlaysCollection,
      visDefinitionModel: visDefinitionModel,
      mapDefinitionModel: mapDefModel,
      stateDefinitionModel: stateDefModel,
      mapModeModel: mapModeModel,
      configModel: configModel,
      editorModel: editorModel,
      editFeatureOverlay: editFeatureOverlay
    });

    // Expose things after Map initialization
    window.deepInsightsIntegrations = deepInsightsIntegrations;
    window.styleManager = styleManager;
    window.dashboard = dashboard;
    window.vis = vis;
  });
};

if (visDefinitionModel.get('version') === 2 && modals) {
  visDefinitionModel.bind('change:version', function () {
    mapcapsCollection.fetch();
    mapCreation();
  }, this);

  modals.create(function (modalModel) {
    return new EditorVisualizationWarningView({
      modalModel: modalModel,
      visDefinitionModel: visDefinitionModel
    });
  }, true);
} else {
  mapCreation();
}

var settingsCollection = new Backbone.Collection(SettingsOptions(overlaysCollection, mapDefModel, userModel));

var editorTabPaneView = createEditorMenuTabPane([
  {
    icon: 'pencilMenu',
    selected: true,
    createContentView: function () {
      editorModel.set({settingsView: false});
      return new EditorMapView({
        basemaps: basemaps,
        userActions: userActions,
        configModel: configModel,
        userModel: userModel,
        editorModel: editorModel,
        pollingModel: backgroundPollingModel,
        mapDefinitionModel: mapDefModel,
        onboardings: onboardings,
        modals: modals,
        visDefinitionModel: visDefinitionModel,
        layerDefinitionsCollection: layerDefinitionsCollection,
        analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
        widgetDefinitionsCollection: widgetDefinitionsCollection,
        mapcapsCollection: mapcapsCollection,
        privacyCollection: privacyCollection,
        legendDefinitionsCollection: legendDefinitionsCollection,
        mapModeModel: mapModeModel,
        stateDefinitionModel: stateDefModel,
        onboardingNotification: onboardingNotification,
        settingsCollection: settingsCollection
      });
    }
  }, {
    icon: 'settings',
    createContentView: function () {
      editorModel.set({settingsView: true});
      return new SettingsView({
        mapDefinitionModel: mapDefModel,
        overlaysCollection: overlaysCollection,
        mapcapsCollection: mapcapsCollection,
        visDefinitionModel: visDefinitionModel,
        privacyCollection: privacyCollection,
        configModel: configModel,
        userModel: userModel,
        modals: modals,
        editorModel: editorModel,
        settingsCollection: settingsCollection,
        stateDefinitionModel: stateDefModel
      });
    }
  }
], {
  tabPaneOptions: {
    className: 'Editor-wrapper',
    template: editorPaneTemplate,
    url: userModel.get('base_url'),
    avatar_url: userModel.get('avatar_url'),
    tabPaneItemOptions: {
      tagName: 'li',
      className: 'EditorMenu-navigationItem'
    }
  },
  tabPaneItemIconOptions: {
    tagName: 'button',
    template: editorPaneIconItemTemplate,
    className: 'EditorMenu-navigationLink'
  }
});

$('.js-editor').prepend(editorTabPaneView.render().$el);

editorTabPaneView.listenTo(editorModel, 'change:edition', function (m) {
  editorTabPaneView.$('.Editor-panelWrapper').toggleClass('is-larger', m.isEditing());
});
editorTabPaneView.add_related_model(editorModel);

if (!configModel.get('cartodb_com_hosted')) {
  var feedbackView = new FeedbackButtonView({ modals: modals });
  $('.js-editorMenu').append(feedbackView.render().el);
}

document.title = visDefinitionModel.get('name') + ' | CARTO';

if (window.__backboneAgent) {
  window.__backboneAgent.handleBackbone(Backbone);
}

// Expose the root stuff to be able to inspect and modify state from
// developer console (before views)
window.configModel = configModel;
window.modals = modals;
window.onboardings = onboardings;
window.userActions = userActions;
window.userModel = userModel;
window.viewFactory = viewFactory;
window.visDefinitionModel = visDefinitionModel;
window.layerDefinitionsCollection = layerDefinitionsCollection;
window.widgetDefinitionsCollection = widgetDefinitionsCollection;
window.analysisDefinitionsCollection = analysisDefinitionsCollection;
window.analysisDefinitionNodesCollection = analysisDefinitionNodesCollection;
window.legendDefinitionsCollection = legendDefinitionsCollection;
window.editorModel = editorModel;
window.mapDefModel = mapDefModel;
window.overlaysCollection = overlaysCollection;
window.mapcapsCollection = mapcapsCollection;
window.stateDefModel = stateDefModel;
window.settingsCollection = settingsCollection;
<commit_msg>Force vector in builder for testing purposes<commit_after>var ACTIVE_LOCALE = window.ACTIVE_LOCALE;
if (ACTIVE_LOCALE !== 'en') {
  require('moment/locale/' + ACTIVE_LOCALE);
}
var Locale = require('../../locale/index');
var Polyglot = require('node-polyglot');
var polyglot = new Polyglot({
  locale: ACTIVE_LOCALE, // Needed for pluralize behaviour
  phrases: Locale[ACTIVE_LOCALE]
});
window._t = polyglot.t.bind(polyglot);

var $ = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
var deepInsights = require('cartodb-deep-insights.js');
var ConfigModel = require('./data/config-model');
var EditorMapView = require('./editor/editor-map-view');
var MapDefinitionModel = require('./data/map-definition-model');
var AnalysisDefinitionNodesCollection = require('./data/analysis-definition-nodes-collection');
var AnalysisDefinitionsCollection = require('./data/analysis-definitions-collection');
var LayerDefinitionsCollection = require('./data/layer-definitions-collection');
var WidgetDefinitionsCollection = require('./data/widget-definitions-collection');
var VisDefinitionModel = require('./data/vis-definition-model');
var createEditorMenuTabPane = require('./components/tab-pane/create-editor-menu-tab-pane');
var editorPaneTemplate = require('./editor/editor-pane.tpl');
var editorPaneIconItemTemplate = require('./editor/editor-pane-icon.tpl');
var ModalsServiceModel = require('./components/modals/modals-service-model');
var AnalysesService = require('./editor/layers/layer-content-views/analyses/analyses-service.js');
var OnboardingsServiceModel = require('./components/onboardings/onboardings-service-model');
var BuilderOnboardingLauncher = require('./components/onboardings/builder/launcher');
var viewFactory = require('./components/view-factory');
var UserModel = require('./data/user-model');
var UserNotifications = require('./data/user-notifications');
var EditorModel = require('./data/editor-model');
var UserActions = require('./data/user-actions');
var ImporterManager = require('./components/background-importer/background-importer');
var BackgroundPollingModel = require('./data/editor-background-polling-model');
var StyleManager = require('./editor/style/style-manager');
var DeepInsightsIntegrations = require('./deep-insights-integrations');
var EditFeatureOverlay = require('./deep-insights-integration/edit-feature-overlay');
var Notifier = require('./components/notifier/notifier');
var MetricsTracker = require('./components/metrics/metrics-tracker');
var FeedbackButtonView = require('./editor/feedback/feedback-button-view');
var SettingsOptions = require('./data/map-settings');
var SettingsView = require('./editor/editor-settings-view');
var OverlaysCollection = require('./data/overlays-definition-collection');
var MapcapsCollection = require('./data/mapcaps-collection');
var PrivacyCollection = require('./components/modals/publish/privacy-collection');
var CreatePrivacyOptions = require('./components/modals/publish/create-privacy-options');
var UserGroupFetcher = require('./data/users-group-fetcher');
var State = require('./data/state-definition-model');
var LegendDefinitionsCollection = require('./data/legends/legend-definitions-collection');
var LegendsState = require('./data/legends/legends-state');
var LegendFactory = require('./editor/layers/layer-content-views/legend/legend-factory');
var EditorVisualizationWarningView = require('./components/modals/editor-visualization-warning/editor-visualization-warning-view');
var MapModeModel = require('./map-mode-model');
var BuilderActivatedNotification = require('./components/onboardings/builder-activated/builder-activated-notification-view');
var NodeGeometryTracker = require('./node-geometry-tracker');
var WidgetsService = require('./editor/widgets/widgets-service');
var DataServicesApiCheck = require('./editor/layers/layer-content-views/analyses/analyses-quota/analyses-quota-info');
var AppNotifications = require('./app-notifications');

// JSON data passed from entry point (editor/visualizations/show.html):
var vizJSON = window.vizJSON;
var stateJSON = window.stateJSON;
var userData = window.userData;
var frontendConfig = window.frontendConfig;
var visualizationData = window.visualizationData;
var layersData = window.layersData;
var analysesData = window.analysesData;
var builderNotifications = window.builderNotifications;
var dashboardNotifications = window.dashboardNotifications;
var mapcapsData = window.mapcapsData;
var overlaysData = window.overlaysData;
var basemaps = window.basemaps;
var mapzenApiKey = window.mapzenApiKey;

var configModel = new ConfigModel(
  _.defaults(
    {
      base_url: userData.base_url,
      api_key: userData.api_key
    },
    frontendConfig
  )
);

DataServicesApiCheck.get(configModel).fetch();

var onboardingNotification = new UserNotifications(builderNotifications, {
  key: 'builder',
  configModel: configModel
});

var userModel = new UserModel(userData, {
  configModel: configModel
});

var editorModel = new EditorModel();

var visDefinitionModel = new VisDefinitionModel(visualizationData, {
  configModel: configModel
});
var modals = new ModalsServiceModel();
var onboardings = new OnboardingsServiceModel();
onboardings.editorModel = editorModel;

UserGroupFetcher.track({
  userModel: userModel,
  configModel: configModel,
  acl: visDefinitionModel.getPermissionModel().acl
});

var stateDefModel = new State({
  json: stateJSON
}, {
  visDefinitionModel: visDefinitionModel
});

var mapId = visualizationData.map_id;

var analysisDefinitionNodesCollection = new AnalysisDefinitionNodesCollection(null, {
  userModel: userModel,
  configModel: configModel,
  relatedTableData: visualizationData.related_tables
});

var layerDefinitionsCollection = new LayerDefinitionsCollection(null, {
  configModel: configModel,
  userModel: userModel,
  analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
  mapId: mapId,
  stateDefinitionModel: stateDefModel
});

var analysisDefinitionsCollection = new AnalysisDefinitionsCollection(analysesData, {
  configModel: configModel,
  analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
  layerDefinitionsCollection: layerDefinitionsCollection,
  vizId: visDefinitionModel.id
});

layerDefinitionsCollection.resetByLayersData(layersData);

// Track geometry changes over any node definition model
NodeGeometryTracker.track({
  analysisDefinitionsCollection: analysisDefinitionsCollection,
  analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
  layerDefinitionsCollection: layerDefinitionsCollection
});

var widgetDefinitionsCollection = new WidgetDefinitionsCollection(null, {
  configModel: configModel,
  mapId: mapId,
  layerDefinitionsCollection: layerDefinitionsCollection,
  analysisDefinitionNodesCollection: analysisDefinitionNodesCollection
});

vizJSON.widgets.forEach(function (d) {
  widgetDefinitionsCollection.add(d);
});

var legendDefinitionsCollection = new LegendDefinitionsCollection(null, {
  configModel: configModel,
  layerDefinitionsCollection: layerDefinitionsCollection,
  vizId: visDefinitionModel.id
});
legendDefinitionsCollection.resetByData(vizJSON);
LegendFactory.init(legendDefinitionsCollection);
LegendsState.init(layerDefinitionsCollection, legendDefinitionsCollection);

Notifier.init({
  editorModel: editorModel,
  visDefinitionModel: visDefinitionModel
});

AppNotifications.init();

MetricsTracker.init({
  userId: userModel.get('id'),
  visId: visDefinitionModel.get('id'),
  configModel: configModel
});

BuilderOnboardingLauncher.init({
  onboardings: onboardings,
  userModel: userModel,
  editorModel: editorModel,
  onboardingNotification: onboardingNotification
});

AnalysesService.init({
  onboardings: onboardings,
  layerDefinitionsCollection: layerDefinitionsCollection,
  modals: modals,
  userModel: userModel,
  configModel: configModel
});

var userActions = UserActions({
  userModel: userModel,
  analysisDefinitionsCollection: analysisDefinitionsCollection,
  analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
  layerDefinitionsCollection: layerDefinitionsCollection,
  widgetDefinitionsCollection: widgetDefinitionsCollection
});

var privacyOptions = CreatePrivacyOptions(visDefinitionModel, userModel);
var privacyCollection = new PrivacyCollection(privacyOptions);

var mapcapsCollection = new MapcapsCollection(mapcapsData, {
  visDefinitionModel: visDefinitionModel
});

var backgroundPollingModel = new BackgroundPollingModel({
  importsPolling: false
}, {
  configModel: configModel,
  userModel: userModel,
  userActions: userActions
});

ImporterManager.init({
  pollingModel: backgroundPollingModel,
  createVis: false,
  userModel: userModel,
  configModel: configModel,
  modals: modals
});

var mapDefModel = new MapDefinitionModel(
  _.extend(
    vizJSON,
    {
      id: visualizationData.map_id
    }
  ),
  {
    parse: true,
    configModel: configModel,
    userModel: userModel,
    layerDefinitionsCollection: layerDefinitionsCollection
  }
);

var overlaysCollection = new OverlaysCollection(overlaysData, {
  configModel: configModel,
  visId: visDefinitionModel.id
});

var mapModeModel = new MapModeModel();

WidgetsService.init({
  analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
  editorModel: editorModel,
  layerDefinitionsCollection: layerDefinitionsCollection,
  modals: modals,
  userActions: userActions,
  widgetDefinitionsCollection: widgetDefinitionsCollection
});

var mapCreation = function () {
  BuilderOnboardingLauncher.launch();

  if (!configModel.get('cartodb_com_hosted')) {
    if (userModel.get('actions').builder_enabled && userModel.get('show_builder_activated_message') &&
        _.isEmpty(dashboardNotifications)) {
      var builderActivatedNotification = new UserNotifications(dashboardNotifications, {
        key: 'dashboard',
        configModel: configModel
      });

      var builderActivatedNotificationView = new BuilderActivatedNotification({
        builderActivatedNotification: builderActivatedNotification
      });

      $('.js-editor').addClass('Editor--topBar');
      builderActivatedNotificationView.bind('clean', function () {
        $('.js-editor').removeClass('Editor--topBar');
      }, this);
    }
  }

  deepInsights.createDashboard('#dashboard', vizJSON, {
    apiKey: configModel.get('api_key'),
    no_cdn: false,
    cartodb_logo: false,
    renderMenu: false,
    show_empty_infowindow_fields: true,
    showLimitErrors: true,
    state: stateJSON,
    interactiveFeatures: true,
    layerSelectorEnabled: false,
    mapzenApiKey: mapzenApiKey,
    vector: true // disable vector rendering
  }, function (error, dashboard) {
    if (error) {
      console.error('Dashboard has some errors:\n', error);
    }

    var vis = dashboard.getMap();
    var dashboardView = dashboard.getView();

    dashboardView.listenTo(editorModel, 'change:edition', function (m) {
      dashboardView.$el.toggleClass('is-dark', m.isEditing());
    });

    var styleManager = new StyleManager(layerDefinitionsCollection, vis.map, configModel);

    var editFeatureOverlay = new EditFeatureOverlay({
      map: vis.map,
      mapModeModel: mapModeModel,
      modals: modals
    });
    editFeatureOverlay.hide();
    vis.addCustomOverlay(editFeatureOverlay);

    var deepInsightsIntegrations = new DeepInsightsIntegrations({
      onboardings: onboardings,
      userModel: userModel,
      deepInsightsDashboard: dashboard,
      analysisDefinitionsCollection: analysisDefinitionsCollection,
      analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
      layerDefinitionsCollection: layerDefinitionsCollection,
      legendDefinitionsCollection: legendDefinitionsCollection,
      widgetDefinitionsCollection: widgetDefinitionsCollection,
      overlayDefinitionsCollection: overlaysCollection,
      visDefinitionModel: visDefinitionModel,
      mapDefinitionModel: mapDefModel,
      stateDefinitionModel: stateDefModel,
      mapModeModel: mapModeModel,
      configModel: configModel,
      editorModel: editorModel,
      editFeatureOverlay: editFeatureOverlay
    });

    // Expose things after Map initialization
    window.deepInsightsIntegrations = deepInsightsIntegrations;
    window.styleManager = styleManager;
    window.dashboard = dashboard;
    window.vis = vis;
  });
};

if (visDefinitionModel.get('version') === 2 && modals) {
  visDefinitionModel.bind('change:version', function () {
    mapcapsCollection.fetch();
    mapCreation();
  }, this);

  modals.create(function (modalModel) {
    return new EditorVisualizationWarningView({
      modalModel: modalModel,
      visDefinitionModel: visDefinitionModel
    });
  }, true);
} else {
  mapCreation();
}

var settingsCollection = new Backbone.Collection(SettingsOptions(overlaysCollection, mapDefModel, userModel));

var editorTabPaneView = createEditorMenuTabPane([
  {
    icon: 'pencilMenu',
    selected: true,
    createContentView: function () {
      editorModel.set({settingsView: false});
      return new EditorMapView({
        basemaps: basemaps,
        userActions: userActions,
        configModel: configModel,
        userModel: userModel,
        editorModel: editorModel,
        pollingModel: backgroundPollingModel,
        mapDefinitionModel: mapDefModel,
        onboardings: onboardings,
        modals: modals,
        visDefinitionModel: visDefinitionModel,
        layerDefinitionsCollection: layerDefinitionsCollection,
        analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
        widgetDefinitionsCollection: widgetDefinitionsCollection,
        mapcapsCollection: mapcapsCollection,
        privacyCollection: privacyCollection,
        legendDefinitionsCollection: legendDefinitionsCollection,
        mapModeModel: mapModeModel,
        stateDefinitionModel: stateDefModel,
        onboardingNotification: onboardingNotification,
        settingsCollection: settingsCollection
      });
    }
  }, {
    icon: 'settings',
    createContentView: function () {
      editorModel.set({settingsView: true});
      return new SettingsView({
        mapDefinitionModel: mapDefModel,
        overlaysCollection: overlaysCollection,
        mapcapsCollection: mapcapsCollection,
        visDefinitionModel: visDefinitionModel,
        privacyCollection: privacyCollection,
        configModel: configModel,
        userModel: userModel,
        modals: modals,
        editorModel: editorModel,
        settingsCollection: settingsCollection,
        stateDefinitionModel: stateDefModel
      });
    }
  }
], {
  tabPaneOptions: {
    className: 'Editor-wrapper',
    template: editorPaneTemplate,
    url: userModel.get('base_url'),
    avatar_url: userModel.get('avatar_url'),
    tabPaneItemOptions: {
      tagName: 'li',
      className: 'EditorMenu-navigationItem'
    }
  },
  tabPaneItemIconOptions: {
    tagName: 'button',
    template: editorPaneIconItemTemplate,
    className: 'EditorMenu-navigationLink'
  }
});

$('.js-editor').prepend(editorTabPaneView.render().$el);

editorTabPaneView.listenTo(editorModel, 'change:edition', function (m) {
  editorTabPaneView.$('.Editor-panelWrapper').toggleClass('is-larger', m.isEditing());
});
editorTabPaneView.add_related_model(editorModel);

if (!configModel.get('cartodb_com_hosted')) {
  var feedbackView = new FeedbackButtonView({ modals: modals });
  $('.js-editorMenu').append(feedbackView.render().el);
}

document.title = visDefinitionModel.get('name') + ' | CARTO';

if (window.__backboneAgent) {
  window.__backboneAgent.handleBackbone(Backbone);
}

// Expose the root stuff to be able to inspect and modify state from
// developer console (before views)
window.configModel = configModel;
window.modals = modals;
window.onboardings = onboardings;
window.userActions = userActions;
window.userModel = userModel;
window.viewFactory = viewFactory;
window.visDefinitionModel = visDefinitionModel;
window.layerDefinitionsCollection = layerDefinitionsCollection;
window.widgetDefinitionsCollection = widgetDefinitionsCollection;
window.analysisDefinitionsCollection = analysisDefinitionsCollection;
window.analysisDefinitionNodesCollection = analysisDefinitionNodesCollection;
window.legendDefinitionsCollection = legendDefinitionsCollection;
window.editorModel = editorModel;
window.mapDefModel = mapDefModel;
window.overlaysCollection = overlaysCollection;
window.mapcapsCollection = mapcapsCollection;
window.stateDefModel = stateDefModel;
window.settingsCollection = settingsCollection;
<|endoftext|>


<commit_before>self.$config = {
  landing: false,
  debug: false,
  repo: 'soruly/whatanime.ga',
  twitter: 'soruly',
  url: 'https://whatanime.ga',
  sidebar: false,
  disableSidebarToggle: true,
  nav: {
    default: []
  },
  icons: [],
  plugins: []
}
<commit_msg>Enable sidebar on API docs<commit_after>self.$config = {
  landing: false,
  debug: false,
  repo: 'soruly/whatanime.ga',
  twitter: 'soruly',
  url: 'https://whatanime.ga',
  sidebar: true,
  disableSidebarToggle: false,
  nav: {
    default: []
  },
  icons: [],
  plugins: []
}
<|endoftext|>


<commit_before>import React from 'react'
import { ApolloProvider } from 'react-apollo'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router } from 'react-router-dom'

import './styles/bootstrap-theme/wepickheroes.css'
import './styles/layout.css'

import { client } from './api'
import App from './components/App'
import registerServiceWorker from './registerServiceWorker'

const app = (
    <ApolloProvider client={client}>
        <Router>
            <App />
        </Router>
    </ApolloProvider>
)

ReactDOM.render(app, document.getElementById('root'))
registerServiceWorker()
<commit_msg>Unregister service worker<commit_after>import React from 'react'
import { ApolloProvider } from 'react-apollo'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router } from 'react-router-dom'

import './styles/bootstrap-theme/wepickheroes.css'
import './styles/layout.css'

import { client } from './api'
import App from './components/App'
import { unregister } from './registerServiceWorker'

const app = (
    <ApolloProvider client={client}>
        <Router>
            <App />
        </Router>
    </ApolloProvider>
)

ReactDOM.render(app, document.getElementById('root'))
unregister()
<|endoftext|>