<commit_before>/*
 * L.TileLayer is used for standard xyz-numbered tile layers.
 */

L.TileLayer = L.Class.extend({
	includes: L.Mixin.Events,

	options: {
		minZoom: 0,
		maxZoom: 18,
		tileSize: 256,
		subdomains: 'abc',
		errorTileUrl: '',
		attribution: '',
		zoomOffset: 0,
		opacity: 1,
		/* (undefined works too)
		zIndex: null,
		tms: false,
		continuousWorld: false,
		noWrap: false,
		zoomReverse: false,
		detectRetina: false,
		reuseTiles: false,
		tileBounds: false,
		*/
		unloadInvisibleTiles: L.Browser.mobile,
		updateWhenIdle: L.Browser.mobile
	},

	initialize: function (url, options) {
		options = L.Util.setOptions(this, options);

		// detecting retina displays, adjusting tileSize and zoom levels
		if (options.detectRetina && L.Browser.retina && options.maxZoom > 0) {

			options.tileSize = Math.floor(options.tileSize / 2);
			options.zoomOffset++;

			if (options.minZoom > 0) {
				options.minZoom--;
			}
			this.options.maxZoom--;
		}

		this._url = url;

		var subdomains = this.options.subdomains;

		if (typeof subdomains === 'string') {
			this.options.subdomains = subdomains.split('');
		}
	},

	onAdd: function (map) {
		this._map = map;

		// create a container div for tiles
		this._initContainer();

		// create an image to clone for tiles
		this._createTileProto();

		// set up events
		map.on({
			'viewreset': this._resetCallback,
			'moveend': this._update
		}, this);

		if (!this.options.updateWhenIdle) {
			this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this);
			map.on('move', this._limitedUpdate, this);
		}

		this._reset();
		this._update();
	},

	addTo: function (map) {
		map.addLayer(this);
		return this;
	},

	onRemove: function (map) {
		map._panes.tilePane.removeChild(this._container);

		map.off({
			'viewreset': this._resetCallback,
			'moveend': this._update
		}, this);

		if (!this.options.updateWhenIdle) {
			map.off('move', this._limitedUpdate, this);
		}

		this._container = null;
		this._map = null;
	},

	bringToFront: function () {
		var pane = this._map._panes.tilePane;

		if (this._container) {
			pane.appendChild(this._container);
			this._setAutoZIndex(pane, Math.max);
		}

		return this;
	},

	bringToBack: function () {
		var pane = this._map._panes.tilePane;

		if (this._container) {
			pane.insertBefore(this._container, pane.firstChild);
			this._setAutoZIndex(pane, Math.min);
		}

		return this;
	},

	getAttribution: function () {
		return this.options.attribution;
	},

	setOpacity: function (opacity) {
		this.options.opacity = opacity;

		if (this._map) {
			this._updateOpacity();
		}

		return this;
	},

	setZIndex: function (zIndex) {
		this.options.zIndex = zIndex;
		this._updateZIndex();

		return this;
	},

	setUrl: function (url, noRedraw) {
		this._url = url;

		if (!noRedraw) {
			this.redraw();
		}

		return this;
	},

	redraw: function () {
		if (this._map) {
			this._map._panes.tilePane.empty = false;
			this._reset(true);
			this._update();
		}
		return this;
	},

	_updateZIndex: function () {
		if (this._container && this.options.zIndex !== undefined) {
			this._container.style.zIndex = this.options.zIndex;
		}
	},

	_setAutoZIndex: function (pane, compare) {

		var layers = pane.getElementsByClassName('leaflet-layer'),
			edgeZIndex = -compare(Infinity, -Infinity), // -Ifinity for max, Infinity for min
			zIndex;

		for (var i = 0, len = layers.length; i < len; i++) {

			if (layers[i] !== this._container) {
				zIndex = parseInt(layers[i].style.zIndex, 10);

				if (!isNaN(zIndex)) {
					edgeZIndex = compare(edgeZIndex, zIndex);
				}
			}
		}

		this._container.style.zIndex = isFinite(edgeZIndex) ? edgeZIndex + compare(1, -1) : '';
	},

	_updateOpacity: function () {
		L.DomUtil.setOpacity(this._container, this.options.opacity);

		// stupid webkit hack to force redrawing of tiles
		var i,
			tiles = this._tiles;

		if (L.Browser.webkit) {
			for (i in tiles) {
				if (tiles.hasOwnProperty(i)) {
					tiles[i].style.webkitTransform += ' translate(0,0)';
				}
			}
		}
	},

	_initContainer: function () {
		var tilePane = this._map._panes.tilePane;

		if (!this._container || tilePane.empty) {
			this._container = L.DomUtil.create('div', 'leaflet-layer');

			this._updateZIndex();

			tilePane.appendChild(this._container);

			if (this.options.opacity < 1) {
				this._updateOpacity();
			}
		}
	},

	_resetCallback: function (e) {
		this._reset(e.hard);
	},

	_reset: function (clearOldContainer) {
		var key,
			tiles = this._tiles;

		for (key in tiles) {
			if (tiles.hasOwnProperty(key)) {
				this.fire('tileunload', {tile: tiles[key]});
			}
		}

		this._tiles = {};
		this._tilesToLoad = 0;

		if (this.options.reuseTiles) {
			this._unusedTiles = [];
		}

		if (clearOldContainer && this._container) {
			this._container.innerHTML = "";
		}

		this._initContainer();
	},

	_update: function (e) {
		if (this._map._panTransition && this._map._panTransition._inProgress) { return; }

		var bounds   = this._map.getPixelBounds(),
		    zoom     = this._map.getZoom(),
		    tileSize = this.options.tileSize;

		if (zoom > this.options.maxZoom || zoom < this.options.minZoom) {
			return;
		}

		var nwTilePoint = new L.Point(
				Math.floor(bounds.min.x / tileSize),
				Math.floor(bounds.min.y / tileSize)),
			seTilePoint = new L.Point(
				Math.floor(bounds.max.x / tileSize),
				Math.floor(bounds.max.y / tileSize)),
			tileBounds = new L.Bounds(nwTilePoint, seTilePoint);

		this._addTilesFromCenterOut(tileBounds);

		if (this.options.unloadInvisibleTiles || this.options.reuseTiles) {
			this._removeOtherTiles(tileBounds);
		}
	},

	_addTilesFromCenterOut: function (bounds) {
		var queue = [],
			center = bounds.getCenter();

		var j, i, point;

		for (j = bounds.min.y; j <= bounds.max.y; j++) {
			for (i = bounds.min.x; i <= bounds.max.x; i++) {
				point = new L.Point(i, j);

				if (this._tileShouldBeLoaded(point)) {
					queue.push(point);
				}
			}
		}

		var tilesToLoad = queue.length;

		if (tilesToLoad === 0) { return; }

		// load tiles in order of their distance to center
		queue.sort(function (a, b) {
			return a.distanceTo(center) - b.distanceTo(center);
		});

		var fragment = document.createDocumentFragment();

		// if its the first batch of tiles to load
		if (!this._tilesToLoad) {
			this.fire('loading');
		}

		this._tilesToLoad += tilesToLoad;

		for (i = 0; i < tilesToLoad; i++) {
			this._addTile(queue[i], fragment);
		}

		this._container.appendChild(fragment);
	},

	_tileShouldBeLoaded: function (tilePoint) {
		if ((tilePoint.x + ':' + tilePoint.y) in this._tiles) {
			return false; // already loaded
		}

		if (!this.options.continuousWorld) {
			var limit = this._getWrapTileNum();

			if (this.options.noWrap && (tilePoint.x < 0 || tilePoint.x >= limit) ||
				                        tilePoint.y < 0 || tilePoint.y >= limit) {
				return false; // exceeds world bounds
			}
		}

		if(this.options.tileBounds) {
			var tileSize = this.options.tileSize,
				nwPoint = tilePoint.multiplyBy(tileSize),
				sePoint = nwPoint.add(new L.Point(tileSize, tileSize)),
				nw = this._map.unproject(nwPoint),
				se = this._map.unproject(sePoint),
				bounds = new L.LatLngBounds([nw, se]);

			if(!this.options.tileBounds.intersects(bounds)) {
				return false;
			}
		}

		return true;
	},

	_removeOtherTiles: function (bounds) {
		var kArr, x, y, key;

		for (key in this._tiles) {
			if (this._tiles.hasOwnProperty(key)) {
				kArr = key.split(':');
				x = parseInt(kArr[0], 10);
				y = parseInt(kArr[1], 10);

				// remove tile if it's out of bounds
				if (x < bounds.min.x || x > bounds.max.x || y < bounds.min.y || y > bounds.max.y) {
					this._removeTile(key);
				}
			}
		}
	},

	_removeTile: function (key) {
		var tile = this._tiles[key];

		this.fire("tileunload", {tile: tile, url: tile.src});

		if (this.options.reuseTiles) {
			L.DomUtil.removeClass(tile, 'leaflet-tile-loaded');
			this._unusedTiles.push(tile);
		} else if (tile.parentNode === this._container) {
			this._container.removeChild(tile);
		}

		if (!L.Browser.android) { //For https://github.com/CloudMade/Leaflet/issues/137
			tile.src = L.Util.emptyImageUrl;
		}

		delete this._tiles[key];
	},

	_addTile: function (tilePoint, container) {
		var tilePos = this._getTilePos(tilePoint);

		// get unused tile - or create a new tile
		var tile = this._getTile();

		// Chrome 20 layouts much faster with top/left (Verify with timeline, frames)
		// android 4 browser has display issues with top/left and requires transform instead
		// android 3 browser not tested
		// android 2 browser requires top/left or tiles disappear on load or first drag (reappear after zoom) https://github.com/CloudMade/Leaflet/issues/866
		// (other browsers don't currently care) - see debug/hacks/jitter.html for an example
		L.DomUtil.setPosition(tile, tilePos, L.Browser.chrome || L.Browser.android23);

		this._tiles[tilePoint.x + ':' + tilePoint.y] = tile;

		this._loadTile(tile, tilePoint);

		if (tile.parentNode !== this._container) {
			container.appendChild(tile);
		}
	},

	_getZoomForUrl: function () {

		var options = this.options,
			zoom = this._map.getZoom();

		if (options.zoomReverse) {
			zoom = options.maxZoom - zoom;
		}

		return zoom + options.zoomOffset;
	},

	_getTilePos: function (tilePoint) {
		var origin = this._map.getPixelOrigin(),
			tileSize = this.options.tileSize;

		return tilePoint.multiplyBy(tileSize).subtract(origin);
	},

	// image-specific code (override to implement e.g. Canvas or SVG tile layer)

	getTileUrl: function (tilePoint) {
		this._adjustTilePoint(tilePoint);

		return L.Util.template(this._url, L.Util.extend({
			s: this._getSubdomain(tilePoint),
			z: this._getZoomForUrl(),
			x: tilePoint.x,
			y: tilePoint.y
		}, this.options));
	},

	_getWrapTileNum: function () {
		// TODO refactor, limit is not valid for non-standard projections
		return Math.pow(2, this._getZoomForUrl());
	},

	_adjustTilePoint: function (tilePoint) {

		var limit = this._getWrapTileNum();

		// wrap tile coordinates
		if (!this.options.continuousWorld && !this.options.noWrap) {
			tilePoint.x = ((tilePoint.x % limit) + limit) % limit;
		}

		if (this.options.tms) {
			tilePoint.y = limit - tilePoint.y - 1;
		}
	},

	_getSubdomain: function (tilePoint) {
		var index = (tilePoint.x + tilePoint.y) % this.options.subdomains.length;
		return this.options.subdomains[index];
	},

	_createTileProto: function () {
		var img = this._tileImg = L.DomUtil.create('img', 'leaflet-tile');
		img.galleryimg = 'no';

		var tileSize = this.options.tileSize;
		img.style.width = tileSize + 'px';
		img.style.height = tileSize + 'px';
	},

	_getTile: function () {
		if (this.options.reuseTiles && this._unusedTiles.length > 0) {
			var tile = this._unusedTiles.pop();
			this._resetTile(tile);
			return tile;
		}
		return this._createTile();
	},

	_resetTile: function (tile) {
		// Override if data stored on a tile needs to be cleaned up before reuse
	},

	_createTile: function () {
		var tile = this._tileImg.cloneNode(false);
		tile.onselectstart = tile.onmousemove = L.Util.falseFn;
		return tile;
	},

	_loadTile: function (tile, tilePoint) {
		tile._layer  = this;
		tile.onload  = this._tileOnLoad;
		tile.onerror = this._tileOnError;

		tile.src     = this.getTileUrl(tilePoint);
	},

    _tileLoaded: function () {
        this._tilesToLoad--;
        if (!this._tilesToLoad) {
            this.fire('load');
        }
    },

	_tileOnLoad: function (e) {
		var layer = this._layer;

		//Only if we are loading an actual image
		if (this.src !== L.Util.emptyImageUrl) {
			L.DomUtil.addClass(this, 'leaflet-tile-loaded');

			layer.fire('tileload', {
				tile: this,
				url: this.src
			});
		}

		layer._tileLoaded();
	},

	_tileOnError: function (e) {
		var layer = this._layer;

		layer.fire('tileerror', {
			tile: this,
			url: this.src
		});

		var newUrl = layer.options.errorTileUrl;
		if (newUrl) {
			this.src = newUrl;
		}

        layer._tileLoaded();
    }
});

