.surface containing the rendering
- container: null, // root-level group within the surface
- backdrop: null, // coloured backdrop (MapCSS canvas element)
- connection: null, // data store
- controller: null, // UI controller
- uis: {},
+ var zoombehavior = d3.behavior.zoom()
+ .translate(projection.translate())
+ .scale(projection.scale())
+ .scaleExtent([256, 134217728]);
- tilegroup: null, // group within container for adding bitmap tiles
- tiles: {}, // index of tile objects
- tilebaseURL: 'http://ecn.t0.tiles.virtualearth.net/tiles/a$quadkey.jpeg?g=587&mkt=en-gb&n=z', // Bing imagery URL
+ zoombehavior.on('zoom', redraw);
- dragging: false, // current drag state
- dragged: false, // was most recent click a drag?
- dragx: NaN, // click co-ordinates at previously recorded drag event
- dragy: NaN, // |
- startdragx: NaN, // click co-ordinates at start of drag
- startdragy: NaN, // |
- dragtime: NaN, // timestamp of mouseup (compared to stop resulting click from firing)
- dragconnect: null, // event listener for endDrag
+ var surface = d3.selectAll(obj.selector)
+ .append('svg')
+ .attr({ width: width, height: width })
+ .call(zoombehavior);
- containerx: 0, // screen co-ordinates of container
- containery: 0, // |
- centrelat: NaN, // lat/long and bounding box of map
- centrelon: NaN, // |
- extent: {}, // |
- mapheight: NaN, // size of map object in pixels
- mapwidth: NaN, // |
+ var defs = surface.append('defs');
- layers: null, // array-like object of Groups, one for each OSM layer
- minlayer: -5, // minimum OSM layer supported
- maxlayer: 5, // maximum OSM layer supported
+ var clipPath = defs.append('clipPath')
+ .attr('id', 'clip')
+ .append('rect')
+ .attr('id', 'clip-rect')
+ .attr({ x: 0, y: 0 })
+ .attr({ width: width, height: height });
- elastic: null, // Group for drawing elastic band
+ var tilegroup = surface.append('g')
+ .attr('clip-path', 'url(#clip)'),
+ container = surface.append('g')
+ .attr('clip-path', 'url(#clip)');
- ruleset: null, // map style
+ var r = container.append('g');
- constructor: function(obj) {
- // summary: The main map display, containing the individual sprites (UIs) for each entity.
- // obj: Object An object containing .lat, .lon, .scale, .div (the name of the
to be used),
- // .connection, .width (px) and .height (px) properties.
+ layers[0] = {
+ root: r,
+ fill: r.append('g'),
+ casing: r.append('g'),
+ stroke: r.append('g'),
+ text: r.append('g'),
+ hit: r.append('g')
+ };
- this.mapwidth = obj.width ? obj.width : 800;
- this.mapheight = obj.height ? obj.height : 400;
+ var elastic = container.append('g');
- // Initialise variables
- this.uis = {};
- this.div=document.getElementById(obj.div);
- this.surface=Gfx.createSurface(obj.div, this.mapwidth, this.mapheight);
- this.backdrop=this.surface.createRect({
- x: 0,
- y: 0,
- width: this.mapwidth,
- height: this.mapheight
- }).setFill(new dojo.Color([255,255,245,1]));
- this.tilegroup = this.surface.createGroup();
- this.container = this.surface.createGroup();
- this.connection = obj.connection;
- this.zoom = obj.zoom ? obj.zoom : 17;
- this.baselon = obj.lon;
- this.baselat = obj.lat;
- this.baselatp = this.lat2latp(obj.lat);
- this._setScaleFactor();
- this.updateCoordsFromViewportPosition();
+ var download = _.debounce(function() {
+ connection.loadFromAPI(extent(), drawVector);
+ }, 1000);
- // Cache the margin box, since this is expensive.
- this.marginBox = domGeom.getMarginBox(this.div);
+ function extent() {
+ return [
+ projection.invert([0, 0]),
+ projection.invert([width, height])];
+ }
- // Initialise layers
- this.layers={};
- for (var l=this.minlayer; l<=this.maxlayer; l++) {
- var r=this.container.createGroup();
- this.layers[l]={
- root: r,
- fill: r.createGroup(),
- casing: r.createGroup(),
- stroke: r.createGroup(),
- text: r.createGroup(),
- hit: r.createGroup()
- };
+ function select(d) {
+ selection = [d._id];
+ }
+
+ function key(d) { return d._id; }
+
+ function classes(pre) {
+ return function(d) {
+ var tags = d.tags;
+ var c = [pre];
+ function clean(x) {
+ return tagclasses.indexOf(x) !== -1;
}
-
- // Create group for elastic band
- this.elastic = this.container.createGroup();
-
- // Make draggable
- this.backdrop.connect("onmousedown", _.bind(this.startDrag, this));
- this.tilegroup.connect("onmousedown", _.bind(this.startDrag, this));
- this.surface.connect("onclick", _.bind(this.clickSurface, this));
- this.surface.connect("onmousemove", _.bind(this.processMove, this));
- this.surface.connect("onmousedown", _.bind(this._mouseEvent, this));
- this.surface.connect("onmouseup", _.bind(this._mouseEvent, this));
- },
-
- setController:function(controller) {
- // summary: Set the controller that will handle events on the map (e.g. mouse clicks).
- this.controller = controller;
- },
-
- _moveToPosition:function(group, position) {
- // summary: Supplementary method for dojox.gfx.
- // This should ideally be core Dojo stuff: see http://bugs.dojotoolkit.org/ticket/15296
- var parent=group.getParent();
- if (!parent) { return; }
- this._moveChildToPosition(parent,group,position);
- if (position === group.rawNode.parentNode.childNodes.length) {
- group.rawNode.parentNode.appendChild(group.rawNode);
- } else {
- group.rawNode.parentNode.insertBefore(group.rawNode, group.rawNode.parentNode.childNodes[position]);
+ for (var k in tags) {
+ if (!clean(k)) continue;
+ c.push(k + '-' + tags[k]);
+ c.push(k);
}
- },
-
- _moveChildToPosition: function(parent, child, position) {
- for (var i = 0; i < parent.children.length; ++i){
- if (parent.children[i] === child){
- parent.children.splice(i, 1);
- parent.children.splice(position, 0, child);
- break;
- }
+ if (selection.indexOf(d._id) !== -1) {
+ c.push('active');
}
- },
+ return c.join(' ');
+ };
+ }
- // ----------------------------
- // Sprite and EntityUI handling
+ var icons = {
+ tourism: ['hotel'],
+ shop: [
+ 'convenience',
+ 'supermarket'],
+ amenity:
+ [
+ 'atm',
+ 'bank',
+ 'cafe',
+ 'pub',
+ 'place',
+ 'parking',
+ 'bicycle_parking',
+ 'pharmacy',
+ 'pharmacy',
+ 'police',
+ 'post_box',
+ 'recycling',
+ 'restaurant',
+ 'school',
+ 'taxi',
+ 'telephone']
+ };
- sublayer:function(layer,groupType,sublayer) {
- // summary: Find the gfx.Group for a given OSM layer and rendering sublayer, creating it
- // if necessary. Note that sublayers are only implemented for stroke and fill.
- // groupType: String 'casing','text','hit','stroke', or 'fill'
- var collection = this.layers[layer][groupType], sub;
- switch (groupType) {
- case 'casing':
- case 'text':
- case 'hit':
- return collection;
+ function markerimage(d) {
+ for (var k in icons) {
+ if (d.tags[k] && icons[k].indexOf(d.tags[k]) !== -1) {
+ return 'icons/' + d.tags[k] + '.png';
}
- // Find correct sublayer, inserting if necessary
- var insertAt=collection.children.length;
- for (var i = 0; i < collection.children.length; i++) {
- sub=collection.children[i];
- if (sub.sublayer==sublayer) { return sub; }
- else if (sub.sublayer>sublayer) {
- sub = collection.createGroup();
- this._moveToPosition(sub,i);
- sub.sublayer=sublayer;
- return sub;
- }
- }
- sub = collection.createGroup().moveToFront();
- sub.sublayer=sublayer;
- return sub; // dojox.gfx.Group
- },
+ }
+ }
- createUI: function(e, stateClasses) {
- // summary: Create a UI (sprite) for an entity, assigning any specified state classes
- // (temporary attributes such as ':hover' or ':selected')
- if (!this.uis[e.id]) {
- if (e.entityType === 'node') {
- this.uis[e.id] = new iD.renderer.NodeUI(e, this, stateClasses);
- } else if (e.entityType === 'way') {
- this.uis[e.id] = new iD.renderer.WayUI(e, this, stateClasses);
- }
- } else {
- this.uis[e.id].setStateClasses(stateClasses).redraw();
- }
- },
+ function selectClick(d) {
+ select(d);
+ drawVector();
+ }
- getUI: function(e) {
- // summary: Return the UI for an entity, if it exists.
- return this.uis[e.id]; // iD.renderer.EntityUI
- },
+ function nodeline(d) {
+ return linegen(d.nodes);
+ }
- refreshUI: function(e) {
- // summary: Redraw the UI for an entity.
- if (this.uis[e.id]) { this.uis[e.id].redraw(); }
- },
+ var highway_stack = [
+ 'motorway',
+ 'motorway_link',
+ 'trunk',
+ 'trunk_link',
+ 'primary',
+ 'primary_link',
+ 'secondary',
+ 'tertiary',
+ 'unclassified',
+ 'residential',
+ 'service',
+ 'footway'
+ ];
- deleteUI: function(e) {
- // summary: Delete the UI for an entity.
- if (this.uis[e.id]) {
- this.uis[e.id].removeSprites();
- delete this.uis[e.id];
- }
- },
+ function waystack(a, b) {
+ if (!a || !b) return 0;
+ if (a.tags.layer !== undefined && b.tags.layer !== undefined) {
+ return a.tags.layer - b.tags.layer;
+ }
+ if (a.tags.bridge) return 1;
+ if (b.tags.bridge) return -1;
+ var as = 0, bs = 0;
+ if (a.tags.highway && b.tags.highway) {
+ as -= highway_stack.indexOf(a.tags.highway);
+ bs -= highway_stack.indexOf(b.tags.highway);
+ }
+ return as - bs;
+ }
- download: function() {
- // summary: Ask the connection to download data for the current viewport.
- $('#progress').show().addClass('spinner');
- this.connection.loadFromAPI(this.extent, _.bind(this.updateUIs, this));
- },
+ function drawVector() {
+ var all = connection.all();
- updateUIs: function() {
- // summary: Draw/refresh all EntityUIs within the bbox, and remove any others.
- // redraw: Boolean Should we redraw any UIs that are already present?
- // remove: Boolean Should we delete any UIs that are no longer in the bbox?
- $('#progress').hide().removeClass('spinner');
- var o = this.connection.getObjectsByBbox(this.extent);
- var touch = _(o.inside).chain()
- .filter(function(w) { return w.loaded; })
- .map(_.bind(function(e) {
- if (!this.uis[e.id]) {
- this.createUI(e);
- } else {
- this.uis[e.id].redraw();
- }
- return '' + e.id;
- }, this)).value();
- _.each(_.difference(_.keys(this.uis), touch), _.bind(function(k) {
- console.log(k);
- this.deleteUI(k);
- }, this));
- },
-
- // -------------
- // Zoom handling
-
- zoomIn: function() {
- // summary: Zoom in by one level (unless maximum reached).
- return this.setZoom(this.zoom + 1);
- },
-
- zoomOut: function() {
- // summary: Zoom out by one level (unless minimum reached).
- this.setZoom(this.zoom - 1);
- this.download();
- return this;
- },
-
- setZoom: function(zoom) {
- if (zoom < this.MINSCALE || zoom > this.MAXSCALE) return this;
- // summary: Redraw the map at a new zoom level.
- this.zoom = zoom;
- this._setScaleFactor();
- this._blankTiles();
- this.setCentre({
- lat: this.centrelat,
- lon: this.centrelon
+ var ways = all.filter(function(a) {
+ return a.entityType === 'way' && !a.isClosed();
+ }),
+ areas = all.filter(function(a) {
+ return a.entityType === 'way' && a.isClosed();
+ }),
+ points = all.filter(function(a) {
+ return a.entityType === 'node';
});
- this.updateUIs(true, true);
- return this;
- },
- _setScaleFactor: function() {
- // summary: Calculate the scaling factor for this zoom level.
- this.zoomfactor = this.MASTERSCALE/Math.pow(2, 13 - this.zoom);
- },
+ var defpaths = defs.selectAll('path')
+ .data(ways, key),
+ fills = layers[0].fill.selectAll('path.area')
+ .data(areas, key),
+ casings = layers[0].casing.selectAll('use.casing')
+ .data(ways, key),
+ strokes = layers[0].stroke.selectAll('use.stroke')
+ .data(ways, key),
+ texts = layers[0].text.selectAll('text')
+ .data(ways.filter(function(w) {
+ return !!w.tags.name;
+ }), key),
+ markers = layers[0].hit.selectAll('image.marker')
+ .data(points, key);
- // ----------------------
- // Elastic band redrawing
+ var _id = selection[0];
+ var active_entity = all.filter(function(a) {
+ return a._id === _id;
+ });
- clearElastic: function() {
- // summary: Remove the elastic band used to draw new ways.
- this.elastic.clear();
- },
+ var handles = layers[0].hit.selectAll('circle.handle')
+ .data(active_entity.length ? active_entity[0].nodes : [], key);
- drawElastic: function(x1,y1,x2,y2) {
- // summary: Draw the elastic band (for new ways) between two points.
- this.elastic.clear();
- // **** Next line is SVG-specific
- this.elastic.rawNode.setAttribute("pointer-events","none");
- this.elastic.createPolyline( [{ x:x1, y:y1 }, { x:x2, y:y2 }] ).setStroke( {
- color: [0, 0, 0, 1],
- style: 'Solid',
- width: 1
+ defpaths.exit().remove();
+ texts.exit().remove();
+ handles.exit().remove();
+ fills.exit().remove();
+ markers.exit().remove();
+ casings.exit().remove();
+ strokes.exit().remove();
+
+ defpaths.enter().append('path');
+
+ defpaths.attr('d', nodeline)
+ .attr('id', function(d) {
+ return 'd' + d._id;
});
- },
- // -------------
- // Tile handling
- // ** FIXME: see docs
- loadTiles: function() {
- // summary: Load all tiles for the current viewport. This is a bare-bones function
- // at present: it needs configurable URLs (not just Bing), attribution/logo
- // support, and to be 'nudgable' (i.e. adjust the offset).
- var tl = this.locationCoord({
- lat: this.extent.north,
- lon: this.extent.west
- }, this.zoom),
- br = this.locationCoord({
- lat: this.extent.south,
- lon: this.extent.east
- }, this.zoom),
- tileKeys = _.keys(this.tiles),
- seen = [],
- coord = { z: this.zoom };
+ function usehref(d) {
+ return '#d' + d._id;
+ }
- for (coord.x = tl.x; coord.x <= br.x; coord.x++) {
- for (coord.y = tl.y; coord.y <= br.y; coord.y++) {
- if (!this._getTile(coord)) {
- this._fetchTile(coord);
- }
- seen.push(iD.Util.tileKey(coord));
- }
- }
+ fills.enter().append('path')
+ .on('click', selectClick);
- _.each(_.without(tileKeys, seen), _.bind(function(key) {
- delete this.tiles[key];
- }, this));
- },
+ fills.attr('d', nodeline)
+ .attr('class', classes('area'));
- _fetchTile: function(coord) {
- // summary: Load a tile image at the given tile co-ordinates.
- var t = this.tilegroup.createImage({
- x: Math.floor(this.lon2coord(this.tile2lon(coord.x))),
- y: Math.floor(this.lat2coord(this.tile2lat(coord.y))),
- width: 256,
- height: 256,
- src: this._tileURL(coord)
+ casings.enter().append('use');
+ casings.sort(waystack)
+ .attr('xlink:href', usehref)
+ .attr('class', classes('casing'));
+
+ strokes.enter().append('use')
+ .on('click', selectClick);
+
+ strokes.sort(waystack).attr('xlink:href', usehref)
+ .attr('class', classes('stroke'));
+
+ markers.enter().append('image');
+ markers.attr('class', classes('marker'))
+ .attr({ width: 16, height: 16 })
+ .attr('xlink:href', markerimage)
+ .attr('transform', function(d) {
+ return 'translate(' + projection(d) + ')';
});
- this._assignTile(coord, t);
- },
- _getTile: function(coord) {
- // summary: See if this tile is already loaded.
- return this.tiles[iD.Util.tileKey(coord)];
- },
+ var textems = texts.enter().append('text')
+ .attr('dy', 3);
- _assignTile: function(coord, t) {
- // summary: Store a reference to the tile so we know it's loaded.
- this.tiles[iD.Util.tileKey(coord)] = t;
- },
+ textems.append('textPath')
+ .attr('xlink:href', usehref)
+ .attr('startOffset', '50%')
+ .text(function(d) { return d.tags.name; });
- _tileURL: function(coord) {
- // summary: Calculate the URL for a tile at the given co-ordinates.
- var u = '';
- for (var zoom = coord.z; zoom > 0; zoom--) {
- var byte = 0;
- var mask = 1 << (zoom - 1);
- if ((coord.x & mask) !== 0) byte++;
- if ((coord.y & mask) !== 0) byte += 2;
- u += byte.toString();
- }
- return this.tilebaseURL
- .replace('$z', coord.z)
- .replace('$x', coord.x)
- .replace('$y', coord.y)
- .replace('$quadkey', u);
- },
+ handles.enter().append('circle')
+ .attr('class', 'handle')
+ .attr('r', 5)
+ .on('click', selectClick);
+ handles.attr('transform', function(d) {
+ return 'translate(' + projection(d) + ')';
+ });
+ }
+
+ // -------------
+ // Zoom handling
+ function zoomIn() {
+ // summary: Zoom in by one level (unless maximum reached).
+ return setZoom(getZoom() + 1);
+ }
- _blankTiles: function() {
- // summary: Unload all tiles and remove from the display.
- this.tilegroup.clear();
- this.tiles = {};
- },
+ function zoomOut() {
+ // summary: Zoom out by one level (unless minimum reached).
+ return setZoom(getZoom() - 1);
+ }
- // -------------------------------------------
- // Co-ordinate management, dragging and redraw
+ function getZoom(zoom) {
+ var s = projection.scale();
+ return Math.max(Math.log(s) / Math.log(2) - 8, 0);
+ }
- startDrag: function(e) {
- // summary: Start dragging the map in response to a mouse-down.
- // e: MouseEvent The mouse-down event that triggered it.
- var srcElement = (e.gfxTarget === this.backdrop) ?
- e.gfxTarget : e.gfxTarget.parent;
- Event.stop(e);
- this.dragging = true;
- this.dragged = false;
- this.dragx = this.dragy=NaN;
- this.startdragx = e.clientX;
- this.startdragy = e.clientY;
- this.dragconnect = srcElement.connect("onmouseup", _.bind(this.endDrag, this));
- },
+ function setZoom(zoom) {
+ // summary: Redraw the map at a new zoom level.
+ projection.scale(256 * Math.pow(2, zoom - 1));
+ zoombehavior.scale(projection.scale());
+ drawVector();
+ redraw();
+ return map;
+ }
- endDrag: function(e) {
- // summary: Stop dragging the map in response to a mouse-up.
- // e: MouseEvent The mouse-up event that triggered it.
- Event.stop(e);
- dojo.disconnect(this.dragconnect);
- this.dragging=false;
- this.dragtime=e.timeStamp;
- this.updateCoordsFromViewportPosition();
- if (Math.abs(e.clientX - this.startdragx) < 3 &&
- Math.abs(e.clientY - this.startdragy) < 3) {
- return;
- }
- this.download();
- },
+ function tilesForView() {
+ var t = projection.translate(),
+ s = projection.scale(),
+ z = Math.max(Math.log(s) / Math.log(2) - 8, 0);
+ rz = Math.floor(z),
+ ts = 256 * Math.pow(2, z - rz);
- processMove: function(e) {
- // summary: Drag the map to a new origin.
- // e: MouseEvent The mouse-move event that triggered it.
- var x = e.clientX;
- var y = e.clientY;
- if (this.dragging) {
- if (this.dragx) {
- this.containerx += (x - this.dragx);
- this.containery += (y - this.dragy);
- this.updateOrigin();
- this.dragged=true;
- }
- this.dragx = x;
- this.dragy = y;
- } else {
- this.controller.entityMouseEvent(e,null);
- }
- },
+ // This is the 0, 0 px of the projection
+ var tile_origin = [s / 2 - t[0], s / 2 - t[1]],
+ coords = [],
+ cols = d3.range(Math.max(0, Math.floor((tile_origin[0] - width) / ts)),
+ Math.max(0, Math.ceil((tile_origin[0] + width) / ts))),
+ rows = d3.range(Math.max(0, Math.floor((tile_origin[1] - height) / ts)),
+ Math.max(0, Math.ceil((tile_origin[1] + height) / ts)));
- updateOrigin: function() {
- // summary: Tell Dojo to update the viewport origin.
- this.container.setTransform([Matrix.translate(this.containerx, this.containery)]);
- this.tilegroup.setTransform([Matrix.translate(this.containerx, this.containery)]);
- },
+ cols.forEach(function(x) {
+ rows.forEach(function(y) { coords.push([Math.floor(z), x, y]); });
+ });
+ return coords;
+ }
- _mouseEvent: function(e) {
- // summary: Catch mouse events on the surface but not the tiles - in other words,
- // on drawn items that don't have their own hitzones, like the fill of a shape.
- if (e.type=='mousedown') { this.startDrag(e); }
- // ** FIXME: we may want to reinstate this at some point...
- // this.controller.entityMouseEvent(e,null);
- },
- updateCoordsFromViewportPosition: function(e) {
- // summary: Update centre and bbox from the current viewport origin.
- this._updateCoords(this.containerx, this.containery);
- },
+ function tileUrl(coord) {
+ var tmpl = 'http://ecn.t0.tiles.virtualearth.net/tiles/a$quadkey.jpeg?g=587&mkt=en-gb&n=z';
+ var u = '';
+ for (var zoom = coord[0]; zoom > 0; zoom--) {
+ var byte = 0;
+ var mask = 1 << (zoom - 1);
+ if ((coord[1] & mask) !== 0) byte++;
+ if ((coord[2] & mask) !== 0) byte += 2;
+ u += byte.toString();
+ }
+ return tmpl.replace('$quadkey', u);
+ }
- setCentre: function(loc) {
- // summary: Update centre and bbox to a specified lat/lon.
- var coord = this.locationCoord(loc, this.zoom);
- this._updateCoords(
- -coord.x - this.mapwidth / 2,
- -coord.y - this.mapheight / 2);
- return this;
- },
+ function redraw() {
+ if (d3.event) {
+ projection
+ .translate(d3.event.translate)
+ .scale(d3.event.scale);
+ }
- setCenter: function(loc) { this.setCentre(loc); },
+ var t = projection.translate(),
+ s = projection.scale(),
+ z = Math.max(Math.log(s) / Math.log(2) - 8, 0);
+ rz = Math.floor(z),
+ ts = 256 * Math.pow(2, z - rz);
- _updateCoords:function(x, y) {
- // summary: Set centre and bbox.
- this.containerx = x;
- this.containery = y;
- this.updateOrigin();
- this.centrelon = this.coord2lon(-x + this.mapwidth/2);
- this.centrelat = this.coord2lat(-y + this.mapheight/2);
+ // This is the 0, 0 px of the projection
+ var tile_origin = [s / 2 - t[0], s / 2 - t[1]],
+ coords = tilesForView();
- this.extent = {
- north: this.coord2lat(-y),
- south: this.coord2lat(-y + this.mapheight),
- west: this.coord2lon(-x),
- east: this.coord2lon(-x + this.mapwidth)
- };
+ var tiles = tilegroup.selectAll('image.tile')
+ .data(coords, function(d) { return d.join(','); });
- this.loadTiles();
- },
+ tiles.exit().remove();
+ tiles.enter().append('image')
+ .attr('class', 'tile')
+ .attr('xlink:href', tileUrl);
+ tiles.attr({ width: ts, height: ts })
+ .attr('transform', function(d) {
+ return 'translate(' + [(d[1] * ts) - tile_origin[0], (d[2] * ts) - tile_origin[1]] + ')';
+ });
+ drawVector();
+ download();
+ }
- clickSurface:function(e) {
- // summary: Handle a click on an empty area of the map.
- if (this.dragged && e.timeStamp==this.dragtime) { return; }
- this.controller.entityMouseEvent(e,null);
- },
+ function setCentre(loc) {
+ // summary: Update centre and bbox to a specified lat/lon.
+ var t = projection.translate(),
+ ll = projection([loc.lon, loc.lat]);
+ projection.translate([
+ t[0] - ll[0] + width / 2,
+ t[1] - ll[1] + height / 2]);
+ zoombehavior.translate(projection.translate());
+ redraw();
+ return map;
+ }
- // -----------------------
- // Co-ordinate conversions
+ map.download = download;
+ map.extent = extent;
+ map.setCentre = setCentre;
+ map.setCenter = setCentre;
- latp2coord:function(a) { return -(a-this.baselatp)*this.zoomfactor; },
- coord2latp:function(a) { return a/-this.zoomfactor+this.baselatp; },
- lon2coord:function(a) { return (a-this.baselon)*this.zoomfactor; },
- coord2lon:function(a) { return a/this.zoomfactor+this.baselon; },
- lon2screen:function(a) { return this.lon2coord(a) + this.marginBox.l + this.containerx; },
+ map.getZoom = getZoom;
+ map.setZoom = setZoom;
+ map.zoomIn = zoomIn;
+ map.zoomOut = zoomOut;
- lat2latp:function(a) { return 180/Math.PI * Math.log(Math.tan(Math.PI/4+a*(Math.PI/180)/2)); },
- latp2lat:function(a) { return 180/Math.PI * (2 * Math.atan(Math.exp(a*Math.PI/180)) - Math.PI/2); },
- lat2coord:function(a) { return -(this.lat2latp(a)-this.baselatp)*this.zoomfactor; },
- coord2lat:function(a) { return this.latp2lat(a/-this.zoomfactor+this.baselatp); },
- lat2screen:function(a) { return this.lat2coord(a) + this.marginBox.t + this.containery; },
+ map.connection = connection;
+ map.controller = controller;
+ map.projection = projection;
- locationCoord: function(ll, z) {
- var z2 = Math.pow(2, z), d2r = Math.PI / 180;
- return {
- z: z,
- x: Math.floor((ll.lon + 180) / 360 * z2),
- y: Math.floor((1 - Math.log(Math.tan(ll.lat * d2r) +
- 1 / Math.cos(ll.lat * d2r)) / Math.PI) / 2 * z2)
- };
- },
- lon2tile:function(a) { return (Math.floor((a+180)/360*Math.pow(2,this.zoom))); },
- lat2tile:function(a) { return (Math.floor((1-Math.log(Math.tan(a*Math.PI/180) + 1/Math.cos(a*Math.PI/180))/Math.PI)/2 *Math.pow(2,this.zoom))); },
- tile2lon:function(a) { return (a/Math.pow(2,this.zoom)*360-180); },
- tile2lat:function(a) {
- var n=Math.PI-2*Math.PI*a/Math.pow(2,this.zoom);
- return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
- },
-
- // Turn event co-ordinates into map co-ordinates
-
- mouseX: function(e) { return e.clientX - this.marginBox.l - this.containerx; },
- mouseY: function(e) { return e.clientY - this.marginBox.t - this.containery; }
- });
-
- // ----------------------------------------------------------------------
- // End of module
-});
+ redraw();
+ return map;
+};
diff --git a/js/iD/renderer/NodeUI.js b/js/iD/renderer/NodeUI.js
deleted file mode 100755
index 163fcacbb..000000000
--- a/js/iD/renderer/NodeUI.js
+++ /dev/null
@@ -1,107 +0,0 @@
-// iD/renderer/NodeUI.js
-// NodeUI classes for iD
-
-define(['dojo/_base/declare','dojox/gfx/_base','iD/renderer/EntityUI'],
- function(declare, g) {
-
-// ----------------------------------------------------------------------
-// NodeUI class
-
-declare("iD.renderer.NodeUI", [iD.renderer.EntityUI], {
- constructor:function() {
- // summary: A UI (rendering) representing a node.
- this.redraw();
- },
- getEnhancedTags:function() {
- var tags=this.inherited(arguments);
- if (!this.entity.entity.hasParentWays()) { tags[':poi']='yes'; }
- // add junction and dupe
- return tags;
- },
- redraw:function() {
- // summary: Draw the object (mostly icons) and add hitzone sprites.
- var node = this.entity;
- this.removeSprites();
-
- // Tags, position and styleList
- var x = Math.floor(this.map.lon2coord(this.entity.lon));
- var y = Math.floor(this.map.latp2coord(this.entity.latp));
- var tags = this.getEnhancedTags();
- this.refreshStyleList(tags);
-
- // Iterate through each subpart, drawing any styles on that layer
- var drawn = false;
- var s, p, t, w, h;
- for (i = 0; i < this.styleList.subparts.length; i++) {
- var subpart=this.styleList.subparts[i];
- p = this.styleList.pointStyles[subpart];
- if (!p || !p.drawn()) { continue; }
- s = this.styleList.shapeStyles[subpart];
- t = this.styleList.textStyles[subpart];
- w = p.icon_width ? p.icon_width : 16;
- h = p.icon_height ? p.icon_height: w;
-
- // Draw icon
- var shape;
- if (p.icon_image === 'square') shape = this.targetGroup('stroke', p.sublayer)
- .createRect({
- x: x-w/2,
- y: y-h/2,
- width: w,
- height: h
- });
- else if (p.icon_image === 'circle') shape = this.targetGroup('stroke', p.sublayer)
- .createCircle({
- cx: x,
- cy: y,
- r: w
- });
- else shape = this.targetGroup('stroke',p.sublayer)
- .createImage({
- width: w,
- height: h,
- x: x-w/2,
- y: y-h/2,
- src: p.icon_image
- });
- if (p.icon_image === 'square' || p.icon_image === 'circle') {
- shape.setStroke(s.shapeStrokeStyler()).setFill(s.shapeFillStyler());
- }
- this.recordSprite(shape);
-
- // Add text label
- // Add hit-zone
- var hit;
- if (p.icon_image === 'circle') {
- hit = this.targetGroup('hit').createCircle({
- cx: x,
- cy: y,
- r: w
- });
- } else {
- hit = this.targetGroup('hit').createRect({
- x: x-w/2,
- y: y-h/2,
- width: w,
- height: h
- });
- }
- hit.setFill([0,1,0,0]).setStroke({
- width:2,
- color:[0,0,0,0]
- });
- this.recordSprite(hit);
- hit.source = this;
- hit.connect("onclick", _.bind(this.entityMouseEvent, this));
- hit.connect("onmousedown", _.bind(this.entityMouseEvent, this));
- hit.connect("onmouseup", _.bind(this.entityMouseEvent, this));
- hit.connect("onmouseenter", _.bind(this.entityMouseEvent, this));
- hit.connect("onmouseleave", _.bind(this.entityMouseEvent, this));
- }
- }
-});
-
-
-// ----------------------------------------------------------------------
-// End of module
-});
diff --git a/js/iD/renderer/WayUI.js b/js/iD/renderer/WayUI.js
deleted file mode 100755
index 3ae0def54..000000000
--- a/js/iD/renderer/WayUI.js
+++ /dev/null
@@ -1,146 +0,0 @@
-// iD/renderer/WayUI.js
-// WayUI classes for iD
-// **** TODO:
-// multipolygon support - http://mail.dojotoolkit.org/pipermail/dojo-interest/2011-January/052042.html
-// support 'interactive'
-// line decoration, dots etc.
-// fill images
-// opacity
-
-define(['dojo/_base/declare','iD/renderer/EntityUI'], function(declare) {
-
-// ----------------------------------------------------------------------
-// WayUI class
-
-declare("iD.renderer.WayUI", [iD.renderer.EntityUI], {
- constructor: function() {
- // summary: A UI (rendering) representing a way.
- this.redraw();
- },
- getEnhancedTags: function() {
- var tags = this.inherited(arguments);
- if (this.entity.isClosed()) { tags[':area']='yes'; }
- return tags;
- },
- recalculate: function() {
- // summary: Not yet implemented - calculate length/centrepoint of UI for use in rendering.
- // ** FIXME: todo
- },
- redraw: function() {
- // summary: Draw the object and add hitzone sprites.
- var way = this.entity,
- maxwidth = 4,
- i;
-
- this.removeSprites();
- if (!way.nodes.length) { return; }
-
- // Create tags and calculate styleList
- var tags = this.getEnhancedTags();
- this.refreshStyleList(tags);
-
- // List of co-ordinates
- var coords = _.map(way.nodes, _.bind(function(node) {
- return {
- x: this.map.lon2coord(node.lon),
- y: this.map.latp2coord(node.latp)
- };
- }, this));
-
- // Iterate through each subpart, drawing any styles on that layer
- var drawn = false;
- for (i = 0; i < this.styleList.subparts.length; i++) {
- var subpart = this.styleList.subparts[i];
- if (this.styleList.shapeStyles[subpart]) {
- var s = this.styleList.shapeStyles[subpart], line;
-
- // Stroke
- if (s.width) {
- line = this.targetGroup('stroke',s.sublayer)
- .createPolyline(coords)
- .setStroke(s.strokeStyler());
-
- this.recordSprite(line);
- maxwidth = Math.max(maxwidth, s.width);
- drawn = true;
- }
-
- // Fill
- if (!isNaN(s.fill_color)) {
- line = this.targetGroup('fill',s.sublayer)
- .createPolyline(coords)
- .setFill(s.fillStyler());
-
- this.recordSprite(line);
- drawn = true;
- }
-
- // Casing
- if (s.casing_width) {
- line = this.targetGroup('casing')
- .createPolyline(coords)
- .setStroke(s.casingStyler());
-
- this.recordSprite(line);
- maxwidth = Math.max(maxwidth, s.width + s.casing_width * 2);
- drawn = true;
- }
- }
-
- // Text label on path
- if (this.styleList.textStyles[subpart]) {
- var t = this.styleList.textStyles[subpart];
- if (t.text && tags[t.text]) {
- var tp=this.recordSprite(this.targetGroup('text')
- .createTextPath(t.textStyler(tags[t.text]))
- .setFont(t.fontStyler())
- .setFill(t.fillStyler())
- .moveTo(coords[0].x,coords[0].y));
- for (var j=1; j
1) { sc.push('junction'); }
- this.map.createUI(node,sc);
- }
-
- return this;
- },
-
- entityMouseEvent:function(event) {
- this.inherited(arguments);
- }
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
diff --git a/js/iD/renderer/renderer.js b/js/iD/renderer/renderer.js
new file mode 100644
index 000000000..593d9bb7a
--- /dev/null
+++ b/js/iD/renderer/renderer.js
@@ -0,0 +1 @@
+iD.renderer = {};
diff --git a/js/iD/styleparser/Condition.js b/js/iD/styleparser/Condition.js
deleted file mode 100755
index 6c509b6f4..000000000
--- a/js/iD/styleparser/Condition.js
+++ /dev/null
@@ -1,45 +0,0 @@
-// iD/styleparser/Condition.js
-
-define(['dojo/_base/declare'], function(declare){
-
-// ----------------------------------------------------------------------
-// Condition base class
-
-declare("iD.styleparser.Condition", null, {
- type: '', // eq/ne/regex etc.
- params: [], // what to test against
-
- constructor:function(_type) {
- // summary: A condition to evaluate.
- this.type =_type;
- this.params=Array.prototype.slice.call(arguments,1);
- },
-
- test:function(tags) {
- // summary: Run the condition against the supplied tags.
- var p=this.params;
- switch (this.type) {
- case 'eq': return (tags[p[0]]==p[1]);
- case 'ne': return (tags[p[0]]!=p[1]);
- case 'regex': var r=new RegExp(p[1],"i");
- return (r.test(tags[p[0]]));
- case 'true': return (tags[p[0]]=='true' || tags[p[0]]=='yes' || tags[p[0]]=='1');
- case 'false': return (tags[p[0]]=='false' || tags[p[0]]=='no' || tags[p[0]]=='0');
- case 'set': return (tags[p[0]] !== undefined && tags[p[0]]!=='');
- case 'unset': return (tags[p[0]] === undefined || tags[p[0]]==='');
- case '<': return (Number(tags[p[0]])< Number(p[1]));
- case '<=': return (Number(tags[p[0]])<=Number(p[1]));
- case '>': return (Number(tags[p[0]])> Number(p[1]));
- case '>=': return (Number(tags[p[0]])>=Number(p[1]));
- }
- return false;
- },
-
- toString:function() {
- return "["+this.type+": "+this.params+"]";
- }
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
diff --git a/js/iD/styleparser/Rule.js b/js/iD/styleparser/Rule.js
deleted file mode 100755
index 5fffb211f..000000000
--- a/js/iD/styleparser/Rule.js
+++ /dev/null
@@ -1,55 +0,0 @@
-// iD/styleparser/Rule.js
-
-define(['dojo/_base/declare','dojo/_base/array'], function(declare,array){
-
-// ----------------------------------------------------------------------
-// Rule class
-
-declare("iD.styleparser.Rule", null, {
-
- conditions: [], // the Conditions to be evaluated for the Rule to be fulfilled
- isAnd: true, // do all Conditions need to be true for the Rule to be fulfilled? (Always =true for MapCSS)
- minZoom: 0, // minimum zoom level at which the Rule is fulfilled
- maxZoom: 255, // maximum zoom level at which the Rule is fulfilled
- subject: '', // entity type to which the Rule applies: 'way', 'node', 'relation', 'area' (closed way) or 'line' (unclosed way)
-
- constructor: function(_subject) {
- // summary: A MapCSS selector. Contains a list of Conditions; the entity type to which the selector applies;
- // and the zoom levels at which it is true. way[waterway=river][boat=yes] would be parsed into one Rule.
- // The selectors and declaration together form a StyleChooser.
- this.subject=_subject;
- this.conditions=[];
- },
-
- addCondition: function(_condition) {
- // summary: Add a condition to this rule.
- this.conditions.push(_condition);
- },
-
- test: function(entity,tags,zoom) {
- // summary: Evaluate the Rule on the given entity, tags and zoom level.
- // returns: true if the Rule passes, false if the conditions aren't fulfilled.
- if ((this.subject !== '') && (entity.entityType !== this.subject)) {
- return false;
- }
- if (zoomthis.maxZoom) { return false; }
-
- var v=true; var i=0; var isAnd=this.isAnd;
- array.forEach(this.conditions, function(condition) {
- var r=condition.test(tags);
- if (i === 0) { v=r; }
- else if (isAnd) { v=v && r; }
- else { v = v || r; }
- i++;
- });
- return v;
- },
-
- toString:function() {
- return this.subject+" z"+this.minZoom+"-"+this.maxZoom+": "+this.conditions;
- }
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
diff --git a/js/iD/styleparser/RuleChain.js b/js/iD/styleparser/RuleChain.js
deleted file mode 100755
index 96b1658c0..000000000
--- a/js/iD/styleparser/RuleChain.js
+++ /dev/null
@@ -1,83 +0,0 @@
-// iD/styleparser/RuleChain.js
-
-define(['dojo/_base/declare','iD/styleparser/Rule'], function(declare){
-
-// ----------------------------------------------------------------------
-// RuleChain base class
-// In contrast to Halcyon, note that length() is a function, not a getter property
-
-/** A descendant list of MapCSS selectors (Rules).
-
- For example,
- relation[type=route] way[highway=primary]
- ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
- first Rule second Rule
- |------------|---------|
- |
- one RuleChain
-
-*/
-
-declare("iD.styleparser.RuleChain", null, {
-
- rules:[], // list of Rules
- subpart: 'default', // subpart name, as in way[highway=primary]::centreline
-
- constructor:function() {
- // summary: A descendant list of MapCSS selectors (Rules).
- this.rules=[];
- },
-
- // Functions to define the RuleChain
-
- addRule:function(_subject) {
- this.rules.push(new iD.styleparser.Rule(_subject));
- },
-
- addConditionToLast:function(_condition) {
- this.rules[this.rules.length-1].addCondition(_condition);
- },
-
- addZoomToLast:function(z1,z2) {
- this.rules[this.rules.length-1].minZoom=z1;
- this.rules[this.rules.length-1].maxZoom=z2;
- },
-
-
- length:function() {
- return this.rules.length;
- },
-
- setSubpart:function(subpart) {
- this.subpart = subpart || 'default';
- },
-
- // Test a ruleChain
- // - run a set of tests in the chain
- // works backwards from at position "pos" in array, or -1 for the last
- // separate tags object is required in case they've been dynamically retagged
- // - if they fail, return false
- // - if they succeed, and it's the last in the chain, return happily
- // - if they succeed, and there's more in the chain, rerun this for each parent until success
-
- test: function(pos, entity, tags, zoom) {
- // summary: Test a rule chain by running all the tests in reverse order.
- if (this.rules.length === 0) { return false; }
- if (pos==-1) { pos=this.rules.length-1; }
-
- var r = this.rules[pos];
- if (!r.test(entity, tags, zoom)) { return false; }
- if (pos === 0) { return true; }
-
- var o = entity.entity.parentObjects();
- for (var i = 0; i < o.length; i++) {
- var p=o[i];
- if (this.test(pos-1, p, p.tags, zoom)) { return true; }
- }
- return false;
- }
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
diff --git a/js/iD/styleparser/RuleSet.js b/js/iD/styleparser/RuleSet.js
deleted file mode 100755
index f2277d0be..000000000
--- a/js/iD/styleparser/RuleSet.js
+++ /dev/null
@@ -1,458 +0,0 @@
-// iD/styleparser/RuleSet.js
-
-define(['dojo/_base/xhr','dojo/_base/lang','dojo/_base/declare','dojo/_base/array','iD/styleparser/Style','iD/styleparser/StyleChooser','iD/styleparser/Condition','iD/styleparser/StyleList'], function(xhr,lang,declare,array){
-
-// ----------------------------------------------------------------------
-// RuleSet base class
-// needs to cope with nested CSS files
-// doesn't do untagged nodes optimisation
-
-declare("iD.styleparser.RuleSet", null, {
-
- choosers: [], // list of StyleChoosers
- callback: null,
-
- constructor: function() {
- // summary: An entire stylesheet in parsed form.
- this.choosers = [];
- },
-
- registerCallback: function(callback) {
- // summary: Set a callback function to be called when the CSS is loaded and parsed.
- this.callback = callback;
- },
-
- getStyles: function(entity, tags, zoom) {
- // summary: Find the styles for a given entity.
- var sl=new iD.styleparser.StyleList();
- for (var i in this.choosers) {
- this.choosers[i].updateStyles(entity, tags, sl, zoom);
- }
- return sl; // iD.styleparser.StyleList
- },
-
- loadFromCSS:function(url) {
- // summary: Load a MapCSS file from a URL, then throw it at the parser when it's loaded.
- xhr.get({ url: url, load: lang.hitch(this, "parseCSS") });
- },
-
- parseCSS:function(css) {
- // summary: Parse a CSS document into a set of StyleChoosers.
- var previous=0; // what was the previous CSS word?
- var sc = new iD.styleparser.StyleChooser(); // currently being assembled
- this.choosers = [];
- css = css.replace(/[\r\n]/g,""); // strip linebreaks because JavaScript doesn't have the /s modifier
-
- var o = {};
- while (css.length>0) {
-
- // CSS comment
- if ((o=this.COMMENT.exec(css))) {
- css=css.replace(this.COMMENT,'');
-
- // Whitespace (probably only at beginning of file)
- } else if ((o=this.WHITESPACE.exec(css))) {
- css=css.replace(this.WHITESPACE,'');
-
- // Class - .motorway, .builtup, :hover
- } else if ((o=this.CLASS.exec(css))) {
- if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
-
- css=css.replace(this.CLASS,'');
- sc.currentChain().addConditionToLast(new iD.styleparser.Condition('set',o[1]));
- previous=this.oCONDITION;
-
- // Not class - !.motorway, !.builtup, !:hover
- } else if ((o=this.NOT_CLASS.exec(css))) {
- if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
-
- css=css.replace(this.NOT_CLASS,'');
- sc.currentChain().addConditionToLast(new iD.styleparser.Condition('unset',o[1]));
- previous=this.oCONDITION;
-
- // Zoom
- } else if ((o=this.ZOOM.exec(css))) {
- if (previous!=this.oOBJECT && previous!=this.oCONDITION) { sc.currentChain().addRule(); }
-
- css=css.replace(this.ZOOM,'');
- var z=parseZoom(o[1]);
- sc.currentChain().addZoomToLast(z[0],z[1]);
- sc.zoomSpecific=true;
- previous=this.oZOOM;
-
- // Grouping - just a comma
- } else if ((o=this.GROUP.exec(css))) {
- css=css.replace(this.GROUP,'');
- sc.newRuleChain();
- previous=this.oGROUP;
-
- // Condition - [highway=primary]
- } else if ((o=this.CONDITION.exec(css))) {
- if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
- if (previous!=this.oOBJECT && previous!=this.oZOOM && previous!=this.oCONDITION) { sc.currentChain().addRule(); }
- css=css.replace(this.CONDITION,'');
- sc.currentChain().addConditionToLast(this.parseCondition(o[1]));
- previous=this.oCONDITION;
-
- // Object - way, node, relation
- } else if ((o=this.OBJECT.exec(css))) {
- if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
-
- css=css.replace(this.OBJECT,'');
- sc.currentChain().addRule(o[1]);
- previous=this.oOBJECT;
-
- // Subpart - ::centreline
- } else if ((o=this.SUBPART.exec(css))) {
- if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
- css=css.replace(this.SUBPART,'');
- sc.currentChain().setSubpart(o[1]);
- previous=this.oSUBPART;
-
- // Declaration - {...}
- } else if ((o=this.DECLARATION.exec(css))) {
- css=css.replace(this.DECLARATION,'');
- sc.addStyles(this.parseDeclaration(o[1]));
- previous=this.oDECLARATION;
-
- // Unknown pattern
- } else if ((o=this.UNKNOWN.exec(css))) {
- css=css.replace(this.UNKNOWN,'');
- // console.log("unknown: "+o[1]);
-
- } else {
- // console.log("choked on "+css);
- return;
- }
- }
- if (previous==this.oDECLARATION) { this.saveChooser(sc); sc=new iD.styleparser.StyleChooser(); }
- if (this.callback) { this.callback(); }
- },
-
- saveChooser:function(sc) {
- this.choosers.push(sc);
- },
-
- parseDeclaration:function(s) {
- var styles=[];
- var t={};
- var o={};
- var k, v;
-
- // Create styles
- var ss = new iD.styleparser.ShapeStyle();
- var ps = new iD.styleparser.PointStyle();
- var ts = new iD.styleparser.TextStyle();
- var hs = new iD.styleparser.ShieldStyle();
- var xs = new iD.styleparser.InstructionStyle();
-
- var r=s.split(';');
- var isEval={};
- for (var i in r) {
- var a=r[i];
- if ((o=this.ASSIGNMENT_EVAL.exec(a))) { k=o[1].replace(this.DASH,'_'); t[k]=o[2]; isEval[k]=true; }
- else if ((o=this.ASSIGNMENT.exec(a))) { k=o[1].replace(this.DASH,'_'); t[k]=o[2]; }
- else if ((o=this.SET_TAG_EVAL.exec(a))) { } // xs.addSetTag(o[1],this.saveEval(o[2]));
- else if ((o=this.SET_TAG.exec(a))) { xs.addSetTag(o[1],o[2]); }
- else if ((o=this.SET_TAG_TRUE.exec(a))) { xs.addSetTag(o[1],true); }
- else if ((o=this.EXIT.exec(a))) { xs.setPropertyFromString('breaker',true); }
- }
-
- // Find sublayer
- var sub=5;
- if (t['z_index']) { sub=Number(t['z_index']); delete t['z_index']; }
- ss.sublayer=ps.sublayer=ts.sublayer=hs.sublayer=sub;
- xs.sublayer=10;
-
- // Find "interactive" property - it's true unless explicitly set false
- var inter=true;
- if (t['interactive']) { inter=t['interactive'].match(this.FALSE) ? false : true; delete t['interactive']; }
- ss.interactive=ps.interactive=ts.interactive=hs.interactive=xs.interactive=inter;
-
- // Munge special values
- // (we should stop doing this and do it in the style instead)
- if (t['font_weight'] ) { t['font_bold' ] = t['font_weight' ].match(this.BOLD ) ? true : false; delete t['font_weight']; }
- if (t['font_style'] ) { t['font_italic'] = t['font_style' ].match(this.ITALIC) ? true : false; delete t['font_style']; }
- if (t['text_decoration']) { t['font_underline'] = t['text_decoration'].match(this.UNDERLINE) ? true : false; delete t['text_decoration']; }
- if (t['text_position'] ) { t['text_center'] = t['text_position' ].match(this.CENTER) ? true : false; delete t['text_position']; }
- if (t['text_transform']) {
- if (t['text_transform'].match(this.CAPS)) { t['font_caps']=true; } else { t['font_caps']=false; }
- delete t['text_transform'];
- }
-
- // Assign each property to the appropriate style
- for (a in t) {
- // Parse properties
- // ** also do units, e.g. px/pt/m
- if (a.match(this.COLOR)) { v = this.parseCSSColor(t[a]); }
- else { v = t[a]; }
-
- // Set in styles
- if (ss.has(a)) { ss.setPropertyFromString(a,v,isEval[a]); }
- else if (ps.has(a)) { ps.setPropertyFromString(a,v,isEval[a]); }
- else if (ts.has(a)) { ts.setPropertyFromString(a,v,isEval[a]); }
- else if (hs.has(a)) { hs.setPropertyFromString(a,v,isEval[a]); }
- else {
- // console.log(a+" not found");
- }
- }
-
- // Add each style to list
- if (ss.edited) { styles.push(ss); }
- if (ps.edited) { styles.push(ps); }
- if (ts.edited) { styles.push(ts); }
- if (hs.edited) { styles.push(hs); }
- if (xs.edited) { styles.push(xs); }
- return styles;
- },
-
- parseZoom:function(s) {
- var o={};
- if ((o=this.ZOOM_MINMAX.exec(s))) { return [o[1],o[2]]; }
- else if ((o=this.ZOOM_MIN.exec(s) )) { return [o[1], maxscale]; }
- else if ((o=this.ZOOM_MAX.exec(s) )) { return [minscale, o[1]]; }
- else if ((o=this.ZOOM_SINGLE.exec(s))) { return [o[1],o[1]]; }
- return null;
- },
-
- parseCondition:function(s) {
- var o={};
- if ((o=this.CONDITION_TRUE.exec(s))) { return new iD.styleparser.Condition('true' ,o[1]); }
- else if ((o=this.CONDITION_FALSE.exec(s))) { return new iD.styleparser.Condition('false',o[1]); }
- else if ((o=this.CONDITION_SET.exec(s))) { return new iD.styleparser.Condition('set' ,o[1]); }
- else if ((o=this.CONDITION_UNSET.exec(s))) { return new iD.styleparser.Condition('unset',o[1]); }
- else if ((o=this.CONDITION_NE.exec(s))) { return new iD.styleparser.Condition('ne' ,o[1],o[2]); }
- else if ((o=this.CONDITION_GT.exec(s))) { return new iD.styleparser.Condition('>' ,o[1],o[2]); }
- else if ((o=this.CONDITION_GE.exec(s))) { return new iD.styleparser.Condition('>=' ,o[1],o[2]); }
- else if ((o=this.CONDITION_LT.exec(s))) { return new iD.styleparser.Condition('<' ,o[1],o[2]); }
- else if ((o=this.CONDITION_LE.exec(s))) { return new iD.styleparser.Condition('<=' ,o[1],o[2]); }
- else if ((o=this.CONDITION_REGEX.exec(s))) { return new iD.styleparser.Condition('regex',o[1],o[2]); }
- else if ((o=this.CONDITION_EQ.exec(s))) { return new iD.styleparser.Condition('eq' ,o[1],o[2]); }
- return null;
- },
-
- parseCSSColor:function(colorStr) {
- colorStr = colorStr.toLowerCase();
- if (this.CSSCOLORS[colorStr]) {
- return this.CSSCOLORS[colorStr];
- } else {
- var match = this.HEX.exec(colorStr);
- if ( match ) {
- if ( match[1].length == 3) {
- // repeat digits. #abc => 0xaabbcc
- return Number("0x"+match[1].charAt(0)+match[1].charAt(0)+
- match[1].charAt(1)+match[1].charAt(1)+
- match[1].charAt(2)+match[1].charAt(2));
- } else if ( match[1].length == 6) {
- return Number("0x"+match[1]);
- } else {
- return Number("0x000000"); //as good as any
- }
- }
- }
- return 0;
- },
-
- // Regular expression tests and other constants
-
- WHITESPACE :/^\s+/,
- COMMENT :/^\/\*.+?\*\/\s*/,
- CLASS :/^([\.:]\w+)\s*/,
- NOT_CLASS :/^!([\.:]\w+)\s*/,
- ZOOM :/^\|\s*z([\d\-]+)\s*/i,
- GROUP :/^,\s*/i,
- CONDITION :/^\[(.+?)\]\s*/,
- OBJECT :/^(\w+)\s*/,
- DECLARATION :/^\{(.+?)\}\s*/,
- SUBPART :/^::(\w+)\s*/,
- UNKNOWN :/^(\S+)\s*/,
-
- ZOOM_MINMAX :/^(\d+)\-(\d+)$/,
- ZOOM_MIN :/^(\d+)\-$/,
- ZOOM_MAX :/^\-(\d+)$/,
- ZOOM_SINGLE :/^(\d+)$/,
-
- CONDITION_TRUE :/^\s*([:\w]+)\s*=\s*yes\s*$/i,
- CONDITION_FALSE :/^\s*([:\w]+)\s*=\s*no\s*$/i,
- CONDITION_SET :/^\s*([:\w]+)\s*$/,
- CONDITION_UNSET :/^\s*!([:\w]+)\s*$/,
- CONDITION_EQ :/^\s*([:\w]+)\s*=\s*(.+)\s*$/,
- CONDITION_NE :/^\s*([:\w]+)\s*!=\s*(.+)\s*$/,
- CONDITION_GT :/^\s*([:\w]+)\s*>\s*(.+)\s*$/,
- CONDITION_GE :/^\s*([:\w]+)\s*>=\s*(.+)\s*$/,
- CONDITION_LT :/^\s*([:\w]+)\s*<\s*(.+)\s*$/,
- CONDITION_LE :/^\s*([:\w]+)\s*<=\s*(.+)\s*$/,
- CONDITION_REGEX :/^\s*([:\w]+)\s*=~\/\s*(.+)\/\s*$/,
-
- ASSIGNMENT_EVAL :/^\s*(\S+)\s*\:\s*eval\s*\(\s*'(.+?)'\s*\)\s*$/i,
- ASSIGNMENT :/^\s*(\S+)\s*\:\s*(.+?)\s*$/,
- SET_TAG_EVAL :/^\s*set\s+(\S+)\s*=\s*eval\s*\(\s*'(.+?)'\s*\)\s*$/i,
- SET_TAG :/^\s*set\s+(\S+)\s*=\s*(.+?)\s*$/i,
- SET_TAG_TRUE :/^\s*set\s+(\S+)\s*$/i,
- EXIT :/^\s*exit\s*$/i,
-
- oZOOM: 2,
- oGROUP: 3,
- oCONDITION: 4,
- oOBJECT: 5,
- oDECLARATION: 6,
- oSUBPART: 7,
-
- DASH: /\-/g,
- COLOR: /color$/,
- BOLD: /^bold$/i,
- ITALIC: /^italic|oblique$/i,
- UNDERLINE: /^underline$/i,
- CAPS: /^uppercase$/i,
- CENTER: /^center$/i,
- FALSE: /^(no|false|0)$/i,
-
- HEX: /^#([0-9a-f]+)$/i,
-
- CSSCOLORS: {
- aliceblue:0xf0f8ff,
- antiquewhite:0xfaebd7,
- aqua:0x00ffff,
- aquamarine:0x7fffd4,
- azure:0xf0ffff,
- beige:0xf5f5dc,
- bisque:0xffe4c4,
- black:0x000000,
- blanchedalmond:0xffebcd,
- blue:0x0000ff,
- blueviolet:0x8a2be2,
- brown:0xa52a2a,
- burlywood:0xdeb887,
- cadetblue:0x5f9ea0,
- chartreuse:0x7fff00,
- chocolate:0xd2691e,
- coral:0xff7f50,
- cornflowerblue:0x6495ed,
- cornsilk:0xfff8dc,
- crimson:0xdc143c,
- cyan:0x00ffff,
- darkblue:0x00008b,
- darkcyan:0x008b8b,
- darkgoldenrod:0xb8860b,
- darkgray:0xa9a9a9,
- darkgreen:0x006400,
- darkkhaki:0xbdb76b,
- darkmagenta:0x8b008b,
- darkolivegreen:0x556b2f,
- darkorange:0xff8c00,
- darkorchid:0x9932cc,
- darkred:0x8b0000,
- darksalmon:0xe9967a,
- darkseagreen:0x8fbc8f,
- darkslateblue:0x483d8b,
- darkslategray:0x2f4f4f,
- darkturquoise:0x00ced1,
- darkviolet:0x9400d3,
- deeppink:0xff1493,
- deepskyblue:0x00bfff,
- dimgray:0x696969,
- dodgerblue:0x1e90ff,
- firebrick:0xb22222,
- floralwhite:0xfffaf0,
- forestgreen:0x228b22,
- fuchsia:0xff00ff,
- gainsboro:0xdcdcdc,
- ghostwhite:0xf8f8ff,
- gold:0xffd700,
- goldenrod:0xdaa520,
- gray:0x808080,
- green:0x008000,
- greenyellow:0xadff2f,
- honeydew:0xf0fff0,
- hotpink:0xff69b4,
- indianred:0xcd5c5c,
- indigo:0x4b0082,
- ivory:0xfffff0,
- khaki:0xf0e68c,
- lavender:0xe6e6fa,
- lavenderblush:0xfff0f5,
- lawngreen:0x7cfc00,
- lemonchiffon:0xfffacd,
- lightblue:0xadd8e6,
- lightcoral:0xf08080,
- lightcyan:0xe0ffff,
- lightgoldenrodyellow:0xfafad2,
- lightgrey:0xd3d3d3,
- lightgreen:0x90ee90,
- lightpink:0xffb6c1,
- lightsalmon:0xffa07a,
- lightseagreen:0x20b2aa,
- lightskyblue:0x87cefa,
- lightslategray:0x778899,
- lightsteelblue:0xb0c4de,
- lightyellow:0xffffe0,
- lime:0x00ff00,
- limegreen:0x32cd32,
- linen:0xfaf0e6,
- magenta:0xff00ff,
- maroon:0x800000,
- mediumaquamarine:0x66cdaa,
- mediumblue:0x0000cd,
- mediumorchid:0xba55d3,
- mediumpurple:0x9370d8,
- mediumseagreen:0x3cb371,
- mediumslateblue:0x7b68ee,
- mediumspringgreen:0x00fa9a,
- mediumturquoise:0x48d1cc,
- mediumvioletred:0xc71585,
- midnightblue:0x191970,
- mintcream:0xf5fffa,
- mistyrose:0xffe4e1,
- moccasin:0xffe4b5,
- navajowhite:0xffdead,
- navy:0x000080,
- oldlace:0xfdf5e6,
- olive:0x808000,
- olivedrab:0x6b8e23,
- orange:0xffa500,
- orangered:0xff4500,
- orchid:0xda70d6,
- palegoldenrod:0xeee8aa,
- palegreen:0x98fb98,
- paleturquoise:0xafeeee,
- palevioletred:0xd87093,
- papayawhip:0xffefd5,
- peachpuff:0xffdab9,
- peru:0xcd853f,
- pink:0xffc0cb,
- plum:0xdda0dd,
- powderblue:0xb0e0e6,
- purple:0x800080,
- red:0xff0000,
- rosybrown:0xbc8f8f,
- royalblue:0x4169e1,
- saddlebrown:0x8b4513,
- salmon:0xfa8072,
- sandybrown:0xf4a460,
- seagreen:0x2e8b57,
- seashell:0xfff5ee,
- sienna:0xa0522d,
- silver:0xc0c0c0,
- skyblue:0x87ceeb,
- slateblue:0x6a5acd,
- slategray:0x708090,
- snow:0xfffafa,
- springgreen:0x00ff7f,
- steelblue:0x4682b4,
- tan:0xd2b48c,
- teal:0x008080,
- thistle:0xd8bfd8,
- tomato:0xff6347,
- turquoise:0x40e0d0,
- violet:0xee82ee,
- wheat:0xf5deb3,
- white:0xffffff,
- whitesmoke:0xf5f5f5,
- yellow:0xffff00,
- yellowgreen:0x9acd32 },
-
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
diff --git a/js/iD/styleparser/Style.js b/js/iD/styleparser/Style.js
deleted file mode 100755
index 4bde63d76..000000000
--- a/js/iD/styleparser/Style.js
+++ /dev/null
@@ -1,240 +0,0 @@
-// iD/styleparser/Style.js
-
-define(['dojo/_base/declare','dojo/_base/array'], function(declare,array){
-
-// ----------------------------------------------------------------------
-// Style base class
-// fillStyler not done for text yet
-
-declare("iD.styleparser.Style", null, {
- merged: false,
- edited: false,
- sublayer: 5,
- interactive: true,
- properties: [],
- styleType: 'Style',
- evals: null,
-
- constructor: function() {
- // summary: Base class for a set of painting attributes, into which the CSS declaration is parsed.
- this.evals = {};
- },
-
- drawn: function() {
- return false;
- },
-
- has: function(k) {
- return this.properties.indexOf(k)>-1;
- },
-
- mergeWith: function(additional) {
- for (var prop in this.properties) {
- if (additional[prop]) {
- this[prop]=additional[prop];
- }
- }
- this.merged=true;
- },
-
- setPropertyFromString: function(k,v,isEval) {
- this.edited=true;
- if (isEval) { this.evals[k]=v; return; }
-
- if (typeof(this[k])=='boolean') {
- v=Boolean(v);
- } else if (typeof(this[k])=='number') {
- v=Number(v);
- } else if (this[k] && this[k].constructor==Array) {
- v = v.split(',').map(function(a) { return Number(a); });
- }
- this[k]=v;
- return true;
- },
-
- runEvals: function(tags) {
- for (var k in this.evals) {
- this.setPropertyFromString(k,eval("with (tags) {"+this.evals[k]+"}"),false);
- }
- },
-
- dojoColor: function(rgb,a) {
- var b=rgb % 256;
- var g=(rgb-b) % 65536;
- var r=(rgb-b-g) % 16777216;
- return new dojo.Color([r/65536,g/256,b,a]);
- },
-
- toString: function() {
- var str = '';
- for (var k in this.properties) {
- if (this.hasOwnProperty(k)) { str+=k+"="+this[k]+"; "; }
- }
- return str;
- }
-});
-
-
-// ----------------------------------------------------------------------
-// InstructionStyle class
-
-declare("iD.styleparser.InstructionStyle", [iD.styleparser.Style], {
- set_tags: null,
- breaker: false,
- styleType: 'InstructionStyle',
- addSetTag: function(k,v) {
- this.edited=true;
- if (!this.set_tags) this.set_tags={};
- this.set_tags[k]=v;
- }
-});
-
-// ----------------------------------------------------------------------
-// PointStyle class
-
-declare("iD.styleparser.PointStyle", [iD.styleparser.Style], {
- properties: ['icon_image','icon_width','icon_height','rotation'],
- icon_image: null,
- icon_width: 0,
- icon_height: NaN,
- rotation: NaN,
- styleType: 'PointStyle',
- drawn:function() {
- return (this.icon_image !== null);
- },
- maxwidth:function() {
- return this.evals.icon_width ? 0 : this.icon_width;
- }
-});
-
-// ----------------------------------------------------------------------
-// ShapeStyle class
-
-declare("iD.styleparser.ShapeStyle", [iD.styleparser.Style], {
- properties: ['width','color','opacity','dashes','linecap','linejoin','line_style',
- 'fill_image','fill_color','fill_opacity','casing_width','casing_color','casing_opacity','casing_dashes','layer'],
-
- width:0, color:NaN, opacity:NaN, dashes:[],
- linecap:null, linejoin:null, line_style:null,
- fill_image:null, fill_color:NaN, fill_opacity:NaN,
- casing_width:NaN, casing_color:NaN, casing_opacity:NaN, casing_dashes:[],
-
- layer:NaN, // optional layer override (usually set by OSM tag)
- styleType: 'ShapeStyle',
-
- drawn:function() {
- return (this.fill_image || !isNaN(this.fill_color) || this.width || this.casing_width);
- },
- maxwidth:function() {
- // If width is set by an eval, then we can't use it to calculate maxwidth, or it'll just grow on each invocation...
- if (this.evals.width || this.evals.casing_width) { return 0; }
- return (this.width + (this.casing_width ? this.casing_width*2 : 0));
- },
- strokeStyler:function() {
- var cap,join;
- switch (this.linecap ) { case 'round': cap ='round'; break; case 'square': cap='square'; break; default: cap ='butt' ; break; }
- switch (this.linejoin) { case 'bevel': join='bevel'; break; case 'miter' : join=4 ; break; default: join='round'; break; }
- return {
- color: this.dojoColor(this.color ? this.color : 0, this.opacity ? this.opacity : 1),
- style: 'Solid', // needs to parse dashes
- width: this.width,
- cap: cap,
- join: join
- };
- },
- shapeStrokeStyler:function() {
- if (isNaN(this.casing_color)) { return { width:0 }; }
- return {
- color: this.dojoColor(this.casing_color, this.casing_opacity ? this.casing_opacity : 1),
- width: this.casing_width ? this.casing_width : 1
- };
- },
- shapeFillStyler:function() {
- if (isNaN(this.color)) { return null; }
- return this.dojoColor(this.color, this.opacity ? this.opacity : 1);
- },
- fillStyler:function() {
- return this.dojoColor(this.fill_color, this.fill_opacity ? this.fill_opacity : 1);
- },
- casingStyler:function() {
- var cap,join;
- switch (this.linecap ) { case 'round': cap ='round'; break; case 'square': cap='square'; break; default: cap ='butt' ; break; }
- switch (this.linejoin) { case 'bevel': join='bevel'; break; case 'miter' : join=4 ; break; default: join='round'; break; }
- return {
- color: this.dojoColor(this.casing_color ? this.casing_color : 0, this.casing_opacity ? this.casing_opacity : 1),
- width: this.width+this.casing_width*2,
- style: 'Solid',
- cap: cap,
- join: join
- };
- }
-});
-
-// ----------------------------------------------------------------------
-// TextStyle class
-
-declare("iD.styleparser.TextStyle", [iD.styleparser.Style], {
-
- properties: ['font_family','font_bold','font_italic','font_caps','font_underline','font_size',
- 'text_color','text_offset','max_width',
- 'text','text_halo_color','text_halo_radius','text_center',
- 'letter_spacing'],
-
- font_family: null,
- font_bold: false,
- font_italic: false,
- font_underline: false,
- font_caps: false,
- font_size: NaN,
- text_color: NaN,
- text_offset: NaN,
- max_width: NaN,
- text: null,
- text_halo_color: NaN,
- text_halo_radius: 0,
- text_center: true,
- letter_spacing: 0,
- styleType: 'TextStyle',
-
- drawn: function() {
- return (this.text !== null);
- },
- fontStyler:function() {
- return {
- family: this.font_family ? this.font_family : 'Arial',
- size: this.font_size ? this.font_size*2 : '10px' ,
- weight: this.font_bold ? 'bold' : 'normal',
- style: this.font_italic ? 'italic' : 'normal'
- };
- },
- textStyler:function(_text) {
- return {
- decoration: this.font_underline ? 'underline' : 'none',
- align: 'middle',
- text: _text
- };
- },
- fillStyler:function() {
- // not implemented yet
- return this.dojoColor(0,1);
- }
- // getTextFormat, getHaloFilter, writeNameLabel
-});
-
-// ----------------------------------------------------------------------
-// ShieldStyle class
-
-declare("iD.styleparser.ShieldStyle", [iD.styleparser.Style], {
- properties: ['shield_image','shield_width','shield_height'],
- shield_image: null,
- shield_width: NaN,
- shield_height: NaN,
- styleType: 'ShieldStyle',
- drawn:function() {
- return (shield_image !== null);
- }
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
diff --git a/js/iD/styleparser/StyleChooser.js b/js/iD/styleparser/StyleChooser.js
deleted file mode 100755
index 8b856f2b8..000000000
--- a/js/iD/styleparser/StyleChooser.js
+++ /dev/null
@@ -1,87 +0,0 @@
-// iD/styleparser/StyleChooser.js
-
-define(['dojo/_base/declare','dojo/_base/lang','iD/styleparser/RuleChain'], function(declare,lang){
-
-declare("iD.styleparser.StyleChooser", null, {
-
- // UpdateStyles doesn't support image-widths yet
- // or setting maxwidth/_width
-
- ruleChains:[], // array of RuleChains (each one an array of Rules)
- styles:[], // array of ShapeStyle/ShieldStyle/TextStyle/PointStyle
- zoomSpecific:false, // are any of the rules zoom-specific?
-
- rcpos:0,
- stylepos:0,
-
- constructor:function() {
- // summary: A combination of the selectors (ruleChains) and declaration (styles).
- // For example, way[highway=footway] node[barrier=gate] { icon: gate.png; } is one StyleChooser.
- this.ruleChains=[new iD.styleparser.RuleChain()];
- this.styles=[];
- },
-
- currentChain:function() {
- return this.ruleChains[this.ruleChains.length-1];
- },
-
- newRuleChain:function() {
- // summary: Starts a new ruleChain in this.ruleChains.
- if (this.ruleChains[this.ruleChains.length-1].length()>0) {
- this.ruleChains.push(new iD.styleparser.RuleChain());
- }
- },
-
- addStyles:function(a) {
- this.styles=this.styles.concat(a);
- },
-
- updateStyles:function(entity, tags, sl, zoom) {
- if (this.zoomSpecific) { sl.validAt=zoom; }
-
- // Are any of the ruleChains fulfilled?
- var w;
- for (var i in this.ruleChains) {
- var c=this.ruleChains[i];
- if (c.test(-1, entity, tags, zoom)) {
- sl.addSubpart(c.subpart);
-
- // Update StyleList
- for (var j in this.styles) {
- var r=this.styles[j];
- var a;
- switch (r.styleType) {
-
- case 'ShapeStyle' : sl.maxwidth=Math.max(sl.maxwidth,r.maxwidth());
- a=sl.shapeStyles; break;
- case 'ShieldStyle': a=sl.shieldStyles; break;
- case 'TextStyle' : a=sl.textStyles; break;
- case 'PointStyle' : sl.maxwidth=Math.max(sl.maxwidth,r.maxwidth());
- a=sl.pointStyles; break;
- case 'InstructionStyle':
- if (InstructionStyle(r).breaker) { return; }
- for (var k in InstructionStyle(r).set_tags) { tags[k]=InstructionStyle(r).set_tags[k]; }
- break;
- }
- if (r.drawn) { tags[':drawn']='yes'; }
- tags._width = sl.maxwidth;
-
- r.runEvals(tags);
- if (a[c.subpart]) {
- // If there's already a style on this sublayer, then merge them
- // (making a deep copy if necessary to avoid altering the root style)
- if (!a[c.subpart].merged) { a[c.subpart]=lang.clone(a[c.subpart]); }
- a[c.subpart].mergeWith(r);
- } else {
- // Otherwise, just assign it
- a[c.subpart]=r;
- }
- }
- }
- }
- }
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
diff --git a/js/iD/styleparser/StyleList.js b/js/iD/styleparser/StyleList.js
deleted file mode 100755
index e9bc441b7..000000000
--- a/js/iD/styleparser/StyleList.js
+++ /dev/null
@@ -1,81 +0,0 @@
-// iD/styleparser/StyleList.js
-
-define(['dojo/_base/declare'], function(declare){
-
-// ----------------------------------------------------------------------
-// StyleList class
-
-
-declare("iD.styleparser.StyleList", null, {
-
- shapeStyles: {},
- textStyles: {},
- pointStyles: {},
- shieldStyles: {},
- maxwidth: 0,
- subparts: [], // List of subparts used in this StyleList
- validAt: -1, // Zoom level this is valid at (or -1 at all levels - saves recomputing)
-
- constructor:function() {
- // summary: A StyleList object is the full list of all styles applied to
- // a drawn entity (i.e. node/way). Each array element applies to that
- // sublayer (z-index). If there is no element, nothing is drawn on that sublayer.
- // StyleLists are created by StyleChooser.getStyles.
- this.shapeStyles={};
- this.textStyles={};
- this.pointStyles={};
- this.shieldStyles={};
- this.subparts=[];
- },
-
- hasStyles:function() {
- // summary: Does this StyleList contain any styles?
- return (this.hasShapeStyles() || this.hasTextStyles() || this.hasPointStyles() || this.hasShieldStyles());
- },
-
- hasFills:function() {
- // summary: Does this StyleList contain any styles with a fill?
- for (var s in this.shapeStyles) {
- if (!isNaN(this.shapeStyles(s).fill_color) || this.shapeStyles(s).fill_image) return true;
- }
- return false;
- },
-
- layerOverride:function() {
- // summary: If this StyleList manually forces an OSM layer, return it, otherwise null.
- for (var s in this.shapeStyles) {
- if (!isNaN(this.shapeStyles[s].layer)) return this.shapeStyles[s].layer;
- }
- return NaN;
- },
-
- addSubpart:function(s) {
- // summary: Record that a subpart is used in this StyleList.
- if (this.subparts.indexOf(s)==-1) { this.subparts.push(s); }
- },
-
- isValidAt:function(zoom) {
- // summary: Is this StyleList valid at a given zoom?
- return (this.validAt==-1 || this.validAt==zoom);
- },
-
- toString:function() {
- // summary: Summarise StyleList as String - for debugging
- var str = '';
- var k;
- for (k in this.shapeStyles ) { str+="- SS "+k+"="+this.shapeStyles[k]+"\n"; }
- for (k in this.textStyles ) { str+="- TS "+k+"="+this.textStyles[k]+"\n"; }
- for (k in this.pointStyles ) { str+="- PS "+k+"="+this.pointStyles[k]+"\n"; }
- for (k in this.shieldStyles) { str+="- sS "+k+"="+this.shieldStyles[k]+"\n"; }
- return str;
- },
-
- hasShapeStyles:function() { for (var a in shapeStyles ) { return true; } return false; },
- hasTextStyles:function() { for (var a in textStyles ) { return true; } return false; },
- hasPointStyles:function() { for (var a in pointStyles ) { return true; } return false; },
- hasShieldStyles:function() { for (var a in shieldStyles) { return true; } return false; }
-});
-
-// ----------------------------------------------------------------------
-// End of module
-});
diff --git a/js/lib/d3.v2.min.js b/js/lib/d3.v2.min.js
new file mode 100644
index 000000000..0b4ea58fd
--- /dev/null
+++ b/js/lib/d3.v2.min.js
@@ -0,0 +1,4 @@
+(function(){function e(e,t){try{for(var n in t)Object.defineProperty(e.prototype,n,{value:t[n],enumerable:!1})}catch(r){e.prototype=t}}function t(e){var t=-1,n=e.length,r=[];while(++t=0?e.substring(t):(t=e.length,""),r=[];while(t>0)r.push(e.substring(t-=3,t+3));return r.reverse().join(",")+n}function b(e,t){var n=Math.pow(10,Math.abs(8-t)*3);return{scale:t>8?function(e){return e/n}:function(e){return e*n},symbol:e}}function w(e){return function(t){return t<=0?0:t>=1?1:e(t)}}function E(e){return function(t){return 1-e(1-t)}}function S(e){return function(t){return.5*(t<.5?e(2*t):2-e(2-2*t))}}function x(e){return e}function T(e){return function(t){return Math.pow(t,e)}}function N(e){return 1-Math.cos(e*Math.PI/2)}function C(e){return Math.pow(2,10*(e-1))}function k(e){return 1-Math.sqrt(1-e*e)}function L(e,t){var n;return arguments.length<2&&(t=.45),arguments.length<1?(e=1,n=t/4):n=t/(2*Math.PI)*Math.asin(1/e),function(r){return 1+e*Math.pow(2,10*-r)*Math.sin((r-n)*2*Math.PI/t)}}function A(e){return e||(e=1.70158),function(t){return t*t*((e+1)*t-e)}}function O(e){return e<1/2.75?7.5625*e*e:e<2/2.75?7.5625*(e-=1.5/2.75)*e+.75:e<2.5/2.75?7.5625*(e-=2.25/2.75)*e+.9375:7.5625*(e-=2.625/2.75)*e+.984375}function M(){d3.event.stopPropagation(),d3.event.preventDefault()}function _(){var e=d3.event,t;while(t=e.sourceEvent)e=t;return e}function D(e){var t=new d,n=0,r=arguments.length;while(++n360?e-=360:e<0&&(e+=360),e<60?s+(o-s)*e/60:e<180?o:e<240?s+(o-s)*(240-e)/60:s}function i(e){return Math.round(r(e)*255)}var s,o;return e%=360,e<0&&(e+=360),t=t<0?0:t>1?1:t,n=n<0?0:n>1?1:n,o=n<=.5?n*(1+t):n+t-n*t,s=2*n-o,U(i(e+120),i(e),i(e-120))}function Z(e,t,n){return new et(e,t,n)}function et(e,t,n){this.h=e,this.c=t,this.l=n}function tt(e,t,n){return nt(n,Math.cos(e*=Math.PI/180)*t,Math.sin(e)*t)}function nt(e,t,n){return new rt(e,t,n)}function rt(e,t,n){this.l=e,this.a=t,this.b=n}function it(e,t,n){var r=(e+16)/116,i=r+t/500,s=r-n/200;return i=ot(i)*ys,r=ot(r)*bs,s=ot(s)*ws,U(at(3.2404542*i-1.5371385*r-.4985314*s),at(-0.969266*i+1.8760108*r+.041556*s),at(.0556434*i-.2040259*r+1.0572252*s))}function st(e,t,n){return Z(Math.atan2(n,t)/Math.PI*180,Math.sqrt(t*t+n*n),e)}function ot(e){return e>.206893034?e*e*e:(e-4/29)/7.787037}function ut(e){return e>.008856?Math.pow(e,1/3):7.787037*e+4/29}function at(e){return Math.round(255*(e<=.00304?12.92*e:1.055*Math.pow(e,1/2.4)-.055))}function ft(e){return Qi(e,ks),e}function lt(e){return function(){return Ss(e,this)}}function ct(e){return function(){return xs(e,this)}}function ht(e,t){function n(){this.removeAttribute(e)}function r(){this.removeAttributeNS(e.space,e.local)}function i(){this.setAttribute(e,t)}function s(){this.setAttributeNS(e.space,e.local,t)}function o(){var n=t.apply(this,arguments);n==null?this.removeAttribute(e):this.setAttribute(e,n)}function u(){var n=t.apply(this,arguments);n==null?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}return e=d3.ns.qualify(e),t==null?e.local?r:n:typeof t=="function"?e.local?u:o:e.local?s:i}function pt(e){return new RegExp("(?:^|\\s+)"+d3.requote(e)+"(?:\\s+|$)","g")}function dt(e,t){function n(){var n=-1;while(++n0&&(e=e.substring(0,o)),t?i:r}function St(e,t){for(var n=0,r=e.length;nt?c():(v.active=t,i.forEach(function(t,n){(n=n.call(e,m,u))&&h.push(n)}),s.start.call(e,m,u),l(r)||d3.timer(l,0,n),1)}function l(n){if(v.active!==t)return c();var r=(n-p)/d,i=o(r),a=h.length;while(a>0)h[--a].call(e,i);if(r>=1)return c(),_s=t,s.end.call(e,m,u),_s=0,1}function c(){return--v.count||delete e.__transition__,1}var h=[],p=e.delay,d=e.duration,v=(e=e.node).__transition__||(e.__transition__={active:0,count:0}),m=e.__data__;++v.count,p<=r?f(r):d3.timer(f,p,n)})},0,n),e}function Nt(e){var t=_s,n=Fs,r=Bs,i=js;return _s=this.id,Fs=this.ease(),St(this,function(t,n,r){Bs=t.delay,js=t.duration,e.call(t=t.node,t.__data__,n,r)}),_s=t,Fs=n,Bs=r,js=i,this}function Ct(e,t,n){return n!=""&&Is}function kt(e,t){return d3.tween(e,F(t))}function Lt(){var e,t=Date.now(),n=Us;while(n)e=t-n.then,e>=n.delay&&(n.flush=n.callback(e)),n=n.next;var r=At()-t;r>24?(isFinite(r)&&(clearTimeout(Ws),Ws=setTimeout(Lt,r)),zs=0):(zs=1,Xs(Lt))}function At(){var e=null,t=Us,n=Infinity;while(t)t.flush?(delete Rs[t.callback.id],t=e?e.next=t.next:Us=t.next):(n=Math.min(n,t.then+t.delay),t=(e=t).next);return n}function Ot(e,t){var n=e.ownerSVGElement||e;if(n.createSVGPoint){var r=n.createSVGPoint();if(Vs<0&&(window.scrollX||window.scrollY)){n=d3.select(document.body).append("svg").style("position","absolute").style("top",0).style("left",0);var i=n[0][0].getScreenCTM();Vs=!i.f&&!i.e,n.remove()}return Vs?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(e.getScreenCTM().inverse()),[r.x,r.y]}var s=e.getBoundingClientRect();return[t.clientX-s.left-e.clientLeft,t.clientY-s.top-e.clientTop]}function Mt(){}function _t(e){var t=e[0],n=e[e.length-1];return t2?zt:Ut,a=r?q:I;return o=i(e,t,a,n),u=i(t,e,a,d3.interpolate),s}function s(e){return o(e)}var o,u;return s.invert=function(e){return u(e)},s.domain=function(t){return arguments.length?(e=t.map(Number),i()):e},s.range=function(e){return arguments.length?(t=e,i()):t},s.rangeRound=function(e){return s.range(e).interpolate(d3.interpolateRound)},s.clamp=function(e){return arguments.length?(r=e,i()):r},s.interpolate=function(e){return arguments.length?(n=e,i()):n},s.ticks=function(t){return qt(e,t)},s.tickFormat=function(t){return Rt(e,t)},s.nice=function(){return Pt(e,Ft),i()},s.copy=function(){return Bt(e,t,n,r)},i()}function jt(e,t){return d3.rebind(e,t,"range","rangeRound","interpolate","clamp")}function Ft(e){return e=Math.pow(10,Math.round(Math.log(e)/Math.LN10)-1),e&&{floor:function(t){return Math.floor(t/e)*e},ceil:function(t){return Math.ceil(t/e)*e}}}function It(e,t){var n=_t(e),r=n[1]-n[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),s=t/r*i;return s<=.15?i*=10:s<=.35?i*=5:s<=.75&&(i*=2),n[0]=Math.ceil(n[0]/i)*i,n[1]=Math.floor(n[1]/i)*i+i*.5,n[2]=i,n}function qt(e,t){return d3.range.apply(d3,It(e,t))}function Rt(e,t){return d3.format(",."+Math.max(0,-Math.floor(Math.log(It(e,t)[2])/Math.LN10+.01))+"f")}function Ut(e,t,n,r){var i=n(e[0],e[1]),s=r(t[0],t[1]);return function(e){return s(i(e))}}function zt(e,t,n,r){var i=[],s=[],o=0,u=Math.min(e.length,t.length)-1;e[u]0;f--)i.push(r(s)*f)}else{for(;sa;o--);i=i.slice(s,o)}return i},n.tickFormat=function(e,i){arguments.length<2&&(i=$s);if(arguments.length<1)return i;var s=Math.max(.1,e/n.ticks().length),o=t===Vt?(u=-1e-12,Math.floor):(u=1e-12,Math.ceil),u;return function(e){return e/r(o(t(e)+u))<=s?i(e):""}},n.copy=function(){return Wt(e.copy(),t)},jt(n,e)}function Xt(e){return Math.log(e<0?0:e)/Math.LN10}function Vt(e){return-Math.log(e>0?0:-e)/Math.LN10}function $t(e,t){function n(t){return e(r(t))}var r=Jt(t),i=Jt(1/t);return n.invert=function(t){return i(e.invert(t))},n.domain=function(t){return arguments.length?(e.domain(t.map(r)),n):e.domain().map(i)},n.ticks=function(e){return qt(n.domain(),e)},n.tickFormat=function(e){return Rt(n.domain(),e)},n.nice=function(){return n.domain(Pt(n.domain(),Ft))},n.exponent=function(e){if(!arguments.length)return t;var s=n.domain();return r=Jt(t=e),i=Jt(1/t),n.domain(s)},n.copy=function(){return $t(e.copy(),t)},jt(n,e)}function Jt(e){return function(t){return t<0?-Math.pow(-t,e):Math.pow(t,e)}}function Kt(e,t){function n(t){return o[((s.get(t)||s.set(t,e.push(t)))-1)%o.length]}function i(t,n){return d3.range(e.length).map(function(e){return t+n*e})}var s,o,u;return n.domain=function(i){if(!arguments.length)return e;e=[],s=new r;var o=-1,u=i.length,a;while(++o1){u=t[1],s=e[a],a++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(s[0]-u[0])+","+(s[1]-u[1])+","+s[0]+","+s[1];for(var f=2;f9&&(s=n*3/Math.sqrt(s),o[u]=s*r,o[u+1]=s*i));u=-1;while(++u<=a)s=(e[Math.min(a,u+1)][0]-e[Math.max(0,u-1)][0])/(6*(1+o[u]*o[u])),t.push([s||0,o[u]*s||0]);return t}function Cn(e){return e.length<3?an(e):e[0]+vn(e,Nn(e))}function kn(e){var t,n=-1,r=e.length,i,s;while(++n1){var r=_t(e.domain()),i,s=-1,o=t.length,u=(t[1]-t[0])/++n,a,f;while(++s0;)(f=+t[s]-a*u)>=r[0]&&i.push(f);for(--s,a=0;++ar&&(n=t,r=i);return n}function sr(e){return e.reduce(or,0)}function or(e,t){return e+t[1]}function ur(e,t){return ar(e,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ar(e,t){var n=-1,r=+e[0],i=(e[1]-r)/t,s=[];while(++n<=t)s[n]=i*n+r;return s}function fr(e){return[d3.min(e),d3.max(e)]}function lr(e,t){return d3.rebind(e,t,"sort","children","value"),e.links=dr,e.nodes=function(t){return vo=!0,(e.nodes=e)(t)},e}function cr(e){return e.children}function hr(e){return e.value}function pr(e,t){return t.value-e.value}function dr(e){return d3.merge(e.map(function(e){return(e.children||[]).map(function(t){return{source:e,target:t}})}))}function vr(e,t){return e.value-t.value}function mr(e,t){var n=e._pack_next;e._pack_next=t,t._pack_prev=e,t._pack_next=n,n._pack_prev=t}function gr(e,t){e._pack_next=t,t._pack_prev=e}function yr(e,t){var n=t.x-e.x,r=t.y-e.y,i=e.r+t.r;return i*i-n*n-r*r>.001}function br(e){function t(e){r=Math.min(e.x-e.r,r),i=Math.max(e.x+e.r,i),s=Math.min(e.y-e.r,s),o=Math.max(e.y+e.r,o)}if(!(n=e.children)||!(p=n.length))return;var n,r=Infinity,i=-Infinity,s=Infinity,o=-Infinity,u,a,f,l,c,h,p;n.forEach(wr),u=n[0],u.x=-u.r,u.y=0,t(u);if(p>1){a=n[1],a.x=a.r,a.y=0,t(a);if(p>2){f=n[2],xr(u,a,f),t(f),mr(u,f),u._pack_prev=f,mr(f,a),a=u._pack_next;for(l=3;l0&&(e=r)}return e}function _r(e,t){return e.x-t.x}function Dr(e,t){return t.x-e.x}function Pr(e,t){return e.depth-t.depth}function Hr(e,t){function n(e,r){var i=e.children;if(i&&(a=i.length)){var s,o=null,u=-1,a;while(++u=0)s=r[i]._tree,s.prelim+=t,s.mod+=t,t+=s.shift+(n+=s.change)}function jr(e,t,n){e=e._tree,t=t._tree;var r=n/(t.number-e.number);e.change+=r,t.change-=r,t.shift+=n,t.prelim+=n,t.mod+=n}function Fr(e,t,n){return e._tree.ancestor.parent==t.parent?e._tree.ancestor:n}function Ir(e){return{x:e.x,y:e.y,dx:e.dx,dy:e.dy}}function qr(e,t){var n=e.x+t[3],r=e.y+t[0],i=e.dx-t[1]-t[3],s=e.dy-t[0]-t[2];return i<0&&(n+=i/2,i=0),s<0&&(r+=s/2,s=0),{x:n,y:r,dx:i,dy:s}}function Rr(e,t){function n(e,r){d3.text(e,t,function(e){r(e&&n.parse(e))})}function r(t){return t.map(i).join(e)}function i(e){return o.test(e)?'"'+e.replace(/\"/g,'""')+'"':e}var s=new RegExp("\r\n|["+e+"\r\n]","g"),o=new RegExp('["'+e+"\n]"),u=e.charCodeAt(0);return n.parse=function(e){var t;return n.parseRows(e,function(e,n){if(n){var r={},i=-1,s=t.length;while(++i=e.length)return i;if(l)return l=!1,r;var t=s.lastIndex;if(e.charCodeAt(t)===34){var n=t;while(n++0}function si(e,t,n){return(n[0]-t[0])*(e[1]-t[1])<(n[1]-t[1])*(e[0]-t[0])}function oi(e,t,n,r){var i=e[0],s=t[0],o=n[0],u=r[0],a=e[1],f=t[1],l=n[1],c=r[1],h=i-o,p=s-i,d=u-o,v=a-l,m=f-a,g=c-l,y=(d*v-g*h)/(g*p-d*m);return[i+y*p,a+y*m]}function ui(e,t){var n={list:e.map(function(e,t){return{index:t,x:e[0],y:e[1]}}).sort(function(e,t){return e.yt.y?1:e.xt.x?1:0}),bottomSite:null},r={list:[],leftEnd:null,rightEnd:null,init:function(){r.leftEnd=r.createHalfEdge(null,"l"),r.rightEnd=r.createHalfEdge(null,"l"),r.leftEnd.r=r.rightEnd,r.rightEnd.l=r.leftEnd,r.list.unshift(r.leftEnd,r.rightEnd)},createHalfEdge:function(e,t){return{edge:e,side:t,vertex:null,l:null,r:null}},insert:function(e,t){t.l=e,t.r=e.r,e.r.l=t,e.r=t},leftBound:function(e){var t=r.leftEnd;do t=t.r;while(t!=r.rightEnd&&i.rightOf(t,e));return t=t.l,t},del:function(e){e.l.r=e.r,e.r.l=e.l,e.edge=null},right:function(e){return e.r},left:function(e){return e.l},leftRegion:function(e){return e.edge==null?n.bottomSite:e.edge.region[e.side]},rightRegion:function(e){return e.edge==null?n.bottomSite:e.edge.region[wo[e.side]]}},i={bisect:function(e,t){var n={region:{l:e,r:t},ep:{l:null,r:null}},r=t.x-e.x,i=t.y-e.y,s=r>0?r:-r,o=i>0?i:-i;return n.c=e.x*r+e.y*i+(r*r+i*i)*.5,s>o?(n.a=1,n.b=i/r,n.c/=r):(n.b=1,n.a=r/i,n.c/=i),n},intersect:function(e,t){var n=e.edge,r=t.edge;if(!n||!r||n.region.r==r.region.r)return null;var i=n.a*r.b-n.b*r.a;if(Math.abs(i)<1e-10)return null;var s=(n.c*r.b-r.c*n.b)/i,o=(r.c*n.a-n.c*r.a)/i,u=n.region.r,a=r.region.r,f,l;u.y=l.region.r.x;return c&&f.side==="l"||!c&&f.side==="r"?null:{x:s,y:o}},rightOf:function(e,t){var n=e.edge,r=n.region.r,i=t.x>r.x;if(i&&e.side==="l")return 1;if(!i&&e.side==="r")return 0;if(n.a===1){var s=t.y-r.y,o=t.x-r.x,u=0,a=0;!i&&n.b<0||i&&n.b>=0?a=u=s>=n.b*o:(a=t.x+t.y*n.b>n.c,n.b<0&&(a=!a),a||(u=1));if(!u){var f=r.x-n.region.l.x;a=n.b*(o*o-s*s)h*h+p*p}return e.side==="l"?a:!a},endPoint:function(e,n,r){e.ep[n]=r;if(!e.ep[wo[n]])return;t(e)},distance:function(e,t){var n=e.x-t.x,r=e.y-t.y;return Math.sqrt(n*n+r*r)}},s={list:[],insert:function(e,t,n){e.vertex=t,e.ystar=t.y+n;for(var r=0,i=s.list,o=i.length;ru.ystar||e.ystar==u.ystar&&t.x>u.vertex.x)continue;break}i.splice(r,0,e)},del:function(e){for(var t=0,n=s.list,r=n.length;td.y&&(v=p,p=d,d=v,b="r"),y=i.bisect(p,d),h=r.createHalfEdge(y,b),r.insert(l,h),i.endPoint(y,wo[b],g),m=i.intersect(l,h),m&&(s.del(l),s.insert(l,m,i.distance(m,p))),m=i.intersect(h,c),m&&s.insert(h,m,i.distance(m,p))}}for(a=r.right(r.leftEnd);a!=r.rightEnd;a=r.right(a))t(a.edge)}function ai(){return{leaf:!0,nodes:[],point:null}}function fi(e,t,n,r,i,s){if(!e(t,n,r,i,s)){var o=(n+i)*.5,u=(r+s)*.5,a=t.nodes;a[0]&&fi(e,a[0],n,r,o,u),a[1]&&fi(e,a[1],o,r,i,u),a[2]&&fi(e,a[2],n,u,o,s),a[3]&&fi(e,a[3],o,u,i,s)}}function li(e){return{x:e[0],y:e[1]}}function ci(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function hi(e){return e.substring(0,3)}function pi(e,t,n,r){var i,s,o=0,u=t.length,a=n.length;while(o=a)return-1;i=t.charCodeAt(o++);if(i==37){s=Uo[t.charAt(o++)];if(!s||(r=s(e,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}function di(e){return new RegExp("^(?:"+e.map(d3.requote).join("|")+")","i")}function vi(e){var t=new r,n=-1,i=e.length;while(++n68?1900:2e3)}function Ci(e,t,n){zo.lastIndex=0;var r=zo.exec(t.substring(n,n+2));return r?(e.m=r[0]-1,n+=r[0].length):-1}function ki(e,t,n){zo.lastIndex=0;var r=zo.exec(t.substring(n,n+2));return r?(e.d=+r[0],n+=r[0].length):-1}function Li(e,t,n){zo.lastIndex=0;var r=zo.exec(t.substring(n,n+2));return r?(e.H=+r[0],n+=r[0].length):-1}function Ai(e,t,n){zo.lastIndex=0;var r=zo.exec(t.substring(n,n+2));return r?(e.M=+r[0],n+=r[0].length):-1}function Oi(e,t,n){zo.lastIndex=0;var r=zo.exec(t.substring(n,n+2));return r?(e.S=+r[0],n+=r[0].length):-1}function Mi(e,t,n){zo.lastIndex=0;var r=zo.exec(t.substring(n,n+3));return r?(e.L=+r[0],n+=r[0].length):-1}function _i(e,t,n){var r=Wo.get(t.substring(n,n+=2).toLowerCase());return r==null?-1:(e.p=r,n)}function Di(e){var t=e.getTimezoneOffset(),n=t>0?"-":"+",r=~~(Math.abs(t)/60),i=Math.abs(t)%60;return n+Mo(r)+Mo(i)}function Pi(e){return e.toISOString()}function Hi(e,t,n){function r(t){var n=e(t),r=s(n,1);return t-n1)while(ot?1:e>=t?0:NaN},d3.descending=function(e,t){return te?1:t>=e?0:NaN},d3.mean=function(e,t){var n=e.length,r,i=0,s=-1,o=0;if(arguments.length===1)while(++s1&&(e=e.map(t)),e=e.filter(f),e.length?d3.quantile(e.sort(d3.ascending),.5):undefined},d3.min=function(e,t){var n=-1,r=e.length,i,s;if(arguments.length===1){while(++ns&&(i=s)}else{while(++ns&&(i=s)}return i},d3.max=function(e,t){var n=-1,r=e.length,i,s;if(arguments.length===1){while(++ni&&(i=s)}else{while(++ni&&(i=s)}return i},d3.extent=function(e,t){var n=-1,r=e.length,i,s,o;if(arguments.length===1){while(++ns&&(i=s),os&&(i=s),o1);return e+t*n*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(e,t){var n=arguments.length;n<2&&(t=1),n<1&&(e=0);var r=d3.random.normal();return function(){return Math.exp(e+t*r())}},irwinHall:function(e){return function(){for(var t=0,n=0;n>>1;e.call(t,t[s],s)>>1;n0&&(i=s);return i},d3.last=function(e,t){var n=0,r=e.length,i=e[0],s;arguments.length===1&&(t=d3.ascending);while(++n=i.length)return u?u.call(n,t):o?t.sort(o):t;var a=-1,f=t.length,l=i[s++],c,h,p=new r,d,v={};while(++a=i.length)return e;var r=[],o=s[n++],u;for(u in e)r.push({key:u,values:t(e[u],n)});return o&&r.sort(function(e,t){return o(e.key,t.key)}),r}var n={},i=[],s=[],o,u;return n.map=function(t){return e(t,0)},n.entries=function(n){return t(e(n,0),0)},n.key=function(e){return i.push(e),n},n.sortKeys=function(e){return s[i.length-1]=e,n},n.sortValues=function(e){return o=e,n},n.rollup=function(e){return u=e,n},n},d3.keys=function(e){var t=[];for(var n in e)t.push(n);return t},d3.values=function(e){var t=[];for(var n in e)t.push(e[n]);return t},d3.entries=function(e){var t=[];for(var n in e)t.push({key:n,value:e[n]});return t},d3.permute=function(e,t){var n=[],r=-1,i=t.length;while(++rt)r.push(o/i);else while((o=e+n*++s)=200&&e<300||e===304?r:null)}},r.send(null)},d3.text=function(e,t,n){function r(e){n(e&&e.responseText)}arguments.length<3&&(n=t,t=null),d3.xhr(e,t,r)},d3.json=function(e,t){d3.text(e,"application/json",function(e){t(e?JSON.parse(e):null)})},d3.html=function(e,t){d3.text(e,"text/html",function(e){if(e!=null){var n=document.createRange();n.selectNode(document.body),e=n.createContextualFragment(e)}t(e)})},d3.xml=function(e,t,n){function r(e){n(e&&e.responseXML)}arguments.length<3&&(n=t,t=null),d3.xhr(e,t,r)};var ts={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};d3.ns={prefix:ts,qualify:function(e){var t=e.indexOf(":"),n=e;return t>=0&&(n=e.substring(0,t),e=e.substring(t+1)),ts.hasOwnProperty(n)?{space:ts[n],local:e}:e}},d3.dispatch=function(){var e=new d,t=-1,n=arguments.length;while(++t0&&(r=e.substring(n+1),e=e.substring(0,n)),arguments.length<2?this[e].on(r):this[e].on(r,t)},d3.format=function(e){var t=ns.exec(e),n=t[1]||" ",r=t[3]||"",i=t[5],s=+t[6],o=t[7],u=t[8],a=t[9],f=1,l="",c=!1;u&&(u=+u.substring(1)),i&&(n="0",o&&(s-=Math.floor((s-1)/4)));switch(a){case"n":o=!0,a="g";break;case"%":f=100,l="%",a="f";break;case"p":f=100,l="%",a="r";break;case"d":c=!0,u=0;break;case"s":f=-1,a="r"}return a=="r"&&!u&&(a="g"),a=rs.get(a)||g,function(e){if(c&&e%1)return"";var t=e<0&&(e=-e)?"-":r;if(f<0){var h=d3.formatPrefix(e,u);e=h.scale(e),l=h.symbol}else e*=f;e=a(e,u);if(i){var p=e.length+t.length;p=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/,rs=d3.map({g:function(e,t){return e.toPrecision(t)},e:function(e,t){return e.toExponential(t)},f:function(e,t){return e.toFixed(t)},r:function(e,t){return d3.round(e,t=m(e,t)).toFixed(Math.max(0,Math.min(20,t)))}}),is=["y","z","a","f","p","n","μ","m","","k","M","G","T","P","E","Z","Y"].map(b);d3.formatPrefix=function(e,t){var n=0;return e&&(e<0&&(e*=-1),t&&(e=d3.round(e,m(e,t))),n=1+Math.floor(1e-12+Math.log(e)/Math.LN10),n=Math.max(-24,Math.min(24,Math.floor((n<=0?n+1:n-1)/3)*3))),is[8+n/3]};var ss=T(2),os=T(3),us=function(){return x},as=d3.map({linear:us,poly:T,quad:function(){return ss},cubic:function(){return os},sin:function(){return N},exp:function(){return C},circle:function(){return k},elastic:L,back:A,bounce:function(){return O}}),fs=d3.map({"in":x,out:E,"in-out":S,"out-in":function(e){return S(E(e))}});d3.ease=function(e){var t=e.indexOf("-"),n=t>=0?e.substring(0,t):e,r=t>=0?e.substring(t+1):"in";return n=as.get(n)||us,r=fs.get(r)||x,w(r(n.apply(null,Array.prototype.slice.call(arguments,1))))},d3.event=null,d3.transform=function(e){var t=document.createElementNS(d3.ns.prefix.svg,"g");return(d3.transform=function(e){t.setAttribute("transform",e);var n=t.transform.baseVal.consolidate();return new P(n?n.matrix:cs)})(e)},P.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var ls=180/Math.PI,cs={a:1,b:0,c:0,d:1,e:0,f:0};d3.interpolate=function(e,t){var n=d3.interpolators.length,r;while(--n>=0&&!(r=d3.interpolators[n](e,t)));return r},d3.interpolateNumber=function(e,t){return t-=e,function(n){return e+t*n}},d3.interpolateRound=function(e,t){return t-=e,function(n){return Math.round(e+t*n)}},d3.interpolateString=function(e,t){var n,r,i,s=0,o=0,u=[],a=[],f,l;hs.lastIndex=0;for(r=0;n=hs.exec(t);++r)n.index&&u.push(t.substring(s,o=n.index)),a.push({i:u.length,x:n[0]}),u.push(null),s=hs.lastIndex;s180?l+=360:l-f>180&&(f+=360),r.push({i:n.push(n.pop()+"rotate(",null,")")-2,x:d3.interpolateNumber(f,l)})):l&&n.push(n.pop()+"rotate("+l+")"),c!=h?r.push({i:n.push(n.pop()+"skewX(",null,")")-2,x:d3.interpolateNumber(c,h)}):h&&n.push(n.pop()+"skewX("+h+")"),p[0]!=d[0]||p[1]!=d[1]?(i=n.push(n.pop()+"scale(",null,",",null,")"),r.push({i:i-4,x:d3.interpolateNumber(p[0],d[0])},{i:i-2,x:d3.interpolateNumber(p[1],d[1])})):(d[0]!=1||d[1]!=1)&&n.push(n.pop()+"scale("+d+")"),i=r.length,function(e){var t=-1,s;while(++t180?s-=360:s<-180&&(s+=360),function(e){return Y(n+s*e,r+o*e,i+u*e)+""}},d3.interpolateLab=function(e,t){e=d3.lab(e),t=d3.lab(t);var n=e.l,r=e.a,i=e.b,s=t.l-n,o=t.a-r,u=t.b-i;return function(e){return it(n+s*e,r+o*e,i+u*e)+""}},d3.interpolateHcl=function(e,t){e=d3.hcl(e),t=d3.hcl(t);var n=e.h,r=e.c,i=e.l,s=t.h-n,o=t.c-r,u=t.l-i;return s>180?s-=360:s<-180&&(s+=360),function(e){return tt(n+s*e,r+o*e,i+u*e)+""}},d3.interpolateArray=function(e,t){var n=[],r=[],i=e.length,s=t.length,o=Math.min(e.length,t.length),u;for(u=0;u=0;)if(s=n[r])i&&i!==s.nextSibling&&i.parentNode.insertBefore(s,i),i=s;return this},ks.sort=function(e){e=wt.apply(this,arguments);for(var t=-1,n=this.length;++t=Zs?e?"M0,"+s+"A"+s+","+s+" 0 1,1 0,"+ -s+"A"+s+","+s+" 0 1,1 0,"+s+"M0,"+e+"A"+e+","+e+" 0 1,0 0,"+ -e+"A"+e+","+e+" 0 1,0 0,"+e+"Z":"M0,"+s+"A"+s+","+s+" 0 1,1 0,"+ -s+"A"+s+","+s+" 0 1,1 0,"+s+"Z":e?"M"+s*l+","+s*c+"A"+s+","+s+" 0 "+f+",1 "+s*h+","+s*p+"L"+e*h+","+e*p+"A"+e+","+e+" 0 "+f+",0 "+e*l+","+e*c+"Z":"M"+s*l+","+s*c+"A"+s+","+s+" 0 "+f+",1 "+s*h+","+s*p+"L0,0"+"Z"}var t=en,n=tn,r=nn,i=rn;return e.innerRadius=function(n){return arguments.length?(t=u(n),e):t},e.outerRadius=function(t){return arguments.length?(n=u(t),e):n},e.startAngle=function(t){return arguments.length?(r=u(t),e):r},e.endAngle=function(t){return arguments.length?(i=u(t),e):i},e.centroid=function(){var e=(t.apply(this,arguments)+n.apply(this,arguments))/2,s=(r.apply(this,arguments)+i.apply(this,arguments))/2+Ys;return[Math.cos(s)*e,Math.sin(s)*e]},e};var Ys=-Math.PI/2,Zs=2*Math.PI-1e-6;d3.svg.line=function(){return sn(i)};var eo=d3.map({linear:an,"linear-closed":fn,"step-before":ln,"step-after":cn,basis:gn,"basis-open":yn,"basis-closed":bn,bundle:wn,cardinal:dn,"cardinal-open":hn,"cardinal-closed":pn,monotone:Cn});eo.forEach(function(e,t){t.key=e,t.closed=/-closed$/.test(e)});var to=[0,2/3,1/3,0],no=[0,1/3,2/3,0],ro=[0,1/6,2/3,1/6];d3.svg.line.radial=function(){var e=sn(kn);return e.radius=e.x,delete e.x,e.angle=e.y,delete e.y,e},ln.reverse=cn,cn.reverse=ln,d3.svg.area=function(){return Ln(i)},d3.svg.area.radial=function(){var e=Ln(kn);return e.radius=e.x,delete e.x,e.innerRadius=e.x0,delete e.x0,e.outerRadius=e.x1,delete e.x1,e.angle=e.y,delete e.y,e.startAngle=e.y0,delete e.y0,e.endAngle=e.y1,delete e.y1,e},d3.svg.chord=function(){function e(e,u){var a=t(this,s,e,u),f=t(this,o,e,u);return"M"+a.p0+r(a.r,a.p1,a.a1-a.a0)+(n(a,f)?i(a.r,a.p1,a.r,a.p0):i(a.r,a.p1,f.r,f.p0)+r(f.r,f.p1,f.a1-f.a0)+i(f.r,f.p1,a.r,a.p0))+"Z"}function t(e,t,n,r){var i=t.call(e,n,r),s=a.call(e,i,r),o=f.call(e,i,r)+Ys,u=l.call(e,i,r)+Ys;return{r:s,a0:o,a1:u,p0:[s*Math.cos(o),s*Math.sin(o)],p1:[s*Math.cos(u),s*Math.sin(u)]}}function n(e,t){return e.a0==t.a0&&e.a1==t.a1}function r(e,t,n){return"A"+e+","+e+" 0 "+ +(n>Math.PI)+",1 "+t}function i(e,t,n,r){return"Q 0,0 "+r}var s=An,o=On,a=Mn,f=nn,l=rn;return e.radius=function(t){return arguments.length?(a=u(t),e):a},e.source=function(t){return arguments.length?(s=u(t),e):s},e.target=function(t){return arguments.length?(o=u(t),e):o},e.startAngle=function(t){return arguments.length?(f=u(t),e):f},e.endAngle=function(t){return arguments.length?(l=u(t),e):l},e},d3.svg.diagonal=function(){function e(e,i){var s=t.call(this,e,i),o=n.call(this,e,i),u=(s.y+o.y)/2,a=[s,{x:s.x,y:u},{x:o.x,y:u},o];return a=a.map(r),"M"+a[0]+"C"+a[1]+" "+a[2]+" "+a[3]}var t=An,n=On,r=Pn;return e.source=function(n){return arguments.length?(t=u(n),e):t},e.target=function(t){return arguments.length?(n=u(t),e):n},e.projection=function(t){return arguments.length?(r=t,e):r},e},d3.svg.diagonal.radial=function(){var e=d3.svg.diagonal(),t=Pn,n=e.projection;return e.projection=function(e){return arguments.length?n(Hn(t=e)):t},e},d3.svg.mouse=d3.mouse,d3.svg.touches=d3.touches,d3.svg.symbol=function(){function e(e,r){return(io.get(t.call(this,e,r))||Fn)(n.call(this,e,r))}var t=jn,n=Bn;return e.type=function(n){return arguments.length?(t=u(n),e):t},e.size=function(t){return arguments.length?(n=u(t),e):n},e};var io=d3.map({circle:Fn,cross:function(e){var t=Math.sqrt(e/5)/2;return"M"+ -3*t+","+ -t+"H"+ -t+"V"+ -3*t+"H"+t+"V"+ -t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+ -t+"V"+t+"H"+ -3*t+"Z"},diamond:function(e){var t=Math.sqrt(e/(2*oo)),n=t*oo;return"M0,"+ -t+"L"+n+",0"+" 0,"+t+" "+ -n+",0"+"Z"},square:function(e){var t=Math.sqrt(e)/2;return"M"+ -t+","+ -t+"L"+t+","+ -t+" "+t+","+t+" "+ -t+","+t+"Z"},"triangle-down":function(e){var t=Math.sqrt(e/so),n=t*so/2;return"M0,"+n+"L"+t+","+ -n+" "+ -t+","+ -n+"Z"},"triangle-up":function(e){var t=Math.sqrt(e/so),n=t*so/2;return"M0,"+ -n+"L"+t+","+n+" "+ -t+","+n+"Z"}});d3.svg.symbolTypes=io.keys();var so=Math.sqrt(3),oo=Math.tan(30*Math.PI/180);d3.svg.axis=function(){function e(e){e.each(function(){var e=d3.select(this),c=a==null?t.ticks?t.ticks.apply(t,u):t.domain():a,h=f==null?t.tickFormat?t.tickFormat.apply(t,u):String:f,p=Rn(t,c,l),d=e.selectAll(".minor").data(p,String),v=d.enter().insert("line","g").attr("class","tick minor").style("opacity",1e-6),m=d3.transition(d.exit()).style("opacity",1e-6).remove(),g=d3.transition(d).style("opacity",1),y=e.selectAll("g").data(c,String),b=y.enter().insert("g","path").style("opacity",1e-6),w=d3.transition(y.exit()).style("opacity",1e-6).remove(),E=d3.transition(y).style("opacity",1),S,x=Dt(t),T=e.selectAll(".domain").data([0]),N=T.enter().append("path").attr("class","domain"),C=d3.transition(T),k=t.copy(),L=this.__chart__||k;this.__chart__=k,b.append("line").attr("class","tick"),b.append("text");var A=b.select("line"),O=E.select("line"),M=y.select("text").text(h),_=b.select("text"),D=E.select("text");switch(n){case"bottom":S=In,v.attr("y2",i),g.attr("x2",0).attr("y2",i),A.attr("y2",r),_.attr("y",Math.max(r,0)+o),O.attr("x2",0).attr("y2",r),D.attr("x",0).attr("y",Math.max(r,0)+o),M.attr("dy",".71em").attr("text-anchor","middle"),C.attr("d","M"+x[0]+","+s+"V0H"+x[1]+"V"+s);break;case"top":S=In,v.attr("y2",-i),g.attr("x2",0).attr("y2",-i),A.attr("y2",-r),_.attr("y",-(Math.max(r,0)+o)),O.attr("x2",0).attr("y2",-r),D.attr("x",0).attr("y",-(Math.max(r,0)+o)),M.attr("dy","0em").attr("text-anchor","middle"),C.attr("d","M"+x[0]+","+ -s+"V0H"+x[1]+"V"+ -s);break;case"left":S=qn,v.attr("x2",-i),g.attr("x2",-i).attr("y2",0),A.attr("x2",-r),_.attr("x",-(Math.max(r,0)+o)),O.attr("x2",-r).attr("y2",0),D.attr("x",-(Math.max(r,0)+o)).attr("y",0),M.attr("dy",".32em").attr("text-anchor","end"),C.attr("d","M"+ -s+","+x[0]+"H0V"+x[1]+"H"+ -s);break;case"right":S=qn,v.attr("x2",i),g.attr("x2",i).attr("y2",0),A.attr("x2",r),_.attr("x",Math.max(r,0)+o),O.attr("x2",r).attr("y2",0),D.attr("x",Math.max(r,0)+o).attr("y",0),M.attr("dy",".32em").attr("text-anchor","start"),C.attr("d","M"+s+","+x[0]+"H0V"+x[1]+"H"+s)}if(t.ticks)b.call(S,L),E.call(S,k),w.call(S,k),v.call(S,L),g.call(S,k),m.call(S,k);else{var P=k.rangeBand()/2,H=function(e){return k(e)+P};b.call(S,H),E.call(S,H)}})}var t=d3.scale.linear(),n="bottom",r=6,i=6,s=6,o=3,u=[10],a=null,f,l=0;return e.scale=function(n){return arguments.length?(t=n,e):t},e.orient=function(t){return arguments.length?(n=t,e):n},e.ticks=function(){return arguments.length?(u=arguments,e):u},e.tickValues=function(t){return arguments.length?(a=t,e):a},e.tickFormat=function(t){return arguments.length?(f=t,e):f},e.tickSize=function(t,n,o){if(!arguments.length)return r;var u=arguments.length-1;return r=+t,i=u>1?+n:r,s=u>0?+arguments[u]:r,e},e.tickPadding=function(t){return arguments.length?(o=+t,e):o},e.tickSubdivide=function(t){return arguments.length?(l=+t,e):l},e},d3.svg.brush=function(){function e(s){s.each(function(){var s=d3.select(this),f=s.selectAll(".background").data([0]),l=s.selectAll(".extent").data([0]),c=s.selectAll(".resize").data(a,String),h;s.style("pointer-events","all").on("mousedown.brush",i).on("touchstart.brush",i),f.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),l.enter().append("rect").attr("class","extent").style("cursor","move"),c.enter().append("g").attr("class",function(e){return"resize "+e}).style("cursor",function(e){return uo[e]}).append("rect").attr("x",function(e){return/[ew]$/.test(e)?-3:null}).attr("y",function(e){return/^[ns]/.test(e)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),c.style("display",e.empty()?"none":null),c.exit().remove(),o&&(h=Dt(o),f.attr("x",h[0]).attr("width",h[1]-h[0]),n(s)),u&&(h=Dt(u),f.attr("y",h[0]).attr("height",h[1]-h[0]),r(s)),t(s)})}function t(e){e.selectAll(".resize").attr("transform",function(e){return"translate("+f[+/e$/.test(e)][0]+","+f[+/^s/.test(e)][1]+")"})}function n(e){e.select(".extent").attr("x",f[0][0]),e.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1][0]-f[0][0])}function r(e){e.select(".extent").attr("y",f[0][1]),e.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1][1]-f[0][1])}function i(){function i(){var e=d3.event.changedTouches;return e?d3.touches(v,e)[0]:d3.mouse(v)}function a(){d3.event.keyCode==32&&(S||(x=null,T[0]-=f[1][0],T[1]-=f[1][1],S=2),M())}function c(){d3.event.keyCode==32&&S==2&&(T[0]+=f[1][0],T[1]+=f[1][1],S=0,M())}function h(){var e=i(),s=!1;N&&(e[0]+=N[0],e[1]+=N[1]),S||(d3.event.altKey?(x||(x=[(f[0][0]+f[1][0])/2,(f[0][1]+f[1][1])/2]),T[0]=f[+(e[0]0?a=e:a=0:e>0&&(r.start({type:"start",alpha:a=e}),d3.timer(n.tick)),n):a},n.start=function(){function e(e,n){var i=t(r),s=-1,o=i.length,u;while(++si&&(i=u),r.push(u)}for(o=0;o0){s=-1;while(++s=a[0]&&d<=a[1]&&(l=o[d3.bisect(f,d,1,h)-1],l.y+=p,l.push(e[s]))}return o}var t=!0,n=Number,r=fr,i=ur;return e.value=function(t){return arguments.length?(n=t,e):n},e.range=function(t){return arguments.length?(r=u(t),e):r},e.bins=function(t){return arguments.length?(i=typeof t=="number"?function(e){return ar(e,t)}:u(t),e):i},e.frequency=function(n){return arguments.length?(t=!!n,e):t},e},d3.layout.hierarchy=function(){function e(t,o,u){var a=i.call(n,t,o),f=vo?t:{data:t};f.depth=o,u.push(f);if(a&&(c=a.length)){var l=-1,c,h=f.children=[],p=0,d=o+1,v;while(++l0){var l=n*f/2;Hr(o,function(e){e.r+=l}),Hr(o,br),Hr(o,function(e){e.r-=l}),f=Math.max(2*o.r/u,2*o.r/a)}return Sr(o,u/2,a/2,1/f),s}var t=d3.layout.hierarchy().sort(vr),n=0,r=[1,1];return e.size=function(t){return arguments.length?(r=t,e):r},e.padding=function(t){return arguments.length?(n=+t,e):n},lr(e,t)},d3.layout.cluster=function(){function e(e,i){var s=t.call(this,e,i),o=s[0],u,a=0,f,l;Hr(o,function(e){var t=e.children;t&&t.length?(e.x=Nr(t),e.y=Tr(t)):(e.x=u?a+=n(e,u):0,e.y=0,u=e)});var c=Cr(o),h=kr(o),p=c.x-n(c,h)/2,d=h.x+n(h,c)/2;return Hr(o,function(e){e.x=(e.x-p)/(d-p)*r[0],e.y=(1-(o.y?e.y/o.y:1))*r[1]}),s}var t=d3.layout.hierarchy().sort(null).value(null),n=Lr,r=[1,1];return e.separation=function(t){return arguments.length?(n=t,e):n},e.size=function(t){return arguments.length?(r=t,e):r},lr(e,t)},d3.layout.tree=function(){function e(e,i){function s(e,t){var r=e.children,i=e._tree;if(r&&(o=r.length)){var o,a=r[0],f,l=a,c,h=-1;while(++h0&&(jr(Fr(o,e,r),e,h),a+=h,f+=h),l+=o._tree.mod,a+=i._tree.mod,c+=u._tree.mod,f+=s._tree.mod;o&&!Or(s)&&(s._tree.thread=o,s._tree.mod+=l-f),i&&!Ar(u)&&(u._tree.thread=i,u._tree.mod+=a-c,r=e)}return r}var a=t.call(this,e,i),f=a[0];Hr(f,function(e,t){e._tree={ancestor:e,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),s(f),o(f,-f._tree.prelim);var l=Mr(f,Dr),c=Mr(f,_r),h=Mr(f,Pr),p=l.x-n(l,c)/2,d=c.x+n(c,l)/2,v=h.depth||1;return Hr(f,function(e){e.x=(e.x-p)/(d-p)*r[0],e.y=e.depth/v*r[1],delete e._tree}),a}var t=d3.layout.hierarchy().sort(null).value(null),n=Lr,r=[1,1];return e.separation=function(t){return arguments.length?(n=t,e):n},e.size=function(t){return arguments.length?(r=t,e):r},lr(e,t)},d3.layout.treemap=function(){function e(e,t){var n=-1,r=e.length,i,s;while(++n0)u.push(f=a[d-1]),u.area+=f.area,(h=r(u,p))<=c?(a.pop(),c=h):(u.area-=u.pop().area,i(u,p,o,!1),p=Math.min(o.dx,o.dy),u.length=u.area=0,c=Infinity);u.length&&(i(u,p,o,!0),u.length=u.area=0),s.forEach(t)}}function n(t){var r=t.children;if(r&&r.length){var s=l(t),o=r.slice(),u,a=[];e(o,s.dx*s.dy/t.value),a.area=0;while(u=o.pop())a.push(u),a.area+=u.area,u.z!=null&&(i(a,u.z?s.dx:s.dy,s,!o.length),a.length=a.area=0);r.forEach(n)}}function r(e,t){var n=e.area,r,i=0,s=Infinity,o=-1,u=e.length;while(++oi&&(i=r)}return n*=n,t*=t,n?Math.max(t*i*p/n,n/(t*s*p)):Infinity}function i(e,t,n,r){var i=-1,s=e.length,o=n.x,a=n.y,f=t?u(e.area/t):0,l;if(t==n.dx){if(r||f>n.dy)f=n.dy;while(++in.dx)f=n.dx;while(++i50?n:s<-140?r:o<21?i:t)(e)}var t=d3.geo.albers(),n=d3.geo.albers().origin([-160,60]).parallels([55,65]),r=d3.geo.albers().origin([-160,20]).parallels([8,18]),i=d3.geo.albers().origin([-60,10]).parallels([8,18]);return e.scale=function(s){return arguments.length?(t.scale(s),n.scale(s*.6),r.scale(s),i.scale(s*1.5),e.translate(t.translate())):t.scale()},e.translate=function(s){if(!arguments.length)return t.translate();var o=t.scale()/1e3,u=s[0],a=s[1];return t.translate(s),n.translate([u-400*o,a+170*o]),r.translate([u-190*o,a+200*o]),i.translate([u+580*o,a+430*o]),e},e.scale(t.scale())},d3.geo.bonne=function(){function e(e){var u=e[0]*mo-r,a=e[1]*mo-i;if(s){var f=o+s-a,l=u*Math.cos(a)/f;u=f*Math.sin(l),a=f*Math.cos(l)-o}else u*=Math.cos(a),a*=-1;return[t*u+n[0],t*a+n[1]]}var t=200,n=[480,250],r,i,s,o;return e.invert=function(e){var i=(e[0]-n[0])/t,u=(e[1]-n[1])/t;if(s){var a=o+u,f=Math.sqrt(i*i+a*a);u=o+s-f,i=r+f*Math.atan2(i,a)/Math.cos(u)}else u*=-1,i/=Math.cos(u);return[i/mo,u/mo]},e.parallel=function(t){return arguments.length?(o=1/Math.tan(s=t*mo),e):s/mo},e.origin=function(t){return arguments.length?(r=t[0]*mo,i=t[1]*mo,e):[r/mo,i/mo]},e.scale=function(
+n){return arguments.length?(t=+n,e):t},e.translate=function(t){return arguments.length?(n=[+t[0],+t[1]],e):n},e.origin([0,0]).parallel(45)},d3.geo.equirectangular=function(){function e(e){var r=e[0]/360,i=-e[1]/360;return[t*r+n[0],t*i+n[1]]}var t=500,n=[480,250];return e.invert=function(e){var r=(e[0]-n[0])/t,i=(e[1]-n[1])/t;return[360*r,-360*i]},e.scale=function(n){return arguments.length?(t=+n,e):t},e.translate=function(t){return arguments.length?(n=[+t[0],+t[1]],e):n},e},d3.geo.mercator=function(){function e(e){var r=e[0]/360,i=-(Math.log(Math.tan(Math.PI/4+e[1]*mo/2))/mo)/360;return[t*r+n[0],t*Math.max(-0.5,Math.min(.5,i))+n[1]]}var t=500,n=[480,250];return e.invert=function(e){var r=(e[0]-n[0])/t,i=(e[1]-n[1])/t;return[360*r,2*Math.atan(Math.exp(-360*i*mo))/mo-90]},e.scale=function(n){return arguments.length?(t=+n,e):t},e.translate=function(t){return arguments.length?(n=[+t[0],+t[1]],e):n},e},d3.geo.path=function(){function e(e,t){typeof s=="function"&&(o=zr(s.apply(this,arguments))),f(e);var n=a.length?a.join(""):null;return a=[],n}function t(e){return u(e).join(",")}function n(e){var t=i(e[0]),n=0,r=e.length;while(++n0){a.push("M");while(++o0){a.push("M");while(++lr&&(r=e),si&&(i=s)}),[[t,n],[r,i]]};var go={Feature:Xr,FeatureCollection:Vr,GeometryCollection:$r,LineString:Jr,MultiLineString:Kr,MultiPoint:Jr,MultiPolygon:Qr,Point:Gr,Polygon:Yr};d3.geo.circle=function(){function e(){}function t(e){return a.distance(e)=l*l+c*c?r[s].index=-1:(r[h].index=-1,d=r[s].angle,h=s,p=o)):(d=r[s].angle,h=s,p=o);i.push(u);for(s=0,o=0;s<2;++o)r[o].index!==-1&&(i.push(r[o].index),s++);v=i.length;for(;o=0?(n=e.ep.r,r=e.ep.l):(n=e.ep.l,r=e.ep.r),e.a===1?(o=n?n.y:-1e6,i=e.c-e.b*o,u=r?r.y:1e6,s=e.c-e.b*u):(i=n?n.x:-1e6,o=e.c-e.a*i,s=r?r.x:1e6,u=e.c-e.a*s);var a=[i,o],f=[s,u];t[e.region.l.index].push(a,f),t[e.region.r.index].push(a,f)}),t.map(function(t,n){var r=e[n][0],i=e[n][1];return t.forEach(function(e){e.angle=Math.atan2(e[0]-r,e[1]-i)}),t.sort(function(e,t){return e.angle-t.angle}).filter(function(e,n){return!n||e.angle-t[n-1].angle>1e-10})})};var wo={l:"r",r:"l"};d3.geom.delaunay=function(e){var t=e.map(function(){return[]}),n=[];return ui(e,function(n){t[n.region.l.index].push(e[n.region.r.index])}),t.forEach(function(t,r){var i=e[r],s=i[0],o=i[1];t.forEach(function(e){e.angle=Math.atan2(e[0]-s,e[1]-o)}),t.sort(function(e,t){return e.angle-t.angle});for(var u=0,a=t.length-1;u=u,l=t.y>=a,c=(l<<1)+f;e.leaf=!1,e=e.nodes[c]||(e.nodes[c]=ai()),f?n=u:i=u,l?r=a:o=a,s(e,t,n,r,i,o)}var u,a=-1,f=e.length;f&&isNaN(e[0].x)&&(e=e.map(li));if(arguments.length<5)if(arguments.length===3)i=r=n,n=t;else{t=n=Infinity,r=i=-Infinity;while(++ar&&(r=u.x),u.y>i&&(i=u.y);var l=r-t,c=i-n;l>c?i=n+l:r=t+c}var h=ai();return h.add=function(e){s(h,e,t,n,r,i)},h.visit=function(e){fi(e,h,t,n,r,i)},e.forEach(h.add),h},d3.time={};var Eo=Date,So=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];ci.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){xo.setUTCDate.apply(this._,arguments)},setDay:function(){xo.setUTCDay.apply(this._,arguments)},setFullYear:function(){xo.setUTCFullYear.apply(this._,arguments)},setHours:function(){xo.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){xo.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){xo.setUTCMinutes.apply(this._,arguments)},setMonth:function(){xo.setUTCMonth.apply(this._,arguments)},setSeconds:function(){xo.setUTCSeconds.apply(this._,arguments)},setTime:function(){xo.setTime.apply(this._,arguments)}};var xo=Date.prototype,To="%a %b %e %H:%M:%S %Y",No="%m/%d/%y",Co="%H:%M:%S",ko=So,Lo=ko.map(hi),Ao=["January","February","March","April","May","June","July","August","September","October","November","December"],Oo=Ao.map(hi);d3.time.format=function(e){function t(t){var r=[],i=-1,s=0,o,u;while(++i=12?"PM":"AM"},S:function(e){return Mo(e.getSeconds())},U:function(e){return Mo(d3.time.sundayOfYear(e))},w:function(e){return e.getDay()},W:function(e){return Mo(d3.time.mondayOfYear(e))},x:d3.time.format(No),X:d3.time.format(Co),y:function(e){return Mo(e.getFullYear()%100)},Y:function(e){return Do(e.getFullYear()%1e4)},Z:Di,"%":function(e){return"%"}},Uo={a:mi,A:gi,b:yi,B:bi,c:wi,d:ki,e:ki,H:Li,I:Li,L:Mi,m:Ci,M:Ai,p:_i,S:Oi,x:Ei,X:Si,y:Ti,Y:xi},zo=/^\s*\d+/,Wo=d3.map({am:0,pm:1});d3.time.format.utc=function(e){function t(e){try{Eo=ci;var t=new Eo;return t._=e,n(t)}finally{Eo=Date}}var n=d3.time.format(e);return t.parse=function(e){try{Eo=ci;var t=n.parse(e);return t&&t._}finally{Eo=Date}},t.toString=n.toString,t};var Xo=d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ");d3.time.format.iso=Date.prototype.toISOString?Pi:Xo,Pi.parse=function(e){var t=new Date(e);return isNaN(t)?null:t},Pi.toString=Xo.toString,d3.time.second=Hi(function(e){return new Eo(Math.floor(e/1e3)*1e3)},function(e,t){e.setTime(e.getTime()+Math.floor(t)*1e3)},function(e){return e.getSeconds()}),d3.time.seconds=d3.time.second.range,d3.time.seconds.utc=d3.time.second.utc.range,d3.time.minute=Hi(function(e){return new Eo(Math.floor(e/6e4)*6e4)},function(e,t){e.setTime(e.getTime()+Math.floor(t)*6e4)},function(e){return e.getMinutes()}),d3.time.minutes=d3.time.minute.range,d3.time.minutes.utc=d3.time.minute.utc.range,d3.time.hour=Hi(function(e){var t=e.getTimezoneOffset()/60;return new Eo((Math.floor(e/36e5-t)+t)*36e5)},function(e,t){e.setTime(e.getTime()+Math.floor(t)*36e5)},function(e){return e.getHours()}),d3.time.hours=d3.time.hour.range,d3.time.hours.utc=d3.time.hour.utc.range,d3.time.day=Hi(function(e){var t=new Eo(1970,0);return t.setFullYear(e.getFullYear(),e.getMonth(),e.getDate()),t},function(e,t){e.setDate(e.getDate()+t)},function(e){return e.getDate()-1}),d3.time.days=d3.time.day.range,d3.time.days.utc=d3.time.day.utc.range,d3.time.dayOfYear=function(e){var t=d3.time.year(e);return Math.floor((e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*6e4)/864e5)},So.forEach(function(e,t){e=e.toLowerCase(),t=7-t;var n=d3.time[e]=Hi(function(e){return(e=d3.time.day(e)).setDate(e.getDate()-(e.getDay()+t)%7),e},function(e,t){e.setDate(e.getDate()+Math.floor(t)*7)},function(e){var n=d3.time.year(e).getDay();return Math.floor((d3.time.dayOfYear(e)+(n+t)%7)/7)-(n!==t)});d3.time[e+"s"]=n.range,d3.time[e+"s"].utc=n.utc.range,d3.time[e+"OfYear"]=function(e){var n=d3.time.year(e).getDay();return Math.floor((d3.time.dayOfYear(e)+(n+t)%7)/7)}}),d3.time.week=d3.time.sunday,d3.time.weeks=d3.time.sunday.range,d3.time.weeks.utc=d3.time.sunday.utc.range,d3.time.weekOfYear=d3.time.sundayOfYear,d3.time.month=Hi(function(e){return e=d3.time.day(e),e.setDate(1),e},function(e,t){e.setMonth(e.getMonth()+t)},function(e){return e.getMonth()}),d3.time.months=d3.time.month.range,d3.time.months.utc=d3.time.month.utc.range,d3.time.year=Hi(function(e){return e=d3.time.day(e),e.setMonth(0,1),e},function(e,t){e.setFullYear(e.getFullYear()+t)},function(e){return e.getFullYear()}),d3.time.years=d3.time.year.range,d3.time.years.utc=d3.time.year.utc.range;var Vo=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],$o=[[d3.time.second,1],[d3.time.second,5],[d3.time.second,15],[d3.time.second,30],[d3.time.minute,1],[d3.time.minute,5],[d3.time.minute,15],[d3.time.minute,30],[d3.time.hour,1],[d3.time.hour,3],[d3.time.hour,6],[d3.time.hour,12],[d3.time.day,1],[d3.time.day,2],[d3.time.week,1],[d3.time.month,1],[d3.time.month,3],[d3.time.year,1]],Jo=[[d3.time.format("%Y"),function(e){return!0}],[d3.time.format("%B"),function(e){return e.getMonth()}],[d3.time.format("%b %d"),function(e){return e.getDate()!=1}],[d3.time.format("%a %d"),function(e){return e.getDay()&&e.getDate()!=1}],[d3.time.format("%I %p"),function(e){return e.getHours()}],[d3.time.format("%I:%M"),function(e){return e.getMinutes()}],[d3.time.format(":%S"),function(e){return e.getSeconds()}],[d3.time.format(".%L"),function(e){return e.getMilliseconds()}]],Ko=d3.scale.linear(),Qo=qi(Jo);$o.year=function(e,t){return Ko.domain(e.map(Ui)).ticks(t).map(Ri)},d3.time.scale=function(){return ji(d3.scale.linear(),$o,Qo)};var Go=$o.map(function(e){return[e[0].utc,e[1]]}),Yo=[[d3.time.format.utc("%Y"),function(e){return!0}],[d3.time.format.utc("%B"),function(e){return e.getUTCMonth()}],[d3.time.format.utc("%b %d"),function(e){return e.getUTCDate()!=1}],[d3.time.format.utc("%a %d"),function(e){return e.getUTCDay()&&e.getUTCDate()!=1}],[d3.time.format.utc("%I %p"),function(e){return e.getUTCHours()}],[d3.time.format.utc("%I:%M"),function(e){return e.getUTCMinutes()}],[d3.time.format.utc(":%S"),function(e){return e.getUTCSeconds()}],[d3.time.format.utc(".%L"),function(e){return e.getUTCMilliseconds()}]],Zo=qi(Yo);Go.year=function(e,t){return Ko.domain(e.map(Wi)).ticks(t).map(zi)},d3.time.scale.utc=function(){return ji(d3.scale.linear(),Go,Zo)}})();
\ No newline at end of file