aboutsummaryrefslogtreecommitdiffstats
path: root/dist
diff options
context:
space:
mode:
Diffstat (limited to 'dist')
-rw-r--r--dist/svg.js635
-rw-r--r--dist/svg.min.js4
2 files changed, 384 insertions, 255 deletions
diff --git a/dist/svg.js b/dist/svg.js
index 7cec3bd..f3a0b84 100644
--- a/dist/svg.js
+++ b/dist/svg.js
@@ -1,50 +1,54 @@
-/* svg.js v0.8-5-g5e3ff07 - svg regex color viewbox bbox element container fx event group arrange defs mask pattern gradient doc shape wrap rect ellipse line poly path image text nested sugar - svgjs.com/license */
-(function() {
+/* svg.js v0.9 - svg regex color viewbox bbox element container fx event group arrange defs mask pattern gradient doc shape wrap rect ellipse line poly path image text nested sugar - svgjs.com/license */
+;(function() {
- this.svg = function(element) {
+ this.SVG = function(element) {
if (SVG.supported)
return new SVG.Doc(element)
}
- // The main wrapping element
- this.SVG = {
- /* default namespaces */
- ns: 'http://www.w3.org/2000/svg'
- , xlink: 'http://www.w3.org/1999/xlink'
+ // DEPRECATED!!! Use SVG() instead
+ this.svg = function(element) {
+ console.warn('WARNING: svg() is deprecated, please use SVG() instead.')
+ return SVG(element)
+ }
+
+ // Default namespaces
+ SVG.ns = 'http://www.w3.org/2000/svg'
+ SVG.xlink = 'http://www.w3.org/1999/xlink'
+
+ // Element id sequence
+ SVG.did = 1000
+
+ // Get next named element id
+ SVG.eid = function(name) {
+ return 'Svgjs' + name.charAt(0).toUpperCase() + name.slice(1) + 'Element' + (SVG.did++)
+ }
+
+ // Method for element creation
+ SVG.create = function(name) {
+ /* create element */
+ var element = document.createElementNS(this.ns, name)
+
+ /* apply unique id */
+ element.setAttribute('id', this.eid(name))
- /* element id sequence */
- , did: 1000
+ return element
+ }
- // Get next named element id
- , eid: function(name) {
- return 'Svgjs' + name.charAt(0).toUpperCase() + name.slice(1) + 'Element' + (SVG.did++)
- }
- // Method for element creation
- , create: function(name) {
- /* create element */
- var element = document.createElementNS(this.ns, name)
-
- /* apply unique id */
- element.setAttribute('id', this.eid(name))
-
- return element
- }
// Method for extending objects
- , extend: function() {
- var modules, methods, key, i
-
- /* get list of modules */
- modules = Array.prototype.slice.call(arguments)
-
- /* get object with extensions */
- methods = modules.pop()
-
- for (i = modules.length - 1; i >= 0; i--)
- if (modules[i])
- for (key in methods)
- modules[i].prototype[key] = methods[key]
- }
+ SVG.extend = function() {
+ var modules, methods, key, i
+
+ /* get list of modules */
+ modules = Array.prototype.slice.call(arguments)
+ /* get object with extensions */
+ methods = modules.pop()
+
+ for (i = modules.length - 1; i >= 0; i--)
+ if (modules[i])
+ for (key in methods)
+ modules[i].prototype[key] = methods[key]
}
// svg support test
@@ -53,24 +57,39 @@
!! document.createElementNS(SVG.ns,'svg').createSVGRect
})()
- if (!SVG.supported) return false;
+ if (!SVG.supported) return false
SVG.regex = {
+ /* parse unit value */
+ unit: /^([\d\.]+)([a-z%]{0,2})$/
- unit: /^([\d\.]+)([a-z%]{0,2})$/
+ /* parse hex value */
+ , hex: /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i
- , hex: /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i
-
- , rgb: /rgb\((\d+),(\d+),(\d+),([\d\.]+)\)/
-
- , hsb: /hsb\((\d+),(\d+),(\d+),([\d\.]+)\)/
-
- , isHex: /^#/i
-
- , isRgb: /^rgb\(/
+ /* parse rgb value */
+ , rgb: /rgb\((\d+),(\d+),(\d+),([\d\.]+)\)/
+
+ /* parse hsb value */
+ , hsb: /hsb\((\d+),(\d+),(\d+),([\d\.]+)\)/
+
+ /* test hex value */
+ , isHex: /^#[a-f0-9]{3,6}$/i
+
+ /* test rgb value */
+ , isRgb: /^rgb\(/
- , isHsb: /^hsb\(/
+ /* test hsb value */
+ , isHsb: /^hsb\(/
+ /* test css declaration */
+ , isCss: /[^:]+:[^;]+;?/
+
+ /* test css property */
+ , isStyle: /^font|text|leading|cursor/
+
+ /* test for blank string */
+ , isBlank: /^(\s+)?$/
+
}
SVG.Color = function(color) {
@@ -116,7 +135,6 @@
this.r = color.r
this.g = color.g
this.b = color.b
-
}
}
@@ -290,7 +308,7 @@
this.y = box.y + element.trans.y
/* add the center */
- this.cx = box.x + element.trans.x + box.width / 2
+ this.cx = box.x + element.trans.x + box.width / 2
this.cy = box.y + element.trans.y + box.height / 2
/* plain width and height */
@@ -320,7 +338,7 @@
}
/* initialize style store */
- this.style = {}
+ this.styles = {}
/* initialize transformation store with defaults */
this.trans = {
@@ -409,6 +427,7 @@
, remove: function() {
if (this.parent)
this.parent.remove(this)
+
return this
}
// Get parent document
@@ -424,24 +443,29 @@
if (arguments.length < 2) {
/* apply every attribute individually if an object is passed */
if (typeof a == 'object')
- for (v in a) this.attr(v, a[v])
+ for (v in a)
+ this.attr(v, a[v])
/* act as a getter for style attributes */
else if (this._isStyle(a))
return a == 'text' ?
this.content :
a == 'leading' ?
- this[a] :
- this.style[a]
+ this.leading() :
+ this.style(a)
/* act as a getter if the first and only argument is not an object */
else
- return this.attrs[a]
+ return this.attrs[a] || this.node.getAttribute(a)
} else if (v === null) {
/* remove value */
this.node.removeAttribute(a)
+ } else if (a == 'style') {
+ /* redirect to the style method */
+ return this.style(v)
+
} else {
/* store value */
this.attrs[a] = v
@@ -472,28 +496,38 @@
a == 'text' ?
this.text(v) :
a == 'leading' ?
- this[a] = v :
- this.style[a] = v
-
- this.text(this.content)
+ this.leading(v) :
+ this.style(a, v)
+
+ /* rebuild if required */
+ if (this.rebuild)
+ this.rebuild()
}
}
return this
}
// Manage transformations
- , transform: function(o) {
- /* act as a getter if the first argument is a string */
- if (typeof o === 'string')
- return this.trans[o]
+ , transform: function(o, v) {
+ if (typeof o === 'string') {
+ /* act as a getter if only one string argument is given */
+ if (arguments.length < 2)
+ return this.trans[o]
+ /* apply transformations as object if key value arguments are given*/
+ var transform = {}
+ transform[o] = v
+
+ return this.transform(transform)
+ }
+
/* ... otherwise continue as a setter */
- var key, transform = []
+ var transform = []
/* merge values */
- for (key in o)
- if (o[key] != null)
- this.trans[key] = o[key]
+ for (v in o)
+ if (o[v] != null)
+ this.trans[v] = o[v]
/* alias current transformations */
o = this.trans
@@ -524,6 +558,52 @@
/* add only te required transformations */
return this.attr('transform', transform.join(' '))
}
+ // Dynamic style generator
+ , style: function(s, v) {
+ if (arguments.length == 0) {
+ /* get full style */
+ return this.attr('style')
+
+ } else if (arguments.length < 2) {
+ /* apply every style individually if an object is passed */
+ if (typeof s == 'object') {
+ for (v in s) this.style(v, s[v])
+
+ } else if (SVG.regex.isCss.test(s)) {
+ /* parse css string */
+ s = s.split(';')
+
+ /* apply every definition individually */
+ for (var i = 0; i < s.length; i++) {
+ v = s[i].split(':')
+
+ if (v.length == 2)
+ this.style(v[0].replace(/\s+/g, ''), v[1].replace(/^\s+/,'').replace(/\s+$/,''))
+ }
+ } else {
+ /* act as a getter if the first and only argument is not an object */
+ return this.styles[s]
+ }
+
+ } else if (v === null) {
+ /* remove value */
+ delete this.styles[s]
+
+ } else {
+ /* store value */
+ this.styles[s] = v
+ }
+
+ /* rebuild style string */
+ s = ''
+ for (v in this.styles)
+ s += v + ':' + this.styles[v] + ';'
+
+ /* apply style */
+ this.node.setAttribute('style', s)
+
+ return this
+ }
// Store data values on svg nodes
, data: function(a, v, r) {
if (arguments.length < 2) {
@@ -554,19 +634,15 @@
}
// Show element
, show: function() {
- this.node.style.display = ''
-
- return this
+ return this.style('display', '')
}
// Hide element
, hide: function() {
- this.node.style.display = 'none'
-
- return this
+ return this.style('display', 'none')
}
// Is element visible?
, visible: function() {
- return this.node.style.display != 'none'
+ return this.style('display') != 'none'
}
// Private: find svg parent by instance
, _parent: function(parent) {
@@ -579,7 +655,7 @@
}
// Private: tester method for style detection
, _isStyle: function(attr) {
- return typeof attr == 'string' && this._isText() ? (/^font|text|leading/).test(attr) : false
+ return typeof attr == 'string' ? SVG.regex.isStyle.test(attr) : false
}
// Private: element type tester
, _isText: function() {
@@ -755,7 +831,7 @@
duration = duration == null ? 1000 : duration
ease = ease || '<>'
- var akeys, tkeys, tvalues
+ var akeys, tkeys, skeys
, element = this.target
, fx = this
, start = new Date().getTime()
@@ -764,24 +840,29 @@
/* start animation */
this.interval = setInterval(function(){
// This code was borrowed from the emile.js micro framework by Thomas Fuchs, aka MadRobby.
- var index
+ var i, key
, time = new Date().getTime()
, pos = time > finish ? 1 : (time - start) / duration
/* collect attribute keys */
if (akeys == null) {
akeys = []
- for (var key in fx.attrs)
+ for (key in fx.attrs)
akeys.push(key)
}
/* collect transformation keys */
if (tkeys == null) {
tkeys = []
- for (var key in fx.trans)
+ for (key in fx.trans)
tkeys.push(key)
-
- tvalues = {}
+ }
+
+ /* collect style keys */
+ if (skeys == null) {
+ skeys = []
+ for (key in fx.styles)
+ skeys.push(key)
}
/* apply easing */
@@ -801,23 +882,23 @@
if (fx._move)
element.move(fx._at(fx._move.x, pos), fx._at(fx._move.y, pos))
else if (fx._center)
- element.move(fx._at(fx._center.x, pos), fx._at(fx._center.y, pos))
+ element.center(fx._at(fx._center.x, pos), fx._at(fx._center.y, pos))
/* run all size properties */
if (fx._size)
element.size(fx._at(fx._size.width, pos), fx._at(fx._size.height, pos))
/* animate attributes */
- for (index = akeys.length - 1; index >= 0; index--)
- element.attr(akeys[index], fx._at(fx.attrs[akeys[index]], pos))
+ for (i = akeys.length - 1; i >= 0; i--)
+ element.attr(akeys[i], fx._at(fx.attrs[akeys[i]], pos))
/* animate transformations */
- if (tkeys.length > 0) {
- for (index = tkeys.length - 1; index >= 0; index--)
- tvalues[tkeys[index]] = fx._at(fx.trans[tkeys[index]], pos)
-
- element.transform(tvalues)
- }
+ for (i = tkeys.length - 1; i >= 0; i--)
+ element.transform(tkeys[i], fx._at(fx.trans[tkeys[i]], pos))
+
+ /* animate styles */
+ for (i = skeys.length - 1; i >= 0; i--)
+ element.style(skeys[i], fx._at(fx.styles[skeys[i]], pos))
/* callback for each keyframe */
if (fx._during)
@@ -844,12 +925,23 @@
else
this.attrs[a] = { from: this.target.attr(a), to: v }
- return this;
+ return this
}
// Add animatable transformations
- , transform: function(o) {
- for (var key in o)
- this.trans[key] = { from: this.target.trans[key], to: o[key] }
+ , transform: function(t, v) {
+ for (var key in t)
+ this.trans[key] = { from: this.target.trans[key], to: t[key] }
+
+ return this
+ }
+ // Add animatable styles
+ , style: function(s, v) {
+ if (typeof s == 'object')
+ for (var key in s)
+ this.style(key, s[key])
+
+ else
+ this.styles[s] = { from: this.target.style(s), to: v }
return this
}
@@ -866,11 +958,18 @@
}
// Add animatable size
, size: function(width, height) {
- var box = this.target.bbox()
-
- this._size = {
- width: { from: box.width, to: width }
- , height: { from: box.height, to: height }
+ if (this.target instanceof SVG.Text) {
+ /* animate font size for Text elements */
+ this.attr('font-size', width)
+
+ } else {
+ /* animate bbox based size for all other elements */
+ var box = this.target.bbox()
+
+ this._size = {
+ width: { from: box.width, to: width }
+ , height: { from: box.height, to: height }
+ }
}
return this
@@ -906,6 +1005,7 @@
/* reset storage for properties that need animation */
this.attrs = {}
this.trans = {}
+ this.styles = {}
this._move = null
this._size = null
this._after = null
@@ -986,28 +1086,27 @@
// })
- ;[ 'click',
- 'dblclick',
- 'mousedown',
- 'mouseup',
- 'mouseover',
- 'mouseout',
- 'mousemove',
- 'mouseenter',
- 'mouseleave',
- 'touchstart',
- 'touchend',
- 'touchmove',
- 'touchcancel' ].forEach(function(event) {
+ ;[ 'click'
+ , 'dblclick'
+ , 'mousedown'
+ , 'mouseup'
+ , 'mouseover'
+ , 'mouseout'
+ , 'mousemove'
+ , 'mouseenter'
+ , 'mouseleave'
+ , 'touchstart'
+ , 'touchend'
+ , 'touchmove'
+ , 'touchcancel' ].forEach(function(event) {
/* add event to SVG.Element */
SVG.Element.prototype[event] = function(f) {
var self = this
/* bind event to element rather than element node */
- this.node['on' + event] = typeof f == 'function'
- ? function() { return f.apply(self, arguments); }
- : null
+ this.node['on' + event] = typeof f == 'function' ?
+ function() { return f.apply(self, arguments) } : null
return this
}
@@ -1037,14 +1136,14 @@
SVG.on(this.node, event, listener)
return this
- },
+ }
// Unbind event from listener
- off: function(event, listener) {
+ , off: function(event, listener) {
SVG.off(this.node, event, listener)
return this
}
- });
+ })
SVG.G = function() {
this.constructor.call(this, SVG.create('g'))
@@ -1091,11 +1190,9 @@
}
// Send given element one step backward
, backward: function() {
- var i
-
this.parent.level()
- i = this.position()
+ var i = this.position()
if (i > 1)
this.parent.remove(this).add(this, i - 1)
@@ -1171,11 +1268,11 @@
block(element)
return element.attr({
- x: 0,
- y: 0,
- width: width,
- height: height,
- patternUnits: 'userSpaceOnUse'
+ x: 0
+ , y: 0
+ , width: width
+ , height: height
+ , patternUnits: 'userSpaceOnUse'
})
}
@@ -1198,25 +1295,25 @@
return this.type == 'radial' ?
this.attr({ fx: x + '%', fy: y + '%' }) :
this.attr({ x1: x + '%', y1: y + '%' })
- },
+ }
// To position
- to: function(x, y) {
+ , to: function(x, y) {
return this.type == 'radial' ?
this.attr({ cx: x + '%', cy: y + '%' }) :
this.attr({ x2: x + '%', y2: y + '%' })
- },
+ }
// Radius for radial gradient
- radius: function(radius) {
+ , radius: function(radius) {
return this.type == 'radial' ?
this.attr({ r: radius + '%' }) :
this
- },
+ }
// Add a color stop
- at: function(stop) {
+ , at: function(stop) {
return this.put(new SVG.Stop(stop))
- },
+ }
// Update gradient
- update: function(block) {
+ , update: function(block) {
/* remove all stops */
while (this.node.hasChildNodes())
this.node.removeChild(this.node.lastChild)
@@ -1225,9 +1322,9 @@
block(this)
return this
- },
+ }
// Return the fill id
- fill: function() {
+ , fill: function() {
return 'url(#' + this.attr('id') + ')'
}
@@ -1264,20 +1361,16 @@
/* add color stops */
update: function(o) {
- var index,
- style = '',
- attr = ['opacity', 'color']
+ var index
+ , attr = ['opacity', 'color']
/* build style attribute */
for (index = attr.length - 1; index >= 0; index--)
if (o[attr[index]] != null)
- style += 'stop-' + attr[index] + ':' + o[attr[index]] + ';'
+ this.style('stop-' + attr[index], o[attr[index]])
/* set attributes */
- return this.attr({
- offset: (o.offset != null ? o.offset : this.attrs.offset || 0) + '%',
- style: style
- })
+ return this.attr('offset', (o.offset != null ? o.offset : this.attrs.offset || 0) + '%')
}
})
@@ -1309,9 +1402,9 @@
// Basically it sets the position of the svg node to absolute
// when the dom is loaded, and resets it to relative a few milliseconds later.
SVG.Doc.prototype.stage = function() {
- var check,
- element = this,
- wrapper = document.createElement('div')
+ var check
+ , element = this
+ , wrapper = document.createElement('div')
/* set temp wrapper to position relative */
wrapper.style.cssText = 'position:relative;height:100%;'
@@ -1323,10 +1416,10 @@
/* check for dom:ready */
check = function() {
if (document.readyState === 'complete') {
- element.attr('style', 'position:absolute;')
+ element.style('position:absolute;')
setTimeout(function() {
/* set position back to relative */
- element.attr('style', 'position:relative;')
+ element.style('position:relative;')
/* remove temp wrapper */
element.parent.removeChild(element.node.parentNode)
@@ -1349,7 +1442,7 @@
}
// Inherit from SVG.Element
- SVG.Shape.prototype = new SVG.Element()
+ SVG.Shape.prototype = new SVG.Element
SVG.Wrap = function(element) {
this.constructor.call(this, SVG.create('g'))
@@ -1367,30 +1460,30 @@
// Move wrapper around
move: function(x, y) {
return this.transform({
- x: x,
- y: y
+ x: x
+ , y: y
})
- },
+ }
// Set the actual size in pixels
- size: function(width, height) {
+ , size: function(width, height) {
var scale = width / this._b.width
this.child.transform({
- scaleX: scale,
- scaleY: height != null ? height / this._b.height : scale
+ scaleX: scale
+ , scaleY: height != null ? height / this._b.height : scale
})
return this
- },
+ }
// Move by center
- center: function(x, y) {
+ , center: function(x, y) {
return this.move(
- x + (this._b.width * this.child.trans.scaleX) / -2,
- y + (this._b.height * this.child.trans.scaleY) / -2
+ x + (this._b.width * this.child.trans.scaleX) / -2
+ , y + (this._b.height * this.child.trans.scaleY) / -2
)
- },
+ }
// Create distributed attr
- attr: function(a, v, n) {
+ , attr: function(a, v, n) {
/* call individual attributes if an object is given */
if (typeof a == 'object') {
for (v in a) this.attr(v, a[v])
@@ -1413,9 +1506,9 @@
}
return this
- },
+ }
// Distribute plot method to child
- plot: function(data) {
+ , plot: function(data) {
/* plot new shape */
this.child.plot(data)
@@ -1424,8 +1517,8 @@
/* reposition element withing wrapper */
this.child.transform({
- x: -this._b.x,
- y: -this._b.y
+ x: -this._b.x
+ , y: -this._b.y
})
return this
@@ -1438,7 +1531,7 @@
}
// Inherit from SVG.Shape
- SVG.Rect.prototype = new SVG.Shape()
+ SVG.Rect.prototype = new SVG.Shape
SVG.Ellipse = function() {
this.constructor.call(this, SVG.create('ellipse'))
@@ -1458,15 +1551,15 @@
},
// Custom size function
size: function(width, height) {
- return this.
- attr({ rx: width / 2, ry: (height != null ? height : width) / 2 }).
- center()
+ return this
+ .attr({ rx: width / 2, ry: (height != null ? height : width) / 2 })
+ .center()
},
// Custom center function
center: function(x, y) {
return this.attr({
- cx: x || (this.attrs.x || 0) + (this.attrs.rx || 0),
- cy: y || (this.attrs.y || 0) + (this.attrs.ry || 0)
+ cx: x != null ? x : (this.attrs.x || 0) + (this.attrs.rx || 0)
+ , cy: y != null ? y : (this.attrs.y || 0) + (this.attrs.ry || 0)
})
}
@@ -1490,24 +1583,25 @@
var bbox = this.bbox()
return this.attr({
- x1: this.attr('x1') - bbox.x + x,
- y1: this.attr('y1') - bbox.y + y,
- x2: this.attr('x2') - bbox.x + x,
- y2: this.attr('y2') - bbox.y + y
+ x1: this.attr('x1') - bbox.x + x
+ , y1: this.attr('y1') - bbox.y + y
+ , x2: this.attr('x2') - bbox.x + x
+ , y2: this.attr('y2') - bbox.y + y
})
- },
+ }
// Move element by its center
- center: function(x, y) {
+ , center: function(x, y) {
var bbox = this.bbox()
return this.move(x - bbox.width / 2, y - bbox.height / 2)
- },
+ }
// Set line size by width and height
- size: function(width, height) {
+ , size: function(width, height) {
var bbox = this.bbox()
- this.attr(this.attr('x1') < this.attr('x2') ? 'x2' : 'x1', bbox.x + width)
- return this.attr(this.attr('y1') < this.attr('y2') ? 'y2' : 'y1', bbox.y + height)
+ return this
+ .attr(this.attr('x1') < this.attr('x2') ? 'x2' : 'x1', bbox.x + width)
+ .attr(this.attr('y1') < this.attr('y2') ? 'y2' : 'y1', bbox.y + height)
}
})
@@ -1515,10 +1609,10 @@
SVG.extend(SVG.Container, {
line: function(x1, y1, x2, y2) {
return this.put(new SVG.Line().attr({
- x1: x1,
- y1: y1,
- x2: x2,
- y2: y2
+ x1: x1
+ , y1: y1
+ , x2: x2
+ , y2: y2
}))
}
})
@@ -1537,7 +1631,7 @@
}
// Inherit from SVG.Shape
- SVG.Polyline.prototype = new SVG.Shape()
+ SVG.Polyline.prototype = new SVG.Shape
// Add polygon-specific functions
SVG.extend(SVG.Polyline, SVG.Poly)
@@ -1547,7 +1641,7 @@
}
// Inherit from SVG.Shape
- SVG.Polygon.prototype = new SVG.Shape()
+ SVG.Polygon.prototype = new SVG.Shape
// Add polygon-specific functions
SVG.extend(SVG.Polygon, SVG.Poly)
@@ -1560,21 +1654,20 @@
SVG.Path.prototype = new SVG.Shape()
SVG.extend(SVG.Path, {
-
- /* move using transform */
+ // Move using transform
move: function(x, y) {
this.transform({
x: x,
y: y
})
- },
+ }
- /* set path data */
- plot: function(data) {
+ // Set path data
+ , plot: function(data) {
return this.attr('d', data || 'M0,0')
}
- });
+ })
SVG.Image = function() {
this.constructor.call(this, SVG.create('image'))
@@ -1593,78 +1686,118 @@
})
- var _styleAttr = ['size', 'family', 'weight', 'stretch', 'variant', 'style']
+ var _styleAttr = ('size family weight stretch variant style').split(' ')
SVG.Text = function() {
this.constructor.call(this, SVG.create('text'))
/* define default style */
- this.style = { 'font-size': 16, 'font-family': 'Helvetica', 'text-anchor': 'start' }
- this.leading = 1.2
+ this.styles = {
+ 'font-size': 16
+ , 'font-family': 'Helvetica'
+ , 'text-anchor': 'start'
+ }
+
+ this._leading = 1.2
}
// Inherit from SVG.Element
- SVG.Text.prototype = new SVG.Shape()
+ SVG.Text.prototype = new SVG.Shape
SVG.extend(SVG.Text, {
// Set the text content
text: function(text) {
- /* update the content */
- this.content = text = text || 'text'
- this.lines = []
+ /* act as getter */
+ if (text == null)
+ return this.content
- var index, length, tspan,
- style = this._style(),
- parent = this.doc(),
- lines = text.split("\n"),
- size = this.style['font-size']
+ /* remove existing lines */
+ this.clear()
- /* remove existing child nodes */
- while (this.node.hasChildNodes())
- this.node.removeChild(this.node.lastChild)
+ /* update the content */
+ this.content = SVG.regex.isBlank.test(text) ? 'text' : text
+
+ var i, il
+ , lines = text.split('\n')
/* build new lines */
- for (index = 0, length = lines.length; index < length; index++) {
- /* create new tspan and set attributes */
- tspan = new SVG.TSpan().
- text(lines[index]).
- attr({
- dy: size * this.leading - (index == 0 ? size * 0.3 : 0),
- x: (this.attrs.x || 0),
- style: style
- })
+ for (i = 0, il = lines.length; i < il; i++)
+ this.tspan(lines[i])
- /* add new tspan */
- this.node.appendChild(tspan.node)
- this.lines.push(tspan)
- }
-
/* set style */
- return this.attr('style', style)
- },
-
- // Build style based on _styleAttr
- _style: function() {
- var index, style = ''
+ return this.attr('style', this.style())
+ }
+ // Create a tspan
+ , tspan: function(text) {
+ var tspan = new SVG.TSpan().text(text)
- for (index = _styleAttr.length - 1; index >= 0; index--)
- if (this.style['font-' + _styleAttr[index]] != null)
- style += 'font-' + _styleAttr[index] + ':' + this.style['font-' + _styleAttr[index]] + ';'
+ /* add new tspan */
+ this.node.appendChild(tspan.node)
+ this.lines.push(tspan)
- style += 'text-anchor:' + this.style['text-anchor'] + ';'
-
- return style
+ return tspan.attr('style', this.style())
+ }
+ // Move element by its center
+ , center: function(x, y) {
+ var anchor = this.style('text-anchor')
+ , box = this.bbox()
+ , x = anchor == 'start' ?
+ x - box.width / 2 :
+ anchor == 'end' ?
+ x + box.width / 2 : x
+
+ return this.move(x, y - box.height / 2)
+ }
+ // Set font size
+ , size: function(size) {
+ return this.attr('font-size', size)
+ }
+ // Set / get leading
+ , leading: function(value) {
+ /* act as getter */
+ if (value == null)
+ return this._leading
+
+ /* act as setter */
+ this._leading = value
+
+ return this.rebuild()
+ }
+ // rebuild appearance type
+ , rebuild: function() {
+ var i, il
+ , size = this.styles['font-size']
+
+ /* define position of all lines */
+ for (i = 0, il = this.lines.length; i < il; i++)
+ this.lines[i].attr({
+ dy: size * this._leading - (i == 0 ? size * 0.3 : 0)
+ , x: (this.attrs.x || 0)
+ , style: this.style()
+ })
+
+ return this
+ }
+ // Clear all lines
+ , clear: function() {
+ /* remove existing child nodes */
+ while (this.node.hasChildNodes())
+ this.node.removeChild(this.node.lastChild)
+
+ this.lines = []
+
+ return this
}
})
-
+ // tspan class
SVG.TSpan = function() {
this.constructor.call(this, SVG.create('tspan'))
}
// Inherit from SVG.Shape
- SVG.TSpan.prototype = new SVG.Shape()
+ SVG.TSpan.prototype = new SVG.Shape
// Include the container object
SVG.extend(SVG.TSpan, {
@@ -1675,12 +1808,12 @@
return this
}
- });
+ })
SVG.Nested = function() {
this.constructor.call(this, SVG.create('svg'))
- this.attr('style', 'overflow:visible')
+ this.style('overflow', 'visible')
}
// Inherit from SVG.Container
@@ -1750,23 +1883,19 @@
if (SVG.Text) {
- SVG.extend(SVG.Text, {
+ SVG.extend(SVG.Text, SVG.FX, {
// Set font
font: function(o) {
- var key, attr = {}
-
- for (key in o)
- key == 'leading' ?
- attr[key] = o[key] :
+ for (var key in o)
key == 'anchor' ?
- attr['text-anchor'] = o[key] :
+ this.attr('text-anchor', o[key]) :
_styleAttr.indexOf(key) > -1 ?
- attr['font-'+ key] = o[key] :
- void 0
-
- return this.attr(attr).text(this.content)
+ this.attr('font-'+ key, o[key]) :
+ this.attr(key, o[key])
+
+ return this
}
-
+
})
}
diff --git a/dist/svg.min.js b/dist/svg.min.js
index 37d363f..b406ded 100644
--- a/dist/svg.min.js
+++ b/dist/svg.min.js
@@ -1,2 +1,2 @@
-/* svg.js v0.8-5-g5e3ff07 - svg regex color viewbox bbox element container fx event group arrange defs mask pattern gradient doc shape wrap rect ellipse line poly path image text nested sugar - svgjs.com/license */
-(function(){this.svg=function(e){if(SVG.supported)return new SVG.Doc(e)},this.SVG={ns:"http://www.w3.org/2000/svg",xlink:"http://www.w3.org/1999/xlink",did:1e3,eid:function(e){return"Svgjs"+e.charAt(0).toUpperCase()+e.slice(1)+"Element"+SVG.did++},create:function(e){var t=document.createElementNS(this.ns,e);return t.setAttribute("id",this.eid(e)),t},extend:function(){var e,t,n,r;e=Array.prototype.slice.call(arguments),t=e.pop();for(r=e.length-1;r>=0;r--)if(e[r])for(n in t)e[r].prototype[n]=t[n]}},SVG.supported=function(){return!!document.createElementNS&&!!document.createElementNS(SVG.ns,"svg").createSVGRect}();if(!SVG.supported)return!1;SVG.regex={unit:/^([\d\.]+)([a-z%]{0,2})$/,hex:/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,rgb:/rgb\((\d+),(\d+),(\d+),([\d\.]+)\)/,hsb:/hsb\((\d+),(\d+),(\d+),([\d\.]+)\)/,isHex:/^#/i,isRgb:/^rgb\(/,isHsb:/^hsb\(/},SVG.Color=function(e){var t;this.r=0,this.g=0,this.b=0,typeof e=="string"?SVG.regex.isRgb.test(e)?(t=SVG.regex.rgb.exec(e.replace(/\s/g,"")),this.r=parseInt(m[1]),this.g=parseInt(m[2]),this.b=parseInt(m[3])):SVG.regex.isHex.test(e)?(t=SVG.regex.hex.exec(this._fullHex(e)),this.r=parseInt(t[1],16),this.g=parseInt(t[2],16),this.b=parseInt(t[3],16)):SVG.regex.isHsb.test(e)&&(t=SVG.regex.hsb.exec(e.replace(/\s/g,"")),e=this._hsbToRgb(t[1],t[2],t[3])):typeof e=="object"&&(SVG.Color.isHsb(e)&&(e=this._hsbToRgb(e.h,e.s,e.b)),this.r=e.r,this.g=e.g,this.b=e.b)},SVG.extend(SVG.Color,{toString:function(){return this.toHex()},toHex:function(){return"#"+this._compToHex(this.r)+this._compToHex(this.g)+this._compToHex(this.b)},toRgb:function(){return"rgb("+[this.r,this.g,this.b].join()+")"},brightness:function(){return this.r/255*.3+this.g/255*.59+this.b/255*.11},_hsbToRgb:function(e,t,n){var i,s;e=parseInt(e)%360,e<0&&(e+=360),t=parseInt(t),t=t>100?100:t,n=parseInt(n),n=(n<0?0:n>100?100:n)*255/100,i=n*t/100,s=i*(e*256/60%256)/256;switch(Math.floor(e/60)){case 0:r=n,g=n-i+s,b=n-i;break;case 1:r=n-s,g=n,b=n-i;break;case 2:r=n-i,g=n,b=n-i+s;break;case 3:r=n-i,g=n-s,b=n;break;case 4:r=n-i+s,g=n-i,b=n;break;case 5:r=n,g=n-i,b=n-s}return{r:Math.floor(r+.5),g:Math.floor(g+.5),b:Math.floor(b+.5)}},_fullHex:function(e){return e.length==4?["#",e.substring(1,2),e.substring(1,2),e.substring(2,3),e.substring(2,3),e.substring(3,4),e.substring(3,4)].join(""):e},_compToHex:function(e){var t=e.toString(16);return t.length==1?"0"+t:t}}),SVG.Color.test=function(e){return e+="",SVG.regex.isHex.test(e)||SVG.regex.isRgb.test(e)||SVG.regex.isHsb.test(e)},SVG.Color.isRgb=function(e){return typeof e.r=="number"},SVG.Color.isHsb=function(e){return typeof e.h=="number"},SVG.ViewBox=function(e){var t,n,r,i,s=e.bbox(),o=(e.attr("viewBox")||"").match(/[\d\.]+/g);this.x=s.x,this.y=s.y,this.width=e.node.offsetWidth||e.attr("width"),this.height=e.node.offsetHeight||e.attr("height"),o&&(t=parseFloat(o[0]),n=parseFloat(o[1]),r=parseFloat(o[2])-t,i=parseFloat(o[3])-n,this.zoom=this.width/this.height>r/i?this.height/i:this.width/r,this.x=t,this.y=n,this.width=r,this.height=i),this.zoom=this.zoom||1},SVG.extend(SVG.ViewBox,{toString:function(){return this.x+" "+this.y+" "+this.width+" "+this.height}}),SVG.BBox=function(e){var t=e.node.getBBox();this.x=t.x+e.trans.x,this.y=t.y+e.trans.y,this.cx=t.x+e.trans.x+t.width/2,this.cy=t.y+e.trans.y+t.height/2,this.width=t.width,this.height=t.height},SVG.Element=function(e){this.attrs={"fill-opacity":1,"stroke-opacity":1,"stroke-width":0,fill:"#000",stroke:"#000",opacity:1,x:0,y:0,cx:0,cy:0,width:0,height:0,r:0,rx:0,ry:0},this.style={},this.trans={x:0,y:0,scaleX:1,scaleY:1,rotation:0,skewX:0,skewY:0};if(this.node=e)this.type=e.nodeName,this.attrs.id=e.getAttribute("id")},SVG.extend(SVG.Element,{move:function(e,t){return this.attr({x:e,y:t})},center:function(e,t){var n=this.bbox();return this.move(e-n.width/2,t-n.height/2)},size:function(e,t){return this.attr({width:e,height:t})},clone:function(){var e;if(this instanceof SVG.Wrap)e=this.parent[this.child.node.nodeName](),e.attrs=this.attrs,e.child.trans=this.child.trans,e.child.attr(this.child.attrs).transform({}),e.plot&&e.plot(this.child.attrs[this.child instanceof SVG.Path?"d":"points"]);else{var t=this.node.nodeName;e=t=="rect"?this.parent[t](this.attrs.width,this.attrs.height):t=="ellipse"?this.parent[t](this.attrs.rx*2,this.attrs.ry*2):t=="image"?this.parent[t](this.src):t=="text"?this.parent[t](this.content):t=="g"?this.parent.group():this.parent[t](),e.attr(this.attrs)}return e.trans=this.trans,e.transform({})},remove:function(){return this.parent&&this.parent.remove(this),this},doc:function(){return this._parent(SVG.Doc)},nested:function(){return this._parent(SVG.Nested)},attr:function(e,t,n){if(arguments.length<2){if(typeof e!="object")return this._isStyle(e)?e=="text"?this.content:e=="leading"?this[e]:this.style[e]:this.attrs[e];for(t in e)this.attr(t,e[t])}else if(t===null)this.node.removeAttribute(e);else{this.attrs[e]=t;if(e=="x"&&this._isText())for(var r=this.lines.length-1;r>=0;r--)this.lines[r].attr(e,t);else{e=="stroke-width"&&this.attr("stroke",parseFloat(t)>0?this.attrs.stroke:null);if(SVG.Color.test(t)||SVG.Color.isRgb(t)||SVG.Color.isHsb(t))t=(new SVG.Color(t)).toHex();n!=null?this.node.setAttributeNS(n,e,t):this.node.setAttribute(e,t)}this._isStyle(e)&&(e=="text"?this.text(t):e=="leading"?this[e]=t:this.style[e]=t,this.text(this.content))}return this},transform:function(e){if(typeof e=="string")return this.trans[e];var t,n=[];for(t in e)e[t]!=null&&(this.trans[t]=e[t]);return e=this.trans,e.rotation!=0&&n.push("rotate("+e.rotation+","+(e.cx!=null?e.cx:this.bbox().cx)+","+(e.cy!=null?e.cy:this.bbox().cy)+")"),n.push("scale("+e.scaleX+","+e.scaleY+")"),e.skewX!=0&&n.push("skewX("+e.skewX+")"),e.skewY!=0&&n.push("skewY("+e.skewY+")"),n.push("translate("+e.x+","+e.y+")"),this.attr("transform",n.join(" "))},data:function(e,t,n){if(arguments.length<2)try{return JSON.parse(this.attr("data-"+e))}catch(r){return this.attr("data-"+e)}else this.attr("data-"+e,t===null?null:n===!0?t:JSON.stringify(t));return this},bbox:function(){return new SVG.BBox(this)},inside:function(e,t){var n=this.bbox();return e>n.x&&t>n.y&&e<n.x+n.width&&t<n.y+n.height},show:function(){return this.node.style.display="",this},hide:function(){return this.node.style.display="none",this},visible:function(){return this.node.style.display!="none"},_parent:function(e){var t=this;while(t!=null&&!(t instanceof e))t=t.parent;return t},_isStyle:function(e){return typeof e=="string"&&this._isText()?/^font|text|leading/.test(e):!1},_isText:function(){return this instanceof SVG.Text}}),SVG.Container=function(e){this.constructor.call(this,e)},SVG.Container.prototype=new SVG.Element,SVG.extend(SVG.Container,{add:function(e,t){if(!this.has(e)){t=t==null?this.children().length:t;if(e.parent){var n=e.parent.children().indexOf(e);e.parent.children().splice(n,1)}this.children().splice(t,0,e),this.node.insertBefore(e.node,this.node.childNodes[t]||null),e.parent=this}return this},put:function(e,t){return this.add(e,t),e},has:function(e){return this.children().indexOf(e)>=0},children:function(){return this._children||(this._children=[])},each:function(e){var t,n=this.children();for(t=0,length=n.length;t<length;t++)n[t]instanceof SVG.Shape&&e.apply(n[t],[t,n]);return this},remove:function(e){var t=this.children().indexOf(e);return this.children().splice(t,1),this.node.removeChild(e.node),e.parent=null,this},defs:function(){return this._defs||(this._defs=this.put(new SVG.Defs,0))},level:function(){return this.remove(this.defs()).put(this.defs(),0)},group:function(){return this.put(new SVG.G)},rect:function(e,t){return this.put((new SVG.Rect).size(e,t))},circle:function(e){return this.ellipse(e)},ellipse:function(e,t){return this.put((new SVG.Ellipse).size(e,t))},polyline:function(e){return this.put(new SVG.Wrap(new SVG.Polyline)).plot(e)},polygon:function(e){return this.put(new SVG.Wrap(new SVG.Polygon)).plot(e)},path:function(e){return this.put(new SVG.Wrap(new SVG.Path)).plot(e)},image:function(e,t,n){return t=t!=null?t:100,this.put((new SVG.Image).load(e).size(t,n!=null?n:t))},text:function(e){return this.put((new SVG.Text).text(e))},nested:function(){return this.put(new SVG.Nested)},gradient:function(e,t){return this.defs().gradient(e,t)},pattern:function(e,t,n){return this.defs().pattern(e,t,n)},mask:function(){return this.defs().put(new SVG.Mask)},first:function(){return this.children()[0]instanceof SVG.Defs?this.children()[1]:this.children()[0]},last:function(){return this.children()[this.children().length-1]},viewbox:function(){return arguments.length==0?new SVG.ViewBox(this):this.attr("viewBox",Array.prototype.slice.call(arguments).join(" "))},clear:function(){this._children=[];while(this.node.hasChildNodes())this.node.removeChild(this.node.lastChild);return this}}),SVG.FX=function(e){this.target=e},SVG.extend(SVG.FX,{animate:function(e,t){e=e==null?1e3:e,t=t||"<>";var n,r,i,s=this.target,o=this,u=(new Date).getTime(),a=u+e;return this.interval=setInterval(function(){var f,l=(new Date).getTime(),c=l>a?1:(l-u)/e;if(n==null){n=[];for(var h in o.attrs)n.push(h)}if(r==null){r=[];for(var h in o.trans)r.push(h);i={}}c=t=="<>"?-Math.cos(c*Math.PI)/2+.5:t==">"?Math.sin(c*Math.PI/2):t=="<"?-Math.cos(c*Math.PI/2)+1:t=="-"?c:typeof t=="function"?t(c):c,o._move?s.move(o._at(o._move.x,c),o._at(o._move.y,c)):o._center&&s.move(o._at(o._center.x,c),o._at(o._center.y,c)),o._size&&s.size(o._at(o._size.width,c),o._at(o._size.height,c));for(f=n.length-1;f>=0;f--)s.attr(n[f],o._at(o.attrs[n[f]],c));if(r.length>0){for(f=r.length-1;f>=0;f--)i[r[f]]=o._at(o.trans[r[f]],c);s.transform(i)}o._during&&o._during.call(s,c,function(e,t){return o._at({from:e,to:t},c)}),l>a&&(clearInterval(o.interval),o._after?o._after.apply(s,[o]):o.stop())},e>10?10:e),this},attr:function(e,t,n){if(typeof e=="object")for(var r in e)this.attr(r,e[r]);else this.attrs[e]={from:this.target.attr(e),to:t};return this},transform:function(e){for(var t in e)this.trans[t]={from:this.target.trans[t],to:e[t]};return this},move:function(e,t){var n=this.target.bbox();return this._move={x:{from:n.x,to:e},y:{from:n.y,to:t}},this},size:function(e,t){var n=this.target.bbox();return this._size={width:{from:n.width,to:e},height:{from:n.height,to:t}},this},center:function(e,t){var n=this.target.bbox();return this._move={x:{from:n.cx,to:e-n.width/2},y:{from:n.cy,to:t-n.height/2}},this},during:function(e){return this._during=e,this},after:function(e){return this._after=e,this},stop:function(){return clearInterval(this.interval),this.attrs={},this.trans={},this._move=null,this._size=null,this._after=null,this._during=null,this},_at:function(e,t){return typeof e.from=="number"?e.from+(e.to-e.from)*t:SVG.regex.unit.test(e.to)?this._unit(e,t):e.to&&(e.to.r||SVG.Color.test(e.to))?this._color(e,t):t<1?e.from:e.to},_unit:function(e,t){var n,r;return n=SVG.regex.unit.exec(e.from.toString()),r=parseFloat(n[1]),n=SVG.regex.unit.exec(e.to),r+(parseFloat(n[1])-r)*t+n[2]},_color:function(e,t){var n,r;return t=t<0?0:t>1?1:t,n=new SVG.Color(e.from),r=new SVG.Color(e.to),(new SVG.Color({r:~~(n.r+(r.r-n.r)*t),g:~~(n.g+(r.g-n.g)*t),b:~~(n.b+(r.b-n.b)*t)})).toHex()}}),SVG.extend(SVG.Element,{animate:function(e,t){return(this.fx||(this.fx=new SVG.FX(this))).stop().animate(e,t)},stop:function(){return this.fx.stop(),this}}),["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","mouseenter","mouseleave","touchstart","touchend","touchmove","touchcancel"].forEach(function(e){SVG.Element.prototype[e]=function(t){var n=this;return this.node["on"+e]=typeof t=="function"?function(){return t.apply(n,arguments)}:null,this}}),SVG.on=function(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent("on"+t,n)},SVG.off=function(e,t,n){e.removeEventListener?e.removeEventListener(t,n,!1):e.detachEvent("on"+t,n)},SVG.extend(SVG.Element,{on:function(e,t){return SVG.on(this.node,e,t),this},off:function(e,t){return SVG.off(this.node,e,t),this}}),SVG.G=function(){this.constructor.call(this,SVG.create("g"))},SVG.G.prototype=new SVG.Container,SVG.extend(SVG.G,{move:function(e,t){return this.transform({x:e,y:t})},defs:function(){return this.doc().defs()}}),SVG.extend(SVG.Element,{siblings:function(){return this.parent.children()},position:function(){return this.siblings().indexOf(this)},next:function(){return this.siblings()[this.position()+1]},previous:function(){return this.siblings()[this.position()-1]},forward:function(){return this.parent.remove(this).put(this,this.position()+1)},backward:function(){var e;return this.parent.level(),e=this.position(),e>1&&this.parent.remove(this).add(this,e-1),this},front:function(){return this.parent.remove(this).put(this)},back:function(){return this.parent.level(),this.position()>1&&this.parent.remove(this).add(this,0),this}}),SVG.Defs=function(){this.constructor.call(this,SVG.create("defs"))},SVG.Defs.prototype=new SVG.Container,SVG.Mask=function(){this.constructor.call(this,SVG.create("mask"))},SVG.Mask.prototype=new SVG.Container,SVG.extend(SVG.Element,{maskWith:function(e){return this.mask=e instanceof SVG.Mask?e:this.parent.mask().add(e),this.attr("mask","url(#"+this.mask.attr("id")+")")}}),SVG.Pattern=function(e){this.constructor.call(this,SVG.create("pattern"))},SVG.Pattern.prototype=new SVG.Container,SVG.extend(SVG.Pattern,{fill:function(){return"url(#"+this.attr("id")+")"}}),SVG.extend(SVG.Defs,{pattern:function(e,t,n){var r=this.put(new SVG.Pattern);return n(r),r.attr({x:0,y:0,width:e,height:t,patternUnits:"userSpaceOnUse"})}}),SVG.Gradient=function(e){this.constructor.call(this,SVG.create(e+"Gradient")),this.type=e},SVG.Gradient.prototype=new SVG.Container,SVG.extend(SVG.Gradient,{from:function(e,t){return this.type=="radial"?this.attr({fx:e+"%",fy:t+"%"}):this.attr({x1:e+"%",y1:t+"%"})},to:function(e,t){return this.type=="radial"?this.attr({cx:e+"%",cy:t+"%"}):this.attr({x2:e+"%",y2:t+"%"})},radius:function(e){return this.type=="radial"?this.attr({r:e+"%"}):this},at:function(e){return this.put(new SVG.Stop(e))},update:function(e){while(this.node.hasChildNodes())this.node.removeChild(this.node.lastChild);return e(this),this},fill:function(){return"url(#"+this.attr("id")+")"}}),SVG.extend(SVG.Defs,{gradient:function(e,t){var n=this.put(new SVG.Gradient(e));return t(n),n}}),SVG.Stop=function(e){this.constructor.call(this,SVG.create("stop")),this.update(e)},SVG.Stop.prototype=new SVG.Element,SVG.extend(SVG.Stop,{update:function(e){var t,n="",r=["opacity","color"];for(t=r.length-1;t>=0;t--)e[r[t]]!=null&&(n+="stop-"+r[t]+":"+e[r[t]]+";");return this.attr({offset:(e.offset!=null?e.offset:this.attrs.offset||0)+"%",style:n})}}),SVG.Doc=function(e){this.constructor.call(this,SVG.create("svg")),this.parent=typeof e=="string"?document.getElementById(e):e,this.attr({xmlns:SVG.ns,version:"1.1",width:"100%",height:"100%"}).attr("xlink",SVG.xlink,SVG.ns).defs(),this.stage()},SVG.Doc.prototype=new SVG.Container,SVG.Doc.prototype.stage=function(){var e,t=this,n=document.createElement("div");return n.style.cssText="position:relative;height:100%;",t.parent.appendChild(n),n.appendChild(t.node),e=function(){document.readyState==="complete"?(t.attr("style","position:absolute;"),setTimeout(function(){t.attr("style","position:relative;"),t.parent.removeChild(t.node.parentNode),t.node.parentNode.removeChild(t.node),t.parent.appendChild(t.node)},5)):setTimeout(e,10)},e(),this},SVG.Shape=function(e){this.constructor.call(this,e)},SVG.Shape.prototype=new SVG.Element,SVG.Wrap=function(e){this.constructor.call(this,SVG.create("g")),this.node.insertBefore(e.node,null),this.child=e,this.type=e.node.nodeName},SVG.Wrap.prototype=new SVG.Shape,SVG.extend(SVG.Wrap,{move:function(e,t){return this.transform({x:e,y:t})},size:function(e,t){var n=e/this._b.width;return this.child.transform({scaleX:n,scaleY:t!=null?t/this._b.height:n}),this},center:function(e,t){return this.move(e+this._b.width*this.child.trans.scaleX/-2,t+this._b.height*this.child.trans.scaleY/-2)},attr:function(e,t,n){if(typeof e=="object")for(t in e)this.attr(t,e[t]);else{if(arguments.length<2)return e=="transform"?this.attrs[e]:this.child.attrs[e];e=="transform"?(this.attrs[e]=t,n!=null?this.node.setAttributeNS(n,e,t):this.node.setAttribute(e,t)):this.child.attr(e,t,n)}return this},plot:function(e){return this.child.plot(e),this._b=this.child.bbox(),this.child.transform({x:-this._b.x,y:-this._b.y}),this}}),SVG.Rect=function(){this.constructor.call(this,SVG.create("rect"))},SVG.Rect.prototype=new SVG.Shape,SVG.Ellipse=function(){this.constructor.call(this,SVG.create("ellipse"))},SVG.Ellipse.prototype=new SVG.Shape,SVG.extend(SVG.Ellipse,{move:function(e,t){return this.attrs.x=e,this.attrs.y=t,this.center()},size:function(e,t){return this.attr({rx:e/2,ry:(t!=null?t:e)/2}).center()},center:function(e,t){return this.attr({cx:e||(this.attrs.x||0)+(this.attrs.rx||0),cy:t||(this.attrs.y||0)+(this.attrs.ry||0)})}}),SVG.Line=function(){this.constructor.call(this,SVG.create("line"))},SVG.Line.prototype=new SVG.Shape,SVG.extend(SVG.Line,{move:function(e,t){var n=this.bbox();return this.attr({x1:this.attr("x1")-n.x+e,y1:this.attr("y1")-n.y+t,x2:this.attr("x2")-n.x+e,y2:this.attr("y2")-n.y+t})},center:function(e,t){var n=this.bbox();return this.move(e-n.width/2,t-n.height/2)},size:function(e,t){var n=this.bbox();return this.attr(this.attr("x1")<this.attr("x2")?"x2":"x1",n.x+e),this.attr(this.attr("y1")<this.attr("y2")?"y2":"y1",n.y+t)}}),SVG.extend(SVG.Container,{line:function(e,t,n,r){return this.put((new SVG.Line).attr({x1:e,y1:t,x2:n,y2:r}))}}),SVG.Poly={plot:function(e){return this.attr("points",e||"0,0"),this}},SVG.Polyline=function(){this.constructor.call(this,SVG.create("polyline"))},SVG.Polyline.prototype=new SVG.Shape,SVG.extend(SVG.Polyline,SVG.Poly),SVG.Polygon=function(){this.constructor.call(this,SVG.create("polygon"))},SVG.Polygon.prototype=new SVG.Shape,SVG.extend(SVG.Polygon,SVG.Poly),SVG.Path=function(){this.constructor.call(this,SVG.create("path"))},SVG.Path.prototype=new SVG.Shape,SVG.extend(SVG.Path,{move:function(e,t){this.transform({x:e,y:t})},plot:function(e){return this.attr("d",e||"M0,0")}}),SVG.Image=function(){this.constructor.call(this,SVG.create("image"))},SVG.Image.prototype=new SVG.Shape,SVG.extend(SVG.Image,{load:function(e){return this.src=e,e?this.attr("xlink:href",e,SVG.xlink):this}});var e=["size","family","weight","stretch","variant","style"];SVG.Text=function(){this.constructor.call(this,SVG.create("text")),this.style={"font-size":16,"font-family":"Helvetica","text-anchor":"start"},this.leading=1.2},SVG.Text.prototype=new SVG.Shape,SVG.extend(SVG.Text,{text:function(e){this.content=e=e||"text",this.lines=[];var t,n,r,i=this._style(),s=this.doc(),o=e.split("\n"),u=this.style["font-size"];while(this.node.hasChildNodes())this.node.removeChild(this.node.lastChild);for(t=0,n=o.length;t<n;t++)r=(new SVG.TSpan).text(o[t]).attr({dy:u*this.leading-(t==0?u*.3:0),x:this.attrs.x||0,style:i}),this.node.appendChild(r.node),this.lines.push(r);return this.attr("style",i)},_style:function(){var t,n="";for(t=e.length-1;t>=0;t--)this.style["font-"+e[t]]!=null&&(n+="font-"+e[t]+":"+this.style["font-"+e[t]]+";");return n+="text-anchor:"+this.style["text-anchor"]+";",n}}),SVG.TSpan=function(){this.constructor.call(this,SVG.create("tspan"))},SVG.TSpan.prototype=new SVG.Shape,SVG.extend(SVG.TSpan,{text:function(e){return this.node.appendChild(document.createTextNode(e)),this}}),SVG.Nested=function(){this.constructor.call(this,SVG.create("svg")),this.attr("style","overflow:visible")},SVG.Nested.prototype=new SVG.Container,SVG._stroke=["color","width","opacity","linecap","linejoin","miterlimit","dasharray","dashoffset"],SVG._fill=["color","opacity","rule"];var t=function(e,t){return t=="color"?e:e+"-"+t};["fill","stroke"].forEach(function(e){var n={};n[e]=function(n){var r;if(typeof n=="string"||SVG.Color.isRgb(n)||SVG.Color.isHsb(n))this.attr(e,n);else for(index=SVG["_"+e].length-1;index>=0;index--)n[SVG["_"+e][index]]!=null&&this.attr(t(e,SVG["_"+e][index]),n[SVG["_"+e][index]]);return this},SVG.extend(SVG.Shape,SVG.FX,n)}),SVG.extend(SVG.Element,SVG.FX,{rotate:function(e,t,n){return this.transform({rotation:e||0,cx:t,cy:n})},skew:function(e,t){return this.transform({skewX:e||0,skewY:t||0})},scale:function(e,t){return this.transform({scaleX:e,scaleY:t==null?e:t})},opacity:function(e){return this.attr("opacity",e)}}),SVG.Text&&SVG.extend(SVG.Text,{font:function(t){var n,r={};for(n in t)n=="leading"?r[n]=t[n]:n=="anchor"?r["text-anchor"]=t[n]:e.indexOf(n)>-1?r["font-"+n]=t[n]:void 0;return this.attr(r).text(this.content)}})}).call(this); \ No newline at end of file
+/* svg.js v0.9 - svg regex color viewbox bbox element container fx event group arrange defs mask pattern gradient doc shape wrap rect ellipse line poly path image text nested sugar - svgjs.com/license */
+(function(){this.SVG=function(e){if(SVG.supported)return new SVG.Doc(e)},this.svg=function(e){return console.warn("WARNING: svg() is deprecated, please use SVG() instead."),SVG(e)},SVG.ns="http://www.w3.org/2000/svg",SVG.xlink="http://www.w3.org/1999/xlink",SVG.did=1e3,SVG.eid=function(e){return"Svgjs"+e.charAt(0).toUpperCase()+e.slice(1)+"Element"+SVG.did++},SVG.create=function(e){var t=document.createElementNS(this.ns,e);return t.setAttribute("id",this.eid(e)),t},SVG.extend=function(){var e,t,n,r;e=Array.prototype.slice.call(arguments),t=e.pop();for(r=e.length-1;r>=0;r--)if(e[r])for(n in t)e[r].prototype[n]=t[n]},SVG.supported=function(){return!!document.createElementNS&&!!document.createElementNS(SVG.ns,"svg").createSVGRect}();if(!SVG.supported)return!1;SVG.regex={unit:/^([\d\.]+)([a-z%]{0,2})$/,hex:/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,rgb:/rgb\((\d+),(\d+),(\d+),([\d\.]+)\)/,hsb:/hsb\((\d+),(\d+),(\d+),([\d\.]+)\)/,isHex:/^#[a-f0-9]{3,6}$/i,isRgb:/^rgb\(/,isHsb:/^hsb\(/,isCss:/[^:]+:[^;]+;?/,isStyle:/^font|text|leading|cursor/,isBlank:/^(\s+)?$/},SVG.Color=function(e){var t;this.r=0,this.g=0,this.b=0,typeof e=="string"?SVG.regex.isRgb.test(e)?(t=SVG.regex.rgb.exec(e.replace(/\s/g,"")),this.r=parseInt(m[1]),this.g=parseInt(m[2]),this.b=parseInt(m[3])):SVG.regex.isHex.test(e)?(t=SVG.regex.hex.exec(this._fullHex(e)),this.r=parseInt(t[1],16),this.g=parseInt(t[2],16),this.b=parseInt(t[3],16)):SVG.regex.isHsb.test(e)&&(t=SVG.regex.hsb.exec(e.replace(/\s/g,"")),e=this._hsbToRgb(t[1],t[2],t[3])):typeof e=="object"&&(SVG.Color.isHsb(e)&&(e=this._hsbToRgb(e.h,e.s,e.b)),this.r=e.r,this.g=e.g,this.b=e.b)},SVG.extend(SVG.Color,{toString:function(){return this.toHex()},toHex:function(){return"#"+this._compToHex(this.r)+this._compToHex(this.g)+this._compToHex(this.b)},toRgb:function(){return"rgb("+[this.r,this.g,this.b].join()+")"},brightness:function(){return this.r/255*.3+this.g/255*.59+this.b/255*.11},_hsbToRgb:function(e,t,n){var i,s;e=parseInt(e)%360,e<0&&(e+=360),t=parseInt(t),t=t>100?100:t,n=parseInt(n),n=(n<0?0:n>100?100:n)*255/100,i=n*t/100,s=i*(e*256/60%256)/256;switch(Math.floor(e/60)){case 0:r=n,g=n-i+s,b=n-i;break;case 1:r=n-s,g=n,b=n-i;break;case 2:r=n-i,g=n,b=n-i+s;break;case 3:r=n-i,g=n-s,b=n;break;case 4:r=n-i+s,g=n-i,b=n;break;case 5:r=n,g=n-i,b=n-s}return{r:Math.floor(r+.5),g:Math.floor(g+.5),b:Math.floor(b+.5)}},_fullHex:function(e){return e.length==4?["#",e.substring(1,2),e.substring(1,2),e.substring(2,3),e.substring(2,3),e.substring(3,4),e.substring(3,4)].join(""):e},_compToHex:function(e){var t=e.toString(16);return t.length==1?"0"+t:t}}),SVG.Color.test=function(e){return e+="",SVG.regex.isHex.test(e)||SVG.regex.isRgb.test(e)||SVG.regex.isHsb.test(e)},SVG.Color.isRgb=function(e){return typeof e.r=="number"},SVG.Color.isHsb=function(e){return typeof e.h=="number"},SVG.ViewBox=function(e){var t,n,r,i,s=e.bbox(),o=(e.attr("viewBox")||"").match(/[\d\.]+/g);this.x=s.x,this.y=s.y,this.width=e.node.offsetWidth||e.attr("width"),this.height=e.node.offsetHeight||e.attr("height"),o&&(t=parseFloat(o[0]),n=parseFloat(o[1]),r=parseFloat(o[2])-t,i=parseFloat(o[3])-n,this.zoom=this.width/this.height>r/i?this.height/i:this.width/r,this.x=t,this.y=n,this.width=r,this.height=i),this.zoom=this.zoom||1},SVG.extend(SVG.ViewBox,{toString:function(){return this.x+" "+this.y+" "+this.width+" "+this.height}}),SVG.BBox=function(e){var t=e.node.getBBox();this.x=t.x+e.trans.x,this.y=t.y+e.trans.y,this.cx=t.x+e.trans.x+t.width/2,this.cy=t.y+e.trans.y+t.height/2,this.width=t.width,this.height=t.height},SVG.Element=function(e){this.attrs={"fill-opacity":1,"stroke-opacity":1,"stroke-width":0,fill:"#000",stroke:"#000",opacity:1,x:0,y:0,cx:0,cy:0,width:0,height:0,r:0,rx:0,ry:0},this.styles={},this.trans={x:0,y:0,scaleX:1,scaleY:1,rotation:0,skewX:0,skewY:0};if(this.node=e)this.type=e.nodeName,this.attrs.id=e.getAttribute("id")},SVG.extend(SVG.Element,{move:function(e,t){return this.attr({x:e,y:t})},center:function(e,t){var n=this.bbox();return this.move(e-n.width/2,t-n.height/2)},size:function(e,t){return this.attr({width:e,height:t})},clone:function(){var e;if(this instanceof SVG.Wrap)e=this.parent[this.child.node.nodeName](),e.attrs=this.attrs,e.child.trans=this.child.trans,e.child.attr(this.child.attrs).transform({}),e.plot&&e.plot(this.child.attrs[this.child instanceof SVG.Path?"d":"points"]);else{var t=this.node.nodeName;e=t=="rect"?this.parent[t](this.attrs.width,this.attrs.height):t=="ellipse"?this.parent[t](this.attrs.rx*2,this.attrs.ry*2):t=="image"?this.parent[t](this.src):t=="text"?this.parent[t](this.content):t=="g"?this.parent.group():this.parent[t](),e.attr(this.attrs)}return e.trans=this.trans,e.transform({})},remove:function(){return this.parent&&this.parent.remove(this),this},doc:function(){return this._parent(SVG.Doc)},nested:function(){return this._parent(SVG.Nested)},attr:function(e,t,n){if(arguments.length<2){if(typeof e!="object")return this._isStyle(e)?e=="text"?this.content:e=="leading"?this.leading():this.style(e):this.attrs[e]||this.node.getAttribute(e);for(t in e)this.attr(t,e[t])}else if(t===null)this.node.removeAttribute(e);else{if(e=="style")return this.style(t);this.attrs[e]=t;if(e=="x"&&this._isText())for(var r=this.lines.length-1;r>=0;r--)this.lines[r].attr(e,t);else{e=="stroke-width"&&this.attr("stroke",parseFloat(t)>0?this.attrs.stroke:null);if(SVG.Color.test(t)||SVG.Color.isRgb(t)||SVG.Color.isHsb(t))t=(new SVG.Color(t)).toHex();n!=null?this.node.setAttributeNS(n,e,t):this.node.setAttribute(e,t)}this._isStyle(e)&&(e=="text"?this.text(t):e=="leading"?this.leading(t):this.style(e,t),this.rebuild&&this.rebuild())}return this},transform:function(e,t){if(typeof e=="string"){if(arguments.length<2)return this.trans[e];var n={};return n[e]=t,this.transform(n)}var n=[];for(t in e)e[t]!=null&&(this.trans[t]=e[t]);return e=this.trans,e.rotation!=0&&n.push("rotate("+e.rotation+","+(e.cx!=null?e.cx:this.bbox().cx)+","+(e.cy!=null?e.cy:this.bbox().cy)+")"),n.push("scale("+e.scaleX+","+e.scaleY+")"),e.skewX!=0&&n.push("skewX("+e.skewX+")"),e.skewY!=0&&n.push("skewY("+e.skewY+")"),n.push("translate("+e.x+","+e.y+")"),this.attr("transform",n.join(" "))},style:function(e,t){if(arguments.length==0)return this.attr("style");if(arguments.length<2)if(typeof e=="object")for(t in e)this.style(t,e[t]);else{if(!SVG.regex.isCss.test(e))return this.styles[e];e=e.split(";");for(var n=0;n<e.length;n++)t=e[n].split(":"),t.length==2&&this.style(t[0].replace(/\s+/g,""),t[1].replace(/^\s+/,"").replace(/\s+$/,""))}else t===null?delete this.styles[e]:this.styles[e]=t;e="";for(t in this.styles)e+=t+":"+this.styles[t]+";";return this.node.setAttribute("style",e),this},data:function(e,t,n){if(arguments.length<2)try{return JSON.parse(this.attr("data-"+e))}catch(r){return this.attr("data-"+e)}else this.attr("data-"+e,t===null?null:n===!0?t:JSON.stringify(t));return this},bbox:function(){return new SVG.BBox(this)},inside:function(e,t){var n=this.bbox();return e>n.x&&t>n.y&&e<n.x+n.width&&t<n.y+n.height},show:function(){return this.style("display","")},hide:function(){return this.style("display","none")},visible:function(){return this.style("display")!="none"},_parent:function(e){var t=this;while(t!=null&&!(t instanceof e))t=t.parent;return t},_isStyle:function(e){return typeof e=="string"?SVG.regex.isStyle.test(e):!1},_isText:function(){return this instanceof SVG.Text}}),SVG.Container=function(e){this.constructor.call(this,e)},SVG.Container.prototype=new SVG.Element,SVG.extend(SVG.Container,{add:function(e,t){if(!this.has(e)){t=t==null?this.children().length:t;if(e.parent){var n=e.parent.children().indexOf(e);e.parent.children().splice(n,1)}this.children().splice(t,0,e),this.node.insertBefore(e.node,this.node.childNodes[t]||null),e.parent=this}return this},put:function(e,t){return this.add(e,t),e},has:function(e){return this.children().indexOf(e)>=0},children:function(){return this._children||(this._children=[])},each:function(e){var t,n=this.children();for(t=0,length=n.length;t<length;t++)n[t]instanceof SVG.Shape&&e.apply(n[t],[t,n]);return this},remove:function(e){var t=this.children().indexOf(e);return this.children().splice(t,1),this.node.removeChild(e.node),e.parent=null,this},defs:function(){return this._defs||(this._defs=this.put(new SVG.Defs,0))},level:function(){return this.remove(this.defs()).put(this.defs(),0)},group:function(){return this.put(new SVG.G)},rect:function(e,t){return this.put((new SVG.Rect).size(e,t))},circle:function(e){return this.ellipse(e)},ellipse:function(e,t){return this.put((new SVG.Ellipse).size(e,t))},polyline:function(e){return this.put(new SVG.Wrap(new SVG.Polyline)).plot(e)},polygon:function(e){return this.put(new SVG.Wrap(new SVG.Polygon)).plot(e)},path:function(e){return this.put(new SVG.Wrap(new SVG.Path)).plot(e)},image:function(e,t,n){return t=t!=null?t:100,this.put((new SVG.Image).load(e).size(t,n!=null?n:t))},text:function(e){return this.put((new SVG.Text).text(e))},nested:function(){return this.put(new SVG.Nested)},gradient:function(e,t){return this.defs().gradient(e,t)},pattern:function(e,t,n){return this.defs().pattern(e,t,n)},mask:function(){return this.defs().put(new SVG.Mask)},first:function(){return this.children()[0]instanceof SVG.Defs?this.children()[1]:this.children()[0]},last:function(){return this.children()[this.children().length-1]},viewbox:function(){return arguments.length==0?new SVG.ViewBox(this):this.attr("viewBox",Array.prototype.slice.call(arguments).join(" "))},clear:function(){this._children=[];while(this.node.hasChildNodes())this.node.removeChild(this.node.lastChild);return this}}),SVG.FX=function(e){this.target=e},SVG.extend(SVG.FX,{animate:function(e,t){e=e==null?1e3:e,t=t||"<>";var n,r,i,s=this.target,o=this,u=(new Date).getTime(),a=u+e;return this.interval=setInterval(function(){var f,l,c=(new Date).getTime(),h=c>a?1:(c-u)/e;if(n==null){n=[];for(l in o.attrs)n.push(l)}if(r==null){r=[];for(l in o.trans)r.push(l)}if(i==null){i=[];for(l in o.styles)i.push(l)}h=t=="<>"?-Math.cos(h*Math.PI)/2+.5:t==">"?Math.sin(h*Math.PI/2):t=="<"?-Math.cos(h*Math.PI/2)+1:t=="-"?h:typeof t=="function"?t(h):h,o._move?s.move(o._at(o._move.x,h),o._at(o._move.y,h)):o._center&&s.center(o._at(o._center.x,h),o._at(o._center.y,h)),o._size&&s.size(o._at(o._size.width,h),o._at(o._size.height,h));for(f=n.length-1;f>=0;f--)s.attr(n[f],o._at(o.attrs[n[f]],h));for(f=r.length-1;f>=0;f--)s.transform(r[f],o._at(o.trans[r[f]],h));for(f=i.length-1;f>=0;f--)s.style(i[f],o._at(o.styles[i[f]],h));o._during&&o._during.call(s,h,function(e,t){return o._at({from:e,to:t},h)}),c>a&&(clearInterval(o.interval),o._after?o._after.apply(s,[o]):o.stop())},e>10?10:e),this},attr:function(e,t,n){if(typeof e=="object")for(var r in e)this.attr(r,e[r]);else this.attrs[e]={from:this.target.attr(e),to:t};return this},transform:function(e,t){for(var n in e)this.trans[n]={from:this.target.trans[n],to:e[n]};return this},style:function(e,t){if(typeof e=="object")for(var n in e)this.style(n,e[n]);else this.styles[e]={from:this.target.style(e),to:t};return this},move:function(e,t){var n=this.target.bbox();return this._move={x:{from:n.x,to:e},y:{from:n.y,to:t}},this},size:function(e,t){if(this.target instanceof SVG.Text)this.attr("font-size",e);else{var n=this.target.bbox();this._size={width:{from:n.width,to:e},height:{from:n.height,to:t}}}return this},center:function(e,t){var n=this.target.bbox();return this._move={x:{from:n.cx,to:e-n.width/2},y:{from:n.cy,to:t-n.height/2}},this},during:function(e){return this._during=e,this},after:function(e){return this._after=e,this},stop:function(){return clearInterval(this.interval),this.attrs={},this.trans={},this.styles={},this._move=null,this._size=null,this._after=null,this._during=null,this},_at:function(e,t){return typeof e.from=="number"?e.from+(e.to-e.from)*t:SVG.regex.unit.test(e.to)?this._unit(e,t):e.to&&(e.to.r||SVG.Color.test(e.to))?this._color(e,t):t<1?e.from:e.to},_unit:function(e,t){var n,r;return n=SVG.regex.unit.exec(e.from.toString()),r=parseFloat(n[1]),n=SVG.regex.unit.exec(e.to),r+(parseFloat(n[1])-r)*t+n[2]},_color:function(e,t){var n,r;return t=t<0?0:t>1?1:t,n=new SVG.Color(e.from),r=new SVG.Color(e.to),(new SVG.Color({r:~~(n.r+(r.r-n.r)*t),g:~~(n.g+(r.g-n.g)*t),b:~~(n.b+(r.b-n.b)*t)})).toHex()}}),SVG.extend(SVG.Element,{animate:function(e,t){return(this.fx||(this.fx=new SVG.FX(this))).stop().animate(e,t)},stop:function(){return this.fx.stop(),this}}),["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","mouseenter","mouseleave","touchstart","touchend","touchmove","touchcancel"].forEach(function(e){SVG.Element.prototype[e]=function(t){var n=this;return this.node["on"+e]=typeof t=="function"?function(){return t.apply(n,arguments)}:null,this}}),SVG.on=function(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent("on"+t,n)},SVG.off=function(e,t,n){e.removeEventListener?e.removeEventListener(t,n,!1):e.detachEvent("on"+t,n)},SVG.extend(SVG.Element,{on:function(e,t){return SVG.on(this.node,e,t),this},off:function(e,t){return SVG.off(this.node,e,t),this}}),SVG.G=function(){this.constructor.call(this,SVG.create("g"))},SVG.G.prototype=new SVG.Container,SVG.extend(SVG.G,{move:function(e,t){return this.transform({x:e,y:t})},defs:function(){return this.doc().defs()}}),SVG.extend(SVG.Element,{siblings:function(){return this.parent.children()},position:function(){return this.siblings().indexOf(this)},next:function(){return this.siblings()[this.position()+1]},previous:function(){return this.siblings()[this.position()-1]},forward:function(){return this.parent.remove(this).put(this,this.position()+1)},backward:function(){this.parent.level();var e=this.position();return e>1&&this.parent.remove(this).add(this,e-1),this},front:function(){return this.parent.remove(this).put(this)},back:function(){return this.parent.level(),this.position()>1&&this.parent.remove(this).add(this,0),this}}),SVG.Defs=function(){this.constructor.call(this,SVG.create("defs"))},SVG.Defs.prototype=new SVG.Container,SVG.Mask=function(){this.constructor.call(this,SVG.create("mask"))},SVG.Mask.prototype=new SVG.Container,SVG.extend(SVG.Element,{maskWith:function(e){return this.mask=e instanceof SVG.Mask?e:this.parent.mask().add(e),this.attr("mask","url(#"+this.mask.attr("id")+")")}}),SVG.Pattern=function(e){this.constructor.call(this,SVG.create("pattern"))},SVG.Pattern.prototype=new SVG.Container,SVG.extend(SVG.Pattern,{fill:function(){return"url(#"+this.attr("id")+")"}}),SVG.extend(SVG.Defs,{pattern:function(e,t,n){var r=this.put(new SVG.Pattern);return n(r),r.attr({x:0,y:0,width:e,height:t,patternUnits:"userSpaceOnUse"})}}),SVG.Gradient=function(e){this.constructor.call(this,SVG.create(e+"Gradient")),this.type=e},SVG.Gradient.prototype=new SVG.Container,SVG.extend(SVG.Gradient,{from:function(e,t){return this.type=="radial"?this.attr({fx:e+"%",fy:t+"%"}):this.attr({x1:e+"%",y1:t+"%"})},to:function(e,t){return this.type=="radial"?this.attr({cx:e+"%",cy:t+"%"}):this.attr({x2:e+"%",y2:t+"%"})},radius:function(e){return this.type=="radial"?this.attr({r:e+"%"}):this},at:function(e){return this.put(new SVG.Stop(e))},update:function(e){while(this.node.hasChildNodes())this.node.removeChild(this.node.lastChild);return e(this),this},fill:function(){return"url(#"+this.attr("id")+")"}}),SVG.extend(SVG.Defs,{gradient:function(e,t){var n=this.put(new SVG.Gradient(e));return t(n),n}}),SVG.Stop=function(e){this.constructor.call(this,SVG.create("stop")),this.update(e)},SVG.Stop.prototype=new SVG.Element,SVG.extend(SVG.Stop,{update:function(e){var t,n=["opacity","color"];for(t=n.length-1;t>=0;t--)e[n[t]]!=null&&this.style("stop-"+n[t],e[n[t]]);return this.attr("offset",(e.offset!=null?e.offset:this.attrs.offset||0)+"%")}}),SVG.Doc=function(e){this.constructor.call(this,SVG.create("svg")),this.parent=typeof e=="string"?document.getElementById(e):e,this.attr({xmlns:SVG.ns,version:"1.1",width:"100%",height:"100%"}).attr("xlink",SVG.xlink,SVG.ns).defs(),this.stage()},SVG.Doc.prototype=new SVG.Container,SVG.Doc.prototype.stage=function(){var e,t=this,n=document.createElement("div");return n.style.cssText="position:relative;height:100%;",t.parent.appendChild(n),n.appendChild(t.node),e=function(){document.readyState==="complete"?(t.style("position:absolute;"),setTimeout(function(){t.style("position:relative;"),t.parent.removeChild(t.node.parentNode),t.node.parentNode.removeChild(t.node),t.parent.appendChild(t.node)},5)):setTimeout(e,10)},e(),this},SVG.Shape=function(e){this.constructor.call(this,e)},SVG.Shape.prototype=new SVG.Element,SVG.Wrap=function(e){this.constructor.call(this,SVG.create("g")),this.node.insertBefore(e.node,null),this.child=e,this.type=e.node.nodeName},SVG.Wrap.prototype=new SVG.Shape,SVG.extend(SVG.Wrap,{move:function(e,t){return this.transform({x:e,y:t})},size:function(e,t){var n=e/this._b.width;return this.child.transform({scaleX:n,scaleY:t!=null?t/this._b.height:n}),this},center:function(e,t){return this.move(e+this._b.width*this.child.trans.scaleX/-2,t+this._b.height*this.child.trans.scaleY/-2)},attr:function(e,t,n){if(typeof e=="object")for(t in e)this.attr(t,e[t]);else{if(arguments.length<2)return e=="transform"?this.attrs[e]:this.child.attrs[e];e=="transform"?(this.attrs[e]=t,n!=null?this.node.setAttributeNS(n,e,t):this.node.setAttribute(e,t)):this.child.attr(e,t,n)}return this},plot:function(e){return this.child.plot(e),this._b=this.child.bbox(),this.child.transform({x:-this._b.x,y:-this._b.y}),this}}),SVG.Rect=function(){this.constructor.call(this,SVG.create("rect"))},SVG.Rect.prototype=new SVG.Shape,SVG.Ellipse=function(){this.constructor.call(this,SVG.create("ellipse"))},SVG.Ellipse.prototype=new SVG.Shape,SVG.extend(SVG.Ellipse,{move:function(e,t){return this.attrs.x=e,this.attrs.y=t,this.center()},size:function(e,t){return this.attr({rx:e/2,ry:(t!=null?t:e)/2}).center()},center:function(e,t){return this.attr({cx:e!=null?e:(this.attrs.x||0)+(this.attrs.rx||0),cy:t!=null?t:(this.attrs.y||0)+(this.attrs.ry||0)})}}),SVG.Line=function(){this.constructor.call(this,SVG.create("line"))},SVG.Line.prototype=new SVG.Shape,SVG.extend(SVG.Line,{move:function(e,t){var n=this.bbox();return this.attr({x1:this.attr("x1")-n.x+e,y1:this.attr("y1")-n.y+t,x2:this.attr("x2")-n.x+e,y2:this.attr("y2")-n.y+t})},center:function(e,t){var n=this.bbox();return this.move(e-n.width/2,t-n.height/2)},size:function(e,t){var n=this.bbox();return this.attr(this.attr("x1")<this.attr("x2")?"x2":"x1",n.x+e).attr(this.attr("y1")<this.attr("y2")?"y2":"y1",n.y+t)}}),SVG.extend(SVG.Container,{line:function(e,t,n,r){return this.put((new SVG.Line).attr({x1:e,y1:t,x2:n,y2:r}))}}),SVG.Poly={plot:function(e){return this.attr("points",e||"0,0"),this}},SVG.Polyline=function(){this.constructor.call(this,SVG.create("polyline"))},SVG.Polyline.prototype=new SVG.Shape,SVG.extend(SVG.Polyline,SVG.Poly),SVG.Polygon=function(){this.constructor.call(this,SVG.create("polygon"))},SVG.Polygon.prototype=new SVG.Shape,SVG.extend(SVG.Polygon,SVG.Poly),SVG.Path=function(){this.constructor.call(this,SVG.create("path"))},SVG.Path.prototype=new SVG.Shape,SVG.extend(SVG.Path,{move:function(e,t){this.transform({x:e,y:t})},plot:function(e){return this.attr("d",e||"M0,0")}}),SVG.Image=function(){this.constructor.call(this,SVG.create("image"))},SVG.Image.prototype=new SVG.Shape,SVG.extend(SVG.Image,{load:function(e){return this.src=e,e?this.attr("xlink:href",e,SVG.xlink):this}});var e="size family weight stretch variant style".split(" ");SVG.Text=function(){this.constructor.call(this,SVG.create("text")),this.styles={"font-size":16,"font-family":"Helvetica","text-anchor":"start"},this._leading=1.2},SVG.Text.prototype=new SVG.Shape,SVG.extend(SVG.Text,{text:function(e){if(e==null)return this.content;this.clear(),this.content=SVG.regex.isBlank.test(e)?"text":e;var t,n,r=e.split("\n");for(t=0,n=r.length;t<n;t++)this.tspan(r[t]);return this.attr("style",this.style())},tspan:function(e){var t=(new SVG.TSpan).text(e);return this.node.appendChild(t.node),this.lines.push(t),t.attr("style",this.style())},center:function(e,t){var n=this.style("text-anchor"),r=this.bbox(),e=n=="start"?e-r.width/2:n=="end"?e+r.width/2:e;return this.move(e,t-r.height/2)},size:function(e){return this.attr("font-size",e)},leading:function(e){return e==null?this._leading:(this._leading=e,this.rebuild())},rebuild:function(){var e,t,n=this.styles["font-size"];for(e=0,t=this.lines.length;e<t;e++)this.lines[e].attr({dy:n*this._leading-(e==0?n*.3:0),x:this.attrs.x||0,style:this.style()});return this},clear:function(){while(this.node.hasChildNodes())this.node.removeChild(this.node.lastChild);return this.lines=[],this}}),SVG.TSpan=function(){this.constructor.call(this,SVG.create("tspan"))},SVG.TSpan.prototype=new SVG.Shape,SVG.extend(SVG.TSpan,{text:function(e){return this.node.appendChild(document.createTextNode(e)),this}}),SVG.Nested=function(){this.constructor.call(this,SVG.create("svg")),this.style("overflow","visible")},SVG.Nested.prototype=new SVG.Container,SVG._stroke=["color","width","opacity","linecap","linejoin","miterlimit","dasharray","dashoffset"],SVG._fill=["color","opacity","rule"];var t=function(e,t){return t=="color"?e:e+"-"+t};["fill","stroke"].forEach(function(e){var n={};n[e]=function(n){var r;if(typeof n=="string"||SVG.Color.isRgb(n)||SVG.Color.isHsb(n))this.attr(e,n);else for(index=SVG["_"+e].length-1;index>=0;index--)n[SVG["_"+e][index]]!=null&&this.attr(t(e,SVG["_"+e][index]),n[SVG["_"+e][index]]);return this},SVG.extend(SVG.Shape,SVG.FX,n)}),SVG.extend(SVG.Element,SVG.FX,{rotate:function(e,t,n){return this.transform({rotation:e||0,cx:t,cy:n})},skew:function(e,t){return this.transform({skewX:e||0,skewY:t||0})},scale:function(e,t){return this.transform({scaleX:e,scaleY:t==null?e:t})},opacity:function(e){return this.attr("opacity",e)}}),SVG.Text&&SVG.extend(SVG.Text,SVG.FX,{font:function(t){for(var n in t)n=="anchor"?this.attr("text-anchor",t[n]):e.indexOf(n)>-1?this.attr("font-"+n,t[n]):this.attr(n,t[n]);return this}})}).call(this); \ No newline at end of file