L.tileLayer = function (url, options) {
	return new L.TileLayer(url, options);
};
<commit_msg>Rename TileLayer.options.tileBounds to bounds<commit_after>/*
 * L.TileLayer is used for standard xyz-numbered tile layers.
 */

L.TileLayer = L.Class.extend({
	includes: L.Mixin.Events,

	options: {
		minZoom: 0,
		maxZoom: 18,
		tileSize: 256,
		subdomains: 'abc',
		errorTileUrl: '',
		attribution: '',
		zoomOffset: 0,
		opacity: 1,
		/* (undefined works too)
		zIndex: null,
		tms: false,
		continuousWorld: false,
		noWrap: false,
		zoomReverse: false,
		detectRetina: false,
		reuseTiles: false,
		bounds: false,
		*/
		unloadInvisibleTiles: L.Browser.mobile,
		updateWhenIdle: L.Browser.mobile
	},

	initialize: function (url, options) {
		options = L.Util.setOptions(this, options);

		// detecting retina displays, adjusting tileSize and zoom levels
		if (options.detectRetina && L.Browser.retina && options.maxZoom > 0) {

			options.tileSize = Math.floor(options.tileSize / 2);
			options.zoomOffset++;

			if (options.minZoom > 0) {
				options.minZoom--;
			}
			this.options.maxZoom--;
		}

		this._url = url;

		var subdomains = this.options.subdomains;

		if (typeof subdomains === 'string') {
			this.options.subdomains = subdomains.split('');
		}
	},

	onAdd: function (map) {
		this._map = map;

		// create a container div for tiles
		this._initContainer();

		// create an image to clone for tiles
		this._createTileProto();

		// set up events
		map.on({
			'viewreset': this._resetCallback,
			'moveend': this._update
		}, this);

		if (!this.options.updateWhenIdle) {
			this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this);
			map.on('move', this._limitedUpdate, this);
		}

		this._reset();
		this._update();
	},

	addTo: function (map) {
		map.addLayer(this);
		return this;
	},

	onRemove: function (map) {
		map._panes.tilePane.removeChild(this._container);

		map.off({
			'viewreset': this._resetCallback,
			'moveend': this._update
		}, this);

		if (!this.options.updateWhenIdle) {
			map.off('move', this._limitedUpdate, this);
		}

		this._container = null;
		this._map = null;
	},

	bringToFront: function () {
		var pane = this._map._panes.tilePane;

		if (this._container) {
			pane.appendChild(this._container);
			this._setAutoZIndex(pane, Math.max);
		}

		return this;
	},

	bringToBack: function () {
		var pane = this._map._panes.tilePane;

		if (this._container) {
			pane.insertBefore(this._container, pane.firstChild);
			this._setAutoZIndex(pane, Math.min);
		}

		return this;
	},

	getAttribution: function () {
		return this.options.attribution;
	},

	setOpacity: function (opacity) {
		this.options.opacity = opacity;

		if (this._map) {
			this._updateOpacity();
		}

		return this;
	},

	setZIndex: function (zIndex) {
		this.options.zIndex = zIndex;
		this._updateZIndex();

		return this;
	},

	setUrl: function (url, noRedraw) {
		this._url = url;

		if (!noRedraw) {
			this.redraw();
		}

		return this;
	},

	redraw: function () {
		if (this._map) {
			this._map._panes.tilePane.empty = false;
			this._reset(true);
			this._update();
		}
		return this;
	},

	_updateZIndex: function () {
		if (this._container && this.options.zIndex !== undefined) {
			this._container.style.zIndex = this.options.zIndex;
		}
	},

	_setAutoZIndex: function (pane, compare) {

		var layers = pane.getElementsByClassName('leaflet-layer'),
			edgeZIndex = -compare(Infinity, -Infinity), // -Ifinity for max, Infinity for min
			zIndex;

		for (var i = 0, len = layers.length; i < len; i++) {

			if (layers[i] !== this._container) {
				zIndex = parseInt(layers[i].style.zIndex, 10);

				if (!isNaN(zIndex)) {
					edgeZIndex = compare(edgeZIndex, zIndex);
				}
			}
		}

		this._container.style.zIndex = isFinite(edgeZIndex) ? edgeZIndex + compare(1, -1) : '';
	},

	_updateOpacity: function () {
		L.DomUtil.setOpacity(this._container, this.options.opacity);

		// stupid webkit hack to force redrawing of tiles
		var i,
			tiles = this._tiles;

		if (L.Browser.webkit) {
			for (i in tiles) {
				if (tiles.hasOwnProperty(i)) {
					tiles[i].style.webkitTransform += ' translate(0,0)';
				}
			}
		}
	},

	_initContainer: function () {
		var tilePane = this._map._panes.tilePane;

		if (!this._container || tilePane.empty) {
			this._container = L.DomUtil.create('div', 'leaflet-layer');

			this._updateZIndex();

			tilePane.appendChild(this._container);

			if (this.options.opacity < 1) {
				this._updateOpacity();
			}
		}
	},

	_resetCallback: function (e) {
		this._reset(e.hard);
	},

	_reset: function (clearOldContainer) {
		var key,
			tiles = this._tiles;

		for (key in tiles) {
			if (tiles.hasOwnProperty(key)) {
				this.fire('tileunload', {tile: tiles[key]});
			}
		}

		this._tiles = {};
		this._tilesToLoad = 0;

		if (this.options.reuseTiles) {
			this._unusedTiles = [];
		}

		if (clearOldContainer && this._container) {
			this._container.innerHTML = "";
		}

		this._initContainer();
	},

	_update: function (e) {
		if (this._map._panTransition && this._map._panTransition._inProgress) { return; }

		var bounds   = this._map.getPixelBounds(),
		    zoom     = this._map.getZoom(),
		    tileSize = this.options.tileSize;

		if (zoom > this.options.maxZoom || zoom < this.options.minZoom) {
			return;
		}

		var nwTilePoint = new L.Point(
				Math.floor(bounds.min.x / tileSize),
				Math.floor(bounds.min.y / tileSize)),
			seTilePoint = new L.Point(
				Math.floor(bounds.max.x / tileSize),
				Math.floor(bounds.max.y / tileSize)),
			tileBounds = new L.Bounds(nwTilePoint, seTilePoint);

		this._addTilesFromCenterOut(tileBounds);

		if (this.options.unloadInvisibleTiles || this.options.reuseTiles) {
			this._removeOtherTiles(tileBounds);
		}
	},

	_addTilesFromCenterOut: function (bounds) {
		var queue = [],
			center = bounds.getCenter();

		var j, i, point;

		for (j = bounds.min.y; j <= bounds.max.y; j++) {
			for (i = bounds.min.x; i <= bounds.max.x; i++) {
				point = new L.Point(i, j);

				if (this._tileShouldBeLoaded(point)) {
					queue.push(point);
				}
			}
		}

		var tilesToLoad = queue.length;

		if (tilesToLoad === 0) { return; }

		// load tiles in order of their distance to center
		queue.sort(function (a, b) {
			return a.distanceTo(center) - b.distanceTo(center);
		});

		var fragment = document.createDocumentFragment();

		// if its the first batch of tiles to load
		if (!this._tilesToLoad) {
			this.fire('loading');
		}

		this._tilesToLoad += tilesToLoad;

		for (i = 0; i < tilesToLoad; i++) {
			this._addTile(queue[i], fragment);
		}

		this._container.appendChild(fragment);
	},

	_tileShouldBeLoaded: function (tilePoint) {
		if ((tilePoint.x + ':' + tilePoint.y) in this._tiles) {
			return false; // already loaded
		}

		if (!this.options.continuousWorld) {
			var limit = this._getWrapTileNum();

			if (this.options.noWrap && (tilePoint.x < 0 || tilePoint.x >= limit) ||
				                        tilePoint.y < 0 || tilePoint.y >= limit) {
				return false; // exceeds world bounds
			}
		}

		if (this.options.bounds) {
			var tileSize = this.options.tileSize,
				nwPoint = tilePoint.multiplyBy(tileSize),
				sePoint = nwPoint.add(new L.Point(tileSize, tileSize)),
				nw = this._map.unproject(nwPoint),
				se = this._map.unproject(sePoint),
				bounds = new L.LatLngBounds([nw, se]);

			if (!this.options.bounds.intersects(bounds)) {
				return false;
			}
		}

		return true;
	},

	_removeOtherTiles: function (bounds) {
		var kArr, x, y, key;

		for (key in this._tiles) {
			if (this._tiles.hasOwnProperty(key)) {
				kArr = key.split(':');
				x = parseInt(kArr[0], 10);
				y = parseInt(kArr[1], 10);

				// remove tile if it's out of bounds
				if (x < bounds.min.x || x > bounds.max.x || y < bounds.min.y || y > bounds.max.y) {
					this._removeTile(key);
				}
			}
		}
	},

	_removeTile: function (key) {
		var tile = this._tiles[key];

		this.fire("tileunload", {tile: tile, url: tile.src});

		if (this.options.reuseTiles) {
			L.DomUtil.removeClass(tile, 'leaflet-tile-loaded');
			this._unusedTiles.push(tile);
		} else if (tile.parentNode === this._container) {
			this._container.removeChild(tile);
		}

		if (!L.Browser.android) { //For https://github.com/CloudMade/Leaflet/issues/137
			tile.src = L.Util.emptyImageUrl;
		}

		delete this._tiles[key];
	},

	_addTile: function (tilePoint, container) {
		var tilePos = this._getTilePos(tilePoint);

		// get unused tile - or create a new tile
		var tile = this._getTile();

		// Chrome 20 layouts much faster with top/left (Verify with timeline, frames)
		// android 4 browser has display issues with top/left and requires transform instead
		// android 3 browser not tested
		// android 2 browser requires top/left or tiles disappear on load or first drag (reappear after zoom) https://github.com/CloudMade/Leaflet/issues/866
		// (other browsers don't currently care) - see debug/hacks/jitter.html for an example
		L.DomUtil.setPosition(tile, tilePos, L.Browser.chrome || L.Browser.android23);

		this._tiles[tilePoint.x + ':' + tilePoint.y] = tile;

		this._loadTile(tile, tilePoint);

		if (tile.parentNode !== this._container) {
			container.appendChild(tile);
		}
	},

	_getZoomForUrl: function () {

		var options = this.options,
			zoom = this._map.getZoom();

		if (options.zoomReverse) {
			zoom = options.maxZoom - zoom;
		}

		return zoom + options.zoomOffset;
	},

	_getTilePos: function (tilePoint) {
		var origin = this._map.getPixelOrigin(),
			tileSize = this.options.tileSize;

		return tilePoint.multiplyBy(tileSize).subtract(origin);
	},

	// image-specific code (override to implement e.g. Canvas or SVG tile layer)

	getTileUrl: function (tilePoint) {
		this._adjustTilePoint(tilePoint);

		return L.Util.template(this._url, L.Util.extend({
			s: this._getSubdomain(tilePoint),
			z: this._getZoomForUrl(),
			x: tilePoint.x,
			y: tilePoint.y
		}, this.options));
	},

	_getWrapTileNum: function () {
		// TODO refactor, limit is not valid for non-standard projections
		return Math.pow(2, this._getZoomForUrl());
	},

	_adjustTilePoint: function (tilePoint) {

		var limit = this._getWrapTileNum();

		// wrap tile coordinates
		if (!this.options.continuousWorld && !this.options.noWrap) {
			tilePoint.x = ((tilePoint.x % limit) + limit) % limit;
		}

		if (this.options.tms) {
			tilePoint.y = limit - tilePoint.y - 1;
		}
	},

	_getSubdomain: function (tilePoint) {
		var index = (tilePoint.x + tilePoint.y) % this.options.subdomains.length;
		return this.options.subdomains[index];
	},

	_createTileProto: function () {
		var img = this._tileImg = L.DomUtil.create('img', 'leaflet-tile');
		img.galleryimg = 'no';

		var tileSize = this.options.tileSize;
		img.style.width = tileSize + 'px';
		img.style.height = tileSize + 'px';
	},

	_getTile: function () {
		if (this.options.reuseTiles && this._unusedTiles.length > 0) {
			var tile = this._unusedTiles.pop();
			this._resetTile(tile);
			return tile;
		}
		return this._createTile();
	},

	_resetTile: function (tile) {
		// Override if data stored on a tile needs to be cleaned up before reuse
	},

	_createTile: function () {
		var tile = this._tileImg.cloneNode(false);
		tile.onselectstart = tile.onmousemove = L.Util.falseFn;
		return tile;
	},

	_loadTile: function (tile, tilePoint) {
		tile._layer  = this;
		tile.onload  = this._tileOnLoad;
		tile.onerror = this._tileOnError;

		tile.src     = this.getTileUrl(tilePoint);
	},

    _tileLoaded: function () {
        this._tilesToLoad--;
        if (!this._tilesToLoad) {
            this.fire('load');
        }
    },

	_tileOnLoad: function (e) {
		var layer = this._layer;

		//Only if we are loading an actual image
		if (this.src !== L.Util.emptyImageUrl) {
			L.DomUtil.addClass(this, 'leaflet-tile-loaded');

			layer.fire('tileload', {
				tile: this,
				url: this.src
			});
		}

		layer._tileLoaded();
	},

	_tileOnError: function (e) {
		var layer = this._layer;

		layer.fire('tileerror', {
			tile: this,
			url: this.src
		});

		var newUrl = layer.options.errorTileUrl;
		if (newUrl) {
			this.src = newUrl;
		}

        layer._tileLoaded();
    }
});

