summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dirty.html27
-rw-r--r--dist/svg.js1238
-rw-r--r--dist/svg.min.js4
-rw-r--r--gulpfile.js4
-rw-r--r--src/animator.js (renamed from src/drawLoop.js)11
-rw-r--r--src/helpers.js58
-rw-r--r--src/matrix.js85
-rw-r--r--src/morph.js216
-rw-r--r--src/number.js7
-rw-r--r--src/timeline.js220
10 files changed, 669 insertions, 1201 deletions
diff --git a/dirty.html b/dirty.html
new file mode 100644
index 0000000..4896341
--- /dev/null
+++ b/dirty.html
@@ -0,0 +1,27 @@
+
+<!DOCTYPE html>
+<html lang="en" dir="ltr">
+<head>
+ <meta charset="utf-8">
+ <title></title>
+ <script type="text/javascript" src="dist/svg.js"></script>
+</head>
+<body>
+
+<!-- Making the svg -->
+<svg>
+ <rect x=50 y=100 width=200 height=100 fill=blue />
+</svg>
+
+<!-- Modifying the svg -->
+<script>
+
+
+let rect = SVG('rect')
+
+
+
+</script>
+
+</body>
+</html>
diff --git a/dist/svg.js b/dist/svg.js
index 1c92b34..7e80e03 100644
--- a/dist/svg.js
+++ b/dist/svg.js
@@ -6,7 +6,7 @@
* @copyright Wout Fierens <wout@mick-wout.com>
* @license MIT
*
-* BUILT: Tue Apr 17 2018 21:58:30 GMT+1000 (AEST)
+* BUILT: Mon Apr 30 2018 18:47:43 GMT+1000 (AEST)
*/;
(function(root, factory) {
@@ -242,6 +242,13 @@ SVG.utils = {
SVG.defaults = {
+ // Default animation values
+ timeline: {
+ duration: 600,
+ ease: '>',
+ delay: 0,
+ },
+
// Default attribute values
attrs: {
@@ -364,89 +371,6 @@ SVG.Queue = SVG.invent({
}
})
-
-SVG.Draw = {
- nextDraw: null,
- frames: new SVG.Queue(),
- timeouts: new SVG.Queue(),
- frameCount: 0,
- timeoutCount: 0,
- timer: window.performance || window.Date,
-
- frame: function (fn) {
- SVG.Draw.frames.push({
- id: SVG.Draw.frameCount,
- run: fn
- })
-
- if (SVG.Draw.nextDraw === null) {
- SVG.Draw.nextDraw = requestAnimationFrame(SVG.Draw._draw)
- }
-
- return ++SVG.Draw.frameCount
- },
-
- timeout: function (fn, delay) {
- delay = delay || 0
-
- // Work out when the event should fire
- var time = SVG.Draw.timer.now() + delay
-
- // Add the timeout to the end of the queue
- var thisId = SVG.Draw.timeoutCount++
- SVG.Draw.timeouts.push({
- id: thisId,
- run: fn,
- time: time
- })
-
- // Request another animation frame if we need one
- if (SVG.Draw.nextDraw === null) {
- SVG.Draw.nextDraw = requestAnimationFrame(SVG.Draw._draw)
- }
-
- return thisId
- },
-
- cancelTimeout: function (id) {
- // Find the index of the timeout to cancel and remove it
- var index = SVG.Draw.timeouts.remove(function (t) { return t.id == id })
- return index
- },
-
- _draw: function (now) {
- // Run all the timeouts we can run, if they are not ready yet, add them
- // to the end of the queue immediately! (bad timeouts!!! [sarcasm])
- var tracking = true
- var nextTimeout = null
- var lastTimeout = SVG.Draw.timeouts.last()
- while ((nextTimeout = SVG.Draw.timeouts.shift())) {
- // Run the timeout if its time, or push it to the end
- if (now > nextTimeout.time) {
- nextTimeout.run()
- } else {
- SVG.Draw.timeouts.push(nextTimeout)
- }
-
- // If we hit the last item, we should stop shifting out more items
- if (nextTimeout === lastTimeout) break
- }
-
- // Run all of the frames available up until this point
- var lastFrame = SVG.Draw.frames.last()
- var lastFrameId = SVG.Draw.frameCount
- while (SVG.Draw.frames.first() && SVG.Draw.frames.first().id < lastFrameId) {
- var nextFrame = SVG.Draw.frames.shift()
- nextFrame.run(now)
- }
-
- // If we have remaining timeouts or frames, draw until we don't anymore
- SVG.Draw.nextDraw = SVG.Draw.timeouts.length > 0 || SVG.Draw.frames.length > 0
- ? requestAnimationFrame(SVG.Draw._draw)
- : null
- }
-}
-
/* globals fullHex, compToHex */
// Module for color convertions
@@ -1152,7 +1076,6 @@ SVG.Number = SVG.invent({
.times(pos)
.plus(this)
}
-
}
})
@@ -1491,912 +1414,6 @@ SVG.Element = SVG.invent({
}
})
-SVG.easing = {
- '-': function (pos) { return pos },
- '<>': function (pos) { return -Math.cos(pos * Math.PI) / 2 + 0.5 },
- '>': function (pos) { return Math.sin(pos * Math.PI / 2) },
- '<': function (pos) { return -Math.cos(pos * Math.PI / 2) + 1 }
-}
-
-SVG.morph = function (pos) {
- return function (from, to) {
- return new SVG.MorphObj(from, to).at(pos)
- }
-}
-
-SVG.Situation = SVG.invent({
-
- create: function (o) {
- this.init = false
- this.reversed = false
- this.reversing = false
-
- this.duration = new SVG.Number(o.duration).valueOf()
- this.delay = new SVG.Number(o.delay).valueOf()
-
- this.start = +new Date() + this.delay
- this.finish = this.start + this.duration
- this.ease = o.ease
-
- // this.loop is incremented from 0 to this.loops
- // it is also incremented when in an infinite loop (when this.loops is true)
- this.loop = 0
- this.loops = false
-
- this.animations = {
- // functionToCall: [list of morphable objects]
- // e.g. move: [SVG.Number, SVG.Number]
- }
-
- this.attrs = {
- // holds all attributes which are not represented from a function svg.js provides
- // e.g. someAttr: SVG.Number
- }
-
- this.styles = {
- // holds all styles which should be animated
- // e.g. fill-color: SVG.Color
- }
-
- this.transforms = [
- // holds all transformations as transformation objects
- // e.g. [SVG.Rotate, SVG.Translate, SVG.Matrix]
- ]
-
- this.once = {
- // functions to fire at a specific position
- // e.g. "0.5": function foo(){}
- }
- }
-
-})
-
-SVG.Timeline = SVG.invent({
-
- create: function (element) {
- this._target = element
- this.situations = []
- this.active = false
- this.situation = null
- this.paused = false
- this.lastPos = 0
- this.pos = 0
- // The absolute position of an animation is its position in the context of its complete duration (including delay and loops)
- // When performing a delay, absPos is below 0 and when performing a loop, its value is above 1
- this.absPos = 0
- this._speed = 1
- },
-
- extend: {
-
- /**
- * sets or returns the target of this animation
- * @param o object || number In case of Object it holds all parameters. In case of number its the duration of the animation
- * @param ease function || string Function which should be used for easing or easing keyword
- * @param delay Number indicating the delay before the animation starts
- * @return target || this
- */
- animate: function (o, ease, delay) {
- if (typeof o === 'object') {
- ease = o.ease
- delay = o.delay
- o = o.duration
- }
-
- var situation = new SVG.Situation({
- duration: o || 1000,
- delay: delay || 0,
- ease: SVG.easing[ease || '-'] || ease
- })
-
- this.queue(situation)
-
- return this
- },
-
- /**
- * sets a delay before the next element of the queue is called
- * @param delay Duration of delay in milliseconds
- * @return this.target()
- */
- delay: function (delay) {
- // The delay is performed by an empty situation with its duration
- // attribute set to the duration of the delay
- var situation = new SVG.Situation({
- duration: delay,
- delay: 0,
- ease: SVG.easing['-']
- })
-
- return this.queue(situation)
- },
-
- /**
- * sets or returns the target of this animation
- * @param null || target SVG.Element which should be set as new target
- * @return target || this
- */
- target: function (target) {
- if (target && target instanceof SVG.Element) {
- this._target = target
- return this
- }
-
- return this._target
- },
-
- // returns the absolute position at a given time
- timeToAbsPos: function (timestamp) {
- return (timestamp - this.situation.start) / (this.situation.duration / this._speed)
- },
-
- // returns the timestamp from a given absolute positon
- absPosToTime: function (absPos) {
- return this.situation.duration / this._speed * absPos + this.situation.start
- },
-
- // starts the animationloop
- startAnimFrame: function () {
- this.stopAnimFrame()
- this.animationFrame = window.requestAnimationFrame(function () { this.step() }.bind(this))
- },
-
- // cancels the animationframe
- stopAnimFrame: function () {
- window.cancelAnimationFrame(this.animationFrame)
- },
-
- // kicks off the animation - only does something when the queue is currently not active and at least one situation is set
- start: function () {
- // dont start if already started
- if (!this.active && this.situation) {
- this.active = true
- this.startCurrent()
- }
-
- return this
- },
-
- // start the current situation
- startCurrent: function () {
- this.situation.start = +new Date() + this.situation.delay / this._speed
- this.situation.finish = this.situation.start + this.situation.duration / this._speed
- return this.initAnimations().step()
- },
-
- /**
- * adds a function / Situation to the animation queue
- * @param fn function / situation to add
- * @return this
- */
- queue: function (fn) {
- if (typeof fn === 'function' || fn instanceof SVG.Situation) {
- this.situations.push(fn)
- }
-
- if (!this.situation) this.situation = this.situations.shift()
-
- return this
- },
-
- /**
- * pulls next element from the queue and execute it
- * @return this
- */
- dequeue: function () {
- // stop current animation
- this.stop()
-
- // get next animation from queue
- this.situation = this.situations.shift()
-
- if (this.situation) {
- if (this.situation instanceof SVG.Situation) {
- this.start()
- } else {
- // If it is not a SVG.Situation, then it is a function, we execute it
- this.situation(this)
- }
- }
-
- return this
- },
-
- // updates all animations to the current state of the element
- // this is important when one property could be changed from another property
- initAnimations: function () {
- var i, j, source
- var s = this.situation
-
- if (s.init) return this
-
- for (i in s.animations) {
- source = this.target()[i]()
-
- if (!Array.isArray(source)) {
- source = [source]
- }
-
- if (!Array.isArray(s.animations[i])) {
- s.animations[i] = [s.animations[i]]
- }
-
- // if(s.animations[i].length > source.length) {
- // source.concat = source.concat(s.animations[i].slice(source.length, s.animations[i].length))
- // }
-
- for (j = source.length; j--;) {
- // The condition is because some methods return a normal number instead
- // of a SVG.Number
- if (s.animations[i][j] instanceof SVG.Number) {
- source[j] = new SVG.Number(source[j])
- }
-
- s.animations[i][j] = source[j].morph(s.animations[i][j])
- }
- }
-
- for (i in s.attrs) {
- s.attrs[i] = new SVG.MorphObj(this.target().attr(i), s.attrs[i])
- }
-
- for (i in s.styles) {
- s.styles[i] = new SVG.MorphObj(this.target().css(i), s.styles[i])
- }
-
- s.initialTransformation = this.target().matrixify()
-
- s.init = true
- return this
- },
-
- clearQueue: function () {
- this.situations = []
- return this
- },
-
- clearCurrent: function () {
- this.situation = null
- return this
- },
-
- /** stops the animation immediately
- * @param jumpToEnd A Boolean indicating whether to complete the current animation immediately.
- * @param clearQueue A Boolean indicating whether to remove queued animation as well.
- * @return this
- */
- stop: function (jumpToEnd, clearQueue) {
- var active = this.active
- this.active = false
-
- if (clearQueue) {
- this.clearQueue()
- }
-
- if (jumpToEnd && this.situation) {
- // initialize the situation if it was not
- !active && this.startCurrent()
- this.atEnd()
- }
-
- this.stopAnimFrame()
-
- return this.clearCurrent()
- },
-
- /** resets the element to the state where the current element has started
- * @return this
- */
- reset: function () {
- if (this.situation) {
- var temp = this.situation
- this.stop()
- this.situation = temp
- this.atStart()
- }
- return this
- },
-
- // Stop the currently-running animation, remove all queued animations, and complete all animations for the element.
- finish: function () {
- this.stop(true, false)
-
- while (this.dequeue().situation && this.stop(true, false));
-
- this.clearQueue().clearCurrent()
-
- return this
- },
-
- // set the internal animation pointer at the start position, before any loops, and updates the visualisation
- atStart: function () {
- return this.at(0, true)
- },
-
- // set the internal animation pointer at the end position, after all the loops, and updates the visualisation
- atEnd: function () {
- if (this.situation.loops === true) {
- // If in a infinite loop, we end the current iteration
- this.situation.loops = this.situation.loop + 1
- }
-
- if (typeof this.situation.loops === 'number') {
- // If performing a finite number of loops, we go after all the loops
- return this.at(this.situation.loops, true)
- } else {
- // If no loops, we just go at the end
- return this.at(1, true)
- }
- },
-
- // set the internal animation pointer to the specified position and updates the visualisation
- // if isAbsPos is true, pos is treated as an absolute position
- at: function (pos, isAbsPos) {
- var durDivSpd = this.situation.duration / this._speed
-
- this.absPos = pos
- // If pos is not an absolute position, we convert it into one
- if (!isAbsPos) {
- if (this.situation.reversed) this.absPos = 1 - this.absPos
- this.absPos += this.situation.loop
- }
-
- this.situation.start = +new Date() - this.absPos * durDivSpd
- this.situation.finish = this.situation.start + durDivSpd
-
- return this.step(true)
- },
-
- /**
- * sets or returns the speed of the animations
- * @param speed null || Number The new speed of the animations
- * @return Number || this
- */
- speed: function (speed) {
- if (speed === 0) return this.pause()
-
- if (speed) {
- this._speed = speed
- // We use an absolute position here so that speed can affect the delay before the animation
- return this.at(this.absPos, true)
- } else return this._speed
- },
-
- // Make loopable
- loop: function (times, reverse) {
- var c = this.last()
-
- // store total loops
- c.loops = (times != null) ? times : true
- c.loop = 0
-
- if (reverse) c.reversing = true
- return this
- },
-
- // pauses the animation
- pause: function () {
- this.paused = true
- this.stopAnimFrame()
-
- return this
- },
-
- // unpause the animation
- play: function () {
- if (!this.paused) return this
- this.paused = false
- // We use an absolute position here so that the delay before the animation can be paused
- return this.at(this.absPos, true)
- },
-
- /**
- * toggle or set the direction of the animation
- * true sets direction to backwards while false sets it to forwards
- * @param reversed Boolean indicating whether to reverse the animation or not (default: toggle the reverse status)
- * @return this
- */
- reverse: function (reversed) {
- var c = this.last()
-
- if (typeof reversed === 'undefined') c.reversed = !c.reversed
- else c.reversed = reversed
-
- return this
- },
-
- /**
- * returns a float from 0-1 indicating the progress of the current animation
- * @param eased Boolean indicating whether the returned position should be eased or not
- * @return number
- */
- progress: function (easeIt) {
- return easeIt ? this.situation.ease(this.pos) : this.pos
- },
-
- /**
- * adds a callback function which is called when the current animation is finished
- * @param fn Function which should be executed as callback
- * @return number
- */
- after: function (fn) {
- var c = this.last()
- function wrapper (e) {
- if (e.detail.situation === c) {
- fn.call(this, c)
- this.off('finished.fx', wrapper) // prevent memory leak
- }
- }
-
- this.target().on('finished.fx', wrapper)
-
- return this._callStart()
- },
-
- // adds a callback which is called whenever one animation step is performed
- during: function (fn) {
- var c = this.last()
- function wrapper (e) {
- if (e.detail.situation === c) {
- fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, c)
- }
- }
-
- // see above
- this.target().off('during.fx', wrapper).on('during.fx', wrapper)
-
- this.after(function () {
- this.off('during.fx', wrapper)
- })
-
- return this._callStart()
- },
-
- // calls after ALL animations in the queue are finished
- afterAll: function (fn) {
- var wrapper = function wrapper (e) {
- fn.call(this)
- this.off('allfinished.fx', wrapper)
- }
-
- // see above
- this.target().off('allfinished.fx', wrapper).on('allfinished.fx', wrapper)
-
- return this._callStart()
- },
-
- // calls on every animation step for all animations
- duringAll: function (fn) {
- var wrapper = function (e) {
- fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, e.detail.situation)
- }
-
- this.target().off('during.fx', wrapper).on('during.fx', wrapper)
-
- this.afterAll(function () {
- this.off('during.fx', wrapper)
- })
-
- return this._callStart()
- },
-
- last: function () {
- return this.situations.length ? this.situations[this.situations.length - 1] : this.situation
- },
-
- // adds one property to the animations
- add: function (method, args, type) {
- this.last()[type || 'animations'][method] = args
- return this._callStart()
- },
-
- /** perform one step of the animation
- * @param ignoreTime Boolean indicating whether to ignore time and use position directly or recalculate position based on time
- * @return this
- */
- step: function (ignoreTime) {
- // convert current time to an absolute position
- if (!ignoreTime) this.absPos = this.timeToAbsPos(+new Date())
-
- // This part convert an absolute position to a position
- if (this.situation.loops !== false) {
- var absPos, absPosInt, lastLoop
-
- // If the absolute position is below 0, we just treat it as if it was 0
- absPos = Math.max(this.absPos, 0)
- absPosInt = Math.floor(absPos)
-
- if (this.situation.loops === true || absPosInt < this.situation.loops) {
- this.pos = absPos - absPosInt
- lastLoop = this.situation.loop
- this.situation.loop = absPosInt
- } else {
- this.absPos = this.situation.loops
- this.pos = 1
- // The -1 here is because we don't want to toggle reversed when all the loops have been completed
- lastLoop = this.situation.loop - 1
- this.situation.loop = this.situation.loops
- }
-
- if (this.situation.reversing) {
- // Toggle reversed if an odd number of loops as occured since the last call of step
- this.situation.reversed = this.situation.reversed !== Boolean((this.situation.loop - lastLoop) % 2)
- }
- } else {
- // If there are no loop, the absolute position must not be above 1
- this.absPos = Math.min(this.absPos, 1)
- this.pos = this.absPos
- }
-
- // while the absolute position can be below 0, the position must not be below 0
- if (this.pos < 0) this.pos = 0
-
- if (this.situation.reversed) this.pos = 1 - this.pos
-
- // apply easing
- var eased = this.situation.ease(this.pos)
-
- // call once-callbacks
- for (var i in this.situation.once) {
- if (i > this.lastPos && i <= eased) {
- this.situation.once[i].call(this.target(), this.pos, eased)
- delete this.situation.once[i]
- }
- }
-
- // fire during callback with position, eased position and current situation as parameter
- if (this.active) this.target().fire('during', {pos: this.pos, eased: eased, fx: this, situation: this.situation})
-
- // the user may call stop or finish in the during callback
- // so make sure that we still have a valid situation
- if (!this.situation) {
- return this
- }
-
- // apply the actual animation to every property
- this.eachAt()
-
- // do final code when situation is finished
- if ((this.pos === 1 && !this.situation.reversed) || (this.situation.reversed && this.pos === 0)) {
- // stop animation callback
- this.stopAnimFrame()
-
- // fire finished callback with current situation as parameter
- this.target().fire('finished', {fx: this, situation: this.situation})
-
- if (!this.situations.length) {
- this.target().fire('allfinished')
-
- // Recheck the length since the user may call animate in the afterAll callback
- if (!this.situations.length) {
- this.target().off('.fx') // there shouldnt be any binding left, but to make sure...
- this.active = false
- }
- }
-
- // start next animation
- if (this.active) this.dequeue()
- else this.clearCurrent()
- } else if (!this.paused && this.active) {
- // we continue animating when we are not at the end
- this.startAnimFrame()
- }
-
- // save last eased position for once callback triggering
- this.lastPos = eased
- return this
- },
-
- // calculates the step for every property and calls block with it
- eachAt: function () {
- var i, at
- var self = this
- var target = this.target()
- var s = this.situation
-
- // apply animations which can be called trough a method
- for (i in s.animations) {
- at = [].concat(s.animations[i]).map(function (el) {
- return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
- })
-
- target[i].apply(target, at)
- }
-
- // apply animation which has to be applied with attr()
- for (i in s.attrs) {
- at = [i].concat(s.attrs[i]).map(function (el) {
- return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
- })
-
- target.attr.apply(target, at)
- }
-
- // apply animation which has to be applied with css()
- for (i in s.styles) {
- at = [i].concat(s.styles[i]).map(function (el) {
- return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
- })
-
- target.css.apply(target, at)
- }
-
- // animate initialTransformation which has to be chained
- if (s.transforms.length) {
-
- // TODO: ANIMATE THE TRANSFORMS
-
- // // get initial initialTransformation
- // at = s.initialTransformation
- // for(i = 0, len = s.transforms.length; i < len; i++){
- //
- // // get next transformation in chain
- // var a = s.transforms[i]
- //
- // // multiply matrix directly
- // if(a instanceof SVG.Matrix){
- //
- // if(a.relative){
- // at = at.multiply(new SVG.Matrix().morph(a).at(s.ease(this.pos)))
- // }else{
- // at = at.morph(a).at(s.ease(this.pos))
- // }
- // continue
- // }
- //
- // // when transformation is absolute we have to reset the needed transformation first
- // if(!a.relative)
- // a.undo(at.decompose())
- //
- // // and reapply it after
- // at = at.multiply(a.at(s.ease(this.pos)))
- //
- // }
- //
- // // set new matrix on element
- // target.matrix(at)
- }
-
- return this
- },
-
- // adds an once-callback which is called at a specific position and never again
- once: function (pos, fn, isEased) {
- var c = this.last()
- if (!isEased) pos = c.ease(pos)
-
- c.once[pos] = fn
-
- return this
- },
-
- _callStart: function () {
- setTimeout(function () { this.start() }.bind(this), 0)
- return this
- }
-
- },
-
- parent: SVG.Element,
-
- // Add method to parent elements
- construct: {
- // Get fx module or create a new one, then animate with given duration and ease
- animate: function (o, ease, delay) {
- return (this.fx || (this.fx = new SVG.Timeline(this))).animate(o, ease, delay)
- },
- delay: function (delay) {
- return (this.fx || (this.fx = new SVG.Timeline(this))).delay(delay)
- },
- stop: function (jumpToEnd, clearQueue) {
- if (this.fx) {
- this.fx.stop(jumpToEnd, clearQueue)
- }
-
- return this
- },
- finish: function () {
- if (this.fx) {
- this.fx.finish()
- }
-
- return this
- },
- // Pause current animation
- pause: function () {
- if (this.fx) {
- this.fx.pause()
- }
-
- return this
- },
- // Play paused current animation
- play: function () {
- if (this.fx) { this.fx.play() }
-
- return this
- },
- // Set/Get the speed of the animations
- speed: function (speed) {
- if (this.fx) {
- if (speed == null) { return this.fx.speed() } else { this.fx.speed(speed) }
- }
-
- return this
- }
- }
-
-})
-
-// MorphObj is used whenever no morphable object is given
-SVG.MorphObj = SVG.invent({
-
- create: function (from, to) {
- // prepare color for morphing
- if (SVG.Color.isColor(to)) return new SVG.Color(from).morph(to)
- // prepare value list for morphing
- if (SVG.regex.delimiter.test(from)) return new SVG.Array(from).morph(to)
- // prepare number for morphing
- if (SVG.regex.numberAndUnit.test(to)) return new SVG.Number(from).morph(to)
-
- // prepare for plain morphing
- this.value = from
- this.destination = to
- },
-
- extend: {
- at: function (pos, real) {
- return real < 1 ? this.value : this.destination
- },
-
- valueOf: function () {
- return this.value
- }
- }
-
-})
-
-SVG.extend(SVG.Timeline, {
- // Add animatable attributes
- attr: function (a, v, relative) {
- // apply attributes individually
- if (typeof a === 'object') {
- for (var key in a) {
- this.attr(key, a[key])
- }
- } else {
- this.add(a, v, 'attrs')
- }
-
- return this
- },
- // Add animatable styles
- css: function (s, v) {
- if (typeof s === 'object') {
- for (var key in s) {
- this.css(key, s[key])
- }
- } else {
- this.add(s, v, 'styles')
- }
-
- return this
- },
- // Animatable x-axis
- x: function (x, relative) {
- if (this.target() instanceof SVG.G) {
- this.transform({x: x}, relative)
- return this
- }
-
- var num = new SVG.Number(x)
- num.relative = relative
- return this.add('x', num)
- },
- // Animatable y-axis
- y: function (y, relative) {
- if (this.target() instanceof SVG.G) {
- this.transform({y: y}, relative)
- return this
- }
-
- var num = new SVG.Number(y)
- num.relative = relative
- return this.add('y', num)
- },
- // Animatable center x-axis
- cx: function (x) {
- return this.add('cx', new SVG.Number(x))
- },
- // Animatable center y-axis
- cy: function (y) {
- return this.add('cy', new SVG.Number(y))
- },
- // Add animatable move
- move: function (x, y) {
- return this.x(x).y(y)
- },
- // Add animatable center
- center: function (x, y) {
- return this.cx(x).cy(y)
- },
- // Add animatable size
- size: function (width, 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
-
- if (!width || !height) {
- box = this.target().bbox()
- }
-
- if (!width) {
- width = box.width / box.height * height
- }
-
- if (!height) {
- height = box.height / box.width * width
- }
-
- this.add('width', new SVG.Number(width))
- .add('height', new SVG.Number(height))
- }
-
- return this
- },
- // Add animatable width
- width: function (width) {
- return this.add('width', new SVG.Number(width))
- },
- // Add animatable height
- height: function (height) {
- return this.add('height', new SVG.Number(height))
- },
- // Add animatable plot
- plot: function (a, b, c, d) {
- // Lines can be plotted with 4 arguments
- if (arguments.length === 4) {
- return this.plot([a, b, c, d])
- }
-
- return this.add('plot', new (this.target().MorphArray)(a))
- },
- // Add leading method
- leading: function (value) {
- return this.target().leading
- ? this.add('leading', new SVG.Number(value))
- : this
- },
- // Add animatable viewbox
- viewbox: function (x, y, width, height) {
- if (this.target() instanceof SVG.Container) {
- this.add('viewbox', new SVG.Box(x, y, width, height))
- }
-
- return this
- },
- update: function (o) {
- if (this.target() instanceof SVG.Stop) {
- if (typeof o === 'number' || o instanceof SVG.Number) {
- return this.update({
- offset: arguments[0],
- color: arguments[1],
- opacity: arguments[2]
- })
- }
-
- if (o.opacity != null) this.attr('stop-opacity', o.opacity)
- if (o.color != null) this.attr('stop-color', o.color)
- if (o.offset != null) this.attr('offset', o.offset)
- }
-
- return this
- }
-})
-
/* global abcdef, arrayToMatrix, closeEnough */
SVG.Matrix = SVG.invent({
@@ -2409,7 +1426,11 @@ SVG.Matrix = SVG.invent({
source = source instanceof SVG.Element ? source.matrixify()
: typeof source === 'string' ? arrayToMatrix(source.split(SVG.regex.delimiter).map(parseFloat))
: Array.isArray(source) ? arrayToMatrix(source)
- : typeof source === 'object' ? source
+ : (typeof source === 'object' && (
+ source.a != null || source.b != null || source.c != null
+ || source.d != null || source.e != null || source.f != null
+ )) ? source
+ : (typeof source === 'object') ? new SVG.Matrix().transform(source)
: arguments.length === 6 ? arrayToMatrix([].slice.call(arguments))
: base
@@ -2438,59 +1459,28 @@ SVG.Matrix = SVG.invent({
return newMatrix
}
- // Get all of the parameters required to form the matrix
- var flipX = o.flip && (o.flip === 'x' || o.flip === 'both') ? -1 : 1
- var flipY = o.flip && (o.flip === 'y' || o.flip === 'both') ? -1 : 1
- var skewX = o.skew && o.skew.length ? o.skew[0]
- : isFinite(o.skew) ? o.skew
- : isFinite(o.skewX) ? o.skewX
- : 0
- var skewY = o.skew && o.skew.length ? o.skew[1]
- : isFinite(o.skew) ? o.skew
- : isFinite(o.skewY) ? o.skewY
- : 0
- var scaleX = o.scale && o.scale.length ? o.scale[0] * flipX
- : isFinite(o.scale) ? o.scale * flipX
- : isFinite(o.scaleX) ? o.scaleX * flipX
- : flipX
- var scaleY = o.scale && o.scale.length ? o.scale[1] * flipY
- : isFinite(o.scale) ? o.scale * flipY
- : isFinite(o.scaleY) ? o.scaleY * flipY
- : flipY
- var shear = o.shear || 0
- var theta = o.rotate || 0
- var origin = new SVG.Point(o.ox == null ? o.origin : o.ox, o.oy)
- var ox = origin.x
- var oy = origin.y
- var position = new SVG.Point(o.px == null
- ? o.position : o.px, o.py, {x: null, y: null})
- var px = position.x
- var py = position.y
- var translate = new SVG.Point(o.tx == null ? o.translate : o.tx, o.ty)
- var tx = translate.x
- var ty = translate.y
- var relative = new SVG.Point(o.rx == null ? o.relative : o.rx, o.ry)
- var rx = relative.x
- var ry = relative.y
+ // Get the proposed transformations and the current transformations
+ var t = formatTransforms(o)
var currentTransform = new SVG.Matrix(this)
// Construct the resulting matrix
var transformer = new SVG.Matrix()
- .translate(-ox, -oy)
- .scale(scaleX, scaleY)
- .skew(skewX, skewY)
- .shear(shear)
- .rotate(theta)
- .translate(ox, oy)
- .translate(rx, ry)
+ .translate(-t.ox, -t.oy)
+ .scale(t.scaleX, t.scaleY)
+ .skew(t.skewX, t.skewY)
+ .shear(t.shear)
+ .rotate(t.theta)
+ .translate(t.ox, t.oy)
+ .translate(t.rx, t.ry)
.lmultiply(currentTransform)
// If we want the origin at a particular place, we force it there
- if (isFinite(px) || isFinite(py)) {
+ if (isFinite(t.px) || isFinite(t.py)) {
+
// Figure out where the origin went and the delta to get there
- var current = new SVG.Point(ox - rx, oy - ry).transform(transformer)
- var dx = px ? px - current.x : 0
- var dy = py ? py - current.y : 0
+ var current = new SVG.Point(t.ox - t.rx, t.oy - t.ry).transform(transformer)
+ var dx = t.px ? t.px - current.x : 0
+ var dy = t.py ? t.py - current.y : 0
// Apply another translation
transformer = transformer.translate(dx, dy)
@@ -2616,7 +1606,31 @@ SVG.Matrix = SVG.invent({
// Inverses matrix
inverse: function () {
- return new SVG.Matrix(this.native().inverse())
+
+ // Get the current parameters out of the matrix
+ var a = this.a
+ var b = this.b
+ var c = this.c
+ var d = this.d
+ var e = this.e
+ var f = this.f
+
+ // Invert the 2x2 matrix in the top left
+ var det = a * d - b * c
+ if (!det) throw new Error("Cannot invert " + this)
+
+ // Calculate the top 2x2 matrix
+ var na = d / det
+ var nb = -b / det
+ var nc = -c / det
+ var nd = a / det
+
+ // Apply the inverted matrix to the top right
+ var ne = - ( na * e + nc * f )
+ var nf = - ( nb * e + nd * f )
+
+ // Construct the inverted matrix
+ return new SVG.Matrix(na, nb, nc, nd, ne, nf)
},
// Translate matrix
@@ -5290,6 +4304,64 @@ function closeEnough (a, b, threshold) {
return Math.abs(b - a) < (threshold || 1e-6)
}
+// TODO: Refactor this to a static function of matrix.js
+function formatTransforms (o) {
+
+ // Get all of the parameters required to form the matrix
+ var flipBoth = o.flip === 'both' || o.flip === true
+ var flipX = o.flip && (flipBoth || o.flip === 'x') ? -1 : 1
+ var flipY = o.flip && (flipBoth || o.flip === 'y') ? -1 : 1
+ var skewX = o.skew && o.skew.length ? o.skew[0]
+ : isFinite(o.skew) ? o.skew
+ : isFinite(o.skewX) ? o.skewX
+ : 0
+ var skewY = o.skew && o.skew.length ? o.skew[1]
+ : isFinite(o.skew) ? o.skew
+ : isFinite(o.skewY) ? o.skewY
+ : 0
+ var scaleX = o.scale && o.scale.length ? o.scale[0] * flipX
+ : isFinite(o.scale) ? o.scale * flipX
+ : isFinite(o.scaleX) ? o.scaleX * flipX
+ : flipX
+ var scaleY = o.scale && o.scale.length ? o.scale[1] * flipY
+ : isFinite(o.scale) ? o.scale * flipY
+ : isFinite(o.scaleY) ? o.scaleY * flipY
+ : flipY
+ var shear = o.shear || 0
+ var theta = o.rotate || 0
+ var origin = new SVG.Point(o.ox == null ? o.origin : o.ox, o.oy)
+ var ox = origin.x
+ var oy = origin.y
+ var position = new SVG.Point(o.px == null
+ ? o.position : o.px, o.py, {x: null, y: null})
+ var px = position.x
+ var py = position.y
+ var translate = new SVG.Point(o.tx == null ? o.translate : o.tx, o.ty)
+ var tx = translate.x
+ var ty = translate.y
+ var relative = new SVG.Point(o.rx == null ? o.relative : o.rx, o.ry)
+ var rx = relative.x
+ var ry = relative.y
+
+ // Populate all of the values
+ return {
+ scaleX: scaleX,
+ scaleY: scaleY,
+ skewX: skewX,
+ skewY: skewY,
+ shear: shear,
+ theta: theta,
+ rx: rx,
+ ry: ry,
+ tx: tx,
+ ty: ty,
+ ox: ox,
+ oy: oy,
+ px: px,
+ py: py,
+ }
+}
+
/* globals fullBox, domContains, isNulledBox, Exception */
SVG.Box = SVG.invent({
@@ -5453,6 +4525,96 @@ SVG.parser.nodes = {
SVG.parser.nodes.path = SVG.parser.nodes.svg.path().node
+/* global requestAnimationFrame */
+
+SVG.Animator = {
+ nextDraw: null,
+ frames: new SVG.Queue(),
+ timeouts: new SVG.Queue(),
+ frameCount: 0,
+ timeoutCount: 0,
+ timer: window.performance || window.Date,
+
+ frame: function (fn) {
+ SVG.Animator.frames.push({
+ id: SVG.Animator.frameCount,
+ run: fn
+ })
+
+ if (SVG.Animator.nextDraw === null) {
+ SVG.Animator.nextDraw = requestAnimationFrame(SVG.Animator._draw)
+ }
+
+ return ++SVG.Animator.frameCount
+ },
+
+ timeout: function (fn, delay) {
+ delay = delay || 0
+
+ // Work out when the event should fire
+ var time = SVG.Animator.timer.now() + delay
+
+ // Add the timeout to the end of the queue
+ var thisId = SVG.Animator.timeoutCount++
+ SVG.Animator.timeouts.push({
+ id: thisId,
+ run: fn,
+ time: time
+ })
+
+ // Request another animation frame if we need one
+ if (SVG.Animator.nextDraw === null) {
+ SVG.Animator.nextDraw = requestAnimationFrame(SVG.Animator._draw)
+ }
+
+ return thisId
+ },
+
+ cancelTimeout: function (id) {
+ // Find the index of the timeout to cancel and remove it
+ var index = SVG.Animator.timeouts.remove(
+ function (t) {
+ return t.id === id
+ }
+ )
+ return index
+ },
+
+ _draw: function (now) {
+
+ // Run all the timeouts we can run, if they are not ready yet, add them
+ // to the end of the queue immediately! (bad timeouts!!! [sarcasm])
+ var tracking = true
+ var nextTimeout = null
+ var lastTimeout = SVG.Animator.timeouts.last()
+ while ((nextTimeout = SVG.Animator.timeouts.shift())) {
+
+ // Run the timeout if its time, or push it to the end
+ if (now > nextTimeout.time) {
+ nextTimeout.run()
+ } else {
+ SVG.Animator.timeouts.push(nextTimeout)
+ }
+
+ // If we hit the last item, we should stop shifting out more items
+ if (nextTimeout === lastTimeout) break
+ }
+
+ // Run all of the frames available up until this point
+ var lastFrame = SVG.Animator.frames.last()
+ var lastFrameId = SVG.Animator.frameCount
+ while (SVG.Animator.frames.first() && SVG.Animator.frames.first().id < lastFrameId) {
+ var nextFrame = SVG.Animator.frames.shift()
+ nextFrame.run(now)
+ }
+
+ // If we have remaining timeouts or frames, draw until we don't anymore
+ SVG.Animator.nextDraw = SVG.Animator.timeouts.length > 0 || SVG.Animator.frames.length > 0
+ ? requestAnimationFrame(SVG.Animator._draw)
+ : null
+ }
+}
+
return SVG
diff --git a/dist/svg.min.js b/dist/svg.min.js
index c589c44..fdf7f1c 100644
--- a/dist/svg.min.js
+++ b/dist/svg.min.js
@@ -1,2 +1,2 @@
-/*! svg.js v3.0.0 MIT*/;!function(t,e){"function"==typeof define&&define.amd?define(function(){return e(t,t.document)}):"object"==typeof exports?module.exports=t.document?e(t,t.document):function(t){return e(t,t.document)}:t.SVG=e(t,t.document)}("undefined"!=typeof window?window:this,function(t,e){function i(t,i){if(t instanceof w.Element)return t;if("object"==typeof t)return w.adopt(t);if(null==t)return new w.Doc;if("string"==typeof t&&"<"!==t.charAt(0))return w.adopt(e.querySelector(t));var n=w.create("svg");return n.innerHTML=t,t=w.adopt(n.firstElementChild)}function n(t){return!(t.w||t.h||t.x||t.y)}function r(t){return(e.documentElement.contains||function(t){for(;t.parentNode;)t=t.parentNode;return t===e}).call(e.documentElement,t)}function s(t,e,i,n){return i+n.replace(w.regex.dots," .")}function o(t){for(var e=t.slice(0),i=e.length;i--;)Array.isArray(e[i])&&(e[i]=o(e[i]));return e}function a(t,e){return t instanceof e}function h(t,e){return(t.matches||t.matchesSelector||t.msMatchesSelector||t.mozMatchesSelector||t.webkitMatchesSelector||t.oMatchesSelector).call(t,e)}function u(t){return t.toLowerCase().replace(/-(.)/g,function(t,e){return e.toUpperCase()})}function l(t){return t.charAt(0).toUpperCase()+t.slice(1)}function c(t){return 4===t.length?["#",t.substring(1,2),t.substring(1,2),t.substring(2,3),t.substring(2,3),t.substring(3,4),t.substring(3,4)].join(""):t}function f(t){var e=t.toString(16);return 1===e.length?"0"+e:e}function d(t,e,i){if(null==e||null==i){var n=t.bbox();null==e?e=n.width/n.height*i:null==i&&(i=n.height/n.width*e)}return{width:e,height:i}}function p(t){return{a:t[0],b:t[1],c:t[2],d:t[3],e:t[4],f:t[5]}}function m(t){for(var e=0,i=t.length,n="";e<i;e++)n+=t[e][0],null!=t[e][1]&&(n+=t[e][1],null!=t[e][2]&&(n+=" ",n+=t[e][2],null!=t[e][3]&&(n+=" ",n+=t[e][3],n+=" ",n+=t[e][4],null!=t[e][5]&&(n+=" ",n+=t[e][5],n+=" ",n+=t[e][6],null!=t[e][7]&&(n+=" ",n+=t[e][7])))));return n+" "}function v(t){for(var e=t.children.length-1;e>=0;e--)v(t.children[e]);return t.id?w.adopt(t).id(w.eid(t.nodeName)):w.adopt(t)}function x(t){return null==t.x&&(t.x=0,t.y=0,t.width=0,t.height=0),t.w=t.width,t.h=t.height,t.x2=t.x+t.width,t.y2=t.y+t.height,t.cx=t.x+t.width/2,t.cy=t.y+t.height/2,t}function y(t){var e=(t||"").toString().match(w.regex.reference);if(e)return e[1]}function g(t,e,i){return Math.abs(e-t)<(i||1e-6)}if(!e.createElementNS||!e.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect)return{supported:!1};var w=this.SVG=function(t){if(w.supported)return t=i(t)};w.supported=!0,w.ns="http://www.w3.org/2000/svg",w.xmlns="http://www.w3.org/2000/xmlns/",w.xlink="http://www.w3.org/1999/xlink",w.svgjs="http://svgjs.com/svgjs",w.did=1e3,w.eid=function(t){return"Svgjs"+l(t)+w.did++},w.create=function(t){return e.createElementNS(this.ns,t)},w.extend=function(t,e){var i,n;for(t=Array.isArray(t)?t:[t],n=t.length-1;n>=0;n--)if(t[n])for(i in e)t[n].prototype[i]=e[i]},w.invent=function(t){var e="function"==typeof t.create?t.create:function(e){this.constructor(e||w.create(t.create))};return t.inherit&&(e.prototype=new t.inherit),t.extend&&w.extend(e,t.extend),t.construct&&w.extend(t.parent||w.Container,t.construct),e},w.adopt=function(e){if(!e)return null;if(e.instance instanceof w.Element)return e.instance;if(!(e instanceof t.SVGElement))return new w.HtmlNode(e);return"svg"===e.nodeName?new w.Doc(e):"linearGradient"===e.nodeName||"radialGradient"===e.nodeName?new w.Gradient(e):w[l(e.nodeName)]?new(w[l(e.nodeName)])(e):new w.Parent(e)},w.regex={numberAndUnit:/^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i,hex:/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,rgb:/rgb\((\d+),(\d+),(\d+)\)/,reference:/#([a-z0-9\-_]+)/i,transforms:/\)\s*,?\s*/,whitespace:/\s/g,isHex:/^#[a-f0-9]{3,6}$/i,isRgb:/^rgb\(/,isCss:/[^:]+:[^;]+;?/,isBlank:/^(\s+)?$/,isNumber:/^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,isPercent:/^-?[\d.]+%$/,isImage:/\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i,delimiter:/[\s,]+/,hyphen:/([^e])-/gi,pathLetters:/[MLHVCSQTAZ]/gi,isPathLetter:/[MLHVCSQTAZ]/i,numbersWithDots:/((\d?\.\d+(?:e[+-]?\d+)?)((?:\.\d+(?:e[+-]?\d+)?)+))+/gi,dots:/\./g},w.utils={map:function(t,e){var i,n=t.length,r=[];for(i=0;i<n;i++)r.push(e(t[i]));return r},filter:function(t,e){var i,n=t.length,r=[];for(i=0;i<n;i++)e(t[i])&&r.push(t[i]);return r},radians:function(t){return t%360*Math.PI/180},degrees:function(t){return 180*t/Math.PI%360},filterSVGElements:function(e){return this.filter(e,function(e){return e instanceof t.SVGElement})}},w.defaults={attrs:{"fill-opacity":1,"stroke-opacity":1,"stroke-width":0,"stroke-linejoin":"miter","stroke-linecap":"butt",fill:"#000000",stroke:"#000000",opacity:1,x:0,y:0,cx:0,cy:0,width:0,height:0,r:0,rx:0,ry:0,offset:0,"stop-opacity":1,"stop-color":"#000000","font-size":16,"font-family":"Helvetica, Arial, sans-serif","text-anchor":"start"}},w.Queue=w.invent({create:function(){this._first=null,this._last=null,this.length=0,this.id=0},extend:{push:function(t){var e={id:this.id++,value:t};this._last?this._last=this._last.next=e:this._last=this._first=e,this.length++},shift:function(){if(0!=this.length){var t=this._first;return this._first=t.next,this._last=--this.length?this._last:null,t.value}},first:function(){return this._first&&this._first.value},last:function(){return this._last&&this._last.value},remove:function(t){for(var e=null,i=this._first;i&&!t(i);)e=i,i=i.next;if(i&&i===this._first&&(this._first=this._first.next),i&&i===this._last&&(this._last=e),i)return--this.length,e&&(e.next=i.next),i.item}}}),w.Draw={nextDraw:null,frames:new w.Queue,timeouts:new w.Queue,frameCount:0,timeoutCount:0,timer:t.performance||t.Date,frame:function(t){return w.Draw.frames.push({id:w.Draw.frameCount,run:t}),null===w.Draw.nextDraw&&(w.Draw.nextDraw=requestAnimationFrame(w.Draw._draw)),++w.Draw.frameCount},timeout:function(t,e){e=e||0;var i=w.Draw.timer.now()+e,n=w.Draw.timeoutCount++;return w.Draw.timeouts.push({id:n,run:t,time:i}),null===w.Draw.nextDraw&&(w.Draw.nextDraw=requestAnimationFrame(w.Draw._draw)),n},cancelTimeout:function(t){return w.Draw.timeouts.remove(function(e){return e.id==t})},_draw:function(t){for(var e=null,i=w.Draw.timeouts.last();(e=w.Draw.timeouts.shift())&&(t>e.time?e.run():w.Draw.timeouts.push(e),e!==i););for(var n=(w.Draw.frames.last(),w.Draw.frameCount);w.Draw.frames.first()&&w.Draw.frames.first().id<n;){w.Draw.frames.shift().run(t)}w.Draw.nextDraw=w.Draw.timeouts.length>0||w.Draw.frames.length>0?requestAnimationFrame(w.Draw._draw):null}},w.Color=function(t){var e;this.r=0,this.g=0,this.b=0,t&&("string"==typeof t?w.regex.isRgb.test(t)?(e=w.regex.rgb.exec(t.replace(w.regex.whitespace,"")),this.r=parseInt(e[1]),this.g=parseInt(e[2]),this.b=parseInt(e[3])):w.regex.isHex.test(t)&&(e=w.regex.hex.exec(c(t)),this.r=parseInt(e[1],16),this.g=parseInt(e[2],16),this.b=parseInt(e[3],16)):"object"==typeof t&&(this.r=t.r,this.g=t.g,this.b=t.b))},w.extend(w.Color,{toString:function(){return this.toHex()},toHex:function(){return"#"+f(this.r)+f(this.g)+f(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},morph:function(t){return this.destination=new w.Color(t),this},at:function(t){return this.destination?(t=t<0?0:t>1?1:t,new w.Color({r:~~(this.r+(this.destination.r-this.r)*t),g:~~(this.g+(this.destination.g-this.g)*t),b:~~(this.b+(this.destination.b-this.b)*t)})):this}}),w.Color.test=function(t){return t+="",w.regex.isHex.test(t)||w.regex.isRgb.test(t)},w.Color.isRgb=function(t){return t&&"number"==typeof t.r&&"number"==typeof t.g&&"number"==typeof t.b},w.Color.isColor=function(t){return w.Color.isRgb(t)||w.Color.test(t)},w.Array=function(t,e){t=(t||[]).valueOf(),0===t.length&&e&&(t=e.valueOf()),this.value=this.parse(t)},w.extend(w.Array,{morph:function(t){if(this.destination=this.parse(t),this.value.length!==this.destination.length){for(var e=this.value[this.value.length-1],i=this.destination[this.destination.length-1];this.value.length>this.destination.length;)this.destination.push(i);for(;this.value.length<this.destination.length;)this.value.push(e)}return this},settle:function(){for(var t=0,e=this.value.length,i=[];t<e;t++)-1===i.indexOf(this.value[t])&&i.push(this.value[t]);return this.value=i,i},at:function(t){if(!this.destination)return this;for(var e=0,i=this.value.length,n=[];e<i;e++)n.push(this.value[e]+(this.destination[e]-this.value[e])*t);return new w.Array(n)},toString:function(){return this.value.join(" ")},valueOf:function(){return this.value},parse:function(t){return t=t.valueOf(),Array.isArray(t)?t:t.trim().split(w.regex.delimiter).map(parseFloat)},reverse:function(){return this.value.reverse(),this},clone:function(){var t=new this.constructor;return t.value=o(this.value),t}}),w.PointArray=function(t,e){w.Array.call(this,t,e||[[0,0]])},w.PointArray.prototype=new w.Array,w.PointArray.prototype.constructor=w.PointArray,w.extend(w.PointArray,{toString:function(){for(var t=0,e=this.value.length,i=[];t<e;t++)i.push(this.value[t].join(","));return i.join(" ")},toLine:function(){return{x1:this.value[0][0],y1:this.value[0][1],x2:this.value[1][0],y2:this.value[1][1]}},at:function(t){if(!this.destination)return this;for(var e=0,i=this.value.length,n=[];e<i;e++)n.push([this.value[e][0]+(this.destination[e][0]-this.value[e][0])*t,this.value[e][1]+(this.destination[e][1]-this.value[e][1])*t]);return new w.PointArray(n)},parse:function(t){var e=[];if(t=t.valueOf(),Array.isArray(t)){if(Array.isArray(t[0]))return t}else t=t.trim().split(w.regex.delimiter).map(parseFloat);t.length%2!=0&&t.pop();for(var i=0,n=t.length;i<n;i+=2)e.push([t[i],t[i+1]]);return e},move:function(t,e){var i=this.bbox();if(t-=i.x,e-=i.y,!isNaN(t)&&!isNaN(e))for(var n=this.value.length-1;n>=0;n--)this.value[n]=[this.value[n][0]+t,this.value[n][1]+e];return this},size:function(t,e){var i,n=this.bbox();for(i=this.value.length-1;i>=0;i--)n.width&&(this.value[i][0]=(this.value[i][0]-n.x)*t/n.width+n.x),n.height&&(this.value[i][1]=(this.value[i][1]-n.y)*e/n.height+n.y);return this},bbox:function(){var t=-1/0,e=-1/0,i=1/0,n=1/0;return this.value.forEach(function(r){t=Math.max(r[0],t),e=Math.max(r[1],e),i=Math.min(r[0],i),n=Math.min(r[1],n)}),{x:i,y:n,width:t-i,height:e-n}}});for(var b={M:function(t,e,i){return e.x=i.x=t[0],e.y=i.y=t[1],["M",e.x,e.y]},L:function(t,e){return e.x=t[0],e.y=t[1],["L",t[0],t[1]]},H:function(t,e){return e.x=t[0],["H",t[0]]},V:function(t,e){return e.y=t[0],["V",t[0]]},C:function(t,e){return e.x=t[4],e.y=t[5],["C",t[0],t[1],t[2],t[3],t[4],t[5]]},S:function(t,e){return e.x=t[2],e.y=t[3],["S",t[0],t[1],t[2],t[3]]},Q:function(t,e){return e.x=t[2],e.y=t[3],["Q",t[0],t[1],t[2],t[3]]},T:function(t,e){return e.x=t[0],e.y=t[1],["T",t[0],t[1]]},Z:function(t,e,i){return e.x=i.x,e.y=i.y,["Z"]},A:function(t,e){return e.x=t[5],e.y=t[6],["A",t[0],t[1],t[2],t[3],t[4],t[5],t[6]]}},P="mlhvqtcsaz".split(""),A=0,C=P.length;A<C;++A)b[P[A]]=function(t){return function(e,i,n){if("H"===t)e[0]=e[0]+i.x;else if("V"===t)e[0]=e[0]+i.y;else if("A"===t)e[5]=e[5]+i.x,e[6]=e[6]+i.y;else for(var r=0,s=e.length;r<s;++r)e[r]=e[r]+(r%2?i.y:i.x);return b[t](e,i,n)}}(P[A].toUpperCase());w.PathArray=function(t,e){w.Array.call(this,t,e||[["M",0,0]])},w.PathArray.prototype=new w.Array,w.PathArray.prototype.constructor=w.PathArray,w.extend(w.PathArray,{toString:function(){return m(this.value)},move:function(t,e){var i=this.bbox();if(t-=i.x,e-=i.y,!isNaN(t)&&!isNaN(e))for(var n,r=this.value.length-1;r>=0;r--)n=this.value[r][0],"M"===n||"L"===n||"T"===n?(this.value[r][1]+=t,this.value[r][2]+=e):"H"===n?this.value[r][1]+=t:"V"===n?this.value[r][1]+=e:"C"===n||"S"===n||"Q"===n?(this.value[r][1]+=t,this.value[r][2]+=e,this.value[r][3]+=t,this.value[r][4]+=e,"C"===n&&(this.value[r][5]+=t,this.value[r][6]+=e)):"A"===n&&(this.value[r][6]+=t,this.value[r][7]+=e);return this},size:function(t,e){var i,n,r=this.bbox();for(i=this.value.length-1;i>=0;i--)n=this.value[i][0],"M"===n||"L"===n||"T"===n?(this.value[i][1]=(this.value[i][1]-r.x)*t/r.width+r.x,this.value[i][2]=(this.value[i][2]-r.y)*e/r.height+r.y):"H"===n?this.value[i][1]=(this.value[i][1]-r.x)*t/r.width+r.x:"V"===n?this.value[i][1]=(this.value[i][1]-r.y)*e/r.height+r.y:"C"===n||"S"===n||"Q"===n?(this.value[i][1]=(this.value[i][1]-r.x)*t/r.width+r.x,this.value[i][2]=(this.value[i][2]-r.y)*e/r.height+r.y,this.value[i][3]=(this.value[i][3]-r.x)*t/r.width+r.x,this.value[i][4]=(this.value[i][4]-r.y)*e/r.height+r.y,"C"===n&&(this.value[i][5]=(this.value[i][5]-r.x)*t/r.width+r.x,this.value[i][6]=(this.value[i][6]-r.y)*e/r.height+r.y)):"A"===n&&(this.value[i][1]=this.value[i][1]*t/r.width,this.value[i][2]=this.value[i][2]*e/r.height,this.value[i][6]=(this.value[i][6]-r.x)*t/r.width+r.x,this.value[i][7]=(this.value[i][7]-r.y)*e/r.height+r.y);return this},equalCommands:function(t){var e,i,n;for(t=new w.PathArray(t),n=this.value.length===t.value.length,e=0,i=this.value.length;n&&e<i;e++)n=this.value[e][0]===t.value[e][0];return n},morph:function(t){return t=new w.PathArray(t),this.equalCommands(t)?this.destination=t:this.destination=null,this},at:function(t){if(!this.destination)return this;var e,i,n,r,s=this.value,o=this.destination.value,a=[],h=new w.PathArray;for(e=0,i=s.length;e<i;e++){for(a[e]=[s[e][0]],n=1,r=s[e].length;n<r;n++)a[e][n]=s[e][n]+(o[e][n]-s[e][n])*t;"A"===a[e][0]&&(a[e][4]=+(0!==a[e][4]),a[e][5]=+(0!==a[e][5]))}return h.value=a,h},parse:function(t){if(t instanceof w.PathArray)return t.valueOf();var e,i={M:2,L:2,H:1,V:1,C:6,S:4,Q:4,T:2,A:7,Z:0};t="string"==typeof t?t.replace(w.regex.numbersWithDots,s).replace(w.regex.pathLetters," $& ").replace(w.regex.hyphen,"$1 -").trim().split(w.regex.delimiter):t.reduce(function(t,e){return[].concat.call(t,e)},[]);var n=[],r=new w.Point,o=new w.Point,a=0,h=t.length;do{w.regex.isPathLetter.test(t[a])?(e=t[a],++a):"M"===e?e="L":"m"===e&&(e="l"),n.push(b[e].call(null,t.slice(a,a+=i[e.toUpperCase()]).map(parseFloat),r,o))}while(h>a);return n},bbox:function(){return w.parser().path.setAttribute("d",this.toString()),w.parser.nodes.path.getBBox()}}),w.Number=w.invent({create:function(t,e){this.value=0,this.unit=e||"","number"==typeof t?this.value=isNaN(t)?0:isFinite(t)?t:t<0?-3.4e38:3.4e38:"string"==typeof t?(e=t.match(w.regex.numberAndUnit))&&(this.value=parseFloat(e[1]),"%"===e[5]?this.value/=100:"s"===e[5]&&(this.value*=1e3),this.unit=e[5]):t instanceof w.Number&&(this.value=t.valueOf(),this.unit=t.unit)},extend:{toString:function(){return("%"===this.unit?~~(1e8*this.value)/1e6:"s"===this.unit?this.value/1e3:this.value)+this.unit},toJSON:function(){return this.toString()},valueOf:function(){return this.value},plus:function(t){return t=new w.Number(t),new w.Number(this+t,this.unit||t.unit)},minus:function(t){return t=new w.Number(t),new w.Number(this-t,this.unit||t.unit)},times:function(t){return t=new w.Number(t),new w.Number(this*t,this.unit||t.unit)},divide:function(t){return t=new w.Number(t),new w.Number(this/t,this.unit||t.unit)},to:function(t){var e=new w.Number(this);return"string"==typeof t&&(e.unit=t),e},morph:function(t){return this.destination=new w.Number(t),t.relative&&(this.destination.value+=this.value),this},at:function(t){return this.destination?new w.Number(this.destination).minus(this).times(t).plus(this):this}}}),w.HtmlNode=w.invent({create:function(t){this.node=t},extend:{add:function(t,e){return t=i(t),t.node!==this.node.children[e]&&this.node.insertBefore(t.node,this.node.children[e]||null),this},put:function(t,e){return this.add(t,e),t}}}),w.Element=w.invent({create:function(t){this.events={},this.dom={},this.node=t,this.node&&(this.type=t.nodeName,this.node.instance=this,this.events=t.events||{},t.hasAttribute("svgjs:data")&&this.setData(JSON.parse(t.getAttribute("svgjs:data"))||{}))},extend:{x:function(t){return this.attr("x",t)},y:function(t){return this.attr("y",t)},cx:function(t){return null==t?this.x()+this.width()/2:this.x(t-this.width()/2)},cy:function(t){return null==t?this.y()+this.height()/2:this.y(t-this.height()/2)},move:function(t,e){return this.x(t).y(e)},center:function(t,e){return this.cx(t).cy(e)},width:function(t){return this.attr("width",t)},height:function(t){return this.attr("height",t)},size:function(t,e){var i=d(this,t,e);return this.width(new w.Number(i.width)).height(new w.Number(i.height))},clone:function(t){this.writeDataToDom();var e=v(this.node.cloneNode(!0));return t?t.add(e):this.after(e),e},remove:function(){return this.parent()&&this.parent().removeElement(this),this},replace:function(t){return this.after(t).remove(),t},addTo:function(t){return i(t).put(this)},putIn:function(t){return i(t).add(this)},id:function(t){return void 0!==t||this.node.id||(this.node.id=w.eid(this.type)),this.attr("id",t)},inside:function(t,e){var i=this.bbox();return t>i.x&&e>i.y&&t<i.x+i.width&&e<i.y+i.height},show:function(){return this.css("display","")},hide:function(){return this.css("display","none")},visible:function(){return"none"!==this.css("display")},toString:function(){return this.id()},classes:function(){var t=this.attr("class");return null==t?[]:t.trim().split(w.regex.delimiter)},hasClass:function(t){return-1!==this.classes().indexOf(t)},addClass:function(t){if(!this.hasClass(t)){var e=this.classes();e.push(t),this.attr("class",e.join(" "))}return this},removeClass:function(t){return this.hasClass(t)&&this.attr("class",this.classes().filter(function(e){return e!==t}).join(" ")),this},toggleClass:function(t){return this.hasClass(t)?this.removeClass(t):this.addClass(t)},reference:function(t){return w.get(this.attr(t))},parent:function(e){var i=this;if(!i.node.parentNode)return null;if(i=w.adopt(i.node.parentNode),!e)return i;for(;i&&i.node instanceof t.SVGElement;){if("string"==typeof e?i.matches(e):i instanceof e)return i;i=w.adopt(i.node.parentNode)}},doc:function(){var t=this.parent(w.Doc);return t&&t.doc()},defs:function(){return this.doc().defs()},parents:function(t){var e=[],i=this;do{if(!(i=i.parent(t))||!i.node)break;e.push(i)}while(i.parent);return e},matches:function(t){return h(this.node,t)},native:function(){return this.node},svg:function(t){var i,n;if(!(t&&this instanceof w.Parent))return this.writeDataToDom(),this.node.outerHTML;for(i=e.createElementNS(w.ns,"svg"),i.innerHTML=t,n=i.children.length;n--;)this.node.appendChild(i.firstElementChild);return this},writeDataToDom:function(){return this.is(w.Parent)&&this.each(function(){this.writeDataToDom()}),this.node.removeAttribute("svgjs:data"),Object.keys(this.dom).length&&this.node.setAttribute("svgjs:data",JSON.stringify(this.dom)),this},setData:function(t){return this.dom=t,this},is:function(t){return a(this,t)}}}),w.easing={"-":function(t){return t},"<>":function(t){return-Math.cos(t*Math.PI)/2+.5},">":function(t){return Math.sin(t*Math.PI/2)},"<":function(t){return 1-Math.cos(t*Math.PI/2)}},w.morph=function(t){return function(e,i){return new w.MorphObj(e,i).at(t)}},w.Situation=w.invent({create:function(t){this.init=!1,this.reversed=!1,this.reversing=!1,this.duration=new w.Number(t.duration).valueOf(),this.delay=new w.Number(t.delay).valueOf(),this.start=+new Date+this.delay,this.finish=this.start+this.duration,this.ease=t.ease,this.loop=0,this.loops=!1,this.animations={},this.attrs={},this.styles={},this.transforms=[],this.once={}}}),w.Timeline=w.invent({create:function(t){this._target=t,this.situations=[],this.active=!1,this.situation=null,this.paused=!1,this.lastPos=0,this.pos=0,this.absPos=0,this._speed=1},extend:{animate:function(t,e,i){"object"==typeof t&&(e=t.ease,i=t.delay,t=t.duration);var n=new w.Situation({duration:t||1e3,delay:i||0,ease:w.easing[e||"-"]||e});return this.queue(n),this},delay:function(t){var e=new w.Situation({duration:t,delay:0,ease:w.easing["-"]});return this.queue(e)},target:function(t){return t&&t instanceof w.Element?(this._target=t,this):this._target},timeToAbsPos:function(t){return(t-this.situation.start)/(this.situation.duration/this._speed)},absPosToTime:function(t){return this.situation.duration/this._speed*t+this.situation.start},startAnimFrame:function(){this.stopAnimFrame(),this.animationFrame=t.requestAnimationFrame(function(){this.step()}.bind(this))},stopAnimFrame:function(){t.cancelAnimationFrame(this.animationFrame)},start:function(){return!this.active&&this.situation&&(this.active=!0,this.startCurrent()),this},startCurrent:function(){return this.situation.start=+new Date+this.situation.delay/this._speed,this.situation.finish=this.situation.start+this.situation.duration/this._speed,this.initAnimations().step()},queue:function(t){return("function"==typeof t||t instanceof w.Situation)&&this.situations.push(t),this.situation||(this.situation=this.situations.shift()),this},dequeue:function(){return this.stop(),this.situation=this.situations.shift(),this.situation&&(this.situation instanceof w.Situation?this.start():this.situation(this)),this},initAnimations:function(){var t,e,i,n=this.situation;if(n.init)return this;for(t in n.animations)for(i=this.target()[t](),Array.isArray(i)||(i=[i]),Array.isArray(n.animations[t])||(n.animations[t]=[n.animations[t]]),e=i.length;e--;)n.animations[t][e]instanceof w.Number&&(i[e]=new w.Number(i[e])),n.animations[t][e]=i[e].morph(n.animations[t][e]);for(t in n.attrs)n.attrs[t]=new w.MorphObj(this.target().attr(t),n.attrs[t]);for(t in n.styles)n.styles[t]=new w.MorphObj(this.target().css(t),n.styles[t]);return n.initialTransformation=this.target().matrixify(),n.init=!0,this},clearQueue:function(){return this.situations=[],this},clearCurrent:function(){return this.situation=null,this},stop:function(t,e){var i=this.active;return this.active=!1,e&&this.clearQueue(),t&&this.situation&&(!i&&this.startCurrent(),this.atEnd()),this.stopAnimFrame(),this.clearCurrent()},reset:function(){if(this.situation){var t=this.situation;this.stop(),this.situation=t,this.atStart()}return this},finish:function(){for(this.stop(!0,!1);this.dequeue().situation&&this.stop(!0,!1););return this.clearQueue().clearCurrent(),this},atStart:function(){return this.at(0,!0)},atEnd:function(){return!0===this.situation.loops&&(this.situation.loops=this.situation.loop+1),"number"==typeof this.situation.loops?this.at(this.situation.loops,!0):this.at(1,!0)},at:function(t,e){var i=this.situation.duration/this._speed;return this.absPos=t,e||(this.situation.reversed&&(this.absPos=1-this.absPos),this.absPos+=this.situation.loop),this.situation.start=+new Date-this.absPos*i,this.situation.finish=this.situation.start+i,this.step(!0)},speed:function(t){return 0===t?this.pause():t?(this._speed=t,this.at(this.absPos,!0)):this._speed},loop:function(t,e){var i=this.last();return i.loops=null==t||t,i.loop=0,e&&(i.reversing=!0),this},pause:function(){return this.paused=!0,this.stopAnimFrame(),this},play:function(){return this.paused?(this.paused=!1,this.at(this.absPos,!0)):this},reverse:function(t){var e=this.last();return e.reversed=void 0===t?!e.reversed:t,this},progress:function(t){return t?this.situation.ease(this.pos):this.pos},after:function(t){function e(n){n.detail.situation===i&&(t.call(this,i),this.off("finished.fx",e))}var i=this.last();return this.target().on("finished.fx",e),this._callStart()},during:function(t){function e(e){e.detail.situation===i&&t.call(this,e.detail.pos,w.morph(e.detail.pos),e.detail.eased,i)}var i=this.last();return this.target().off("during.fx",e).on("during.fx",e),this.after(function(){this.off("during.fx",e)}),this._callStart()},afterAll:function(t){var e=function e(i){t.call(this),this.off("allfinished.fx",e)};return this.target().off("allfinished.fx",e).on("allfinished.fx",e),this._callStart()},duringAll:function(t){var e=function(e){t.call(this,e.detail.pos,w.morph(e.detail.pos),e.detail.eased,e.detail.situation)};return this.target().off("during.fx",e).on("during.fx",e),this.afterAll(function(){this.off("during.fx",e)}),this._callStart()},last:function(){return this.situations.length?this.situations[this.situations.length-1]:this.situation},add:function(t,e,i){return this.last()[i||"animations"][t]=e,this._callStart()},step:function(t){if(t||(this.absPos=this.timeToAbsPos(+new Date)),!1!==this.situation.loops){var e,i,n;e=Math.max(this.absPos,0),i=Math.floor(e),!0===this.situation.loops||i<this.situation.loops?(this.pos=e-i,n=this.situation.loop,this.situation.loop=i):(this.absPos=this.situation.loops,this.pos=1,n=this.situation.loop-1,this.situation.loop=this.situation.loops),this.situation.reversing&&(this.situation.reversed=this.situation.reversed!==Boolean((this.situation.loop-n)%2))}else this.absPos=Math.min(this.absPos,1),this.pos=this.absPos;this.pos<0&&(this.pos=0),this.situation.reversed&&(this.pos=1-this.pos);var r=this.situation.ease(this.pos);for(var s in this.situation.once)s>this.lastPos&&s<=r&&(this.situation.once[s].call(this.target(),this.pos,r),delete this.situation.once[s]);return this.active&&this.target().fire("during",{pos:this.pos,eased:r,fx:this,situation:this.situation}),this.situation?(this.eachAt(),1===this.pos&&!this.situation.reversed||this.situation.reversed&&0===this.pos?(this.stopAnimFrame(),this.target().fire("finished",{fx:this,situation:this.situation}),this.situations.length||(this.target().fire("allfinished"),this.situations.length||(this.target().off(".fx"),this.active=!1)),this.active?this.dequeue():this.clearCurrent()):!this.paused&&this.active&&this.startAnimFrame(),this.lastPos=r,this):this},eachAt:function(){var t,e,i=this,n=this.target(),r=this.situation;for(t in r.animations)e=[].concat(r.animations[t]).map(function(t){return"string"!=typeof t&&t.at?t.at(r.ease(i.pos),i.pos):t}),n[t].apply(n,e);for(t in r.attrs)e=[t].concat(r.attrs[t]).map(function(t){return"string"!=typeof t&&t.at?t.at(r.ease(i.pos),i.pos):t}),n.attr.apply(n,e);for(t in r.styles)e=[t].concat(r.styles[t]).map(function(t){return"string"!=typeof t&&t.at?t.at(r.ease(i.pos),i.pos):t}),n.css.apply(n,e);return r.transforms.length,this},once:function(t,e,i){var n=this.last();return i||(t=n.ease(t)),n.once[t]=e,this},_callStart:function(){return setTimeout(function(){this.start()}.bind(this),0),this}},parent:w.Element,construct:{animate:function(t,e,i){return(this.fx||(this.fx=new w.Timeline(this))).animate(t,e,i)},delay:function(t){return(this.fx||(this.fx=new w.Timeline(this))).delay(t)},stop:function(t,e){return this.fx&&this.fx.stop(t,e),this},finish:function(){return this.fx&&this.fx.finish(),this},pause:function(){return this.fx&&this.fx.pause(),this},play:function(){return this.fx&&this.fx.play(),this},speed:function(t){if(this.fx){if(null==t)return this.fx.speed();this.fx.speed(t)}return this}}}),w.MorphObj=w.invent({create:function(t,e){return w.Color.isColor(e)?new w.Color(t).morph(e):w.regex.delimiter.test(t)?new w.Array(t).morph(e):w.regex.numberAndUnit.test(e)?new w.Number(t).morph(e):(this.value=t,void(this.destination=e))},extend:{at:function(t,e){return e<1?this.value:this.destination},valueOf:function(){return this.value}}}),w.extend(w.Timeline,{attr:function(t,e,i){if("object"==typeof t)for(var n in t)this.attr(n,t[n]);else this.add(t,e,"attrs");return this},css:function(t,e){if("object"==typeof t)for(var i in t)this.css(i,t[i]);else this.add(t,e,"styles");return this},x:function(t,e){if(this.target()instanceof w.G)return this.transform({x:t},e),this;var i=new w.Number(t);return i.relative=e,this.add("x",i)},y:function(t,e){if(this.target()instanceof w.G)return this.transform({y:t},e),this;var i=new w.Number(t);return i.relative=e,this.add("y",i)},cx:function(t){return this.add("cx",new w.Number(t))},cy:function(t){return this.add("cy",new w.Number(t))},move:function(t,e){return this.x(t).y(e)},center:function(t,e){return this.cx(t).cy(e)},size:function(t,e){if(this.target()instanceof w.Text)this.attr("font-size",t);else{var i;t&&e||(i=this.target().bbox()),t||(t=i.width/i.height*e),e||(e=i.height/i.width*t),this.add("width",new w.Number(t)).add("height",new w.Number(e))}return this},width:function(t){return this.add("width",new w.Number(t))},height:function(t){return this.add("height",new w.Number(t))},plot:function(t,e,i,n){return 4===arguments.length?this.plot([t,e,i,n]):this.add("plot",new(this.target().MorphArray)(t))},leading:function(t){return this.target().leading?this.add("leading",new w.Number(t)):this},viewbox:function(t,e,i,n){return this.target()instanceof w.Container&&this.add("viewbox",new w.Box(t,e,i,n)),this},update:function(t){if(this.target()instanceof w.Stop){if("number"==typeof t||t instanceof w.Number)return this.update({offset:arguments[0],color:arguments[1],opacity:arguments[2]});null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",t.offset)}return this}}),w.Matrix=w.invent({create:function(t){var e,i=p([1,0,0,1,0,0]);for(t=t instanceof w.Element?t.matrixify():"string"==typeof t?p(t.split(w.regex.delimiter).map(parseFloat)):Array.isArray(t)?p(t):"object"==typeof t?t:6===arguments.length?p([].slice.call(arguments)):i,e=N.length-1;e>=0;--e)this[N[e]]=null!=t[N[e]]?t[N[e]]:i[N[e]]},extend:{clone:function(){return new w.Matrix(this)},transform:function(t){if(null!=t.a){var e=new w.Matrix(t);return this.lmultiply(e)}var i=!t.flip||"x"!==t.flip&&"both"!==t.flip?1:-1,n=!t.flip||"y"!==t.flip&&"both"!==t.flip?1:-1,r=t.skew&&t.skew.length?t.skew[0]:isFinite(t.skew)?t.skew:isFinite(t.skewX)?t.skewX:0,s=t.skew&&t.skew.length?t.skew[1]:isFinite(t.skew)?t.skew:isFinite(t.skewY)?t.skewY:0,o=t.scale&&t.scale.length?t.scale[0]*i:isFinite(t.scale)?t.scale*i:isFinite(t.scaleX)?t.scaleX*i:i,a=t.scale&&t.scale.length?t.scale[1]*n:isFinite(t.scale)?t.scale*n:isFinite(t.scaleY)?t.scaleY*n:n,h=t.shear||0,u=t.rotate||0,l=new w.Point(null==t.ox?t.origin:t.ox,t.oy),c=l.x,f=l.y,d=new w.Point(null==t.px?t.position:t.px,t.py,{x:null,y:null}),p=d.x,m=d.y,v=new w.Point(null==t.tx?t.translate:t.tx,t.ty),x=v.x,y=v.y,g=new w.Point(null==t.rx?t.relative:t.rx,t.ry),b=g.x,P=g.y,A=new w.Matrix(this),C=(new w.Matrix).translate(-c,-f).scale(o,a).skew(r,s).shear(h).rotate(u).translate(c,f).translate(b,P).lmultiply(A);if(isFinite(p)||isFinite(m)){var N=new w.Point(c-b,f-P).transform(C),M=p?p-N.x:0,S=m?m-N.y:0;C=C.translate(M,S)}return C=C.translate(x,y)},compose:function(t){var e=t.scaleX||1,i=t.scaleY||1,n=t.shear||0,r=t.rotate||0,s=t.translateX||0,o=t.translateY||0;return(new w.Matrix).scale(e,i).shear(n).rotate(r).translate(s,o).lmultiply(this)},decompose:function(){var t=this.a,e=this.b,i=this.c,n=this.d,r=this.e,s=this.f,o=t*n-e*i,a=o>0?1:-1,h=a*Math.sqrt(t*t+e*e),u=180/Math.PI*Math.atan2(a*e,a*t),l=(t*i+e*n)/o;return{scaleX:h,scaleY:i*h/(l*t-e)||n*h/(l*e+t),shear:l,rotate:u,translateX:r,translateY:s,a:this.a,b:this.b,c:this.c,d:this.d,e:this.e,f:this.f}},morph:function(t){return this.destination=new w.Matrix(t),this},at:function(t){return this.destination?new w.Matrix({a:this.a+(this.destination.a-this.a)*t,b:this.b+(this.destination.b-this.b)*t,c:this.c+(this.destination.c-this.c)*t,d:this.d+(this.destination.d-this.d)*t,e:this.e+(this.destination.e-this.e)*t,f:this.f+(this.destination.f-this.f)*t}):this},multiply:function(t){var e=this,i=new w.Matrix(t),n=e.a*i.a+e.c*i.b,r=e.b*i.a+e.d*i.b,s=e.a*i.c+e.c*i.d,o=e.b*i.c+e.d*i.d,a=e.e+e.a*i.e+e.c*i.f,h=e.f+e.b*i.e+e.d*i.f;return new w.Matrix(n,r,s,o,a,h)},lmultiply:function(t){return new w.Matrix(t).multiply(this)},inverse:function(){return new w.Matrix(this.native().inverse())},translate:function(t,e){var i=new w.Matrix(this);return i.e+=t||0,i.f+=e||0,i},scale:function(t,e,i,n){1===arguments.length?e=t:3===arguments.length&&(n=i,i=e,e=t);var r=new w.Matrix(t,0,0,e,0,0);return this.around(i,n,r)},rotate:function(t,e,i){t=w.utils.radians(t);var n=new w.Matrix(Math.cos(t),Math.sin(t),-Math.sin(t),Math.cos(t),0,0);return this.around(e,i,n)},flip:function(t,e){return"x"===t?this.scale(-1,1,e,0):"y"===t?this.scale(1,-1,0,e):this.scale(-1,-1,t,e||t)},shear:function(t,e,i){var n=new w.Matrix(1,0,t,1,0,0);return this.around(e,i,n)},skew:function(t,e,i,n){1===arguments.length?e=t:3===arguments.length&&(n=i,i=e,e=t),t=w.utils.radians(t),e=w.utils.radians(e)
-;var r=new w.Matrix(1,Math.tan(e),Math.tan(t),1,0,0);return this.around(i,n,r)},skewX:function(t,e,i){return this.skew(t,0,e,i)},skewY:function(t,e,i){return this.skew(0,t,e,i)},around:function(t,e,i){var n=t||0,r=e||0;return this.translate(-n,-r).lmultiply(i).translate(n,r)},native:function(){for(var t=w.parser.nodes.svg.node.createSVGMatrix(),e=N.length-1;e>=0;e--)t[N[e]]=this[N[e]];return t},equals:function(t){var e=new w.Matrix(t);return g(this.a,e.a)&&g(this.b,e.b)&&g(this.c,e.c)&&g(this.d,e.d)&&g(this.e,e.e)&&g(this.f,e.f)},toString:function(){return"matrix("+this.a+","+this.b+","+this.c+","+this.d+","+this.e+","+this.f+")"}},parent:w.Element,construct:{ctm:function(){return new w.Matrix(this.node.getCTM())},screenCTM:function(){if(this instanceof w.Doc&&!this.isRoot()){var t=this.rect(1,1),e=t.node.getScreenCTM();return t.remove(),new w.Matrix(e)}return new w.Matrix(this.node.getScreenCTM())}}}),w.Point=w.invent({create:function(t,e,i){var n;i=i||{x:0,y:0},n=Array.isArray(t)?{x:t[0],y:t[1]}:"object"==typeof t?{x:t.x,y:t.y}:{x:t,y:e},this.x=null==n.x?i.x:n.x,this.y=null==n.y?i.y:n.y},extend:{clone:function(){return new w.Point(this)},morph:function(t,e){return this.destination=new w.Point(t,e),this},at:function(t){return this.destination?new w.Point({x:this.x+(this.destination.x-this.x)*t,y:this.y+(this.destination.y-this.y)*t}):this},native:function(){var t=w.parser.nodes.svg.node.createSVGPoint();return t.x=this.x,t.y=this.y,t},transform:function(t){return new w.Point(this.native().matrixTransform(t.native()))}}}),w.extend(w.Element,{point:function(t,e){return new w.Point(t,e).transform(this.screenCTM().inverse())}}),w.extend(w.Element,{attr:function(t,e,i){if(null==t){for(t={},e=this.node.attributes,i=e.length-1;i>=0;i--)t[e[i].nodeName]=w.regex.isNumber.test(e[i].nodeValue)?parseFloat(e[i].nodeValue):e[i].nodeValue;return t}if("object"==typeof t)for(e in t)this.attr(e,t[e]);else if(null===e)this.node.removeAttribute(t);else{if(null==e)return e=this.node.getAttribute(t),null==e?w.defaults.attrs[t]:w.regex.isNumber.test(e)?parseFloat(e):e;"fill"!==t&&"stroke"!==t||(w.regex.isImage.test(e)&&(e=this.doc().defs().image(e)),e instanceof w.Image&&(e=this.doc().defs().pattern(0,0,function(){this.add(e)}))),"number"==typeof e?e=new w.Number(e):w.Color.isColor(e)?e=new w.Color(e):Array.isArray(e)&&(e=new w.Array(e)),"leading"===t?this.leading&&this.leading(e):"string"==typeof i?this.node.setAttributeNS(i,t,e.toString()):this.node.setAttribute(t,e.toString()),!this.rebuild||"font-size"!==t&&"x"!==t||this.rebuild(t,e)}return this}}),w.extend(w.Element,{untransform:function(){return this.attr("transform",null)},matrixify:function(){return(this.attr("transform")||"").split(w.regex.transforms).slice(0,-1).map(function(t){var e=t.trim().split("(");return[e[0],e[1].split(w.regex.delimiter).map(function(t){return parseFloat(t)})]}).reverse().reduce(function(t,e){return"matrix"===e[0]?t.lmultiply(p(e[1])):t[e[0]].apply(t,e[1])},new w.Matrix)},toParent:function(t){if(this===t)return this;var e=this.screenCTM(),i=t.screenCTM().inverse();return this.addTo(t).untransform().transform(i.multiply(e)),this},toDoc:function(){return this.toParent(this.doc())}}),w.extend(w.Element,{transform:function(t,e){var i=this.bbox();if(null==t||"string"==typeof t){var n=new w.Matrix(this).decompose();return n[t]||n}if("string"==typeof t.origin||null==t.origin&&null==t.ox&&null==t.oy){var r="string"==typeof t.origin?t.origin.toLowerCase().trim():"center",s=i.height,o=i.width,a=i.x,h=i.y;t.ox=r.includes("left")?a:r.includes("right")?a+o:a+o/2,t.oy=r.includes("top")?h:r.includes("bottom")?h+s:h+s/2,t.origin=null}var u=!0===e?this:e||!1,l=new w.Matrix(u).transform(t);return this.attr("transform",l)}}),w.extend(w.Timeline,{transform:function(t,e,i){}}),w.extend(w.Element,{css:function(t,e){var i,n,r={};if(0===arguments.length)return this.node.style.cssText.split(/\s*;\s*/).filter(function(t){return!!t.length}).forEach(function(t){i=t.split(/\s*:\s*/),r[i[0]]=i[1]}),r;if(arguments.length<2){if(Array.isArray(t)){for(n=t.length;n--;)r[u(t[n])]=this.node.style[u(t[n])];return r}if("string"==typeof t)return this.node.style[u(t)];if("object"==typeof t)for(n in t)this.node.style[u(n)]=null==t[n]||w.regex.isBlank.test(t[n])?"":t[n]}return 2===arguments.length&&(this.node.style[u(t)]=null==e||w.regex.isBlank.test(e)?"":e),this}}),w.Parent=w.invent({create:function(t){this.constructor(t)},inherit:w.Element,extend:{children:function(){return w.utils.map(this.node.children,function(t){return w.adopt(t)})},add:function(t,e){return t=i(t),t.node!==this.node.children[e]&&this.node.insertBefore(t.node,this.node.children[e]||null),this},put:function(t,e){return this.add(t,e),t.instance||t},has:function(t){return this.index(t)>=0},index:function(t){return[].slice.call(this.node.children).indexOf(t.node)},get:function(t){return w.adopt(this.node.children[t])},first:function(){return this.get(0)},last:function(){return this.get(this.node.children.length-1)},each:function(t,e){var i,n,r=this.children();for(i=0,n=r.length;i<n;i++)r[i]instanceof w.Element&&t.apply(r[i],[i,r]),e&&r[i]instanceof w.Parent&&r[i].each(t,e);return this},removeElement:function(t){return this.node.removeChild(t.node),this},clear:function(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return delete this._defs,this}}}),w.extend(w.Parent,{flatten:function(t){return this instanceof w.G||this instanceof w.Doc?(t=t||(this instanceof w.Doc&&this.isRoot()?this:this.parent(w.Parent)),this.each(function(){return this instanceof w.Defs?this:this instanceof w.Parent?this.flatten(t):this.toParent(t)}),this.node.firstElementChild||this.remove(),this):this},ungroup:function(t){return this instanceof w.G||this instanceof w.Doc&&!this.isRoot()?(t=t||this.parent(w.Parent),this.each(function(){return this.toParent(t)}),this.remove(),this):this}}),w.Container=w.invent({create:function(t){this.constructor(t)},inherit:w.Parent}),["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","mouseenter","mouseleave","touchstart","touchmove","touchleave","touchend","touchcancel"].forEach(function(t){w.Element.prototype[t]=function(e){return w.on(this,t,e),this}}),w.listenerId=0,w.on=function(t,e,i,n,r){var s=i.bind(n||t),o=t instanceof w.Element?t.node:t;o.instance=o.instance||{events:{}};var a=o.instance.events;i._svgjsListenerId||(i._svgjsListenerId=++w.listenerId),e.split(w.regex.delimiter).forEach(function(t){var e=t.split(".")[0],n=t.split(".")[1]||"*";a[e]=a[e]||{},a[e][n]=a[e][n]||{},a[e][n][i._svgjsListenerId]=s,o.addEventListener(e,s,r||!1)})},w.off=function(t,e,i,n){var r=t instanceof w.Element?t.node:t;if(r.instance&&("function"!=typeof i||(i=i._svgjsListenerId))){var s=r.instance.events;(e||"").split(w.regex.delimiter).forEach(function(t){var e,o,a=t&&t.split(".")[0],h=t&&t.split(".")[1];if(i)s[a]&&s[a][h||"*"]&&(r.removeEventListener(a,s[a][h||"*"][i],n||!1),delete s[a][h||"*"][i]);else if(a&&h){if(s[a]&&s[a][h]){for(o in s[a][h])w.off(r,[a,h].join("."),o);delete s[a][h]}}else if(h)for(t in s)for(e in s[t])h===e&&w.off(r,[t,h].join("."));else if(a){if(s[a]){for(e in s[a])w.off(r,[a,e].join("."));delete s[a]}}else{for(t in s)w.off(r,t);r.instance.events={}}})}},w.extend(w.Element,{on:function(t,e,i,n){return w.on(this,t,e,i,n),this},off:function(t,e){return w.off(this.node,t,e),this},dispatch:function(e,i){return e instanceof t.Event?this.node.dispatchEvent(e):this.node.dispatchEvent(e=new t.CustomEvent(e,{detail:i,cancelable:!0})),e},fire:function(t,e){return this.dispatch(t,e),this}}),w.Defs=w.invent({create:"defs",inherit:w.Container}),w.G=w.invent({create:"g",inherit:w.Container,extend:{},construct:{group:function(){return this.put(new w.G)}}}),w.extend(w.Element,{siblings:function(){return this.parent().children()},position:function(){return this.parent().index(this)},next:function(){return this.siblings()[this.position()+1]},prev:function(){return this.siblings()[this.position()-1]},forward:function(){var t=this.position()+1,e=this.parent();return e.removeElement(this).add(this,t),e instanceof w.Doc&&e.node.appendChild(e.defs().node),this},backward:function(){var t=this.position();return t>0&&this.parent().removeElement(this).add(this,t-1),this},front:function(){var t=this.parent();return t.node.appendChild(this.node),t instanceof w.Doc&&t.node.appendChild(t.defs().node),this},back:function(){return this.position()>0&&this.parent().removeElement(this).add(this,0),this},before:function(t){t.remove();var e=this.position();return this.parent().add(t,e),this},after:function(t){t.remove();var e=this.position();return this.parent().add(t,e+1),this}}),w.Mask=w.invent({create:"mask",inherit:w.Container,extend:{remove:function(){return this.targets().forEach(function(t){t.unmask()}),w.Element.prototype.remove.call(this)},targets:function(){return w.select('svg [mask*="'+this.id()+'"]')}},construct:{mask:function(){return this.defs().put(new w.Mask)}}}),w.extend(w.Element,{maskWith:function(t){var e=t instanceof w.Mask?t:this.parent().mask().add(t);return this.attr("mask",'url("#'+e.id()+'")')},unmask:function(){return this.attr("mask",null)},masker:function(){return this.reference("mask")}}),w.ClipPath=w.invent({create:"clipPath",inherit:w.Container,extend:{remove:function(){return this.targets().forEach(function(t){t.unclip()}),w.Element.prototype.remove.call(this)},targets:function(){return w.select('svg [clip-path*="'+this.id()+'"]')}},construct:{clip:function(){return this.defs().put(new w.ClipPath)}}}),w.extend(w.Element,{clipWith:function(t){var e=t instanceof w.ClipPath?t:this.parent().clip().add(t);return this.attr("clip-path",'url("#'+e.id()+'")')},unclip:function(){return this.attr("clip-path",null)},clipper:function(){return this.reference("clip-path")}}),w.Gradient=w.invent({create:function(t){this.constructor("object"==typeof t?t:w.create(t+"Gradient"))},inherit:w.Container,extend:{stop:function(t,e,i){return this.put(new w.Stop).update(t,e,i)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},url:function(){return"url(#"+this.id()+")"},toString:function(){return this.url()},attr:function(t,e,i){return"transform"===t&&(t="gradientTransform"),w.Container.prototype.attr.call(this,t,e,i)}},construct:{gradient:function(t,e){return this.defs().gradient(t,e)}}}),w.extend([w.Gradient,w.Timeline],{from:function(t,e){return"radialGradient"===(this._target||this).type?this.attr({fx:new w.Number(t),fy:new w.Number(e)}):this.attr({x1:new w.Number(t),y1:new w.Number(e)})},to:function(t,e){return"radialGradient"===(this._target||this).type?this.attr({cx:new w.Number(t),cy:new w.Number(e)}):this.attr({x2:new w.Number(t),y2:new w.Number(e)})}}),w.extend(w.Defs,{gradient:function(t,e){return this.put(new w.Gradient(t)).update(e)}}),w.Stop=w.invent({create:"stop",inherit:w.Element,extend:{update:function(t){return("number"==typeof t||t instanceof w.Number)&&(t={offset:arguments[0],color:arguments[1],opacity:arguments[2]}),null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",new w.Number(t.offset)),this}}}),w.Pattern=w.invent({create:"pattern",inherit:w.Container,extend:{url:function(){return"url(#"+this.id()+")"},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return this.url()},attr:function(t,e,i){return"transform"===t&&(t="patternTransform"),w.Container.prototype.attr.call(this,t,e,i)}},construct:{pattern:function(t,e,i){return this.defs().pattern(t,e,i)}}}),w.extend(w.Defs,{pattern:function(t,e,i){return this.put(new w.Pattern).update(i).attr({x:0,y:0,width:t,height:e,patternUnits:"userSpaceOnUse"})}}),w.Doc=w.invent({create:function(t){this.constructor(t||w.create("svg")),this.namespace()},inherit:w.Container,extend:{isRoot:function(){return!(this.node.parentNode&&this.node.parentNode instanceof t.SVGElement&&"#document"!==this.node.parentNode.nodeName)},doc:function(){return this.isRoot()?this:w.Element.prototype.doc.call(this)},namespace:function(){return this.isRoot()?this.attr({xmlns:w.ns,version:"1.1"}).attr("xmlns:xlink",w.xlink,w.xmlns).attr("xmlns:svgjs",w.svgjs,w.xmlns):this.doc().namespace()},defs:function(){return this.isRoot()?w.adopt(this.node.getElementsByTagName("defs")[0])||this.put(new w.Defs):this.doc().defs()},parent:function(t){return this.isRoot()?"#document"===this.node.parentNode.nodeName?null:this.node.parentNode:w.Element.prototype.parent.call(this,t)},remove:function(){return this.isRoot()?(this.parent()&&this.parent().removeChild(this.node),this):w.Element.prototype.remove.call(this)},clear:function(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return this}},construct:{nested:function(){return this.put(new w.Doc)}}}),w.Shape=w.invent({create:function(t){this.constructor(t)},inherit:w.Element}),w.Bare=w.invent({create:function(t,e){if(this.constructor(w.create(t)),e)for(var i in e.prototype)"function"==typeof e.prototype[i]&&(this[i]=e.prototype[i])},inherit:w.Element,extend:{words:function(t){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return this.node.appendChild(e.createTextNode(t)),this}}}),w.extend(w.Parent,{element:function(t,e){return this.put(new w.Bare(t,e))}}),w.Symbol=w.invent({create:"symbol",inherit:w.Container,construct:{symbol:function(){return this.put(new w.Symbol)}}}),w.Use=w.invent({create:"use",inherit:w.Shape,extend:{element:function(t,e){return this.attr("href",(e||"")+"#"+t,w.xlink)}},construct:{use:function(t,e){return this.put(new w.Use).element(t,e)}}}),w.Rect=w.invent({create:"rect",inherit:w.Shape,construct:{rect:function(t,e){return this.put(new w.Rect).size(t,e)}}}),w.Circle=w.invent({create:"circle",inherit:w.Shape,construct:{circle:function(t){return this.put(new w.Circle).rx(new w.Number(t).divide(2)).move(0,0)}}}),w.extend([w.Circle,w.Timeline],{rx:function(t){return this.attr("r",t)},ry:function(t){return this.rx(t)}}),w.Ellipse=w.invent({create:"ellipse",inherit:w.Shape,construct:{ellipse:function(t,e){return this.put(new w.Ellipse).size(t,e).move(0,0)}}}),w.extend([w.Ellipse,w.Rect,w.Timeline],{rx:function(t){return this.attr("rx",t)},ry:function(t){return this.attr("ry",t)}}),w.extend([w.Circle,w.Ellipse],{x:function(t){return null==t?this.cx()-this.rx():this.cx(t+this.rx())},y:function(t){return null==t?this.cy()-this.ry():this.cy(t+this.ry())},cx:function(t){return null==t?this.attr("cx"):this.attr("cx",t)},cy:function(t){return null==t?this.attr("cy"):this.attr("cy",t)},width:function(t){return null==t?2*this.rx():this.rx(new w.Number(t).divide(2))},height:function(t){return null==t?2*this.ry():this.ry(new w.Number(t).divide(2))},size:function(t,e){var i=d(this,t,e);return this.rx(new w.Number(i.width).divide(2)).ry(new w.Number(i.height).divide(2))}}),w.Line=w.invent({create:"line",inherit:w.Shape,extend:{array:function(){return new w.PointArray([[this.attr("x1"),this.attr("y1")],[this.attr("x2"),this.attr("y2")]])},plot:function(t,e,i,n){return null==t?this.array():(t=void 0!==e?{x1:t,y1:e,x2:i,y2:n}:new w.PointArray(t).toLine(),this.attr(t))},move:function(t,e){return this.attr(this.array().move(t,e).toLine())},size:function(t,e){var i=d(this,t,e);return this.attr(this.array().size(i.width,i.height).toLine())}},construct:{line:function(t,e,i,n){return w.Line.prototype.plot.apply(this.put(new w.Line),null!=t?[t,e,i,n]:[0,0,0,0])}}}),w.Polyline=w.invent({create:"polyline",inherit:w.Shape,construct:{polyline:function(t){return this.put(new w.Polyline).plot(t||new w.PointArray)}}}),w.Polygon=w.invent({create:"polygon",inherit:w.Shape,construct:{polygon:function(t){return this.put(new w.Polygon).plot(t||new w.PointArray)}}}),w.extend([w.Polyline,w.Polygon],{array:function(){return this._array||(this._array=new w.PointArray(this.attr("points")))},plot:function(t){return null==t?this.array():this.clear().attr("points","string"==typeof t?t:this._array=new w.PointArray(t))},clear:function(){return delete this._array,this},move:function(t,e){return this.attr("points",this.array().move(t,e))},size:function(t,e){var i=d(this,t,e);return this.attr("points",this.array().size(i.width,i.height))}}),w.extend([w.Line,w.Polyline,w.Polygon],{MorphArray:w.PointArray,x:function(t){return null==t?this.bbox().x:this.move(t,this.bbox().y)},y:function(t){return null==t?this.bbox().y:this.move(this.bbox().x,t)},width:function(t){var e=this.bbox();return null==t?e.width:this.size(t,e.height)},height:function(t){var e=this.bbox();return null==t?e.height:this.size(e.width,t)}}),w.Path=w.invent({create:"path",inherit:w.Shape,extend:{MorphArray:w.PathArray,array:function(){return this._array||(this._array=new w.PathArray(this.attr("d")))},plot:function(t){return null==t?this.array():this.clear().attr("d","string"==typeof t?t:this._array=new w.PathArray(t))},clear:function(){return delete this._array,this},move:function(t,e){return this.attr("d",this.array().move(t,e))},x:function(t){return null==t?this.bbox().x:this.move(t,this.bbox().y)},y:function(t){return null==t?this.bbox().y:this.move(this.bbox().x,t)},size:function(t,e){var i=d(this,t,e);return this.attr("d",this.array().size(i.width,i.height))},width:function(t){return null==t?this.bbox().width:this.size(t,this.bbox().height)},height:function(t){return null==t?this.bbox().height:this.size(this.bbox().width,t)}},construct:{path:function(t){return this.put(new w.Path).plot(t||new w.PathArray)}}}),w.Image=w.invent({create:"image",inherit:w.Shape,extend:{load:function(e,i){if(!e)return this;var n=new t.Image;return w.on(n,"load",function(t){var r=this.parent(w.Pattern);0===this.width()&&0===this.height()&&this.size(n.width,n.height),r instanceof w.Pattern&&0===r.width()&&0===r.height()&&r.size(this.width(),this.height()),"function"==typeof i&&i.call(this,{width:n.width,height:n.height,ratio:n.width/n.height,url:e})},this),w.on(n,"load error",function(){w.off(n)}),this.attr("href",n.src=e,w.xlink)}},construct:{image:function(t,e){return this.put(new w.Image).size(0,0).load(t,e)}}}),w.Text=w.invent({create:function(t){this.constructor(t||w.create("text")),this.dom.leading=new w.Number(1.3),this._rebuild=!0,this._build=!1,this.attr("font-family",w.defaults.attrs["font-family"])},inherit:w.Parent,extend:{x:function(t){return null==t?this.attr("x"):this.attr("x",t)},y:function(t){var e=this.attr("y"),i="number"==typeof e?e-this.bbox().y:0;return null==t?"number"==typeof e?e-i:e:this.attr("y","number"==typeof t?t+i:t)},cx:function(t){return null==t?this.bbox().cx:this.x(t-this.bbox().width/2)},cy:function(t){return null==t?this.bbox().cy:this.y(t-this.bbox().height/2)},text:function(t){if(void 0===t){var e=this.node.childNodes,i=0;t="";for(var n=0,r=e.length;n<r;++n)"textPath"!==e[n].nodeName?(n!==i&&3!==e[n].nodeType&&!0===w.adopt(e[n]).dom.newLined&&(t+="\n"),t+=e[n].textContent):0===n&&(i=1);return t}if(this.clear().build(!0),"function"==typeof t)t.call(this,this);else{t=t.split("\n");for(var s=0,o=t.length;s<o;s++)this.tspan(t[s]).newLine()}return this.build(!1).rebuild()},leading:function(t){return null==t?this.dom.leading:(this.dom.leading=new w.Number(t),this.rebuild())},rebuild:function(t){if("boolean"==typeof t&&(this._rebuild=t),this._rebuild){var e=this,i=0,n=this.dom.leading*new w.Number(this.attr("font-size"));this.each(function(){this.dom.newLined&&(this.attr("x",e.attr("x")),"\n"===this.text()?i+=n:(this.attr("dy",n+i),i=0))}),this.fire("rebuild")}return this},build:function(t){return this._build=!!t,this},setData:function(t){return this.dom=t,this.dom.leading=new w.Number(t.leading||1.3),this}},construct:{text:function(t){return this.put(new w.Text).text(t)},plain:function(t){return this.put(new w.Text).plain(t)}}}),w.Tspan=w.invent({create:"tspan",inherit:w.Parent,extend:{text:function(t){return null==t?this.node.textContent+(this.dom.newLined?"\n":""):("function"==typeof t?t.call(this,this):this.plain(t),this)},dx:function(t){return this.attr("dx",t)},dy:function(t){return this.attr("dy",t)},newLine:function(){var t=this.parent(w.Text);return this.dom.newLined=!0,this.dy(t.dom.leading*t.attr("font-size")).attr("x",t.x())}}}),w.extend([w.Text,w.Tspan],{plain:function(t){return!1===this._build&&this.clear(),this.node.appendChild(e.createTextNode(t)),this},tspan:function(t){var e=new w.Tspan;return this._build||this.clear(),this.node.appendChild(e.node),e.text(t)},length:function(){return this.node.getComputedTextLength()}}),w.TextPath=w.invent({create:"textPath",inherit:w.Text,parent:w.Parent,extend:{MorphArray:w.PathArray,array:function(){var t=this.track();return t?t.array():null},plot:function(t){var e=this.track(),i=null;return e&&(i=e.plot(t)),null==t?i:this},track:function(){return this.reference("href")}},construct:{textPath:function(t,e){return this.defs().path(e).text(t).addTo(this)}}}),w.extend([w.Text],{path:function(t){var e=new w.TextPath;return t instanceof w.Path||(t=this.doc().defs().path(t)),e.attr("href","#"+t,w.xlink),this.put(e)},textPath:function(){return this.select("textPath")}}),w.extend([w.Path],{text:function(t){if(t instanceof w.Text){var e=t.text();return t.clear().path(this).text(e)}return this.parent().put(new w.Text).path(this).text(t)}}),w.A=w.invent({create:"a",inherit:w.Container,extend:{to:function(t){return this.attr("href",t,w.xlink)},target:function(t){return this.attr("target",t)}},construct:{link:function(t){return this.put(new w.A).to(t)}}}),w.extend(w.Element,{linkTo:function(t){var e=new w.A;return"function"==typeof t?t.call(e,e):e.to(t),this.parent().put(e).put(this)}}),w.Marker=w.invent({create:"marker",inherit:w.Container,extend:{width:function(t){return this.attr("markerWidth",t)},height:function(t){return this.attr("markerHeight",t)},ref:function(t,e){return this.attr("refX",t).attr("refY",e)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return"url(#"+this.id()+")"}},construct:{marker:function(t,e,i){return this.defs().marker(t,e,i)}}}),w.extend(w.Defs,{marker:function(t,e,i){return this.put(new w.Marker).size(t,e).ref(t/2,e/2).viewbox(0,0,t,e).attr("orient","auto").update(i)}}),w.extend([w.Line,w.Polyline,w.Polygon,w.Path],{marker:function(t,e,i,n){var r=["marker"];return"all"!==t&&r.push(t),r=r.join("-"),t=arguments[1]instanceof w.Marker?arguments[1]:this.doc().marker(e,i,n),this.attr(r,t)}}),w.extend(w.Element,{data:function(t,e,i){if("object"==typeof t)for(e in t)this.data(e,t[e]);else if(arguments.length<2)try{return JSON.parse(this.attr("data-"+t))}catch(e){return this.attr("data-"+t)}else this.attr("data-"+t,null===e?null:!0===i||"string"==typeof e||"number"==typeof e?e:JSON.stringify(e));return this}}),w.extend(w.Element,{remember:function(t,e){if("object"==typeof arguments[0])for(var i in t)this.remember(i,t[i]);else{if(1===arguments.length)return this.memory()[t];this.memory()[t]=e}return this},forget:function(){if(0===arguments.length)this._memory={};else for(var t=arguments.length-1;t>=0;t--)delete this.memory()[arguments[t]];return this},memory:function(){return this._memory||(this._memory={})}}),w.get=function(t){var i=e.getElementById(y(t)||t);return w.adopt(i)},w.select=function(t,i){return w.utils.map((i||e).querySelectorAll(t),function(t){return w.adopt(t)})},w.$$=function(t,i){return w.utils.map((i||e).querySelectorAll(t),function(t){return w.adopt(t)})},w.$=function(t,i){return w.adopt((i||e).querySelector(t))},w.extend(w.Parent,{select:function(t){return w.select(t,this.node)}});var N="abcdef".split("");return w.Box=w.invent({create:function(t){var e=[0,0,0,0];t="string"==typeof t?t.split(w.regex.delimiter).map(parseFloat):Array.isArray(t)?t:"object"==typeof t?[null!=t.left?t.left:t.x,null!=t.top?t.top:t.y,t.width,t.height]:4===arguments.length?[].slice.call(arguments):e,this.x=t[0],this.y=t[1],this.width=t[2],this.height=t[3],x(this)},extend:{merge:function(t){var e=Math.min(this.x,t.x),i=Math.min(this.y,t.y);return new w.Box(e,i,Math.max(this.x+this.width,t.x+t.width)-e,Math.max(this.y+this.height,t.y+t.height)-i)},transform:function(t){var e=1/0,i=-1/0,n=1/0,r=-1/0;return[new w.Point(this.x,this.y),new w.Point(this.x2,this.y),new w.Point(this.x,this.y2),new w.Point(this.x2,this.y2)].forEach(function(s){s=s.transform(t),e=Math.min(e,s.x),i=Math.max(i,s.x),n=Math.min(n,s.y),r=Math.max(r,s.y)}),new w.Box(e,n,i-e,r-n)},addOffset:function(){return this.x+=t.pageXOffset,this.y+=t.pageYOffset,this},toString:function(){return this.x+" "+this.y+" "+this.width+" "+this.height},morph:function(t,e,i,n){return this.destination=new w.Box(t,e,i,n),this},at:function(t){return this.destination?new w.Box(this.x+(this.destination.x-this.x)*t,this.y+(this.destination.y-this.y)*t,this.width+(this.destination.width-this.width)*t,this.height+(this.destination.height-this.height)*t):this}},parent:w.Element,construct:{bbox:function(){var t;try{if(t=this.node.getBBox(),n(t)&&!r(this.node))throw new Exception("Element not in the dom")}catch(i){try{var e=this.clone(w.parser().svg).show();t=e.node.getBBox(),e.remove()}catch(t){console.warn("Getting a bounding box of this element is not possible")}}return new w.Box(t)},rbox:function(t){try{var e=new w.Box(this.node.getBoundingClientRect());return t?e.transform(t.screenCTM().inverse()):e.addOffset()}catch(t){return new w.Box}}}}),w.extend([w.Doc,w.Symbol,w.Image,w.Pattern,w.Marker,w.ForeignObject,w.View],{viewbox:function(t,e,i,n){return null==t?new w.Box(this.attr("viewBox")):this.attr("viewBox",new w.Box(t,e,i,n))}}),w.parser=function(){var t;return w.parser.nodes.svg.node.parentNode||(t=e.body||e.documentElement,w.parser.nodes.svg.addTo(t)),w.parser.nodes},w.parser.nodes={svg:w().size(2,0).css({opacity:0,position:"absolute",left:"-100%",top:"-100%",overflow:"hidden"})},w.parser.nodes.path=w.parser.nodes.svg.path().node,w}); \ No newline at end of file
+/*! svg.js v3.0.0 MIT*/;!function(t,e){"function"==typeof define&&define.amd?define(function(){return e(t,t.document)}):"object"==typeof exports?module.exports=t.document?e(t,t.document):function(t){return e(t,t.document)}:t.SVG=e(t,t.document)}("undefined"!=typeof window?window:this,function(t,e){function n(t,n){if(t instanceof b.Element)return t;if("object"==typeof t)return b.adopt(t);if(null==t)return new b.Doc;if("string"==typeof t&&"<"!==t.charAt(0))return b.adopt(e.querySelector(t));var i=b.create("svg");return i.innerHTML=t,t=b.adopt(i.firstElementChild)}function i(t){return!(t.w||t.h||t.x||t.y)}function r(t){return(e.documentElement.contains||function(t){for(;t.parentNode;)t=t.parentNode;return t===e}).call(e.documentElement,t)}function s(t,e,n,i){return n+i.replace(b.regex.dots," .")}function o(t){for(var e=t.slice(0),n=e.length;n--;)Array.isArray(e[n])&&(e[n]=o(e[n]));return e}function a(t,e){return t instanceof e}function h(t,e){return(t.matches||t.matchesSelector||t.msMatchesSelector||t.mozMatchesSelector||t.webkitMatchesSelector||t.oMatchesSelector).call(t,e)}function u(t){return t.toLowerCase().replace(/-(.)/g,function(t,e){return e.toUpperCase()})}function l(t){return t.charAt(0).toUpperCase()+t.slice(1)}function c(t){return 4===t.length?["#",t.substring(1,2),t.substring(1,2),t.substring(2,3),t.substring(2,3),t.substring(3,4),t.substring(3,4)].join(""):t}function f(t){var e=t.toString(16);return 1===e.length?"0"+e:e}function d(t,e,n){if(null==e||null==n){var i=t.bbox();null==e?e=i.width/i.height*n:null==n&&(n=i.height/i.width*e)}return{width:e,height:n}}function p(t){return{a:t[0],b:t[1],c:t[2],d:t[3],e:t[4],f:t[5]}}function m(t){for(var e=0,n=t.length,i="";e<n;e++)i+=t[e][0],null!=t[e][1]&&(i+=t[e][1],null!=t[e][2]&&(i+=" ",i+=t[e][2],null!=t[e][3]&&(i+=" ",i+=t[e][3],i+=" ",i+=t[e][4],null!=t[e][5]&&(i+=" ",i+=t[e][5],i+=" ",i+=t[e][6],null!=t[e][7]&&(i+=" ",i+=t[e][7])))));return i+" "}function x(t){for(var e=t.children.length-1;e>=0;e--)x(t.children[e]);return t.id?b.adopt(t).id(b.eid(t.nodeName)):b.adopt(t)}function v(t){return null==t.x&&(t.x=0,t.y=0,t.width=0,t.height=0),t.w=t.width,t.h=t.height,t.x2=t.x+t.width,t.y2=t.y+t.height,t.cx=t.x+t.width/2,t.cy=t.y+t.height/2,t}function y(t){var e=(t||"").toString().match(b.regex.reference);if(e)return e[1]}function g(t,e,n){return Math.abs(e-t)<(n||1e-6)}function w(t){var e="both"===t.flip||!0===t.flip,n=t.flip&&(e||"x"===t.flip)?-1:1,i=t.flip&&(e||"y"===t.flip)?-1:1,r=t.skew&&t.skew.length?t.skew[0]:isFinite(t.skew)?t.skew:isFinite(t.skewX)?t.skewX:0,s=t.skew&&t.skew.length?t.skew[1]:isFinite(t.skew)?t.skew:isFinite(t.skewY)?t.skewY:0,o=t.scale&&t.scale.length?t.scale[0]*n:isFinite(t.scale)?t.scale*n:isFinite(t.scaleX)?t.scaleX*n:n,a=t.scale&&t.scale.length?t.scale[1]*i:isFinite(t.scale)?t.scale*i:isFinite(t.scaleY)?t.scaleY*i:i,h=t.shear||0,u=t.rotate||0,l=new b.Point(null==t.ox?t.origin:t.ox,t.oy),c=l.x,f=l.y,d=new b.Point(null==t.px?t.position:t.px,t.py,{x:null,y:null}),p=d.x,m=d.y,x=new b.Point(null==t.tx?t.translate:t.tx,t.ty),v=x.x,y=x.y,g=new b.Point(null==t.rx?t.relative:t.rx,t.ry);return{scaleX:o,scaleY:a,skewX:r,skewY:s,shear:h,theta:u,rx:g.x,ry:g.y,tx:v,ty:y,ox:c,oy:f,px:p,py:m}}if(!e.createElementNS||!e.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect)return{supported:!1};var b=this.SVG=function(t){if(b.supported)return t=n(t)};b.supported=!0,b.ns="http://www.w3.org/2000/svg",b.xmlns="http://www.w3.org/2000/xmlns/",b.xlink="http://www.w3.org/1999/xlink",b.svgjs="http://svgjs.com/svgjs",b.did=1e3,b.eid=function(t){return"Svgjs"+l(t)+b.did++},b.create=function(t){return e.createElementNS(this.ns,t)},b.extend=function(t,e){var n,i;for(t=Array.isArray(t)?t:[t],i=t.length-1;i>=0;i--)if(t[i])for(n in e)t[i].prototype[n]=e[n]},b.invent=function(t){var e="function"==typeof t.create?t.create:function(e){this.constructor(e||b.create(t.create))};return t.inherit&&(e.prototype=new t.inherit),t.extend&&b.extend(e,t.extend),t.construct&&b.extend(t.parent||b.Container,t.construct),e},b.adopt=function(e){if(!e)return null;if(e.instance instanceof b.Element)return e.instance;if(!(e instanceof t.SVGElement))return new b.HtmlNode(e);return"svg"===e.nodeName?new b.Doc(e):"linearGradient"===e.nodeName||"radialGradient"===e.nodeName?new b.Gradient(e):b[l(e.nodeName)]?new(b[l(e.nodeName)])(e):new b.Parent(e)},b.regex={numberAndUnit:/^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i,hex:/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,rgb:/rgb\((\d+),(\d+),(\d+)\)/,reference:/#([a-z0-9\-_]+)/i,transforms:/\)\s*,?\s*/,whitespace:/\s/g,isHex:/^#[a-f0-9]{3,6}$/i,isRgb:/^rgb\(/,isCss:/[^:]+:[^;]+;?/,isBlank:/^(\s+)?$/,isNumber:/^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,isPercent:/^-?[\d.]+%$/,isImage:/\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i,delimiter:/[\s,]+/,hyphen:/([^e])-/gi,pathLetters:/[MLHVCSQTAZ]/gi,isPathLetter:/[MLHVCSQTAZ]/i,numbersWithDots:/((\d?\.\d+(?:e[+-]?\d+)?)((?:\.\d+(?:e[+-]?\d+)?)+))+/gi,dots:/\./g},b.utils={map:function(t,e){var n,i=t.length,r=[];for(n=0;n<i;n++)r.push(e(t[n]));return r},filter:function(t,e){var n,i=t.length,r=[];for(n=0;n<i;n++)e(t[n])&&r.push(t[n]);return r},radians:function(t){return t%360*Math.PI/180},degrees:function(t){return 180*t/Math.PI%360},filterSVGElements:function(e){return this.filter(e,function(e){return e instanceof t.SVGElement})}},b.defaults={timeline:{duration:600,ease:">",delay:0},attrs:{"fill-opacity":1,"stroke-opacity":1,"stroke-width":0,"stroke-linejoin":"miter","stroke-linecap":"butt",fill:"#000000",stroke:"#000000",opacity:1,x:0,y:0,cx:0,cy:0,width:0,height:0,r:0,rx:0,ry:0,offset:0,"stop-opacity":1,"stop-color":"#000000","font-size":16,"font-family":"Helvetica, Arial, sans-serif","text-anchor":"start"}},b.Queue=b.invent({create:function(){this._first=null,this._last=null,this.length=0,this.id=0},extend:{push:function(t){var e={id:this.id++,value:t};this._last?this._last=this._last.next=e:this._last=this._first=e,this.length++},shift:function(){if(0!=this.length){var t=this._first;return this._first=t.next,this._last=--this.length?this._last:null,t.value}},first:function(){return this._first&&this._first.value},last:function(){return this._last&&this._last.value},remove:function(t){for(var e=null,n=this._first;n&&!t(n);)e=n,n=n.next;if(n&&n===this._first&&(this._first=this._first.next),n&&n===this._last&&(this._last=e),n)return--this.length,e&&(e.next=n.next),n.item}}}),b.Color=function(t){var e;this.r=0,this.g=0,this.b=0,t&&("string"==typeof t?b.regex.isRgb.test(t)?(e=b.regex.rgb.exec(t.replace(b.regex.whitespace,"")),this.r=parseInt(e[1]),this.g=parseInt(e[2]),this.b=parseInt(e[3])):b.regex.isHex.test(t)&&(e=b.regex.hex.exec(c(t)),this.r=parseInt(e[1],16),this.g=parseInt(e[2],16),this.b=parseInt(e[3],16)):"object"==typeof t&&(this.r=t.r,this.g=t.g,this.b=t.b))},b.extend(b.Color,{toString:function(){return this.toHex()},toHex:function(){return"#"+f(this.r)+f(this.g)+f(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},morph:function(t){return this.destination=new b.Color(t),this},at:function(t){return this.destination?(t=t<0?0:t>1?1:t,new b.Color({r:~~(this.r+(this.destination.r-this.r)*t),g:~~(this.g+(this.destination.g-this.g)*t),b:~~(this.b+(this.destination.b-this.b)*t)})):this}}),b.Color.test=function(t){return t+="",b.regex.isHex.test(t)||b.regex.isRgb.test(t)},b.Color.isRgb=function(t){return t&&"number"==typeof t.r&&"number"==typeof t.g&&"number"==typeof t.b},b.Color.isColor=function(t){return b.Color.isRgb(t)||b.Color.test(t)},b.Array=function(t,e){t=(t||[]).valueOf(),0===t.length&&e&&(t=e.valueOf()),this.value=this.parse(t)},b.extend(b.Array,{morph:function(t){if(this.destination=this.parse(t),this.value.length!==this.destination.length){for(var e=this.value[this.value.length-1],n=this.destination[this.destination.length-1];this.value.length>this.destination.length;)this.destination.push(n);for(;this.value.length<this.destination.length;)this.value.push(e)}return this},settle:function(){for(var t=0,e=this.value.length,n=[];t<e;t++)-1===n.indexOf(this.value[t])&&n.push(this.value[t]);return this.value=n,n},at:function(t){if(!this.destination)return this;for(var e=0,n=this.value.length,i=[];e<n;e++)i.push(this.value[e]+(this.destination[e]-this.value[e])*t);return new b.Array(i)},toString:function(){return this.value.join(" ")},valueOf:function(){return this.value},parse:function(t){return t=t.valueOf(),Array.isArray(t)?t:t.trim().split(b.regex.delimiter).map(parseFloat)},reverse:function(){return this.value.reverse(),this},clone:function(){var t=new this.constructor;return t.value=o(this.value),t}}),b.PointArray=function(t,e){b.Array.call(this,t,e||[[0,0]])},b.PointArray.prototype=new b.Array,b.PointArray.prototype.constructor=b.PointArray,b.extend(b.PointArray,{toString:function(){for(var t=0,e=this.value.length,n=[];t<e;t++)n.push(this.value[t].join(","));return n.join(" ")},toLine:function(){return{x1:this.value[0][0],y1:this.value[0][1],x2:this.value[1][0],y2:this.value[1][1]}},at:function(t){if(!this.destination)return this;for(var e=0,n=this.value.length,i=[];e<n;e++)i.push([this.value[e][0]+(this.destination[e][0]-this.value[e][0])*t,this.value[e][1]+(this.destination[e][1]-this.value[e][1])*t]);return new b.PointArray(i)},parse:function(t){var e=[];if(t=t.valueOf(),Array.isArray(t)){if(Array.isArray(t[0]))return t}else t=t.trim().split(b.regex.delimiter).map(parseFloat);t.length%2!=0&&t.pop();for(var n=0,i=t.length;n<i;n+=2)e.push([t[n],t[n+1]]);return e},move:function(t,e){var n=this.bbox();if(t-=n.x,e-=n.y,!isNaN(t)&&!isNaN(e))for(var i=this.value.length-1;i>=0;i--)this.value[i]=[this.value[i][0]+t,this.value[i][1]+e];return this},size:function(t,e){var n,i=this.bbox();for(n=this.value.length-1;n>=0;n--)i.width&&(this.value[n][0]=(this.value[n][0]-i.x)*t/i.width+i.x),i.height&&(this.value[n][1]=(this.value[n][1]-i.y)*e/i.height+i.y);return this},bbox:function(){var t=-1/0,e=-1/0,n=1/0,i=1/0;return this.value.forEach(function(r){t=Math.max(r[0],t),e=Math.max(r[1],e),n=Math.min(r[0],n),i=Math.min(r[1],i)}),{x:n,y:i,width:t-n,height:e-i}}});for(var A={M:function(t,e,n){return e.x=n.x=t[0],e.y=n.y=t[1],["M",e.x,e.y]},L:function(t,e){return e.x=t[0],e.y=t[1],["L",t[0],t[1]]},H:function(t,e){return e.x=t[0],["H",t[0]]},V:function(t,e){return e.y=t[0],["V",t[0]]},C:function(t,e){return e.x=t[4],e.y=t[5],["C",t[0],t[1],t[2],t[3],t[4],t[5]]},S:function(t,e){return e.x=t[2],e.y=t[3],["S",t[0],t[1],t[2],t[3]]},Q:function(t,e){return e.x=t[2],e.y=t[3],["Q",t[0],t[1],t[2],t[3]]},T:function(t,e){return e.x=t[0],e.y=t[1],["T",t[0],t[1]]},Z:function(t,e,n){return e.x=n.x,e.y=n.y,["Z"]},A:function(t,e){return e.x=t[5],e.y=t[6],["A",t[0],t[1],t[2],t[3],t[4],t[5],t[6]]}},C="mlhvqtcsaz".split(""),P=0,N=C.length;P<N;++P)A[C[P]]=function(t){return function(e,n,i){if("H"===t)e[0]=e[0]+n.x;else if("V"===t)e[0]=e[0]+n.y;else if("A"===t)e[5]=e[5]+n.x,e[6]=e[6]+n.y;else for(var r=0,s=e.length;r<s;++r)e[r]=e[r]+(r%2?n.y:n.x);return A[t](e,n,i)}}(C[P].toUpperCase());b.PathArray=function(t,e){b.Array.call(this,t,e||[["M",0,0]])},b.PathArray.prototype=new b.Array,b.PathArray.prototype.constructor=b.PathArray,b.extend(b.PathArray,{toString:function(){return m(this.value)},move:function(t,e){var n=this.bbox();if(t-=n.x,e-=n.y,!isNaN(t)&&!isNaN(e))for(var i,r=this.value.length-1;r>=0;r--)i=this.value[r][0],"M"===i||"L"===i||"T"===i?(this.value[r][1]+=t,this.value[r][2]+=e):"H"===i?this.value[r][1]+=t:"V"===i?this.value[r][1]+=e:"C"===i||"S"===i||"Q"===i?(this.value[r][1]+=t,this.value[r][2]+=e,this.value[r][3]+=t,this.value[r][4]+=e,"C"===i&&(this.value[r][5]+=t,this.value[r][6]+=e)):"A"===i&&(this.value[r][6]+=t,this.value[r][7]+=e);return this},size:function(t,e){var n,i,r=this.bbox();for(n=this.value.length-1;n>=0;n--)i=this.value[n][0],"M"===i||"L"===i||"T"===i?(this.value[n][1]=(this.value[n][1]-r.x)*t/r.width+r.x,this.value[n][2]=(this.value[n][2]-r.y)*e/r.height+r.y):"H"===i?this.value[n][1]=(this.value[n][1]-r.x)*t/r.width+r.x:"V"===i?this.value[n][1]=(this.value[n][1]-r.y)*e/r.height+r.y:"C"===i||"S"===i||"Q"===i?(this.value[n][1]=(this.value[n][1]-r.x)*t/r.width+r.x,this.value[n][2]=(this.value[n][2]-r.y)*e/r.height+r.y,this.value[n][3]=(this.value[n][3]-r.x)*t/r.width+r.x,this.value[n][4]=(this.value[n][4]-r.y)*e/r.height+r.y,"C"===i&&(this.value[n][5]=(this.value[n][5]-r.x)*t/r.width+r.x,this.value[n][6]=(this.value[n][6]-r.y)*e/r.height+r.y)):"A"===i&&(this.value[n][1]=this.value[n][1]*t/r.width,this.value[n][2]=this.value[n][2]*e/r.height,this.value[n][6]=(this.value[n][6]-r.x)*t/r.width+r.x,this.value[n][7]=(this.value[n][7]-r.y)*e/r.height+r.y);return this},equalCommands:function(t){var e,n,i;for(t=new b.PathArray(t),i=this.value.length===t.value.length,e=0,n=this.value.length;i&&e<n;e++)i=this.value[e][0]===t.value[e][0];return i},morph:function(t){return t=new b.PathArray(t),this.equalCommands(t)?this.destination=t:this.destination=null,this},at:function(t){if(!this.destination)return this;var e,n,i,r,s=this.value,o=this.destination.value,a=[],h=new b.PathArray;for(e=0,n=s.length;e<n;e++){for(a[e]=[s[e][0]],i=1,r=s[e].length;i<r;i++)a[e][i]=s[e][i]+(o[e][i]-s[e][i])*t;"A"===a[e][0]&&(a[e][4]=+(0!==a[e][4]),a[e][5]=+(0!==a[e][5]))}return h.value=a,h},parse:function(t){if(t instanceof b.PathArray)return t.valueOf();var e,n={M:2,L:2,H:1,V:1,C:6,S:4,Q:4,T:2,A:7,Z:0};t="string"==typeof t?t.replace(b.regex.numbersWithDots,s).replace(b.regex.pathLetters," $& ").replace(b.regex.hyphen,"$1 -").trim().split(b.regex.delimiter):t.reduce(function(t,e){return[].concat.call(t,e)},[]);var i=[],r=new b.Point,o=new b.Point,a=0,h=t.length;do{b.regex.isPathLetter.test(t[a])?(e=t[a],++a):"M"===e?e="L":"m"===e&&(e="l"),i.push(A[e].call(null,t.slice(a,a+=n[e.toUpperCase()]).map(parseFloat),r,o))}while(h>a);return i},bbox:function(){return b.parser().path.setAttribute("d",this.toString()),b.parser.nodes.path.getBBox()}}),b.Number=b.invent({create:function(t,e){this.value=0,this.unit=e||"","number"==typeof t?this.value=isNaN(t)?0:isFinite(t)?t:t<0?-3.4e38:3.4e38:"string"==typeof t?(e=t.match(b.regex.numberAndUnit))&&(this.value=parseFloat(e[1]),"%"===e[5]?this.value/=100:"s"===e[5]&&(this.value*=1e3),this.unit=e[5]):t instanceof b.Number&&(this.value=t.valueOf(),this.unit=t.unit)},extend:{toString:function(){return("%"===this.unit?~~(1e8*this.value)/1e6:"s"===this.unit?this.value/1e3:this.value)+this.unit},toJSON:function(){return this.toString()},valueOf:function(){return this.value},plus:function(t){return t=new b.Number(t),new b.Number(this+t,this.unit||t.unit)},minus:function(t){return t=new b.Number(t),new b.Number(this-t,this.unit||t.unit)},times:function(t){return t=new b.Number(t),new b.Number(this*t,this.unit||t.unit)},divide:function(t){return t=new b.Number(t),new b.Number(this/t,this.unit||t.unit)},to:function(t){var e=new b.Number(this);return"string"==typeof t&&(e.unit=t),e},morph:function(t){return this.destination=new b.Number(t),t.relative&&(this.destination.value+=this.value),this},at:function(t){return this.destination?new b.Number(this.destination).minus(this).times(t).plus(this):this}}}),b.HtmlNode=b.invent({create:function(t){this.node=t},extend:{add:function(t,e){return t=n(t),t.node!==this.node.children[e]&&this.node.insertBefore(t.node,this.node.children[e]||null),this},put:function(t,e){return this.add(t,e),t}}}),b.Element=b.invent({create:function(t){this.events={},this.dom={},this.node=t,this.node&&(this.type=t.nodeName,this.node.instance=this,this.events=t.events||{},t.hasAttribute("svgjs:data")&&this.setData(JSON.parse(t.getAttribute("svgjs:data"))||{}))},extend:{x:function(t){return this.attr("x",t)},y:function(t){return this.attr("y",t)},cx:function(t){return null==t?this.x()+this.width()/2:this.x(t-this.width()/2)},cy:function(t){return null==t?this.y()+this.height()/2:this.y(t-this.height()/2)},move:function(t,e){return this.x(t).y(e)},center:function(t,e){return this.cx(t).cy(e)},width:function(t){return this.attr("width",t)},height:function(t){return this.attr("height",t)},size:function(t,e){var n=d(this,t,e);return this.width(new b.Number(n.width)).height(new b.Number(n.height))},clone:function(t){this.writeDataToDom();var e=x(this.node.cloneNode(!0));return t?t.add(e):this.after(e),e},remove:function(){return this.parent()&&this.parent().removeElement(this),this},replace:function(t){return this.after(t).remove(),t},addTo:function(t){return n(t).put(this)},putIn:function(t){return n(t).add(this)},id:function(t){return void 0!==t||this.node.id||(this.node.id=b.eid(this.type)),this.attr("id",t)},inside:function(t,e){var n=this.bbox();return t>n.x&&e>n.y&&t<n.x+n.width&&e<n.y+n.height},show:function(){return this.css("display","")},hide:function(){return this.css("display","none")},visible:function(){return"none"!==this.css("display")},toString:function(){return this.id()},classes:function(){var t=this.attr("class");return null==t?[]:t.trim().split(b.regex.delimiter)},hasClass:function(t){return-1!==this.classes().indexOf(t)},addClass:function(t){if(!this.hasClass(t)){var e=this.classes();e.push(t),this.attr("class",e.join(" "))}return this},removeClass:function(t){return this.hasClass(t)&&this.attr("class",this.classes().filter(function(e){return e!==t}).join(" ")),this},toggleClass:function(t){return this.hasClass(t)?this.removeClass(t):this.addClass(t)},reference:function(t){return b.get(this.attr(t))},parent:function(e){var n=this;if(!n.node.parentNode)return null;if(n=b.adopt(n.node.parentNode),!e)return n;for(;n&&n.node instanceof t.SVGElement;){if("string"==typeof e?n.matches(e):n instanceof e)return n;n=b.adopt(n.node.parentNode)}},doc:function(){var t=this.parent(b.Doc);return t&&t.doc()},defs:function(){return this.doc().defs()},parents:function(t){var e=[],n=this;do{if(!(n=n.parent(t))||!n.node)break;e.push(n)}while(n.parent);return e},matches:function(t){return h(this.node,t)},native:function(){return this.node},svg:function(t){var n,i;if(!(t&&this instanceof b.Parent))return this.writeDataToDom(),this.node.outerHTML;for(n=e.createElementNS(b.ns,"svg"),n.innerHTML=t,i=n.children.length;i--;)this.node.appendChild(n.firstElementChild);return this},writeDataToDom:function(){return this.is(b.Parent)&&this.each(function(){this.writeDataToDom()}),this.node.removeAttribute("svgjs:data"),Object.keys(this.dom).length&&this.node.setAttribute("svgjs:data",JSON.stringify(this.dom)),this},setData:function(t){return this.dom=t,this},is:function(t){return a(this,t)}}}),b.Matrix=b.invent({create:function(t){var e,n=p([1,0,0,1,0,0]);for(t=t instanceof b.Element?t.matrixify():"string"==typeof t?p(t.split(b.regex.delimiter).map(parseFloat)):Array.isArray(t)?p(t):"object"!=typeof t||null==t.a&&null==t.b&&null==t.c&&null==t.d&&null==t.e&&null==t.f?"object"==typeof t?(new b.Matrix).transform(t):6===arguments.length?p([].slice.call(arguments)):n:t,e=M.length-1;e>=0;--e)this[M[e]]=null!=t[M[e]]?t[M[e]]:n[M[e]]},extend:{clone:function(){return new b.Matrix(this)},transform:function(t){if(null!=t.a){var e=new b.Matrix(t);return this.lmultiply(e)}var n=w(t),i=new b.Matrix(this),r=(new b.Matrix).translate(-n.ox,-n.oy).scale(n.scaleX,n.scaleY).skew(n.skewX,n.skewY).shear(n.shear).rotate(n.theta).translate(n.ox,n.oy).translate(n.rx,n.ry).lmultiply(i);if(isFinite(n.px)||isFinite(n.py)){var s=new b.Point(n.ox-n.rx,n.oy-n.ry).transform(r),o=n.px?n.px-s.x:0,a=n.py?n.py-s.y:0;r=r.translate(o,a)}return r=r.translate(tx,ty)},compose:function(t){var e=t.scaleX||1,n=t.scaleY||1,i=t.shear||0,r=t.rotate||0,s=t.translateX||0,o=t.translateY||0;return(new b.Matrix).scale(e,n).shear(i).rotate(r).translate(s,o).lmultiply(this)},decompose:function(){var t=this.a,e=this.b,n=this.c,i=this.d,r=this.e,s=this.f,o=t*i-e*n,a=o>0?1:-1,h=a*Math.sqrt(t*t+e*e),u=180/Math.PI*Math.atan2(a*e,a*t),l=(t*n+e*i)/o;return{scaleX:h,scaleY:n*h/(l*t-e)||i*h/(l*e+t),shear:l,rotate:u,translateX:r,translateY:s,a:this.a,b:this.b,c:this.c,d:this.d,e:this.e,f:this.f}},morph:function(t){return this.destination=new b.Matrix(t),this},at:function(t){return this.destination?new b.Matrix({a:this.a+(this.destination.a-this.a)*t,b:this.b+(this.destination.b-this.b)*t,c:this.c+(this.destination.c-this.c)*t,d:this.d+(this.destination.d-this.d)*t,e:this.e+(this.destination.e-this.e)*t,f:this.f+(this.destination.f-this.f)*t}):this},multiply:function(t){var e=this,n=new b.Matrix(t),i=e.a*n.a+e.c*n.b,r=e.b*n.a+e.d*n.b,s=e.a*n.c+e.c*n.d,o=e.b*n.c+e.d*n.d,a=e.e+e.a*n.e+e.c*n.f,h=e.f+e.b*n.e+e.d*n.f;return new b.Matrix(i,r,s,o,a,h)},lmultiply:function(t){return new b.Matrix(t).multiply(this)},inverse:function(){var t=this.a,e=this.b,n=this.c,i=this.d,r=this.e,s=this.f,o=t*i-e*n;if(!o)throw new Error("Cannot invert "+this);var a=i/o,h=-e/o,u=-n/o,l=t/o,c=-(a*r+u*s),f=-(h*r+l*s);return new b.Matrix(a,h,u,l,c,f)},translate:function(t,e){var n=new b.Matrix(this);return n.e+=t||0,n.f+=e||0,n},scale:function(t,e,n,i){1===arguments.length?e=t:3===arguments.length&&(i=n,n=e,e=t);var r=new b.Matrix(t,0,0,e,0,0);return this.around(n,i,r)},rotate:function(t,e,n){t=b.utils.radians(t);var i=new b.Matrix(Math.cos(t),Math.sin(t),-Math.sin(t),Math.cos(t),0,0);return this.around(e,n,i)},flip:function(t,e){return"x"===t?this.scale(-1,1,e,0):"y"===t?this.scale(1,-1,0,e):this.scale(-1,-1,t,e||t)},shear:function(t,e,n){var i=new b.Matrix(1,0,t,1,0,0);return this.around(e,n,i)},skew:function(t,e,n,i){1===arguments.length?e=t:3===arguments.length&&(i=n,n=e,e=t),t=b.utils.radians(t),e=b.utils.radians(e);var r=new b.Matrix(1,Math.tan(e),Math.tan(t),1,0,0);return this.around(n,i,r)},skewX:function(t,e,n){return this.skew(t,0,e,n)},skewY:function(t,e,n){return this.skew(0,t,e,n)},around:function(t,e,n){var i=t||0,r=e||0;return this.translate(-i,-r).lmultiply(n).translate(i,r)},native:function(){for(var t=b.parser.nodes.svg.node.createSVGMatrix(),e=M.length-1;e>=0;e--)t[M[e]]=this[M[e]];return t},equals:function(t){var e=new b.Matrix(t);return g(this.a,e.a)&&g(this.b,e.b)&&g(this.c,e.c)&&g(this.d,e.d)&&g(this.e,e.e)&&g(this.f,e.f)},toString:function(){return"matrix("+this.a+","+this.b+","+this.c+","+this.d+","+this.e+","+this.f+")"}},parent:b.Element,construct:{ctm:function(){return new b.Matrix(this.node.getCTM())},screenCTM:function(){if(this instanceof b.Doc&&!this.isRoot()){var t=this.rect(1,1),e=t.node.getScreenCTM();return t.remove(),new b.Matrix(e)}return new b.Matrix(this.node.getScreenCTM())}}}),b.Point=b.invent({create:function(t,e,n){var i;n=n||{x:0,y:0},i=Array.isArray(t)?{x:t[0],y:t[1]}:"object"==typeof t?{x:t.x,y:t.y}:{x:t,y:e},this.x=null==i.x?n.x:i.x,this.y=null==i.y?n.y:i.y},extend:{clone:function(){return new b.Point(this)},morph:function(t,e){return this.destination=new b.Point(t,e),this},at:function(t){return this.destination?new b.Point({x:this.x+(this.destination.x-this.x)*t,y:this.y+(this.destination.y-this.y)*t}):this},native:function(){var t=b.parser.nodes.svg.node.createSVGPoint();return t.x=this.x,t.y=this.y,t},transform:function(t){return new b.Point(this.native().matrixTransform(t.native()))}}}),b.extend(b.Element,{point:function(t,e){return new b.Point(t,e).transform(this.screenCTM().inverse())}}),b.extend(b.Element,{attr:function(t,e,n){if(null==t){for(t={},e=this.node.attributes,n=e.length-1;n>=0;n--)t[e[n].nodeName]=b.regex.isNumber.test(e[n].nodeValue)?parseFloat(e[n].nodeValue):e[n].nodeValue;return t}if("object"==typeof t)for(e in t)this.attr(e,t[e]);else if(null===e)this.node.removeAttribute(t);else{if(null==e)return e=this.node.getAttribute(t),null==e?b.defaults.attrs[t]:b.regex.isNumber.test(e)?parseFloat(e):e;"fill"!==t&&"stroke"!==t||(b.regex.isImage.test(e)&&(e=this.doc().defs().image(e)),e instanceof b.Image&&(e=this.doc().defs().pattern(0,0,function(){this.add(e)}))),"number"==typeof e?e=new b.Number(e):b.Color.isColor(e)?e=new b.Color(e):Array.isArray(e)&&(e=new b.Array(e)),"leading"===t?this.leading&&this.leading(e):"string"==typeof n?this.node.setAttributeNS(n,t,e.toString()):this.node.setAttribute(t,e.toString()),!this.rebuild||"font-size"!==t&&"x"!==t||this.rebuild(t,e)}return this}}),b.extend(b.Element,{untransform:function(){return this.attr("transform",null)},matrixify:function(){return(this.attr("transform")||"").split(b.regex.transforms).slice(0,-1).map(function(t){var e=t.trim().split("(");return[e[0],e[1].split(b.regex.delimiter).map(function(t){return parseFloat(t)})]}).reverse().reduce(function(t,e){return"matrix"===e[0]?t.lmultiply(p(e[1])):t[e[0]].apply(t,e[1])},new b.Matrix)},toParent:function(t){if(this===t)return this;var e=this.screenCTM(),n=t.screenCTM().inverse();return this.addTo(t).untransform().transform(n.multiply(e)),this},toDoc:function(){return this.toParent(this.doc())}}),b.extend(b.Element,{transform:function(t,e){var n=this.bbox();if(null==t||"string"==typeof t){var i=new b.Matrix(this).decompose();return i[t]||i}if("string"==typeof t.origin||null==t.origin&&null==t.ox&&null==t.oy){var r="string"==typeof t.origin?t.origin.toLowerCase().trim():"center",s=n.height,o=n.width,a=n.x,h=n.y;t.ox=r.includes("left")?a:r.includes("right")?a+o:a+o/2,t.oy=r.includes("top")?h:r.includes("bottom")?h+s:h+s/2,t.origin=null}var u=!0===e?this:e||!1,l=new b.Matrix(u).transform(t);return this.attr("transform",l)}}),b.extend(b.Timeline,{transform:function(t,e,n){}}),b.extend(b.Element,{css:function(t,e){var n,i,r={};if(0===arguments.length)return this.node.style.cssText.split(/\s*;\s*/).filter(function(t){return!!t.length}).forEach(function(t){n=t.split(/\s*:\s*/),r[n[0]]=n[1]}),r;if(arguments.length<2){if(Array.isArray(t)){for(i=t.length;i--;)r[u(t[i])]=this.node.style[u(t[i])];return r}if("string"==typeof t)return this.node.style[u(t)];if("object"==typeof t)for(i in t)this.node.style[u(i)]=null==t[i]||b.regex.isBlank.test(t[i])?"":t[i]}return 2===arguments.length&&(this.node.style[u(t)]=null==e||b.regex.isBlank.test(e)?"":e),this}}),b.Parent=b.invent({create:function(t){this.constructor(t)},inherit:b.Element,extend:{children:function(){return b.utils.map(this.node.children,function(t){return b.adopt(t)})},add:function(t,e){return t=n(t),t.node!==this.node.children[e]&&this.node.insertBefore(t.node,this.node.children[e]||null),this},put:function(t,e){return this.add(t,e),t.instance||t},has:function(t){return this.index(t)>=0},index:function(t){return[].slice.call(this.node.children).indexOf(t.node)},get:function(t){return b.adopt(this.node.children[t])},first:function(){return this.get(0)},last:function(){return this.get(this.node.children.length-1)},each:function(t,e){var n,i,r=this.children();for(n=0,i=r.length;n<i;n++)r[n]instanceof b.Element&&t.apply(r[n],[n,r]),e&&r[n]instanceof b.Parent&&r[n].each(t,e);return this},removeElement:function(t){return this.node.removeChild(t.node),this},clear:function(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return delete this._defs,this}}}),b.extend(b.Parent,{flatten:function(t){return this instanceof b.G||this instanceof b.Doc?(t=t||(this instanceof b.Doc&&this.isRoot()?this:this.parent(b.Parent)),this.each(function(){return this instanceof b.Defs?this:this instanceof b.Parent?this.flatten(t):this.toParent(t)}),this.node.firstElementChild||this.remove(),this):this},ungroup:function(t){return this instanceof b.G||this instanceof b.Doc&&!this.isRoot()?(t=t||this.parent(b.Parent),this.each(function(){return this.toParent(t)}),this.remove(),this):this}}),b.Container=b.invent({create:function(t){this.constructor(t)},inherit:b.Parent}),["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","mouseenter","mouseleave","touchstart","touchmove","touchleave","touchend","touchcancel"].forEach(function(t){b.Element.prototype[t]=function(e){return b.on(this,t,e),this}}),b.listenerId=0,b.on=function(t,e,n,i,r){var s=n.bind(i||t),o=t instanceof b.Element?t.node:t;o.instance=o.instance||{events:{}};var a=o.instance.events;n._svgjsListenerId||(n._svgjsListenerId=++b.listenerId),e.split(b.regex.delimiter).forEach(function(t){var e=t.split(".")[0],i=t.split(".")[1]||"*";a[e]=a[e]||{},a[e][i]=a[e][i]||{},a[e][i][n._svgjsListenerId]=s,o.addEventListener(e,s,r||!1)})},b.off=function(t,e,n,i){var r=t instanceof b.Element?t.node:t;if(r.instance&&("function"!=typeof n||(n=n._svgjsListenerId))){var s=r.instance.events;(e||"").split(b.regex.delimiter).forEach(function(t){var e,o,a=t&&t.split(".")[0],h=t&&t.split(".")[1];if(n)s[a]&&s[a][h||"*"]&&(r.removeEventListener(a,s[a][h||"*"][n],i||!1),delete s[a][h||"*"][n]);else if(a&&h){if(s[a]&&s[a][h]){for(o in s[a][h])b.off(r,[a,h].join("."),o);delete s[a][h]}}else if(h)for(t in s)for(e in s[t])h===e&&b.off(r,[t,h].join("."));else if(a){if(s[a]){for(e in s[a])b.off(r,[a,e].join("."));delete s[a]}}else{for(t in s)b.off(r,t);r.instance.events={}}})}},b.extend(b.Element,{on:function(t,e,n,i){return b.on(this,t,e,n,i),this},off:function(t,e){return b.off(this.node,t,e),this},dispatch:function(e,n){return e instanceof t.Event?this.node.dispatchEvent(e):this.node.dispatchEvent(e=new t.CustomEvent(e,{detail:n,cancelable:!0})),e},fire:function(t,e){return this.dispatch(t,e),this}}),b.Defs=b.invent({create:"defs",inherit:b.Container}),b.G=b.invent({create:"g",inherit:b.Container,extend:{},construct:{group:function(){return this.put(new b.G)}}}),b.extend(b.Element,{siblings:function(){return this.parent().children()},position:function(){return this.parent().index(this)},next:function(){return this.siblings()[this.position()+1]},prev:function(){return this.siblings()[this.position()-1]},forward:function(){var t=this.position()+1,e=this.parent();return e.removeElement(this).add(this,t),e instanceof b.Doc&&e.node.appendChild(e.defs().node),this},backward:function(){var t=this.position();return t>0&&this.parent().removeElement(this).add(this,t-1),this},front:function(){var t=this.parent();return t.node.appendChild(this.node),t instanceof b.Doc&&t.node.appendChild(t.defs().node),this},back:function(){return this.position()>0&&this.parent().removeElement(this).add(this,0),this},before:function(t){t.remove();var e=this.position();return this.parent().add(t,e),this},after:function(t){t.remove();var e=this.position();return this.parent().add(t,e+1),this}}),b.Mask=b.invent({create:"mask",inherit:b.Container,extend:{remove:function(){return this.targets().forEach(function(t){t.unmask()}),b.Element.prototype.remove.call(this)},targets:function(){return b.select('svg [mask*="'+this.id()+'"]')}},construct:{mask:function(){return this.defs().put(new b.Mask)}}}),b.extend(b.Element,{maskWith:function(t){var e=t instanceof b.Mask?t:this.parent().mask().add(t);return this.attr("mask",'url("#'+e.id()+'")')},unmask:function(){return this.attr("mask",null)},masker:function(){return this.reference("mask")}}),b.ClipPath=b.invent({create:"clipPath",inherit:b.Container,extend:{remove:function(){return this.targets().forEach(function(t){t.unclip()}),b.Element.prototype.remove.call(this)},targets:function(){return b.select('svg [clip-path*="'+this.id()+'"]')}},construct:{clip:function(){return this.defs().put(new b.ClipPath)}}}),b.extend(b.Element,{clipWith:function(t){var e=t instanceof b.ClipPath?t:this.parent().clip().add(t);return this.attr("clip-path",'url("#'+e.id()+'")')},unclip:function(){return this.attr("clip-path",null)},clipper:function(){return this.reference("clip-path")}}),b.Gradient=b.invent({create:function(t){this.constructor("object"==typeof t?t:b.create(t+"Gradient"))},inherit:b.Container,extend:{stop:function(t,e,n){return this.put(new b.Stop).update(t,e,n)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},url:function(){return"url(#"+this.id()+")"},toString:function(){return this.url()},attr:function(t,e,n){return"transform"===t&&(t="gradientTransform"),b.Container.prototype.attr.call(this,t,e,n)}},construct:{gradient:function(t,e){return this.defs().gradient(t,e)}}}),b.extend([b.Gradient,b.Timeline],{from:function(t,e){return"radialGradient"===(this._target||this).type?this.attr({
+fx:new b.Number(t),fy:new b.Number(e)}):this.attr({x1:new b.Number(t),y1:new b.Number(e)})},to:function(t,e){return"radialGradient"===(this._target||this).type?this.attr({cx:new b.Number(t),cy:new b.Number(e)}):this.attr({x2:new b.Number(t),y2:new b.Number(e)})}}),b.extend(b.Defs,{gradient:function(t,e){return this.put(new b.Gradient(t)).update(e)}}),b.Stop=b.invent({create:"stop",inherit:b.Element,extend:{update:function(t){return("number"==typeof t||t instanceof b.Number)&&(t={offset:arguments[0],color:arguments[1],opacity:arguments[2]}),null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",new b.Number(t.offset)),this}}}),b.Pattern=b.invent({create:"pattern",inherit:b.Container,extend:{url:function(){return"url(#"+this.id()+")"},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return this.url()},attr:function(t,e,n){return"transform"===t&&(t="patternTransform"),b.Container.prototype.attr.call(this,t,e,n)}},construct:{pattern:function(t,e,n){return this.defs().pattern(t,e,n)}}}),b.extend(b.Defs,{pattern:function(t,e,n){return this.put(new b.Pattern).update(n).attr({x:0,y:0,width:t,height:e,patternUnits:"userSpaceOnUse"})}}),b.Doc=b.invent({create:function(t){this.constructor(t||b.create("svg")),this.namespace()},inherit:b.Container,extend:{isRoot:function(){return!(this.node.parentNode&&this.node.parentNode instanceof t.SVGElement&&"#document"!==this.node.parentNode.nodeName)},doc:function(){return this.isRoot()?this:b.Element.prototype.doc.call(this)},namespace:function(){return this.isRoot()?this.attr({xmlns:b.ns,version:"1.1"}).attr("xmlns:xlink",b.xlink,b.xmlns).attr("xmlns:svgjs",b.svgjs,b.xmlns):this.doc().namespace()},defs:function(){return this.isRoot()?b.adopt(this.node.getElementsByTagName("defs")[0])||this.put(new b.Defs):this.doc().defs()},parent:function(t){return this.isRoot()?"#document"===this.node.parentNode.nodeName?null:this.node.parentNode:b.Element.prototype.parent.call(this,t)},remove:function(){return this.isRoot()?(this.parent()&&this.parent().removeChild(this.node),this):b.Element.prototype.remove.call(this)},clear:function(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return this}},construct:{nested:function(){return this.put(new b.Doc)}}}),b.Shape=b.invent({create:function(t){this.constructor(t)},inherit:b.Element}),b.Bare=b.invent({create:function(t,e){if(this.constructor(b.create(t)),e)for(var n in e.prototype)"function"==typeof e.prototype[n]&&(this[n]=e.prototype[n])},inherit:b.Element,extend:{words:function(t){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return this.node.appendChild(e.createTextNode(t)),this}}}),b.extend(b.Parent,{element:function(t,e){return this.put(new b.Bare(t,e))}}),b.Symbol=b.invent({create:"symbol",inherit:b.Container,construct:{symbol:function(){return this.put(new b.Symbol)}}}),b.Use=b.invent({create:"use",inherit:b.Shape,extend:{element:function(t,e){return this.attr("href",(e||"")+"#"+t,b.xlink)}},construct:{use:function(t,e){return this.put(new b.Use).element(t,e)}}}),b.Rect=b.invent({create:"rect",inherit:b.Shape,construct:{rect:function(t,e){return this.put(new b.Rect).size(t,e)}}}),b.Circle=b.invent({create:"circle",inherit:b.Shape,construct:{circle:function(t){return this.put(new b.Circle).rx(new b.Number(t).divide(2)).move(0,0)}}}),b.extend([b.Circle,b.Timeline],{rx:function(t){return this.attr("r",t)},ry:function(t){return this.rx(t)}}),b.Ellipse=b.invent({create:"ellipse",inherit:b.Shape,construct:{ellipse:function(t,e){return this.put(new b.Ellipse).size(t,e).move(0,0)}}}),b.extend([b.Ellipse,b.Rect,b.Timeline],{rx:function(t){return this.attr("rx",t)},ry:function(t){return this.attr("ry",t)}}),b.extend([b.Circle,b.Ellipse],{x:function(t){return null==t?this.cx()-this.rx():this.cx(t+this.rx())},y:function(t){return null==t?this.cy()-this.ry():this.cy(t+this.ry())},cx:function(t){return null==t?this.attr("cx"):this.attr("cx",t)},cy:function(t){return null==t?this.attr("cy"):this.attr("cy",t)},width:function(t){return null==t?2*this.rx():this.rx(new b.Number(t).divide(2))},height:function(t){return null==t?2*this.ry():this.ry(new b.Number(t).divide(2))},size:function(t,e){var n=d(this,t,e);return this.rx(new b.Number(n.width).divide(2)).ry(new b.Number(n.height).divide(2))}}),b.Line=b.invent({create:"line",inherit:b.Shape,extend:{array:function(){return new b.PointArray([[this.attr("x1"),this.attr("y1")],[this.attr("x2"),this.attr("y2")]])},plot:function(t,e,n,i){return null==t?this.array():(t=void 0!==e?{x1:t,y1:e,x2:n,y2:i}:new b.PointArray(t).toLine(),this.attr(t))},move:function(t,e){return this.attr(this.array().move(t,e).toLine())},size:function(t,e){var n=d(this,t,e);return this.attr(this.array().size(n.width,n.height).toLine())}},construct:{line:function(t,e,n,i){return b.Line.prototype.plot.apply(this.put(new b.Line),null!=t?[t,e,n,i]:[0,0,0,0])}}}),b.Polyline=b.invent({create:"polyline",inherit:b.Shape,construct:{polyline:function(t){return this.put(new b.Polyline).plot(t||new b.PointArray)}}}),b.Polygon=b.invent({create:"polygon",inherit:b.Shape,construct:{polygon:function(t){return this.put(new b.Polygon).plot(t||new b.PointArray)}}}),b.extend([b.Polyline,b.Polygon],{array:function(){return this._array||(this._array=new b.PointArray(this.attr("points")))},plot:function(t){return null==t?this.array():this.clear().attr("points","string"==typeof t?t:this._array=new b.PointArray(t))},clear:function(){return delete this._array,this},move:function(t,e){return this.attr("points",this.array().move(t,e))},size:function(t,e){var n=d(this,t,e);return this.attr("points",this.array().size(n.width,n.height))}}),b.extend([b.Line,b.Polyline,b.Polygon],{MorphArray:b.PointArray,x:function(t){return null==t?this.bbox().x:this.move(t,this.bbox().y)},y:function(t){return null==t?this.bbox().y:this.move(this.bbox().x,t)},width:function(t){var e=this.bbox();return null==t?e.width:this.size(t,e.height)},height:function(t){var e=this.bbox();return null==t?e.height:this.size(e.width,t)}}),b.Path=b.invent({create:"path",inherit:b.Shape,extend:{MorphArray:b.PathArray,array:function(){return this._array||(this._array=new b.PathArray(this.attr("d")))},plot:function(t){return null==t?this.array():this.clear().attr("d","string"==typeof t?t:this._array=new b.PathArray(t))},clear:function(){return delete this._array,this},move:function(t,e){return this.attr("d",this.array().move(t,e))},x:function(t){return null==t?this.bbox().x:this.move(t,this.bbox().y)},y:function(t){return null==t?this.bbox().y:this.move(this.bbox().x,t)},size:function(t,e){var n=d(this,t,e);return this.attr("d",this.array().size(n.width,n.height))},width:function(t){return null==t?this.bbox().width:this.size(t,this.bbox().height)},height:function(t){return null==t?this.bbox().height:this.size(this.bbox().width,t)}},construct:{path:function(t){return this.put(new b.Path).plot(t||new b.PathArray)}}}),b.Image=b.invent({create:"image",inherit:b.Shape,extend:{load:function(e,n){if(!e)return this;var i=new t.Image;return b.on(i,"load",function(t){var r=this.parent(b.Pattern);0===this.width()&&0===this.height()&&this.size(i.width,i.height),r instanceof b.Pattern&&0===r.width()&&0===r.height()&&r.size(this.width(),this.height()),"function"==typeof n&&n.call(this,{width:i.width,height:i.height,ratio:i.width/i.height,url:e})},this),b.on(i,"load error",function(){b.off(i)}),this.attr("href",i.src=e,b.xlink)}},construct:{image:function(t,e){return this.put(new b.Image).size(0,0).load(t,e)}}}),b.Text=b.invent({create:function(t){this.constructor(t||b.create("text")),this.dom.leading=new b.Number(1.3),this._rebuild=!0,this._build=!1,this.attr("font-family",b.defaults.attrs["font-family"])},inherit:b.Parent,extend:{x:function(t){return null==t?this.attr("x"):this.attr("x",t)},y:function(t){var e=this.attr("y"),n="number"==typeof e?e-this.bbox().y:0;return null==t?"number"==typeof e?e-n:e:this.attr("y","number"==typeof t?t+n:t)},cx:function(t){return null==t?this.bbox().cx:this.x(t-this.bbox().width/2)},cy:function(t){return null==t?this.bbox().cy:this.y(t-this.bbox().height/2)},text:function(t){if(void 0===t){var e=this.node.childNodes,n=0;t="";for(var i=0,r=e.length;i<r;++i)"textPath"!==e[i].nodeName?(i!==n&&3!==e[i].nodeType&&!0===b.adopt(e[i]).dom.newLined&&(t+="\n"),t+=e[i].textContent):0===i&&(n=1);return t}if(this.clear().build(!0),"function"==typeof t)t.call(this,this);else{t=t.split("\n");for(var s=0,o=t.length;s<o;s++)this.tspan(t[s]).newLine()}return this.build(!1).rebuild()},leading:function(t){return null==t?this.dom.leading:(this.dom.leading=new b.Number(t),this.rebuild())},rebuild:function(t){if("boolean"==typeof t&&(this._rebuild=t),this._rebuild){var e=this,n=0,i=this.dom.leading*new b.Number(this.attr("font-size"));this.each(function(){this.dom.newLined&&(this.attr("x",e.attr("x")),"\n"===this.text()?n+=i:(this.attr("dy",i+n),n=0))}),this.fire("rebuild")}return this},build:function(t){return this._build=!!t,this},setData:function(t){return this.dom=t,this.dom.leading=new b.Number(t.leading||1.3),this}},construct:{text:function(t){return this.put(new b.Text).text(t)},plain:function(t){return this.put(new b.Text).plain(t)}}}),b.Tspan=b.invent({create:"tspan",inherit:b.Parent,extend:{text:function(t){return null==t?this.node.textContent+(this.dom.newLined?"\n":""):("function"==typeof t?t.call(this,this):this.plain(t),this)},dx:function(t){return this.attr("dx",t)},dy:function(t){return this.attr("dy",t)},newLine:function(){var t=this.parent(b.Text);return this.dom.newLined=!0,this.dy(t.dom.leading*t.attr("font-size")).attr("x",t.x())}}}),b.extend([b.Text,b.Tspan],{plain:function(t){return!1===this._build&&this.clear(),this.node.appendChild(e.createTextNode(t)),this},tspan:function(t){var e=new b.Tspan;return this._build||this.clear(),this.node.appendChild(e.node),e.text(t)},length:function(){return this.node.getComputedTextLength()}}),b.TextPath=b.invent({create:"textPath",inherit:b.Text,parent:b.Parent,extend:{MorphArray:b.PathArray,array:function(){var t=this.track();return t?t.array():null},plot:function(t){var e=this.track(),n=null;return e&&(n=e.plot(t)),null==t?n:this},track:function(){return this.reference("href")}},construct:{textPath:function(t,e){return this.defs().path(e).text(t).addTo(this)}}}),b.extend([b.Text],{path:function(t){var e=new b.TextPath;return t instanceof b.Path||(t=this.doc().defs().path(t)),e.attr("href","#"+t,b.xlink),this.put(e)},textPath:function(){return this.select("textPath")}}),b.extend([b.Path],{text:function(t){if(t instanceof b.Text){var e=t.text();return t.clear().path(this).text(e)}return this.parent().put(new b.Text).path(this).text(t)}}),b.A=b.invent({create:"a",inherit:b.Container,extend:{to:function(t){return this.attr("href",t,b.xlink)},target:function(t){return this.attr("target",t)}},construct:{link:function(t){return this.put(new b.A).to(t)}}}),b.extend(b.Element,{linkTo:function(t){var e=new b.A;return"function"==typeof t?t.call(e,e):e.to(t),this.parent().put(e).put(this)}}),b.Marker=b.invent({create:"marker",inherit:b.Container,extend:{width:function(t){return this.attr("markerWidth",t)},height:function(t){return this.attr("markerHeight",t)},ref:function(t,e){return this.attr("refX",t).attr("refY",e)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return"url(#"+this.id()+")"}},construct:{marker:function(t,e,n){return this.defs().marker(t,e,n)}}}),b.extend(b.Defs,{marker:function(t,e,n){return this.put(new b.Marker).size(t,e).ref(t/2,e/2).viewbox(0,0,t,e).attr("orient","auto").update(n)}}),b.extend([b.Line,b.Polyline,b.Polygon,b.Path],{marker:function(t,e,n,i){var r=["marker"];return"all"!==t&&r.push(t),r=r.join("-"),t=arguments[1]instanceof b.Marker?arguments[1]:this.doc().marker(e,n,i),this.attr(r,t)}}),b.extend(b.Element,{data:function(t,e,n){if("object"==typeof t)for(e in t)this.data(e,t[e]);else if(arguments.length<2)try{return JSON.parse(this.attr("data-"+t))}catch(e){return this.attr("data-"+t)}else this.attr("data-"+t,null===e?null:!0===n||"string"==typeof e||"number"==typeof e?e:JSON.stringify(e));return this}}),b.extend(b.Element,{remember:function(t,e){if("object"==typeof arguments[0])for(var n in t)this.remember(n,t[n]);else{if(1===arguments.length)return this.memory()[t];this.memory()[t]=e}return this},forget:function(){if(0===arguments.length)this._memory={};else for(var t=arguments.length-1;t>=0;t--)delete this.memory()[arguments[t]];return this},memory:function(){return this._memory||(this._memory={})}}),b.get=function(t){var n=e.getElementById(y(t)||t);return b.adopt(n)},b.select=function(t,n){return b.utils.map((n||e).querySelectorAll(t),function(t){return b.adopt(t)})},b.$$=function(t,n){return b.utils.map((n||e).querySelectorAll(t),function(t){return b.adopt(t)})},b.$=function(t,n){return b.adopt((n||e).querySelector(t))},b.extend(b.Parent,{select:function(t){return b.select(t,this.node)}});var M="abcdef".split("");return b.Box=b.invent({create:function(t){var e=[0,0,0,0];t="string"==typeof t?t.split(b.regex.delimiter).map(parseFloat):Array.isArray(t)?t:"object"==typeof t?[null!=t.left?t.left:t.x,null!=t.top?t.top:t.y,t.width,t.height]:4===arguments.length?[].slice.call(arguments):e,this.x=t[0],this.y=t[1],this.width=t[2],this.height=t[3],v(this)},extend:{merge:function(t){var e=Math.min(this.x,t.x),n=Math.min(this.y,t.y);return new b.Box(e,n,Math.max(this.x+this.width,t.x+t.width)-e,Math.max(this.y+this.height,t.y+t.height)-n)},transform:function(t){var e=1/0,n=-1/0,i=1/0,r=-1/0;return[new b.Point(this.x,this.y),new b.Point(this.x2,this.y),new b.Point(this.x,this.y2),new b.Point(this.x2,this.y2)].forEach(function(s){s=s.transform(t),e=Math.min(e,s.x),n=Math.max(n,s.x),i=Math.min(i,s.y),r=Math.max(r,s.y)}),new b.Box(e,i,n-e,r-i)},addOffset:function(){return this.x+=t.pageXOffset,this.y+=t.pageYOffset,this},toString:function(){return this.x+" "+this.y+" "+this.width+" "+this.height},morph:function(t,e,n,i){return this.destination=new b.Box(t,e,n,i),this},at:function(t){return this.destination?new b.Box(this.x+(this.destination.x-this.x)*t,this.y+(this.destination.y-this.y)*t,this.width+(this.destination.width-this.width)*t,this.height+(this.destination.height-this.height)*t):this}},parent:b.Element,construct:{bbox:function(){var t;try{if(t=this.node.getBBox(),i(t)&&!r(this.node))throw new Exception("Element not in the dom")}catch(n){try{var e=this.clone(b.parser().svg).show();t=e.node.getBBox(),e.remove()}catch(t){console.warn("Getting a bounding box of this element is not possible")}}return new b.Box(t)},rbox:function(t){try{var e=new b.Box(this.node.getBoundingClientRect());return t?e.transform(t.screenCTM().inverse()):e.addOffset()}catch(t){return new b.Box}}}}),b.extend([b.Doc,b.Symbol,b.Image,b.Pattern,b.Marker,b.ForeignObject,b.View],{viewbox:function(t,e,n,i){return null==t?new b.Box(this.attr("viewBox")):this.attr("viewBox",new b.Box(t,e,n,i))}}),b.parser=function(){var t;return b.parser.nodes.svg.node.parentNode||(t=e.body||e.documentElement,b.parser.nodes.svg.addTo(t)),b.parser.nodes},b.parser.nodes={svg:b().size(2,0).css({opacity:0,position:"absolute",left:"-100%",top:"-100%",overflow:"hidden"})},b.parser.nodes.path=b.parser.nodes.svg.path().node,b.Animator={nextDraw:null,frames:new b.Queue,timeouts:new b.Queue,frameCount:0,timeoutCount:0,timer:t.performance||t.Date,frame:function(t){return b.Animator.frames.push({id:b.Animator.frameCount,run:t}),null===b.Animator.nextDraw&&(b.Animator.nextDraw=requestAnimationFrame(b.Animator._draw)),++b.Animator.frameCount},timeout:function(t,e){e=e||0;var n=b.Animator.timer.now()+e,i=b.Animator.timeoutCount++;return b.Animator.timeouts.push({id:i,run:t,time:n}),null===b.Animator.nextDraw&&(b.Animator.nextDraw=requestAnimationFrame(b.Animator._draw)),i},cancelTimeout:function(t){return b.Animator.timeouts.remove(function(e){return e.id===t})},_draw:function(t){for(var e=null,n=b.Animator.timeouts.last();(e=b.Animator.timeouts.shift())&&(t>e.time?e.run():b.Animator.timeouts.push(e),e!==n););for(var i=(b.Animator.frames.last(),b.Animator.frameCount);b.Animator.frames.first()&&b.Animator.frames.first().id<i;){b.Animator.frames.shift().run(t)}b.Animator.nextDraw=b.Animator.timeouts.length>0||b.Animator.frames.length>0?requestAnimationFrame(b.Animator._draw):null}},b}); \ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index 5b511ef..5883790 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -40,7 +40,6 @@ var parts = [
'src/number.js',
'src/HtmlNode.js',
'src/element.js',
- 'src/fx.js',
'src/matrix.js',
'src/point.js',
'src/attr.js',
@@ -81,7 +80,8 @@ var parts = [
'src/helpers.js',
'src/polyfill.js',
'src/boxes.js',
- 'src/parser.js'
+ 'src/parser.js',
+ 'src/animator.js',
]
gulp.task('clean', function () {
diff --git a/src/drawLoop.js b/src/animator.js
index 6b6e6c3..4d37008 100644
--- a/src/drawLoop.js
+++ b/src/animator.js
@@ -1,3 +1,4 @@
+/* global requestAnimationFrame */
SVG.Animator = {
nextDraw: null,
@@ -44,18 +45,24 @@ SVG.Animator = {
cancelTimeout: function (id) {
// Find the index of the timeout to cancel and remove it
- var index = SVG.Animator.timeouts.remove(function (t) { return t.id == id })
+ var index = SVG.Animator.timeouts.remove(
+ function (t) {
+ return t.id === id
+ }
+ )
return index
},
_draw: function (now) {
+
// Run all the timeouts we can run, if they are not ready yet, add them
// to the end of the queue immediately! (bad timeouts!!! [sarcasm])
var tracking = true
var nextTimeout = null
var lastTimeout = SVG.Animator.timeouts.last()
while ((nextTimeout = SVG.Animator.timeouts.shift())) {
- // Run the timeout if its time, or push it to the end
+
+ // Run the timeout if its time, or push it to the end
if (now > nextTimeout.time) {
nextTimeout.run()
} else {
diff --git a/src/helpers.js b/src/helpers.js
index ff8746e..fd8b376 100644
--- a/src/helpers.js
+++ b/src/helpers.js
@@ -203,3 +203,61 @@ var abcdef = 'abcdef'.split('')
function closeEnough (a, b, threshold) {
return Math.abs(b - a) < (threshold || 1e-6)
}
+
+// TODO: Refactor this to a static function of matrix.js
+function formatTransforms (o) {
+
+ // Get all of the parameters required to form the matrix
+ var flipBoth = o.flip === 'both' || o.flip === true
+ var flipX = o.flip && (flipBoth || o.flip === 'x') ? -1 : 1
+ var flipY = o.flip && (flipBoth || o.flip === 'y') ? -1 : 1
+ var skewX = o.skew && o.skew.length ? o.skew[0]
+ : isFinite(o.skew) ? o.skew
+ : isFinite(o.skewX) ? o.skewX
+ : 0
+ var skewY = o.skew && o.skew.length ? o.skew[1]
+ : isFinite(o.skew) ? o.skew
+ : isFinite(o.skewY) ? o.skewY
+ : 0
+ var scaleX = o.scale && o.scale.length ? o.scale[0] * flipX
+ : isFinite(o.scale) ? o.scale * flipX
+ : isFinite(o.scaleX) ? o.scaleX * flipX
+ : flipX
+ var scaleY = o.scale && o.scale.length ? o.scale[1] * flipY
+ : isFinite(o.scale) ? o.scale * flipY
+ : isFinite(o.scaleY) ? o.scaleY * flipY
+ : flipY
+ var shear = o.shear || 0
+ var theta = o.rotate || 0
+ var origin = new SVG.Point(o.ox == null ? o.origin : o.ox, o.oy)
+ var ox = origin.x
+ var oy = origin.y
+ var position = new SVG.Point(o.px == null
+ ? o.position : o.px, o.py, {x: null, y: null})
+ var px = position.x
+ var py = position.y
+ var translate = new SVG.Point(o.tx == null ? o.translate : o.tx, o.ty)
+ var tx = translate.x
+ var ty = translate.y
+ var relative = new SVG.Point(o.rx == null ? o.relative : o.rx, o.ry)
+ var rx = relative.x
+ var ry = relative.y
+
+ // Populate all of the values
+ return {
+ scaleX: scaleX,
+ scaleY: scaleY,
+ skewX: skewX,
+ skewY: skewY,
+ shear: shear,
+ theta: theta,
+ rx: rx,
+ ry: ry,
+ tx: tx,
+ ty: ty,
+ ox: ox,
+ oy: oy,
+ px: px,
+ py: py,
+ }
+}
diff --git a/src/matrix.js b/src/matrix.js
index cab657f..97eaab7 100644
--- a/src/matrix.js
+++ b/src/matrix.js
@@ -43,59 +43,28 @@ SVG.Matrix = SVG.invent({
return newMatrix
}
- // Get all of the parameters required to form the matrix
- var flipX = o.flip && (o.flip === 'x' || o.flip === 'both') ? -1 : 1
- var flipY = o.flip && (o.flip === 'y' || o.flip === 'both') ? -1 : 1
- var skewX = o.skew && o.skew.length ? o.skew[0]
- : isFinite(o.skew) ? o.skew
- : isFinite(o.skewX) ? o.skewX
- : 0
- var skewY = o.skew && o.skew.length ? o.skew[1]
- : isFinite(o.skew) ? o.skew
- : isFinite(o.skewY) ? o.skewY
- : 0
- var scaleX = o.scale && o.scale.length ? o.scale[0] * flipX
- : isFinite(o.scale) ? o.scale * flipX
- : isFinite(o.scaleX) ? o.scaleX * flipX
- : flipX
- var scaleY = o.scale && o.scale.length ? o.scale[1] * flipY
- : isFinite(o.scale) ? o.scale * flipY
- : isFinite(o.scaleY) ? o.scaleY * flipY
- : flipY
- var shear = o.shear || 0
- var theta = o.rotate || 0
- var origin = new SVG.Point(o.ox == null ? o.origin : o.ox, o.oy)
- var ox = origin.x
- var oy = origin.y
- var position = new SVG.Point(o.px == null
- ? o.position : o.px, o.py, {x: null, y: null})
- var px = position.x
- var py = position.y
- var translate = new SVG.Point(o.tx == null ? o.translate : o.tx, o.ty)
- var tx = translate.x
- var ty = translate.y
- var relative = new SVG.Point(o.rx == null ? o.relative : o.rx, o.ry)
- var rx = relative.x
- var ry = relative.y
+ // Get the proposed transformations and the current transformations
+ var t = formatTransforms(o)
var currentTransform = new SVG.Matrix(this)
// Construct the resulting matrix
var transformer = new SVG.Matrix()
- .translate(-ox, -oy)
- .scale(scaleX, scaleY)
- .skew(skewX, skewY)
- .shear(shear)
- .rotate(theta)
- .translate(ox, oy)
- .translate(rx, ry)
+ .translate(-t.ox, -t.oy)
+ .scale(t.scaleX, t.scaleY)
+ .skew(t.skewX, t.skewY)
+ .shear(t.shear)
+ .rotate(t.theta)
+ .translate(t.ox, t.oy)
+ .translate(t.rx, t.ry)
.lmultiply(currentTransform)
// If we want the origin at a particular place, we force it there
- if (isFinite(px) || isFinite(py)) {
+ if (isFinite(t.px) || isFinite(t.py)) {
+
// Figure out where the origin went and the delta to get there
- var current = new SVG.Point(ox - rx, oy - ry).transform(transformer)
- var dx = px ? px - current.x : 0
- var dy = py ? py - current.y : 0
+ var current = new SVG.Point(t.ox - t.rx, t.oy - t.ry).transform(transformer)
+ var dx = t.px ? t.px - current.x : 0
+ var dy = t.py ? t.py - current.y : 0
// Apply another translation
transformer = transformer.translate(dx, dy)
@@ -221,7 +190,31 @@ SVG.Matrix = SVG.invent({
// Inverses matrix
inverse: function () {
- return new SVG.Matrix(this.native().inverse())
+
+ // Get the current parameters out of the matrix
+ var a = this.a
+ var b = this.b
+ var c = this.c
+ var d = this.d
+ var e = this.e
+ var f = this.f
+
+ // Invert the 2x2 matrix in the top left
+ var det = a * d - b * c
+ if (!det) throw new Error("Cannot invert " + this)
+
+ // Calculate the top 2x2 matrix
+ var na = d / det
+ var nb = -b / det
+ var nc = -c / det
+ var nd = a / det
+
+ // Apply the inverted matrix to the top right
+ var ne = - ( na * e + nc * f )
+ var nf = - ( nb * e + nd * f )
+
+ // Construct the inverted matrix
+ return new SVG.Matrix(na, nb, nc, nd, ne, nf)
},
// Translate matrix
diff --git a/src/morph.js b/src/morph.js
index 7e99fef..28584d3 100644
--- a/src/morph.js
+++ b/src/morph.js
@@ -59,11 +59,13 @@ SVG.Morphable = SVG.invent{
var _this = this
+ modifier = this.modifier || function(el) { return el }
+
// for(var i = 0, len = this._from.length; i < len; ++i) {
// arr.push(this.controller(this._from[i], this._to[i]))
// }
- return this.type.fromArray(this.modifier(this._from.map(function (i, index) {
+ return this.type.fromArray(modifier(this._from.map(function (i, index) {
return _this.controller(i, _this._to[i], pos)
})))
},
@@ -129,6 +131,38 @@ SVG.Morphable.TransformBag = SVG.invent({
}
})
+
+SVG.Morphable.ObjectBag = SVG.invent({
+ create: function (obj) {
+ this.values = []
+ this.keys = []
+
+ for(var i in obj) {
+ this.values.push(obj[i])
+ this.keys.push(i)
+ }
+ },
+
+ extend: {
+ valueOf: function () {
+ return this.values
+ },
+
+ toArray: function (){
+ return this.values
+ }
+
+ fromArray: function (arr) {
+ var obj = {}
+
+ for(var i = 0, len = arr.length; i < len; ++i) {
+ obj[this.keys[i]] = arr[i]
+ }
+
+ return obj
+ }
+})
+
SVG.MorphableTypes = [SVG.Number, SVG.Color, SVG.Box, SVG.Matrix, SVG.Morphable.NonMorphable, SVG.Morphable.TransformBag]
SVG.extend(SVG.MorphableTypes, {
to: (item, args) => {
@@ -176,6 +210,24 @@ SVG.extend(SVG.MorphableTypes, {
// 4. Now you get the delta matrix as a result: D = I * inv(M)
+value = null
+init ( ) {
+ if(!morpher.hasFrom()) {
+ morpher.from(el.whatever())
+ }
+
+ value = value == null ? get the value : value
+ return value
+ else
+}
+
+// C R x = D C x = A x
+//
+// (C R inv(C)) C x
+//
+//
+// C R = D C
+// D = C R inv(C)
el.animate().trasform({rotate: 720, scale: 2}, true)
@@ -193,23 +245,80 @@ relative -> start at 0 always - {random stuff}
|> modifier
|> fromArray
-function transform(transforms, relative, affine) {
- affine = transforms.affine || affine
- relative = transforms.relative || relative
+function transform(o, relative, affine) {
+ affine = transforms.affine || affine || !!transform.a
+ relative = transforms.relative || relative || false
+
+ var morpher
+ var el = this.target()
+
+ /**
+ The default of relative is false
+ affine defaults to true if transformations are used and to false when a matrix is given
+
+ We end up with 4 possibilities:
+ false, false: absolute direct matrix morph with SVG.Matrix
+ true, false: relative direct matrix morph with SVG.Marix or relative whatever was passed transformation with ObjectBag
+
+ false, true: absolute affine transformation with SVG.TransformBag
+ true, true: relative whatever was passed transformation with ObjectBag
+ **/
+
+
+ // if we have a relative transformation and its not a matrix
+ // we morph all parameters directly with the ObjectBag
+ // the following cases are covered here:
+ // - true, false with ObjectBag
+ // - true, true with ObjectBag
+ if(relative && transforms.a == null) {
+ morpher = SVG.Morphable.ObjectBag(formatTransforms({})).to(formatTransforms(transforms))
+
+ return this.queue(function() {}, function (pos) {
+ el.pushRightTransform(new Matrix(morpher.at(pos)))
+ })
+ }
+
+ // when we have a matrix and its non affine we transform directly
+ // the following cases are covered here:
+ // - true, false with SVG.Matrix
+ // - false, false with SVG.Matrix
+ /*
+ // this is covered below now
+ if(transforms.a != null && !affine) {
+ var morpher = new SVG.Matrix().to(transforms)
+
+ this.queue(function () {}, function (pos) {
+ if(!relative) {
+ var curr = el.currentTransform()
+ morpher.from(curr)
+ el.pushLeftTransform(morpher.at(pos).multiply(curr.inverse()))
+ } else {
+ el.pushRightTransform(morpher.at(pos))
+ }
+ })
+ }*/
+
+ // what is left is affine morphing for SVG.Matrix and absolute transformations with TransformBag
+ // the following cases are covered here:
+ // - false, true with SVG.Matrix
+ // - false, true with SVG.TransformBag
+ // - true, false with SVG.Matrix
+ // - false, false with SVG.Matrix
// 1. define the final state (T) and decompose it (once) t = [tx, ty, the, lam, sy, sx]
- var morpher = new SVG.Morphable.TransformBag().to(transforms)
+ var morpher = (transforms.a && !affine)
+ ? new SVG.Matrix().to(transforms)
+ : new SVG.Morphable.TransformBag().to(transforms)
- // make sure you have an identity matrix defined as default for relative transforms
- var morpher.from()
- var el = this.target()
+ // create identity Matrix for relative not affine Matrix transformation
+ morpher.from()
+
+ this.queue(function() {}, function (pos) {
- var initFn = relative ? function() {} : function() {
// 2. on every frame: pull the current state of all previous transforms (M - m can change)
- morpher.from(el.transform())
- }
+ var curr = el.currentTransform()
+ if(!relative) morpher.from(curr)
- this.queue(initFn, function (pos) {
// 3. Find the interpolated matrix I(pos) = m + pos * (t - m)
// - Note I(0) = M
// - Note I(1) = T
@@ -217,14 +326,91 @@ function transform(transforms, relative, affine) {
if(!relative) {
// 4. Now you get the delta matrix as a result: D = I * inv(M)
- matrix = matrix.multiply(el.transform().inverse())
+ var delta = matrix.multiply(curr.inverse())
+ el.pushLeftTransform(delta)
+ } else {
+ el.pushRightTransform(matrix)
}
-
- el.pushTransform(matrix)
})
}
+
+/**
+ INIT
+ - save the current transformation
+
+ ELEMENT TIMELINE (one timeline per el)
+ - Reads the current transform and save it to the transformation stack
+ - Runs all available runners, runners will:
+ - Modify their transformation on the stack
+ - Mark their transformation as complete
+ - After each runner, we group the matrix (not for now)
+ - After running the runners, we bundle all contiguous transformations into
+ a single transformation
+
+
+ - transformtionstack is like this: [RunnerB, Matrix, RunnerC]
+ - skip merging for now (premature blabla)
+
+
+el.loop({times: 5, swing: true, wait: [20, 50]})
+
+el.opacity(0)
+ .animate(300).opacity(1)
+ .animate(300, true).scale(5).reverse()
+
+
+for(var i = 0; i < 7; ++i)
+ circle.clone()
+ .scale(3).rotate(0)
+ .loop({swing: false, wait: 500})
+ .scale(1)
+ .rotate(360)
+ .delay(1000)
+ .animate(500, 'swingOut')
+ .scale(3)
+}
+
+fn () => {
+ el.animate().stroke('dashoffset', 213).scale(1)
+ .delay(1)
+ .animate().scale(2)
+ .after(fn)
+}
+
+
+
+When you start an element has a base matrix B - which starts as the identity
+
+ If you modify the matrix, then we have:
+
+ T U V W X B x
+ . . .
+
+ runner.step()
+
+ for all runners in stack:
+ if(runner is done) repalce with matrix
+
+ if(2 matrix next to eachother are done) {
+
+ }
+
+What if
+
+/// RunnerA
+el.animate()
+ .transform({rotate: 30, scale: 2})
+ .transform({rotate: 500}, true)
+
+f| -----A-----
+s| --------B---------
+t| ---------C-------
+
+**/
+
+
SVG.Morphable.TransformList = Object
if(affine) {
diff --git a/src/number.js b/src/number.js
index e6cecc2..5d787ad 100644
--- a/src/number.js
+++ b/src/number.js
@@ -99,12 +99,5 @@ SVG.Number = SVG.invent({
.times(pos)
.plus(this)
}
-
-
-
-new SVG.Color('#2a4e5a').morph('#3b4f2a').at(0.4)
-
-new Morph().from('#2a4e5a').to('#3b4f2a').at(0.3)
-
}
})
diff --git a/src/timeline.js b/src/timeline.js
index 5106058..f2ca933 100644
--- a/src/timeline.js
+++ b/src/timeline.js
@@ -11,7 +11,6 @@ SVG.easing = {
function Runner (timeline) {
// We store a reference to the function to run and the timeline to use
- this.timeline = timeline
this.transforms = []
this.functions = []
this.done = false
@@ -20,13 +19,18 @@ function Runner (timeline) {
this._startTime = timeline._startTime
this._duration = timeline._duration
this._loop = timeline._loop
+ this._active = false
}
+// The runner gets the time from the timeline
Runner.prototype = {
add: function (initFn, runFn) {
- this.initialisers.push(initFn)
- this.functions.push(fn)
+ this.functions.push({
+ initialised: false,
+ initialiser: initFn,
+ runner: runFn,
+ })
},
step: function (time) {
@@ -34,32 +38,23 @@ Runner.prototype = {
// If it is time to do something, act now.
var end = this._start + this._duration
var running = this._start < time && time < end
- if (running && this._running) {
+
+ if (running && !this.timeline._paused) {
var position = (time - this._startTime) / this._duration
- var toRun = this.functions
- for (var i = 0, len = toRun.length, i < len ; ++i) {
- toRun[i](position)
+ for (var i = 0, len = this.functions.length; i < len ; ++i) {
+
+ // If
+ this.functions[i](position)
}
}
- // If we are not paused or stopped, request another frame
- if (this._running) SVG.Animator.frame(closure, this._startTime)
-
// Tell the caller whether this animation is finished
- closure.finished = !running
- },
-
- snap: function () {
-
- },
-
- pause: function () {
-
+ return finished
},
}
-let time = window.performance || window.Date
+var time = window.performance || window.Date
SVG.Timeline = SVG.invent({
@@ -74,17 +69,22 @@ SVG.Timeline = SVG.invent({
this._startTime = time.now()
this._duration = SVG.defaults.duration
this._ease = SVG.defaults.ease
+ this._speed = 1.0
// Play control variables control how the animation proceeds
- this._controller = o instanceof 'function' ? o : null
- this._backwards = false
+ this._controller = null
this._reverse = false
- this._loops = 0
+ this._loops = null
+ this._waits = null
+ this._swing = null
// Keep track of the running animations and their starting parameters
this._baseTransform = null
- this._running = true
+ this._nextFrame = null
+ this._paused = false
+ this._runner = null
this._runners = []
+ this._time = 0
},
extend: {
@@ -92,14 +92,13 @@ SVG.Timeline = SVG.invent({
animate (duration, delay, now) {
// Clear the controller and the looping parameters
- this._controller = null
+ this._controller = duration instanceof Function ? duration : null
this._backwards = false
this._swing = false
this._loops = 0
// If we have a controller, we will use the declarative animation mode
- if(duration instanceof 'function') {
-
+ if(duration instanceof Function) {
this._controller = duration
// If we have an object we are declaring imperative animations
@@ -115,8 +114,14 @@ SVG.Timeline = SVG.invent({
this._startTime = now ? time.now() : (this._startTime + this._duration)
this._duration = duration || SVG.defaults.duration
- // Make a new runner to take care of the
+ // Make a new runner to queue all of the animations onto
+ this._runner = new Runner(this)
+ this._runners.push(this._runner)
+ // Step the animation
+ this._step()
+
+ // Allow for chaining
return this
},
@@ -133,24 +138,21 @@ SVG.Timeline = SVG.invent({
return this
},
- loop (times, swing) {
- this._loops = times
- this._swing = swing
- },
-
play () {
- this._running = true
+ this._paused = false
this._continue()
+ return this
},
pause () {
- this._running = false
+ this._paused = true
+ return this
},
stop () {
this.pause()
- // Cancel all of the requested animation frames
+ // Cancel the next animation frame for this object
},
@@ -159,14 +161,14 @@ SVG.Timeline = SVG.invent({
},
speed (newSpeed) {
-
+ this._speed = newSpeed
},
seek (dt) {
},
- persist (dt || forever) {
+ persist (dtOrForever) {
// 0 by default
},
@@ -175,24 +177,44 @@ SVG.Timeline = SVG.invent({
},
queue (initialise, during) {
+ this._runner.add(initialise, during)
+ },
- // Make a new runner
- var runner = new Runner(this)
- this._runners.push()
+ _step (time) {
- },
+ // If we are paused, just exit
+ if (this._paused) return
- _step (dt) {
+ // Get the time delta from the last time
+ // TODO: Deal with window.blur window.focus to pause animations
+ // HACK: We keep the time below 16ms to avoid driving declarative crazy
+ var dt = this._speed * ((time - this._time) || 16) / 1000
+ dt = dt < 0.1 ? dt : 0.016 // If we missed alot of time, ignore
+ this._time += time
+
+ // Run all of the runners directly
+ var runnersLeft = false
+ for (var i = 0, i < this._runners.length; ; i++) {
+ var runner = this._runners[i]
+ var finished = runner.step(this._time)
+ if (!finished)
+ runnersLeft = true
+ }
+ // Get the next animation frame to keep the simulation going
+ if (runnersLeft)
+ this._nextFrame = draw.frame(this.step.bind(this))
+ else this._nextFrame = null
+ return this
},
// Checks if we are running and continues the animation
_continue () {
if (this._paused) return
-
- // Go through each of the runners and step them
+ if (!this._nextFrame)
+ this._step()
+ return this
},
-
},
// Only elements are animatable
@@ -205,53 +227,73 @@ SVG.Timeline = SVG.invent({
// Get the current timeline or construct a new one
this.timeline = (this.timeline || new SVG.Timeline(this))
.animate(o, delay, now)
+ this.timeline._loops = null
return this.timeline
- }
- }
-}
-
-// Extend the attribute methods separately to avoid cluttering the main
-// Timeline class above
-SVG.extend(SVG.Timeline, {
-
-
- attr: function (a, v) {
- return this.styleAttr('attr', a, v)
- },
+ },
- // Add animatable styles
- css: function (s, v) {
- return this.styleAttr('css', s, v)
- },
+ loop: function(o) {
- styleAttr (type, name, val) {
- // apply attributes individually
- if (typeof name === 'object') {
- for (var key in val) {
- this.styleAttr(type, key, val[key])
+ /*
+ {
+ swing: wether or not the animation should repeat when its done
+ times: the number of times to loop the animation
+ wait: [array] a buffer of times to wait between successive animations
+ delay: defaults to wait
}
+ */
+ this.timeline = (this.timeline || new SVG.Timeline(this))
+
+ // REFACTOR this into an init function
+ this.timeline._waits = [].concat(o.wait || o.delay || 0)
+ this.timeline._loops = o.times || Infinity
+ this.timeline._swing = o.swing || false
+ return this.timeline
}
-
- var morpher = new Morph(this.controller).to(val)
-
- this.queue(
- function () {
- morpher = morpher.from(element[type](name))
- },
- function () {
- this.element[type](name, morpher.at(pos))
- }
- )
-
- return this
- },
-
- zoom(level, point) {
- let morpher = SVG.Number(level).controller(this.controller)
- this.queue(
- () => {morpher = morpher.from(element.zoom())},
- (pos) => {element.zoom(morpher.at(pos), point)}
- )
- return this
}
})
+
+// // Extend the attribute methods separately to avoid cluttering the main
+// // Timeline class above
+// SVG.extend(SVG.Timeline, {
+//
+//
+// attr: function (a, v) {
+// return this.styleAttr('attr', a, v)
+// },
+//
+// // Add animatable styles
+// css: function (s, v) {
+// return this.styleAttr('css', s, v)
+// },
+//
+// styleAttr (type, name, val) {
+// // apply attributes individually
+// if (typeof name === 'object') {
+// for (var key in val) {
+// this.styleAttr(type, key, val[key])
+// }
+// }
+//
+// var morpher = new Morph(this.controller).to(val)
+//
+// this.queue(
+// function () {
+// morpher = morpher.from(element[type](name))
+// },
+// function () {
+// this.element[type](name, morpher.at(pos))
+// }
+// )
+//
+// return this
+// },
+//
+// zoom(level, point) {
+// let morpher = SVG.Number(level).controller(this.controller)
+// this.queue(
+// () => {morpher = morpher.from(element.zoom())},
+// (pos) => {element.zoom(morpher.at(pos), point)}
+// )
+// return this
+// }
+// })