L.tileLayer = function (url, options) {
	return new L.TileLayer(url, options);
};
<|endoftext|>


<commit_before>import _ from "utils/utils";
import EventEmitter from "events";
import {STRINGS} from "./config";
import eio from "engine.io-client";
import {times, constant} from "lodash";
import GameState from "./gamestate";

function message(msg) {
  let args = JSON.parse(msg);
  App.emit(...args);
}

let App = {
  __proto__: new EventEmitter,

  state: {
    id: null,
    name: STRINGS.BRANDING.DEFAULT_USERNAME,

    serverVersion: null,
    numUsers: 0,
    numPlayers: 0,
    numActiveGames: 0,
    roomInfo: [],

    seats: 8,
    title: "",
    gameId: "",
    isPrivate: true,
    modernOnly: false,
    totalChaos: false,
    chaosDraftPacksNumber: 3,
    chaosSealedPacksNumber: 6,
    gametype: "draft",
    gamesubtype: "regular",
    sets: [],
    setsDraft: [],
    setsSealed: [],
    setsDecadentDraft: [],
    availableSets: {},
    list: "",
    cards: 15,
    packs: 3,
    cubePoolSize: 90,

    addBots: true,
    shufflePlayers: true,
    useTimer: true,
    timerLength: "Moderate", // Fast Moderate or Slow

    beep: true,
    notify: false,
    notificationGranted: false,
    chat: false,
    cols: false,
    hidepicks: false,
    deckSize: 40,
    filename: "filename",
    filetype: "txt",
    side: false,
    sort: "rarity",
    log: {},
    cardSize: "normal",
    cardLang: "en",
    game: {},
    mtgJsonVersion: {
      version: "0.0.0",
      date: "1970-01-01"
    },
    messages: [],
    pickNumber: 0,
    packSize: 15,
    gameSeats: 8, // seats of the game being played
    gameState: null, // records the current state of cards is a GameState
    gameStates: {}, // Object representation of the gameState

    get didGameStart() {
      // both round === 0 and round is undefined
      return App.state.round;
    },
    get isSealed() {
      return /sealed/.test(App.state.game.type);
    },
    get isGameFinished() {
      return App.state.round === -1;
    },
    get isDecadentDraft() {
      return /decadent draft/.test(App.state.game.type);
    },

    get notificationBlocked() {
      return ["denied", "notsupported"].includes(App.state.notificationResult);
    }
  },
  init(router) {
    App.on("set", App.set);
    App.on("error", App.error);
    App.on("route", App.route);

    App.restore();
    App.connect();
    router(App);
  },
  register(component) {
    App.connect();

    App.on("set", App.set);
    App.on("error", App.error);
    App.on("route", App.route);

    App.component = component;
  },
  restore() {
    for (let key in this.state) {
      let val = localStorage[key];
      if (val) {
        try {
          this.state[key] = JSON.parse(val);
        } catch(e) {
          delete localStorage[key];
        }
      }
    }

    if (!this.state.id) {
      this.state.id = _.uid();
      localStorage.id = JSON.stringify(this.state.id);
    }
  },
  connect() {
    let {id, name} = App.state;
    let options = {
      query: { id, name }
    };
    if(!this.ws) {
      this.ws = eio(location.href, options);
      this.ws.on("message", message);
    }
  },
  send(...args) {
    let msg = JSON.stringify(args);
    this.ws.send(msg);
  },
  initGameState(id) {
    const { gameStates } = App.state;
    if (!gameStates[id]) {
      App.state.gameState = new GameState();
    } else {
      App.state.gameState = new GameState(gameStates[id]);
    }
    App.state.gameState.on("updateGameState", (gameState) => {
      App.save("gameStates", {
        // ...App.state.gameStates,
        [id]: gameState
      });
    });
  },
  error(err) {
    App.err = err;
    App.route("");
  },
  route(path) {
    if (path === location.hash.slice(1))
      App.update();
    else
      location.hash = path;
  },
  save(key, val) {
    this.state[key] = val;
    localStorage[key] = JSON.stringify(val);
    App.update();
  },
  set(state) {
    Object.assign(App.state, state);
    if (App.state.latestSet) {
      // Default sets to the latest set.
      const defaultSetCode = App.state.latestSet.code;
      const replicateDefaultSet = (desiredLength) => times(desiredLength, constant(defaultSetCode));
      const initializeIfEmpty = (sets, desiredLength) => {
        if (sets.length === 0) {
          sets = replicateDefaultSet(desiredLength);
        }
      };
      initializeIfEmpty(App.state.setsSealed, 6);
      initializeIfEmpty(App.state.setsDraft, 3);
      initializeIfEmpty(App.state.setsDecadentDraft, 36);
    }
    App.update();
  },
  update() {
    if(App.component) {
      App.component.setState(App.state);
    }
  },
  _emit(...args) {
    return App.emit.bind(App, ...args);
  },
  _save(key, val) {
    return App.save.bind(App, key, val);
  },
  link(key, index) {
    let hasIndex = index !== void 0;

    let value = App.state[key];
    if (hasIndex)
      value = value[index];

    function requestChange(val) {
      if (hasIndex) {
        let tmp = App.state[key];
        tmp[index] = val;
        val = tmp;
      }
      App.save(key, val);
    }

    return { requestChange, value };
  },
  updateGameInfos({type, sets, packsInfo}) {
    const savename = type === "draft" ? sets[0] + "-draft" : type;
    const date = new Date();
    const currentTime = date.toISOString().slice(0, 10).replace("T", " ") + "_" + date.toString().slice(16, 21).replace(":", "-");
    const filename = `${savename.replace(/\W/, "-")}_${currentTime}`;

    App.set({
      filename,
      game: {type, sets, packsInfo}
    });
  },
  getZone(zoneName){
    return App.state.gameState.get(zoneName);
  },
  getSortedZone(zoneName) {
    return App.state.gameState.getSortedZone(zoneName, App.state.sort);
  }
};

export default App;
<commit_msg>Fix initialization of default sets (#1056)<commit_after>import _ from "utils/utils";
import EventEmitter from "events";
import {STRINGS} from "./config";
import eio from "engine.io-client";
import {times, constant} from "lodash";
import GameState from "./gamestate";

function message(msg) {
  let args = JSON.parse(msg);
  App.emit(...args);
}

let App = {
  __proto__: new EventEmitter,

  state: {
    id: null,
    name: STRINGS.BRANDING.DEFAULT_USERNAME,

    serverVersion: null,
    numUsers: 0,
    numPlayers: 0,
    numActiveGames: 0,
    roomInfo: [],

    seats: 8,
    title: "",
    gameId: "",
    isPrivate: true,
    modernOnly: false,
    totalChaos: false,
    chaosDraftPacksNumber: 3,
    chaosSealedPacksNumber: 6,
    gametype: "draft",
    gamesubtype: "regular",
    sets: [],
    setsDraft: [],
    setsSealed: [],
    setsDecadentDraft: [],
    availableSets: {},
    list: "",
    cards: 15,
    packs: 3,
    cubePoolSize: 90,

    addBots: true,
    shufflePlayers: true,
    useTimer: true,
    timerLength: "Moderate", // Fast Moderate or Slow

    beep: true,
    notify: false,
    notificationGranted: false,
    chat: false,
    cols: false,
    hidepicks: false,
    deckSize: 40,
    filename: "filename",
    filetype: "txt",
    side: false,
    sort: "rarity",
    log: {},
    cardSize: "normal",
    cardLang: "en",
    game: {},
    mtgJsonVersion: {
      version: "0.0.0",
      date: "1970-01-01"
    },
    messages: [],
    pickNumber: 0,
    packSize: 15,
    gameSeats: 8, // seats of the game being played
    gameState: null, // records the current state of cards is a GameState
    gameStates: {}, // Object representation of the gameState

    get didGameStart() {
      // both round === 0 and round is undefined
      return App.state.round;
    },
    get isSealed() {
      return /sealed/.test(App.state.game.type);
    },
    get isGameFinished() {
      return App.state.round === -1;
    },
    get isDecadentDraft() {
      return /decadent draft/.test(App.state.game.type);
    },

    get notificationBlocked() {
      return ["denied", "notsupported"].includes(App.state.notificationResult);
    }
  },
  init(router) {
    App.on("set", App.set);
    App.on("error", App.error);
    App.on("route", App.route);

    App.restore();
    App.connect();
    router(App);
  },
  register(component) {
    App.connect();

    App.on("set", App.set);
    App.on("error", App.error);
    App.on("route", App.route);

    App.component = component;
  },
  restore() {
    for (let key in this.state) {
      let val = localStorage[key];
      if (val) {
        try {
          this.state[key] = JSON.parse(val);
        } catch(e) {
          delete localStorage[key];
        }
      }
    }

    if (!this.state.id) {
      this.state.id = _.uid();
      localStorage.id = JSON.stringify(this.state.id);
    }
  },
  connect() {
    let {id, name} = App.state;
    let options = {
      query: { id, name }
    };
    if(!this.ws) {
      this.ws = eio(location.href, options);
      this.ws.on("message", message);
    }
  },
  send(...args) {
    let msg = JSON.stringify(args);
    this.ws.send(msg);
  },
  initGameState(id) {
    const { gameStates } = App.state;
    if (!gameStates[id]) {
      App.state.gameState = new GameState();
    } else {
      App.state.gameState = new GameState(gameStates[id]);
    }
    App.state.gameState.on("updateGameState", (gameState) => {
      App.save("gameStates", {
        // ...App.state.gameStates,
        [id]: gameState
      });
    });
  },
  error(err) {
    App.err = err;
    App.route("");
  },
  route(path) {
    if (path === location.hash.slice(1))
      App.update();
    else
      location.hash = path;
  },
  save(key, val) {
    this.state[key] = val;
    localStorage[key] = JSON.stringify(val);
    App.update();
  },
  set(state) {
    Object.assign(App.state, state);
    if (App.state.latestSet) {
      // Default sets to the latest set.
      const defaultSetCode = App.state.latestSet.code;
      const replicateDefaultSet = (desiredLength) => times(desiredLength, constant(defaultSetCode));
      const initializeIfEmpty = (sets, desiredLength) => {
        if (sets.length === 0) {
          sets.push(...replicateDefaultSet(desiredLength));
        }
      };
      initializeIfEmpty(App.state.setsSealed, 6);
      initializeIfEmpty(App.state.setsDraft, 3);
      initializeIfEmpty(App.state.setsDecadentDraft, 36);
    }
    App.update();
  },
  update() {
    if(App.component) {
      App.component.setState(App.state);
    }
  },
  _emit(...args) {
    return App.emit.bind(App, ...args);
  },
  _save(key, val) {
    return App.save.bind(App, key, val);
  },
  link(key, index) {
    let hasIndex = index !== void 0;

    let value = App.state[key];
    if (hasIndex)
      value = value[index];

    function requestChange(val) {
      if (hasIndex) {
        let tmp = App.state[key];
        tmp[index] = val;
        val = tmp;
      }
      App.save(key, val);
    }

    return { requestChange, value };
  },
  updateGameInfos({type, sets, packsInfo}) {
    const savename = type === "draft" ? sets[0] + "-draft" : type;
    const date = new Date();
    const currentTime = date.toISOString().slice(0, 10).replace("T", " ") + "_" + date.toString().slice(16, 21).replace(":", "-");
    const filename = `${savename.replace(/\W/, "-")}_${currentTime}`;

    App.set({
      filename,
      game: {type, sets, packsInfo}
    });
  },
  getZone(zoneName){
    return App.state.gameState.get(zoneName);
  },
  getSortedZone(zoneName) {
    return App.state.gameState.getSortedZone(zoneName, App.state.sort);
  }
};

export default App;
<|endoftext|>


<commit_before>var koa = require('koa');
var csrf = require('koa-csrf');
var _ = require('koa-route');
var common = require('koa-common');
var session = common.session;

module.exports = function(config) {

  var app = koa();

  require('./config')(app, config);
  require('./logger')(app, {
    basePath: __dirname
  });
  require('./utils')(app);
  require('./error')(app);
  require('./render')(app);

  switch(process.env.NODE_ENV) {
    case 'production':
      app.logger.info("################################");
      app.logger.info("### This is PRODUCTION MODE. ###");
      app.logger.info("################################");
      break;
    case 'development':
      app.logger.warn("#################################");
      app.logger.warn("### This is DEVELOPMENT MODE. ###");
      app.logger.warn("#################################");
      break;
    default:
      throw new Error("Unknown environment: " + process.env.NODE_ENV);
  }

  /**
   * Logging
   */

  var morgan = require('morgan')('combined', {
    stream: app.logger.stream
  });

  app.use(function*(next) {
    morgan(this.req, this.res, function(err) {
      if (err) {
        return this.logger.err(err);
      }
    });
    yield next;
  });

  /**
   * Parser
   */
  app.use(function*(next) {
    if(this.method==='POST' && !this.request.header['content-type'].match(/^multipart/)) {
      this.request.body = yield parse(this);
    }
    yield next;
  });

  /**
   * Error handler
   */
  app.use(app.error.handler);

  /**
   * CSRF tokens
   */
  csrf(app);
  app.use(csrf.middleware);

  /**
   * Routes
   */
  require('./routes')(app);

  return app;
};
<commit_msg>Set CSRF token properly<commit_after>var koa = require('koa');
var csrf = require('koa-csrf');
var _ = require('koa-route');
var common = require('koa-common');
var session = common.session;
var consts = require('./consts');

module.exports = function(config) {

  var app = koa();

  require('./config')(app, config);
  require('./logger')(app, {
    basePath: __dirname
  });
  require('./utils')(app);
  require('./error')(app);
  require('./render')(app);

  switch(process.env.NODE_ENV) {
    case 'production':
      app.logger.info("################################");
      app.logger.info("### This is PRODUCTION MODE. ###");
      app.logger.info("################################");
      break;
    case 'development':
      app.logger.warn("#################################");
      app.logger.warn("### This is DEVELOPMENT MODE. ###");
      app.logger.warn("#################################");
      break;
    default:
      throw new Error("Unknown environment: " + process.env.NODE_ENV);
  }

  /**
   * Logging
   */

  var morgan = require('morgan')('combined', {
    stream: app.logger.stream
  });

  app.use(function*(next) {
    morgan(this.req, this.res, function(err) {
      if (err) {
        return this.logger.err(err);
      }
    });
    yield next;
  });

  /**
   * Parser
   */
  app.use(function*(next) {
    if(this.method==='POST' && !this.request.header['content-type'].match(/^multipart/)) {
      this.request.body = yield parse(this);
    }
    yield next;
  });

  /**
   * Error handler
   */
  app.use(app.error.handler);

  /**
   * CSRF tokens
   */
  app.keys = consts.sessionSecretKeys;
  app.use(session());
  csrf(app);
  app.use(csrf.middleware);

  /**
   * Routes
   */
  require('./routes')(app);

  return app;
};
<|endoftext|>


<commit_before>import path from 'path';
import csrf from 'csurf';
import helmet from 'helmet';
import logger from 'morgan';
import express from 'express';
import parser from 'body-parser';
import cookies from 'cookie-parser';
import compression from 'compression';

// Configuration
import routes from './routes';
import config from '../config';
import * as Helpers from './helpers';
import https from './middleware/https';
import bodyclass from './middleware/bodyclass';

// Initialize expess
const app = express();

// App Configuration
app.set('view engine', 'jade');
app.set('views', path.join(__dirname, '/views'));
app.use(logger('dev'));
app.use(compression());
app.use(parser.json());
app.use(parser.urlencoded({extended: false}));
app.use(express.static(path.join(__dirname, '../public')));

// Secruity
app.use(helmet());
app.use(helmet.frameguard('deny'));
app.use(helmet.hsts({maxAge: 7776000000}));

// Utility
app.locals.Helpers = Helpers;

// Middlewares
app.use(https);
app.use(bodyclass);

// Initialize Router
app.use(routes(express.Router()));

// Do it live.
app.listen(config.port, error => {
  console.log(`${config.appname} running on port ${config.port}`);
});
<commit_msg>Trust the proxy<commit_after>import path from 'path';
import csrf from 'csurf';
import helmet from 'helmet';
import logger from 'morgan';
import express from 'express';
import parser from 'body-parser';
import cookies from 'cookie-parser';
import compression from 'compression';

// Configuration
import routes from './routes';
import config from '../config';
import * as Helpers from './helpers';
import https from './middleware/https';
import bodyclass from './middleware/bodyclass';

// Initialize expess
const app = express();

// App Configuration
app.set('trust proxy', 1);
app.set('view engine', 'jade');
app.set('views', path.join(__dirname, '/views'));
app.use(logger('dev'));
app.use(compression());
app.use(parser.json());
app.use(parser.urlencoded({extended: false}));
app.use(express.static(path.join(__dirname, '../public')));

// Secruity
app.use(helmet());
app.use(helmet.frameguard('deny'));
app.use(helmet.hsts({maxAge: 7776000000}));

// Utility
app.locals.Helpers = Helpers;

// Middlewares
app.use(https);
app.use(bodyclass);

// Initialize Router
app.use(routes(express.Router()));

// Do it live.
app.listen(config.port, error => {
  console.log(`${config.appname} running on port ${config.port}`);
});
<|endoftext|>


<commit_before>'use strict';
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');

module.exports = yeoman.generators.Base.extend({
  initializing: function () {
    this.pkg = require('../package.json');
  },

  prompting: function () {
    var done = this.async();

    this.log(yosay(
      'So you want a ' + chalk.red('one pager?')
    ));

    var prompts = [
      {
        type: 'input',
        name: 'projectName',
        message: 'What\'s your project\'s name?',
        default: this.appname
      },
      {
        type: 'confirm',
        name: 'usesCompass',
        message: 'Would you like to use Compass?',
        default: true
      },
      {
        type: 'confirm',
        name: 'usesFoundation',
        message: 'Would you like to use Foundation?',
        default: true
      },
      {
        type: 'confirm',
        name: 'usesjQuery',
        message: 'Would you like to use jQuery?',
        default: true
      },
      {
        type: 'confirm',
        name: 'usesOutdatedBrowser',
        message: 'Would you like to use Outdated Browser?',
        default: true
      },
      {
        type: 'confirm',
        name: 'usesGoogleAnalytics',
        message: 'Would you like to use Google Analytics?',
        default: false
      }
    ];

    this.prompt(prompts, function (props) {
      this.projectName = props.projectName;
      this.usesCompass = props.usesCompass;
      this.usesFoundation = props.usesFoundation;
      this.usesjQuery = props.usesjQuery;
      this.usesOutdatedBrowser = props.usesOutdatedBrowser;
      this.usesGoogleAnalytics = props.usesGoogleAnalytics;

      if (this.usesFoundation) {
        this.usesjQuery = true;
      }

      done();
    }.bind(this));
  },

  writing: {
    app: function () {
      this.fs.copyTpl(
        this.templatePath('_package.json'),
        this.destinationPath('package.json'),
        { projectName: this.projectName }
      );

      this.fs.copyTpl(
        this.templatePath('_bower.json'),
        this.destinationPath('bower.json'),
        { usesjQuery: this.usesjQuery, projectName: this.projectName, usesOutdatedBrowser: this.usesOutdatedBrowser }
      );
    },

    projectfiles: function () {
      this.fs.copy(
        this.templatePath('editorconfig'),
        this.destinationPath('.editorconfig')
      );

      this.fs.copy(
        this.templatePath('jshintrc'),
        this.destinationPath('.jshintrc')
      );

      this.fs.copy(
        this.templatePath('gitignore'),
        this.destinationPath('.gitignore')
      );

      this.fs.copyTpl(
        this.templatePath('jade/_index.jade'),
        this.destinationPath('src/index.jade'),
        { usesjQuery: this.usesjQuery, usesOutdatedBrowser: this.usesOutdatedBrowser, usesGoogleAnalytics: this.usesGoogleAnalytics }
      );

      this.fs.copyTpl(
        this.templatePath('jade/_header.jade'),
        this.destinationPath('src/partials/_header.jade'),
        { projectName: this.projectName, usesOutdatedBrowser: this.usesOutdatedBrowser }
      );

      this.fs.copyTpl(
        this.templatePath('js/_scripts.js'),
        this.destinationPath('src/js/scripts.js'),
        { usesjQuery: this.usesjQuery }
      );

      this.fs.copy(
        this.templatePath('scss/'),
        this.destinationPath('src/scss/')
      );

      this.fs.copy(
        this.templatePath('images/'),
        this.destinationPath('src/images/')
      );
    },

    gruntFile: function () {
      var gruntConfig = {

        sass: {
          dist: {
            options: {
              style: 'compressed',
              quiet: false
            },
            files: {
              '<%= dist %>/css/styles.css': '<%= src %>/scss/styles.scss'
            }
          }
        },

        jade: {
          compile: {
            options: {
              pretty: true,
              data: {
                debug: false
              }
            },
            files: [{
              expand: true,
              cwd: '<%= src %>/',
              src: ['index.jade'],
              ext: '.html',
              dest: '<%= dist %>/'
            }]
          }
        },

        jshint: {
          options: {
            jshintrc: '.jshintrc'
          },
          all: [
            'Gruntfile.js',
            '<%= src %>/js/**/*.js'
          ]
        },

        copy: {
          dist: {
            files: [{
              expand: true,
              flatten: true,
              cwd:'./',
              src: ['bower_components/jquery/dist/jquery.js', 'bower_components/modernizer/modernizr.js', 'bower_components/outdated-browser/outdatedbrowser/outdatedbrowser.js', 'bower_components/outdated-browser/outdatedbrowser/outdatedbrowser.css'],
              dest: '<%= dist %>/vendor/'
            }]
          },
        },

        imagemin: {
          target: {
            files: [{
              expand: true,
              cwd: '<%= src %>/images/',
              src: ['**/*.{jpg,gif,svg,jpeg,png}'],
              dest: '<%= dist %>/images/'
            }]
          }
        },

        uglify: {
          options: {
            preserveComments: 'some',
            mangle: false
          },
          dist: {
            files: {
              '<%= dist %>/js/scripts.js': ['<%= src %>/js/scripts.js']
            }
          }
        },

        watch: {
          grunt: {
            files: ['Gruntfile.js'],
            tasks: ['sass', 'jshint']
          },
          sass: {
            files: '<%= src %>/scss/**/*.scss',
            tasks: ['sass']
          },
          jade: {
            files: '<%= src %>/**/*.jade',
            tasks: ['jade']
          },
          livereload: {
            files: ['<%= src %>/**/*.jade', '!<%= src %>/bower_components/**', '<%= src %>/js/**/*.js', '<%= src %>/scss/**/*.scss', '<%= src %>/images/**/*.{jpg,gif,svg,jpeg,png}'],
            options: {
              livereload: true
            }
          }
        },

        connect: {
          dist: {
            options: {
              port: 9001,
              base: '<%= dist %>/',
              open: true,
              keepalive: false,
              livereload: true,
              hostname: '127.0.0.1'
            }
          }
        },

        defaultTask: ['jade', 'sass', 'imagemin', 'jshint', 'uglify', 'copy', 'connect', 'watch']
      };

      gruntConfig.sass.dist.options.compass = this.usesCompass;

      if (this.usesFoundation) {
        gruntConfig.sass.dist.options.loadPath = '<%= src %>/bower_components/foundation/scss';
      }

      this.fs.copy(
        this.templatePath('_Gruntfile.js'),
        this.destinationPath('Gruntfile.js')
      );

      this.gruntfile.insertConfig('sass', JSON.stringify(gruntConfig.sass));
      this.gruntfile.insertConfig('jade', JSON.stringify(gruntConfig.jade));
      this.gruntfile.insertConfig('jshint', JSON.stringify(gruntConfig.jshint));
      this.gruntfile.insertConfig('copy', JSON.stringify(gruntConfig.copy));
      this.gruntfile.insertConfig('imagemin', JSON.stringify(gruntConfig.imagemin));
      this.gruntfile.insertConfig('uglify', JSON.stringify(gruntConfig.uglify));
      this.gruntfile.insertConfig('watch', JSON.stringify(gruntConfig.watch));
      this.gruntfile.insertConfig('connect', JSON.stringify(gruntConfig.connect));

      this.gruntfile.registerTask('default', gruntConfig.defaultTask);
    },

  },

  install: function () {
    this.installDependencies({
      skipInstall: this.options['skip-install']
    });
  }
});
<commit_msg>forgot to pass usesFoundation to bower.json<commit_after>'use strict';
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');

module.exports = yeoman.generators.Base.extend({
  initializing: function () {
    this.pkg = require('../package.json');
  },

  prompting: function () {
    var done = this.async();

    this.log(yosay(
      'So you want a ' + chalk.red('one pager?')
    ));

    var prompts = [
      {
        type: 'input',
        name: 'projectName',
        message: 'What\'s your project\'s name?',
        default: this.appname
      },
      {
        type: 'confirm',
        name: 'usesCompass',
        message: 'Would you like to use Compass?',
        default: true
      },
      {
        type: 'confirm',
        name: 'usesFoundation',
        message: 'Would you like to use Foundation?',
        default: true
      },
      {
        type: 'confirm',
        name: 'usesjQuery',
        message: 'Would you like to use jQuery?',
        default: true
      },
      {
        type: 'confirm',
        name: 'usesOutdatedBrowser',
        message: 'Would you like to use Outdated Browser?',
        default: true
      },
      {
        type: 'confirm',
        name: 'usesGoogleAnalytics',
        message: 'Would you like to use Google Analytics?',
        default: false
      }
    ];

    this.prompt(prompts, function (props) {
      this.projectName = props.projectName;
      this.usesCompass = props.usesCompass;
      this.usesFoundation = props.usesFoundation;
      this.usesjQuery = props.usesjQuery;
      this.usesOutdatedBrowser = props.usesOutdatedBrowser;
      this.usesGoogleAnalytics = props.usesGoogleAnalytics;

      if (this.usesFoundation) {
        this.usesjQuery = true;
      }

      done();
    }.bind(this));
  },

  writing: {
    app: function () {
      this.fs.copyTpl(
        this.templatePath('_package.json'),
        this.destinationPath('package.json'),
        { projectName: this.projectName }
      );

      this.fs.copyTpl(
        this.templatePath('_bower.json'),
        this.destinationPath('bower.json'),
        { usesjQuery: this.usesjQuery, projectName: this.projectName, usesOutdatedBrowser: this.usesOutdatedBrowser, usesFoundation: this.usesFoundation }
      );
    },

    projectfiles: function () {
      this.fs.copy(
        this.templatePath('editorconfig'),
        this.destinationPath('.editorconfig')
      );

      this.fs.copy(
        this.templatePath('jshintrc'),
        this.destinationPath('.jshintrc')
      );

      this.fs.copy(
        this.templatePath('gitignore'),
        this.destinationPath('.gitignore')
      );

      this.fs.copyTpl(
        this.templatePath('jade/_index.jade'),
        this.destinationPath('src/index.jade'),
        { usesjQuery: this.usesjQuery, usesOutdatedBrowser: this.usesOutdatedBrowser, usesGoogleAnalytics: this.usesGoogleAnalytics }
      );

      this.fs.copyTpl(
        this.templatePath('jade/_header.jade'),
        this.destinationPath('src/partials/_header.jade'),
        { projectName: this.projectName, usesOutdatedBrowser: this.usesOutdatedBrowser }
      );

      this.fs.copyTpl(
        this.templatePath('js/_scripts.js'),
        this.destinationPath('src/js/scripts.js'),
        { usesjQuery: this.usesjQuery }
      );

      this.fs.copy(
        this.templatePath('scss/'),
        this.destinationPath('src/scss/')
      );

      this.fs.copy(
        this.templatePath('images/'),
        this.destinationPath('src/images/')
      );
    },

    gruntFile: function () {
      var gruntConfig = {

        sass: {
          dist: {
            options: {
              style: 'compressed',
              quiet: false
            },
            files: {
              '<%= dist %>/css/styles.css': '<%= src %>/scss/styles.scss'
            }
          }
        },

        jade: {
          compile: {
            options: {
              pretty: true,
              data: {
                debug: false
              }
            },
            files: [{
              expand: true,
              cwd: '<%= src %>/',
              src: ['index.jade'],
              ext: '.html',
              dest: '<%= dist %>/'
            }]
          }
        },

        jshint: {
          options: {
            jshintrc: '.jshintrc'
          },
          all: [
            'Gruntfile.js',
            '<%= src %>/js/**/*.js'
          ]
        },

        copy: {
          dist: {
            files: [{
              expand: true,
              flatten: true,
              cwd:'./',
              src: ['bower_components/jquery/dist/jquery.js', 'bower_components/modernizer/modernizr.js', 'bower_components/outdated-browser/outdatedbrowser/outdatedbrowser.js', 'bower_components/outdated-browser/outdatedbrowser/outdatedbrowser.css'],
              dest: '<%= dist %>/vendor/'
            }]
          },
        },

        imagemin: {
          target: {
            files: [{
              expand: true,
              cwd: '<%= src %>/images/',
              src: ['**/*.{jpg,gif,svg,jpeg,png}'],
              dest: '<%= dist %>/images/'
            }]
          }
        },

        uglify: {
          options: {
            preserveComments: 'some',
            mangle: false
          },
          dist: {
            files: {
              '<%= dist %>/js/scripts.js': ['<%= src %>/js/scripts.js']
            }
          }
        },

        watch: {
          grunt: {
            files: ['Gruntfile.js'],
            tasks: ['sass', 'jshint']
          },
          sass: {
            files: '<%= src %>/scss/**/*.scss',
            tasks: ['sass']
          },
          jade: {
            files: '<%= src %>/**/*.jade',
            tasks: ['jade']
          },
          livereload: {
            files: ['<%= src %>/**/*.jade', '!<%= src %>/bower_components/**', '<%= src %>/js/**/*.js', '<%= src %>/scss/**/*.scss', '<%= src %>/images/**/*.{jpg,gif,svg,jpeg,png}'],
            options: {
              livereload: true
            }
          }
        },

        connect: {
          dist: {
            options: {
              port: 9001,
              base: '<%= dist %>/',
              open: true,
              keepalive: false,
              livereload: true,
              hostname: '127.0.0.1'
            }
          }
        },

        defaultTask: ['jade', 'sass', 'imagemin', 'jshint', 'uglify', 'copy', 'connect', 'watch']
      };

      gruntConfig.sass.dist.options.compass = this.usesCompass;

      if (this.usesFoundation) {
        gruntConfig.sass.dist.options.loadPath = '<%= src %>/bower_components/foundation/scss';
      }

      this.fs.copy(
        this.templatePath('_Gruntfile.js'),
        this.destinationPath('Gruntfile.js')
      );

      this.gruntfile.insertConfig('sass', JSON.stringify(gruntConfig.sass));
      this.gruntfile.insertConfig('jade', JSON.stringify(gruntConfig.jade));
      this.gruntfile.insertConfig('jshint', JSON.stringify(gruntConfig.jshint));
      this.gruntfile.insertConfig('copy', JSON.stringify(gruntConfig.copy));
      this.gruntfile.insertConfig('imagemin', JSON.stringify(gruntConfig.imagemin));
      this.gruntfile.insertConfig('uglify', JSON.stringify(gruntConfig.uglify));
      this.gruntfile.insertConfig('watch', JSON.stringify(gruntConfig.watch));
      this.gruntfile.insertConfig('connect', JSON.stringify(gruntConfig.connect));

      this.gruntfile.registerTask('default', gruntConfig.defaultTask);
    },

  },

  install: function () {
    this.installDependencies({
      skipInstall: this.options['skip-install']
    });
  }
});
<|endoftext|>


<commit_before>var assert = require("assert");
var path = require("path");
var fs = require("fs");
var Q = require("q");
var ReadFileCache = require("./cache").ReadFileCache;
var Watcher = require("./watcher").Watcher;
var contextModule = require("./context");
var BuildContext = contextModule.BuildContext;
var PreferredFileExtension = contextModule.PreferredFileExtension;
var ModuleReader = require("./reader").ModuleReader;
var output = require("./output");
var DirOutput = output.DirOutput;
var StdOutput = output.StdOutput;
var util = require("./util");
var log = util.log;
var Ap = Array.prototype;
var each = Ap.forEach;

// Better stack traces for promises.
Q.longStackSupport = true;

function Commoner() {
    var self = this;
    assert.ok(self instanceof Commoner);

    Object.defineProperties(self, {
        customVersion: { value: null, writable: true },
        resolvers: { value: [] },
        processors: { value: [] }
    });
}

var Cp = Commoner.prototype;

Cp.version = function(version) {
    this.customVersion = version;
    return this; // For chaining.
};

// A resolver is a function that takes a module identifier and returns
// the unmodified source of the corresponding module, either as a string
// or as a promise for a string.
Cp.resolve = function() {
    each.call(arguments, function(resolver) {
        assert.strictEqual(typeof resolver, "function");
        this.resolvers.push(resolver);
    }, this);

    return this; // For chaining.
};

// A processor is a function that takes a module identifier and a string
// representing the source of the module and returns a modified version of
// the source, either as a string or as a promise for a string.
Cp.process = function(processor) {
    each.call(arguments, function(processor) {
        assert.strictEqual(typeof processor, "function");
        this.processors.push(processor);
    }, this);

    return this; // For chaining.
};

Cp.buildP = function(config, sourceDir, outputDir, roots) {
    var self = this;
    var readFileCache = new ReadFileCache(sourceDir);
    var waiting = 0;
    var output = outputDir
        ? new DirOutput(outputDir)
        : new StdOutput;

    if (self.watch) {
        new Watcher(readFileCache).on("changed", function(file) {
            log.err(file + " changed; rebuilding...", "yellow");
            rebuild();
        });
    }

    function outputModules(modules) {
        // Note that output.outputModules comes pre-bound.
        modules.forEach(output.outputModule);
        return modules;
    }

    function finish(result) {
        rebuild.ing = false;

        if (waiting > 0) {
            waiting = 0;
            process.nextTick(rebuild);
        }

        return result;
    }

    function rebuild() {
        if (rebuild.ing) {
            waiting += 1;
            return;
        }

        rebuild.ing = true;

        var context = new BuildContext(config, readFileCache);

        if (self.preferredFileExtension)
            context.setPreferredFileExtension(
                self.preferredFileExtension);

        context.setCacheDirectory(self.cacheDir);

        context.setIgnoreDependencies(self.ignoreDependencies);

        context.setRelativize(self.relativize);

        return new ModuleReader(
            context,
            self.resolvers,
            self.processors
        ).readMultiP(context.expandIdsOrGlobsP(roots))
            .then(context.ignoreDependencies ? pass : collectDepsP)
            .then(outputModules)
            .then(outputDir ? printModuleIds : pass)
            .then(finish, function(err) {
                log.err(err.stack);
                finish();
            });
    }

    return lockOutputDirP(outputDir).then(rebuild);
};

function pass(modules) {
    return modules;
}

function collectDepsP(rootModules) {
    var modules = [];
    var seenIds = {};

    function traverse(module) {
        if (seenIds.hasOwnProperty(module.id))
            return Q.resolve(modules);
        seenIds[module.id] = true;

        return module.getRequiredP().then(function(reqs) {
            return Q.all(reqs.map(traverse));
        }).then(function() {
            modules.push(module);
            return modules;
        });
    }

    return Q.all(rootModules.map(traverse)).then(
        function() { return modules });
}

function printModuleIds(modules) {
    log.out(JSON.stringify(modules.map(function(module) {
        return module.id;
    })));

    return modules;
}

function lockOutputDirP(outputDir) {
    if (!outputDir) {
        // If outputDir is falsy, then there's nothing to lock.
        return Q.resolve(outputDir);
    }

    return util.mkdirP(outputDir).then(function(dir) {
        var lockFile = path.join(outputDir, ".lock.pid");
        return util.acquireLockFileP(lockFile).then(function() {
            return dir;
        }, function(err) {
            throw new Error("output directory " + outputDir + " currently in use");
        });
    });
}

Cp.forceResolve = function(forceId, source) {
    this.resolvers.unshift(function(id) {
        if (id === forceId)
            return source;
    });
};

Cp.cliBuildP = function() {
    var version = this.customVersion || require("../package.json").version;
    return Q.all([this, version]).spread(cliBuildP);
};

function cliBuildP(commoner, version) {
    var options = require("commander");
    var workingDir = process.cwd();
    var sourceDir = workingDir;
    var outputDir = null;
    var roots;

    options.version(version)
        .usage("[options] <source directory> <output directory> [<module ID> [<module ID> ...]]")
        .option("-c, --config [file]", "JSON configuration file (no file means STDIN)")
        .option("-w, --watch", "Continually rebuild")
        .option("-x, --extension <js | coffee | ...>",
                "File extension to assume when resolving module identifiers")
        .option("--relativize", "Rewrite all module identifiers to be relative")
        .option("--follow-requires", "Scan modules for required dependencies")
        .option("--cache-dir <directory>", "Alternate directory to use for disk cache")
        .option("--no-cache-dir", "Disable the disk cache")
        .parse(process.argv.slice(0));

    var pfe = new PreferredFileExtension(options.extension || "js");

    // TODO Decide whether passing options to buildP via instance
    // variables is preferable to passing them as arguments.
    commoner.preferredFileExtension = pfe;
    commoner.watch = options.watch;
    commoner.ignoreDependencies = !options.followRequires;
    commoner.relativize = options.relativize;

    function fileToId(file) {
        file = absolutePath(workingDir, file);
        assert.ok(fs.statSync(file).isFile(), file);
        return pfe.trim(path.relative(sourceDir, file));
    }

    var args = options.args.slice(0);
    var argc = args.length;
    if (argc === 0) {
        if (options.config === true) {
            log.err("Cannot read --config from STDIN when reading " +
                    "source from STDIN");
            process.exit(-1);
        }

        sourceDir = workingDir;
        outputDir = null;
        roots = ["<stdin>"];
        commoner.forceResolve("<stdin>", util.readFromStdinP());

        // Ignore dependencies because we wouldn't know how to find them.
        commoner.ignoreDependencies = true;

    } else {
        var first = absolutePath(workingDir, args[0]);
        var stats = fs.statSync(first);

        if (argc === 1) {
            var firstId = fileToId(first);
            sourceDir = workingDir;
            outputDir = null;
            roots = [firstId];
            commoner.forceResolve(firstId, util.readFileP(first));

            // Ignore dependencies because we wouldn't know how to find them.
            commoner.ignoreDependencies = true;

        } else if (stats.isDirectory(first)) {
            sourceDir = first;
            outputDir = absolutePath(workingDir, args[1]);
            roots = args.slice(2);
            if (roots.length === 0)
                roots.push(commoner.preferredFileExtension.glob());

        } else {
            options.help();
            process.exit(-1);
        }
    }

    commoner.cacheDir = null;
    if (options.cacheDir === false) {
        // Received the --no-cache-dir option, so disable the disk cache.
    } else if (typeof options.cacheDir === "string") {
        commoner.cacheDir = absolutePath(workingDir, options.cacheDir);
    } else if (outputDir) {
        // The default cache directory lives inside the output directory.
        commoner.cacheDir = path.join(outputDir, ".module-cache");
    }

    return Q.all([
        getConfigP(
            workingDir,
            options.config
        ).then(function(config) {
            if ("version" in config) {
                // Leave it alone.
            } else {
                config.version = version;
            }
            return config;
        }),
        sourceDir,
        outputDir,
        roots
    ]).spread(commoner.buildP.bind(commoner));
}

function absolutePath(workingDir, pathToJoin) {
    if (pathToJoin) {
        workingDir = path.normalize(workingDir);
        pathToJoin = path.normalize(pathToJoin);
        if (pathToJoin.charAt(0) !== "/")
            pathToJoin = path.join(workingDir, pathToJoin);
    }
    return pathToJoin;
}

function getConfigP(workingDir, configFile) {
    if (typeof configFile === "undefined")
        return Q.resolve({}); // Empty config.

    var stdin = "/dev/stdin";
    if (configFile === true) {
        // When --config is present but has no argument, default to STDIN.
        configFile = stdin;
    }

    configFile = absolutePath(workingDir, configFile);

    if (configFile === stdin) {
        return util.readJsonFromStdinP(
            1000, // Time limit in milliseconds before warning displayed.
            "Expecting configuration from STDIN (pass --config <file> " +
                "if stuck here)...",
            "yellow"
        );
    }

    return util.readJsonFileP(configFile);
}

exports.Commoner = Commoner;
<commit_msg>Terminate build process on any errors when --watch flag not given.<commit_after>var assert = require("assert");
var path = require("path");
var fs = require("fs");
var Q = require("q");
var ReadFileCache = require("./cache").ReadFileCache;
var Watcher = require("./watcher").Watcher;
var contextModule = require("./context");
var BuildContext = contextModule.BuildContext;
var PreferredFileExtension = contextModule.PreferredFileExtension;
var ModuleReader = require("./reader").ModuleReader;
var output = require("./output");
var DirOutput = output.DirOutput;
var StdOutput = output.StdOutput;
var util = require("./util");
var log = util.log;
var Ap = Array.prototype;
var each = Ap.forEach;

// Better stack traces for promises.
Q.longStackSupport = true;

function Commoner() {
    var self = this;
    assert.ok(self instanceof Commoner);

    Object.defineProperties(self, {
        customVersion: { value: null, writable: true },
        resolvers: { value: [] },
        processors: { value: [] }
    });
}

var Cp = Commoner.prototype;

Cp.version = function(version) {
    this.customVersion = version;
    return this; // For chaining.
};

// A resolver is a function that takes a module identifier and returns
// the unmodified source of the corresponding module, either as a string
// or as a promise for a string.
Cp.resolve = function() {
    each.call(arguments, function(resolver) {
        assert.strictEqual(typeof resolver, "function");
        this.resolvers.push(resolver);
    }, this);

    return this; // For chaining.
};

// A processor is a function that takes a module identifier and a string
// representing the source of the module and returns a modified version of
// the source, either as a string or as a promise for a string.
Cp.process = function(processor) {
    each.call(arguments, function(processor) {
        assert.strictEqual(typeof processor, "function");
        this.processors.push(processor);
    }, this);

    return this; // For chaining.
};

Cp.buildP = function(config, sourceDir, outputDir, roots) {
    var self = this;
    var readFileCache = new ReadFileCache(sourceDir);
    var waiting = 0;
    var output = outputDir
        ? new DirOutput(outputDir)
        : new StdOutput;

    if (self.watch) {
        new Watcher(readFileCache).on("changed", function(file) {
            log.err(file + " changed; rebuilding...", "yellow");
            rebuild();
        });
    }

    function outputModules(modules) {
        // Note that output.outputModules comes pre-bound.
        modules.forEach(output.outputModule);
        return modules;
    }

    function finish(result) {
        rebuild.ing = false;

        if (waiting > 0) {
            waiting = 0;
            process.nextTick(rebuild);
        }

        return result;
    }

    function rebuild() {
        if (rebuild.ing) {
            waiting += 1;
            return;
        }

        rebuild.ing = true;

        var context = new BuildContext(config, readFileCache);

        if (self.preferredFileExtension)
            context.setPreferredFileExtension(
                self.preferredFileExtension);

        context.setCacheDirectory(self.cacheDir);

        context.setIgnoreDependencies(self.ignoreDependencies);

        context.setRelativize(self.relativize);

        return new ModuleReader(
            context,
            self.resolvers,
            self.processors
        ).readMultiP(context.expandIdsOrGlobsP(roots))
            .then(context.ignoreDependencies ? pass : collectDepsP)
            .then(outputModules)
            .then(outputDir ? printModuleIds : pass)
            .then(finish, function(err) {
                log.err(err.stack);
                finish();
            });
    }

    return lockOutputDirP(outputDir).then(rebuild);
};

function pass(modules) {
    return modules;
}

function collectDepsP(rootModules) {
    var modules = [];
    var seenIds = {};

    function traverse(module) {
        if (seenIds.hasOwnProperty(module.id))
            return Q.resolve(modules);
        seenIds[module.id] = true;

        return module.getRequiredP().then(function(reqs) {
            return Q.all(reqs.map(traverse));
        }).then(function() {
            modules.push(module);
            return modules;
        });
    }

    return Q.all(rootModules.map(traverse)).then(
        function() { return modules });
}

function printModuleIds(modules) {
    log.out(JSON.stringify(modules.map(function(module) {
        return module.id;
    })));

    return modules;
}

function lockOutputDirP(outputDir) {
    if (!outputDir) {
        // If outputDir is falsy, then there's nothing to lock.
        return Q.resolve(outputDir);
    }

    return util.mkdirP(outputDir).then(function(dir) {
        var lockFile = path.join(outputDir, ".lock.pid");
        return util.acquireLockFileP(lockFile).then(function() {
            return dir;
        }, function(err) {
            throw new Error("output directory " + outputDir + " currently in use");
        });
    });
}

Cp.forceResolve = function(forceId, source) {
    this.resolvers.unshift(function(id) {
        if (id === forceId)
            return source;
    });
};

Cp.cliBuildP = function() {
    var version = this.customVersion || require("../package.json").version;
    return Q.all([this, version]).spread(cliBuildP);
};

function cliBuildP(commoner, version) {
    var options = require("commander");
    var workingDir = process.cwd();
    var sourceDir = workingDir;
    var outputDir = null;
    var roots;

    options.version(version)
        .usage("[options] <source directory> <output directory> [<module ID> [<module ID> ...]]")
        .option("-c, --config [file]", "JSON configuration file (no file means STDIN)")
        .option("-w, --watch", "Continually rebuild")
        .option("-x, --extension <js | coffee | ...>",
                "File extension to assume when resolving module identifiers")
        .option("--relativize", "Rewrite all module identifiers to be relative")
        .option("--follow-requires", "Scan modules for required dependencies")
        .option("--cache-dir <directory>", "Alternate directory to use for disk cache")
        .option("--no-cache-dir", "Disable the disk cache")
        .parse(process.argv.slice(0));

    var pfe = new PreferredFileExtension(options.extension || "js");

    // TODO Decide whether passing options to buildP via instance
    // variables is preferable to passing them as arguments.
    commoner.preferredFileExtension = pfe;
    commoner.watch = options.watch;
    commoner.ignoreDependencies = !options.followRequires;
    commoner.relativize = options.relativize;

    function fileToId(file) {
        file = absolutePath(workingDir, file);
        assert.ok(fs.statSync(file).isFile(), file);
        return pfe.trim(path.relative(sourceDir, file));
    }

    var args = options.args.slice(0);
    var argc = args.length;
    if (argc === 0) {
        if (options.config === true) {
            log.err("Cannot read --config from STDIN when reading " +
                    "source from STDIN");
            process.exit(-1);
        }

        sourceDir = workingDir;
        outputDir = null;
        roots = ["<stdin>"];
        commoner.forceResolve("<stdin>", util.readFromStdinP());

        // Ignore dependencies because we wouldn't know how to find them.
        commoner.ignoreDependencies = true;

    } else {
        var first = absolutePath(workingDir, args[0]);
        var stats = fs.statSync(first);

        if (argc === 1) {
            var firstId = fileToId(first);
            sourceDir = workingDir;
            outputDir = null;
            roots = [firstId];
            commoner.forceResolve(firstId, util.readFileP(first));

            // Ignore dependencies because we wouldn't know how to find them.
            commoner.ignoreDependencies = true;

        } else if (stats.isDirectory(first)) {
            sourceDir = first;
            outputDir = absolutePath(workingDir, args[1]);
            roots = args.slice(2);
            if (roots.length === 0)
                roots.push(commoner.preferredFileExtension.glob());

        } else {
            options.help();
            process.exit(-1);
        }
    }

    commoner.cacheDir = null;
    if (options.cacheDir === false) {
        // Received the --no-cache-dir option, so disable the disk cache.
    } else if (typeof options.cacheDir === "string") {
        commoner.cacheDir = absolutePath(workingDir, options.cacheDir);
    } else if (outputDir) {
        // The default cache directory lives inside the output directory.
        commoner.cacheDir = path.join(outputDir, ".module-cache");
    }

    var promise = Q.all([
        getConfigP(
            workingDir,
            options.config
        ).then(function(config) {
            if ("version" in config) {
                // Leave it alone.
            } else {
                config.version = version;
            }
            return config;
        }),
        sourceDir,
        outputDir,
        roots
    ]).spread(commoner.buildP.bind(commoner));

    if (!commoner.watch) {
        // If we're building from the command line without --watch, any
        // build errors should immediately terminate the process with a
        // non-zero error code.
        promise = promise.fail(function(err) {
            process.exit(-1);
        });
    }

    return promise;
}

function absolutePath(workingDir, pathToJoin) {
    if (pathToJoin) {
        workingDir = path.normalize(workingDir);
        pathToJoin = path.normalize(pathToJoin);
        if (pathToJoin.charAt(0) !== "/")
            pathToJoin = path.join(workingDir, pathToJoin);
    }
    return pathToJoin;
}

function getConfigP(workingDir, configFile) {
    if (typeof configFile === "undefined")
        return Q.resolve({}); // Empty config.

    var stdin = "/dev/stdin";
    if (configFile === true) {
        // When --config is present but has no argument, default to STDIN.
        configFile = stdin;
    }

    configFile = absolutePath(workingDir, configFile);

    if (configFile === stdin) {
        return util.readJsonFromStdinP(
            1000, // Time limit in milliseconds before warning displayed.
            "Expecting configuration from STDIN (pass --config <file> " +
                "if stuck here)...",
            "yellow"
        );
    }

    return util.readJsonFileP(configFile);
}

exports.Commoner = Commoner;
<|endoftext|>


<commit_before>'use strict';
var util = require('util');
var path = require('path');
var yeoman = require('yeoman-generator');
var cgUtils = require('../utils.js');

var CgangularGenerator = module.exports = function CgangularGenerator(args, options, config) {
    yeoman.generators.Base.apply(this, arguments);

    this.on('end', function () {
        this.config.set('partialDirectory','app/partial/');
        this.config.set('modalDirectory','app/partial/');
        this.config.set('directiveDirectory','app/directive/');
        this.config.set('filterDirectory','app/filter/');
        this.config.set('serviceDirectory','app/service/');
        var inject = {
            js: {
                file: 'app/index.html',
                marker: cgUtils.JS_MARKER,
                template: '<script src="<%= filename %>"></script>'
            },
            less: {
                relativeToModule: true,
                file: 'app/<%= module %>.less',
                marker: cgUtils.LESS_MARKER,
                template: '@import "<%= filename %>";'
            }
        };
        this.config.set('inject',inject);
        this.config.save();
        this.installDependencies({ skipInstall: options['skip-install'] });
    });

    this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
};

util.inherits(CgangularGenerator, yeoman.generators.Base);

CgangularGenerator.prototype.askFor = function askFor() {
    var cb = this.async();

    var prompts = [{
        name: 'appname',
        message: 'What would you like the angular app/module name to be?',
        default: path.basename(process.cwd())
    }];

    this.prompt(prompts, function (props) {
        this.appname = props.appname;
        cb();
    }.bind(this));
};

CgangularGenerator.prototype.askForUiRouter = function askFor() {
    var cb = this.async();

    var prompts = [{
        name: 'router',
        type:'list',
        message: 'Which router would you like to use?',
        default: 0,
        choices: ['Standard Angular Router','Angular UI Router']
    }];

    this.prompt(prompts, function (props) {
        if (props.router === 'Angular UI Router') {
            this.uirouter = true;
            this.routerJs = 'bower_components/angular-ui-router/release/angular-ui-router.js';
            this.routerModuleName = 'ui.router';
            this.routerViewDirective = 'ui-view';
        } else {
            this.uirouter = false;
            this.routerJs = 'bower_components/angular-route/angular-route.js';
            this.routerModuleName = 'ngRoute';
            this.routerViewDirective = 'ng-view';
        }
        this.config.set('uirouter',this.uirouter);
        cb();
    }.bind(this));
};

CgangularGenerator.prototype.app = function app() {
    this.directory('skeleton/','./');
};
<commit_msg>fixing pathing for new projects<commit_after>'use strict';
var util = require('util');
var path = require('path');
var yeoman = require('yeoman-generator');
var cgUtils = require('../utils.js');

var CgangularGenerator = module.exports = function CgangularGenerator(args, options, config) {
    yeoman.generators.Base.apply(this, arguments);

    this.on('end', function () {
        this.config.set('partialDirectory','partial/');
        this.config.set('modalDirectory','partial/');
        this.config.set('directiveDirectory','directive/');
        this.config.set('filterDirectory','filter/');
        this.config.set('serviceDirectory','service/');
        var inject = {
            js: {
                file: 'app/index.html',
                marker: cgUtils.JS_MARKER,
                template: '<script src="<%= filename %>"></script>'
            },
            less: {
                relativeToModule: true,
                file: '<%= module %>.less',
                marker: cgUtils.LESS_MARKER,
                template: '@import "<%= filename %>";'
            }
        };
        this.config.set('inject',inject);
        this.config.save();
        this.installDependencies({ skipInstall: options['skip-install'] });
    });

    this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
};

util.inherits(CgangularGenerator, yeoman.generators.Base);

CgangularGenerator.prototype.askFor = function askFor() {
    var cb = this.async();

    var prompts = [{
        name: 'appname',
        message: 'What would you like the angular app/module name to be?',
        default: path.basename(process.cwd())
    }];

    this.prompt(prompts, function (props) {
        this.appname = props.appname;
        cb();
    }.bind(this));
};

CgangularGenerator.prototype.askForUiRouter = function askFor() {
    var cb = this.async();

    var prompts = [{
        name: 'router',
        type:'list',
        message: 'Which router would you like to use?',
        default: 0,
        choices: ['Standard Angular Router','Angular UI Router']
    }];

    this.prompt(prompts, function (props) {
        if (props.router === 'Angular UI Router') {
            this.uirouter = true;
            this.routerJs = 'bower_components/angular-ui-router/release/angular-ui-router.js';
            this.routerModuleName = 'ui.router';
            this.routerViewDirective = 'ui-view';
        } else {
            this.uirouter = false;
            this.routerJs = 'bower_components/angular-route/angular-route.js';
            this.routerModuleName = 'ngRoute';
            this.routerViewDirective = 'ng-view';
        }
        this.config.set('uirouter',this.uirouter);
        cb();
    }.bind(this));
};

CgangularGenerator.prototype.app = function app() {
    this.directory('skeleton/','./');
};
<|endoftext|>


<commit_before>
/*

  Compiled.js

*/

var Utils     = require("./utils"),
    fs        = require("fs"),
    compilers = require("./compilers"),
    express   = require("express");

module.exports = function(options) {

  var router = express(),
      exts = [];

  // Walk through each file
  Utils.eachFile(options.path, function(file) {

    var ext = file.ext.replace(/^\./, ""),
        compiler = compilers(ext);

    // Error message
    if (!compiler || !compiler.isOk()) console.log("Warning: Package missing to compile", ext, "files. Make sure to `npm install` it.");

    // Add to list of extensions if not present
    if (-1 === exts.indexOf(ext)) exts.push(ext);

    router.get(Utils.makeUrls(options.url, file, options.ext)[0], function(req, res) {
      compiler.compile(fs.readFileSync(file.path, "utf8"), function(err, compiled) {
        return res.type((options.ext) === "js" ? "application/javascript" : "text/css").send(compiled);
      });
    });

  });

  // Set up Browsersync
  Object.keys(exts).forEach(function(ext) {
    Utils.watch(options.path, ext, options.ext);
  });

  return router;

}
<commit_msg>Compiled: allows for webpack bundles<commit_after>
/*

  Compiled.js

*/

var Utils     = require("./utils"),
    fs        = require("fs"),
    Bundler   = require("./bundler"),
    compilers = require("./compilers"),
    express   = require("express");

module.exports = function(options) {

  var router = express(),
      exts = [];

  // Walk through each file
  Utils.eachFile(options.path, options, function(file) {

    var ext      = file.ext.replace(/^\./, ""),
        isBundle = (options.bundleFolders && Utils.isIndexFile(file)),
        compiler = compilers(ext),
        bundler,
        compile;

    // Error message
    if (!compiler || !compiler.isOk()) console.log("Warning: Package missing to compile", ext, "files. Make sure to `npm install` it.");

    // Add to list of extensions if not present
    if (-1 === exts.indexOf(ext)) exts.push(ext);

    // Begin watching bundle if necessary
    if (isBundle) {
      file.folder = "";
      file.name = file.dir.replace(Utils.makePathAbsolute(options.path), "").slice(1);
      bundler = new Bundler({
        entry    : file.path,
        filename : file.name + ".js"
      });
      compile = function(next) { return bundler.get(next); }
    } else {
      compile = function(next) { return compiler.compile(fs.readFileSync(file.path, "utf8"), next); };
    }

    router.get(Utils.makeUrls(options.url, file, options.ext)[0], function(req, res) {
      compile(function(err, compiled) {
        return res.type((options.ext) === "js" ? "application/javascript" : "text/css").send(compiled);
      });
    });

  });

  // Set up Browsersync
  Object.keys(exts).forEach(function(ext) {
    Utils.watch(options.path, ext, options.ext);
  });

  return router;

}
<|endoftext|>


<commit_before>'use strict';
var util = require('util');
var path = require('path');
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var exec = require('child_process').execFile;

var generateGuid = function()
{
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
    return v.toString(16);
  });
}

var WebapiGenerator = yeoman.generators.Base.extend({
  init: function () {
    this.pkg = require('../package.json');

    this.on('end', function () {
      if (!this.options['skip-install']) {

        if(this.nuget){
          this.spawnCommand('tools\\nuget\\nuget.exe', ['install', 'src\\' + this.safeprojectname + '.web\\packages.config', '-OutputDirectory', 'src\\packages']);
        }

        this.installDependencies();
      }
    });
  },

  askFor: function () {
    var done = this.async();

    // have Yeoman greet the user
    this.log(this.yeoman);

    // replace it with a short and sweet description of your generator
    this.log(chalk.magenta('You\'re using the fantastic web api 2.0 for .net'));

    var prompts = [{
      type: 'input',
      name: 'namespace',
      message: 'What is the name of your company or preferred root namespace?',
      default: 'mycompany'
    },
    {
      type: 'input',
      name: 'name',
      message: 'What is the name of your project?',
      default: 'mywebapi'
    },
    {
      type: 'confirm',
      name: 'nuget',
      message: 'Install and run nuget?',
      default: true
    }];

    this.prompt(prompts, function (props) {
      this.namespace = props.namespace ? props.namespace : 'my company';
      this.name = props.name ? props.name : 'my web api';
      this.nuget = props.nuget;

      done();
    }.bind(this));
  },

  defaults: function(){
    this.language = 'c#';
    this.globalclassname = 'WebApiApplication';
    this.asaxentry = '<%@ Application Codebehind';
    this.languageext = 'cs'

    this.safeprojectname = this._.slugify(this.namespace) + '.' + this._.slugify(this.name);

    this.path = 'src/' + this._.slugify(this.namespace) + '.' + this._.slugify(this.name);
    this.nugetpackagesfolder =  '..\\packages\\';

    this.webprojectguid = generateGuid();
  },

  app: function () {
    this.mkdir('src');
    this.mkdir('tools');

    this.template('src/_webapi.sln', this.path + '.sln');

    this.copy('_package.json', 'package.json');
    this.copy('_bower.json', 'bower.json');
  },

  web: function(){
    this.webassemblyguid = generateGuid();

    var pathToWebFolder = this.path + '.web/';

    this.mkdir(pathToWebFolder);
    this.template('src/web/_webapi.web.csproj', pathToWebFolder + this.safeprojectname + '.web.csproj');

    this.template('src/web/_global.asax', pathToWebFolder + 'Global.asax');
    this.template('src/web/_global.asax.cs', pathToWebFolder + 'Global.asax.cs');

    this.copy('src/web/_web.config', pathToWebFolder + 'Web.config');
    this.copy('src/web/_web.debug.config', pathToWebFolder + 'Web.Debug.config');
    this.copy('src/web/_web.release.config', pathToWebFolder + 'Web.Release.config');

    this.mkdir(pathToWebFolder + '/Properties');
    this.template('src/web/properties/_assemblyinfo.cs', pathToWebFolder + 'Properties/AssemblyInfo.cs');

    this.mkdir(pathToWebFolder + '/Controllers');
    this.template('src/web/controllers/_valuescontroller.cs', pathToWebFolder + 'Controllers/ValuesController.cs');

    this.mkdir(pathToWebFolder + '/App_Start');
    this.mkdir(pathToWebFolder + '/App_Data');
  },

  nuget: function(){
    if (this.nuget){
      var cb = this.async();

      this.mkdir('tools/nuget');
      this.fetch('http://nuget.org/nuget.exe', 'tools/nuget', cb);
    }

    this.mkdir('src/packages');
    this.copy('src/web/packages.config', this.path + '.web/packages.config');
  },

  projectfiles: function () {
    this.copy('editorconfig', '.editorconfig');
    this.copy('jshintrc', '.jshintrc');
  }
});

module.exports = WebapiGenerator;<commit_msg>adding mono - mac/linux support<commit_after>'use strict';
var util = require('util');
var path = require('path');
var chalk = require('chalk');
var yeoman = require('yeoman-generator');

var exec = require('child_process').execFile;

var generateGuid = function()
{
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
    return v.toString(16);
  });
}

var WebapiGenerator = yeoman.generators.Base.extend({
  init: function () {
    this.pkg = require('../package.json');

    this.on('end', function () {
      if (!this.options['skip-install']) {

      var isWin = /^win/.test(process.platform);

      if(this.nuget){
        if (isWin){
          this.spawnCommand('tools\\nuget\\nuget.exe', ['install', 'src\\' + this.safeprojectname + '.web\\packages.config', '-OutputDirectory', 'src\\packages']);
        } else {
          this.spawnCommand('mono', ['tools/nuget/nuget.exe', 'install', 'src/' + this.safeprojectname + '.web/packages.config', '-OutputDirectory', 'src/packages']);
        }
      }

        this.installDependencies();
      }
    });
  },

  askFor: function () {
    var done = this.async();

    // have Yeoman greet the user
    this.log(this.yeoman);

    // replace it with a short and sweet description of your generator
    this.log(chalk.magenta('You\'re using the fantastic web api 2.0 for .net'));

    var prompts = [{
      type: 'input',
      name: 'namespace',
      message: 'What is the name of your company or preferred root namespace?',
      default: 'mycompany'
    },
    {
      type: 'input',
      name: 'name',
      message: 'What is the name of your project?',
      default: 'mywebapi'
    },
    {
      type: 'confirm',
      name: 'nuget',
      message: 'Install and run nuget?',
      default: true
    }];

    this.prompt(prompts, function (props) {
      this.namespace = props.namespace ? props.namespace : 'my company';
      this.name = props.name ? props.name : 'my web api';
      this.nuget = props.nuget;

      done();
    }.bind(this));
  },

  defaults: function(){
    this.language = 'c#';
    this.globalclassname = 'WebApiApplication';
    this.asaxentry = '<%@ Application Codebehind';
    this.languageext = 'cs'

    this.safeprojectname = this._.slugify(this.namespace) + '.' + this._.slugify(this.name);

    this.path = 'src/' + this._.slugify(this.namespace) + '.' + this._.slugify(this.name);
    this.nugetpackagesfolder =  '..\\packages\\';

    this.webprojectguid = generateGuid();
  },

  app: function () {
    this.mkdir('src');
    this.mkdir('tools');

    this.template('src/_webapi.sln', this.path + '.sln');

    this.copy('_package.json', 'package.json');
    this.copy('_bower.json', 'bower.json');
  },

  web: function(){
    this.webassemblyguid = generateGuid();

    var pathToWebFolder = this.path + '.web/';

    this.mkdir(pathToWebFolder);
    this.template('src/web/_webapi.web.csproj', pathToWebFolder + this.safeprojectname + '.web.csproj');

    this.template('src/web/_global.asax', pathToWebFolder + 'Global.asax');
    this.template('src/web/_global.asax.cs', pathToWebFolder + 'Global.asax.cs');

    this.copy('src/web/_web.config', pathToWebFolder + 'Web.config');
    this.copy('src/web/_web.debug.config', pathToWebFolder + 'Web.Debug.config');
    this.copy('src/web/_web.release.config', pathToWebFolder + 'Web.Release.config');

    this.mkdir(pathToWebFolder + '/Properties');
    this.template('src/web/properties/_assemblyinfo.cs', pathToWebFolder + 'Properties/AssemblyInfo.cs');

    this.mkdir(pathToWebFolder + '/Controllers');
    this.template('src/web/controllers/_valuescontroller.cs', pathToWebFolder + 'Controllers/ValuesController.cs');

    this.mkdir(pathToWebFolder + '/App_Start');
    this.mkdir(pathToWebFolder + '/App_Data');
  },

  nuget: function(){
    if (this.nuget){
      var cb = this.async();

      this.mkdir('tools/nuget');
      this.fetch('http://nuget.org/nuget.exe', 'tools/nuget', cb);
    }

    this.mkdir('src/packages');
    this.copy('src/web/packages.config', this.path + '.web/packages.config');
  },

  projectfiles: function () {
    this.copy('editorconfig', '.editorconfig');
    this.copy('jshintrc', '.jshintrc');
  }
});

module.exports = WebapiGenerator;
<|endoftext|>