PageSourceSearch

https://www.jamss.co.jp/assets/js/svg-morpheus.js

js jamss.co.jp collected 2026-10-02 17:13:06 UTC 47,918 bytes, 1,906 lines download raw bytes

1/*!
2 * SVG Morpheus v0.3.2
3 * https://github.com/alexk111/SVG-Morpheus
4 *
5 * Copyright (c) 2016 Alex Kaul
6 * License: MIT
7 *
8 * Generated at Saturday, May 14th, 2016, 5:19:19 PM
9 */
10(function () {
11	"use strict";
12
13	/*
14	 * Easing functions
15	 */
16
17	var easings = {};
18	easings["circ-in"] = function (t) {
19		return -1 * (Math.sqrt(1 - t * t) - 1);
20	};
21	easings["circ-out"] = function (t) {
22		return Math.sqrt(1 - (t = t - 1) * t);
23	};
24	easings["circ-in-out"] = function (t) {
25		if ((t /= 1 / 2) < 1) return (-1 / 2) * (Math.sqrt(1 - t * t) - 1);
26		return (1 / 2) * (Math.sqrt(1 - (t -= 2) * t) + 1);
27	};
28	easings["cubic-in"] = function (t) {
29		return t * t * t;
30	};
31	easings["cubic-out"] = function (t) {
32		return --t * t * t + 1;
33	};
34	easings["cubic-in-out"] = function (t) {
35		return t < 0.5
36			? 4 * t * t * t
37			: (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
38	};
39	easings["elastic-in"] = function (t) {
40		var s = 1.70158;
41		var p = 0;
42		var a = 1;
43		if (t == 0) return 0;
44		if (t == 1) return 1;
45		if (!p) p = 0.3;
46		if (a < Math.abs(1)) {
47			a = 1;
48			var s = p / 4;
49		} else var s = (p / (2 * Math.PI)) * Math.asin(1 / a);
50		return -(
51			a *
52			Math.pow(2, 10 * (t -= 1)) *
53			Math.sin(((t - s) * (2 * Math.PI)) / p)
54		);
55	};
56	easings["elastic-out"] = function (t) {
57		var s = 1.70158;
58		var p = 0;
59		var a = 1;
60		if (t == 0) return 0;
61		if (t == 1) return 1;
62		if (!p) p = 0.3;
63		if (a < Math.abs(1)) {
64			a = 1;
65			var s = p / 4;
66		} else var s = (p / (2 * Math.PI)) * Math.asin(1 / a);
67		return (
68			a * Math.pow(2, -10 * t) * Math.sin(((t - s) * (2 * Math.PI)) / p) +
69			1
70		);
71	};
72	easings["elastic-in-out"] = function (t) {
73		var s = 1.70158;
74		var p = 0;
75		var a = 1;
76		if (t == 0) return 0;
77		if ((t /= 1 / 2) == 2) return 1;
78		if (!p) p = 1 * (0.3 * 1.5);
79		if (a < Math.abs(1)) {
80			a = 1;
81			var s = p / 4;
82		} else var s = (p / (2 * Math.PI)) * Math.asin(1 / a);
83		if (t < 1)
84			return (
85				-0.5 *
86				(a *
87					Math.pow(2, 10 * (t -= 1)) *
88					Math.sin(((t - s) * (2 * Math.PI)) / p))
89			);
90		return (
91			a *
92				Math.pow(2, -10 * (t -= 1)) *
93				Math.sin(((t - s) * (2 * Math.PI)) / p) *
94				0.5 +
95			1
96		);
97	};
98	easings["expo-in"] = function (t) {
99		return t == 0 ? 0 : Math.pow(2, 10 * (t - 1));
100	};
101	easings["expo-out"] = function (t) {
102		return t == 1 ? 1 : 1 - Math.pow(2, -10 * t);
103	};
104	easings["expo-in-out"] = function (t) {
105		if (t == 0) return 0;
106		if (t == 1) return 1;
107		if ((t /= 1 / 2) < 1) return (1 / 2) * Math.pow(2, 10 * (t - 1));
108		return (1 / 2) * (-Math.pow(2, -10 * --t) + 2);
109	};
110	easings["linear"] = function (t) {
111		return t;
112	};
113	easings["quad-in"] = function (t) {
114		return t * t;
115	};
116	easings["quad-out"] = function (t) {
117		return t * (2 - t);
118	};
119	easings["quad-in-out"] = function (t) {
120		return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
121	};
122	easings["quart-in"] = function (t) {
123		return t * t * t * t;
124	};
125	easings["quart-out"] = function (t) {
126		return 1 - --t * t * t * t;
127	};
128	easings["quart-in-out"] = function (t) {
129		return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t;
130	};
131	easings["quint-in"] = function (t) {
132		return t * t * t * t * t;
133	};
134	easings["quint-out"] = function (t) {
135		return 1 + --t * t * t * t * t;
136	};
137	easings["quint-in-out"] = function (t) {
138		return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t;
139	};
140	easings["sine-in"] = function (t) {
141		return 1 - Math.cos(t * (Math.PI / 2));
142	};
143	easings["sine-out"] = function (t) {
144		return Math.sin(t * (Math.PI / 2));
145	};
146	easings["sine-in-out"] = function (t) {
147		return (1 / 2) * (1 - Math.cos(Math.PI * t));
148	};
149
150	/*
151	 * Helper functions
152	 */
153
154	var _reqAnimFrame =
155		window.requestAnimationFrame ||
156		window.mozRequestAnimationFrame ||
157		window.webkitRequestAnimationFrame ||
158		window.oRequestAnimationFrame;
159	var _cancelAnimFrame =
160		window.cancelAnimationFrame ||
161		window.mozCancelAnimationFrame ||
162		window.webkitCancelAnimationFrame ||
163		window.oCancelAnimationFrame;
164
165	// Calculate style
166	function styleNormCalc(styleNormFrom, styleNormTo, progress) {
167		var i,
168			len,
169			styleNorm = {};
170		for (i in styleNormFrom) {
171			switch (i) {
172				case "fill":
173				case "stroke":
174					styleNorm[i] = clone(styleNormFrom[i]);
175					styleNorm[i].r =
176						styleNormFrom[i].r +
177						(styleNormTo[i].r - styleNormFrom[i].r) * progress;
178					styleNorm[i].g =
179						styleNormFrom[i].g +
180						(styleNormTo[i].g - styleNormFrom[i].g) * progress;
181					styleNorm[i].b =
182						styleNormFrom[i].b +
183						(styleNormTo[i].b - styleNormFrom[i].b) * progress;
184					styleNorm[i].opacity =
185						styleNormFrom[i].opacity +
186						(styleNormTo[i].opacity - styleNormFrom[i].opacity) *
187							progress;
188					break;
189				case "opacity":
190				case "fill-opacity":
191				case "stroke-opacity":
192				case "stroke-width":
193					styleNorm[i] =
194						styleNormFrom[i] +
195						(styleNormTo[i] - styleNormFrom[i]) * progress;
196					break;
197			}
198		}
199		return styleNorm;
200	}
201
202	function styleNormToString(styleNorm) {
203		var i;
204		var style = {};
205		for (i in styleNorm) {
206			switch (i) {
207				case "fill":
208				case "stroke":
209					style[i] = rgbToString(styleNorm[i]);
210					break;
211				case "opacity":
212				case "fill-opacity":
213				case "stroke-opacity":
214				case "stroke-width":
215					style[i] = styleNorm[i];
216					break;
217			}
218		}
219		return style;
220	}
221
222	function styleToNorm(styleFrom, styleTo) {
223		var styleNorm = [{}, {}];
224		var i;
225		for (i in styleFrom) {
226			switch (i) {
227				case "fill":
228				case "stroke":
229					styleNorm[0][i] = getRGB(styleFrom[i]);
230					if (styleTo[i] === undefined) {
231						styleNorm[1][i] = getRGB(styleFrom[i]);
232						styleNorm[1][i].opacity = 0;
233					}
234					break;
235				case "opacity":
236				case "fill-opacity":
237				case "stroke-opacity":
238				case "stroke-width":
239					styleNorm[0][i] = styleFrom[i];
240					if (styleTo[i] === undefined) {
241						styleNorm[1][i] = 1;
242					}
243					break;
244			}
245		}
246		for (i in styleTo) {
247			switch (i) {
248				case "fill":
249				case "stroke":
250					styleNorm[1][i] = getRGB(styleTo[i]);
251					if (styleFrom[i] === undefined) {
252						styleNorm[0][i] = getRGB(styleTo[i]);
253						styleNorm[0][i].opacity = 0;
254					}
255					break;
256				case "opacity":
257				case "fill-opacity":
258				case "stroke-opacity":
259				case "stroke-width":
260					styleNorm[1][i] = styleTo[i];
261					if (styleFrom[i] === undefined) {
262						styleNorm[0][i] = 1;
263					}
264					break;
265			}
266		}
267		return styleNorm;
268	}
269
270	// Calculate transform progress
271	function transCalc(transFrom, transTo, progress) {
272		var res = {};
273		for (var i in transFrom) {
274			switch (i) {
275				case "rotate":
276					res[i] = [0, 0, 0];
277					for (var j = 0; j < 3; j++) {
278						res[i][j] =
279							transFrom[i][j] +
280							(transTo[i][j] - transFrom[i][j]) * progress;
281					}
282					break;
283			}
284		}
285		return res;
286	}
287
288	function trans2string(trans) {
289		var res = "";
290		if (!!trans.rotate) {
291			res += "rotate(" + trans.rotate.join(" ") + ")";
292		}
293		return res;
294	}
295
296	// Calculate curve progress
297	function curveCalc(curveFrom, curveTo, progress) {
298		var curve = [];
299		for (var i = 0, len1 = curveFrom.length; i < len1; i++) {
300			curve.push([curveFrom[i][0]]);
301			for (var j = 1, len2 = curveFrom[i].length; j < len2; j++) {
302				curve[i].push(
303					curveFrom[i][j] +
304						(curveTo[i][j] - curveFrom[i][j]) * progress
305				);
306			}
307		}
308		return curve;
309	}
310
311	function clone(obj) {
312		var copy;
313
314		// Handle Array
315		if (obj instanceof Array) {
316			copy = [];
317			for (var i = 0, len = obj.length; i < len; i++) {
318				copy[i] = clone(obj[i]);
319			}
320			return copy;
321		}
322
323		// Handle Object
324		if (obj instanceof Object) {
325			copy = {};
326			for (var attr in obj) {
327				if (obj.hasOwnProperty(attr)) {
328					copy[attr] = clone(obj[attr]);
329				}
330			}
331			return copy;
332		}
333
334		return obj;
335	}
336
337	/*
338	 * Useful things from Adobe's Snap.svg adopted to the library needs
339	 */
340
341	/*
342	 * Paths
343	 */
344
345	var spaces =
346		"\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029";
347	var pathCommand = new RegExp(
348		"([a-z])[" +
349			spaces +
350			",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[" +
351			spaces +
352			"]*,?[" +
353			spaces +
354			"]*)+)",
355		"ig"
356	);
357	var pathValues = new RegExp(
358		"(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[" + spaces + "]*,?[" + spaces + "]*",
359		"ig"
360	);
361
362	// Parses given path string into an array of arrays of path segments
363	var parsePathString = function (pathString) {
364		if (!pathString) {
365			return null;
366		}
367
368		if (typeof pathString === typeof []) {
369			return pathString;
370		} else {
371			var paramCounts = {
372					a: 7,
373					c: 6,
374					o: 2,
375					h: 1,
376					l: 2,
377					m: 2,
378					r: 4,
379					q: 4,
380					s: 4,
381					t: 2,
382					v: 1,
383					u: 3,
384					z: 0,
385				},
386				data = [];
387
388			String(pathString).replace(pathCommand, function (a, b, c) {
389				var params = [],
390					name = b.toLowerCase();
391				c.replace(pathValues, function (a, b) {
392					b && params.push(+b);
393				});
394				if (name == "m" && params.length > 2) {
395					data.push([b].concat(params.splice(0, 2)));
396					name = "l";
397					b = b == "m" ? "l" : "L";
398				}
399				if (name == "o" && params.length == 1) {
400					data.push([b, params[0]]);
401				}
402				if (name == "r") {
403					data.push([b].concat(params));
404				} else
405					while (params.length >= paramCounts[name]) {
406						data.push(
407							[b].concat(params.splice(0, paramCounts[name]))
408						);
409						if (!paramCounts[name]) {
410							break;
411						}
412					}
413			});
414
415			return data;
416		}
417	};
418
419	// http://schepers.cc/getting-to-the-point
420	var catmullRom2bezier = function (crp, z) {
421		var d = [];
422		for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) {
423			var p = [
424				{ x: +crp[i - 2], y: +crp[i - 1] },
425				{ x: +crp[i], y: +crp[i + 1] },
426				{ x: +crp[i + 2], y: +crp[i + 3] },
427				{ x: +crp[i + 4], y: +crp[i + 5] },
428			];
429			if (z) {
430				if (!i) {
431					p[0] = { x: +crp[iLen - 2], y: +crp[iLen - 1] };
432				} else if (iLen - 4 == i) {
433					p[3] = { x: +crp[0], y: +crp[1] };
434				}
vendor: 4,946 bytes, lines 434-653
434 else if (iLen - 2 == i) {
435					p[2] = { x: +crp[0], y: +crp[1] };
436					p[3] = { x: +crp[2], y: +crp[3] };
437				}
438			} else {
439				if (iLen - 4 == i) {
440					p[3] = p[2];
441				} else if (!i) {
442					p[0] = { x: +crp[i], y: +crp[i + 1] };
443				}
444			}
445			d.push([
446				"C",
447				(-p[0].x + 6 * p[1].x + p[2].x) / 6,
448				(-p[0].y + 6 * p[1].y + p[2].y) / 6,
449				(p[1].x + 6 * p[2].x - p[3].x) / 6,
450				(p[1].y + 6 * p[2].y - p[3].y) / 6,
451				p[2].x,
452				p[2].y,
453			]);
454		}
455
456		return d;
457	};
458
459	var ellipsePath = function (x, y, rx, ry, a) {
460		if (a == null && ry == null) {
461			ry = rx;
462		}
463		x = +x;
464		y = +y;
465		rx = +rx;
466		ry = +ry;
467		if (a != null) {
468			var rad = Math.PI / 180,
469				x1 = x + rx * Math.cos(-ry * rad),
470				x2 = x + rx * Math.cos(-a * rad),
471				y1 = y + rx * Math.sin(-ry * rad),
472				y2 = y + rx * Math.sin(-a * rad),
473				res = [
474					["M", x1, y1],
475					["A", rx, rx, 0, +(a - ry > 180), 0, x2, y2],
476				];
477		} else {
478			res = [
479				["M", x, y],
480				["m", 0, -ry],
481				["a", rx, ry, 0, 1, 1, 0, 2 * ry],
482				["a", rx, ry, 0, 1, 1, 0, -2 * ry],
483				["z"],
484			];
485		}
486		return res;
487	};
488
489	var pathToAbsolute = function (pathArray) {
490		pathArray = parsePathString(pathArray);
491
492		if (!pathArray || !pathArray.length) {
493			return [["M", 0, 0]];
494		}
495		var res = [],
496			x = 0,
497			y = 0,
498			mx = 0,
499			my = 0,
500			start = 0,
501			pa0;
502		if (pathArray[0][0] == "M") {
503			x = +pathArray[0][1];
504			y = +pathArray[0][2];
505			mx = x;
506			my = y;
507			start++;
508			res[0] = ["M", x, y];
509		}
510		var crz =
511			pathArray.length == 3 &&
512			pathArray[0][0] == "M" &&
513			pathArray[1][0].toUpperCase() == "R" &&
514			pathArray[2][0].toUpperCase() == "Z";
515		for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) {
516			res.push((r = []));
517			pa = pathArray[i];
518			pa0 = pa[0];
519			if (pa0 != pa0.toUpperCase()) {
520				r[0] = pa0.toUpperCase();
521				switch (r[0]) {
522					case "A":
523						r[1] = pa[1];
524						r[2] = pa[2];
525						r[3] = pa[3];
526						r[4] = pa[4];
527						r[5] = pa[5];
528						r[6] = +pa[6] + x;
529						r[7] = +pa[7] + y;
530						break;
531					case "V":
532						r[1] = +pa[1] + y;
533						break;
534					case "H":
535						r[1] = +pa[1] + x;
536						break;
537					case "R":
538						var dots = [x, y].concat(pa.slice(1));
539						for (var j = 2, jj = dots.length; j < jj; j++) {
540							dots[j] = +dots[j] + x;
541							dots[++j] = +dots[j] + y;
542						}
543						res.pop();
544						res = res.concat(catmullRom2bezier(dots, crz));
545						break;
546					case "O":
547						res.pop();
548						dots = ellipsePath(x, y, pa[1], pa[2]);
549						dots.push(dots[0]);
550						res = res.concat(dots);
551						break;
552					case "U":
553						res.pop();
554						res = res.concat(
555							ellipsePath(x, y, pa[1], pa[2], pa[3])
556						);
557						r = ["U"].concat(res[res.length - 1].slice(-2));
558						break;
559					case "M":
560						mx = +pa[1] + x;
561						my = +pa[2] + y;
562					default:
563						for (j = 1, jj = pa.length; j < jj; j++) {
564							r[j] = +pa[j] + (j % 2 ? x : y);
565						}
566				}
567			} else if (pa0 == "R") {
568				dots = [x, y].concat(pa.slice(1));
569				res.pop();
570				res = res.concat(catmullRom2bezier(dots, crz));
571				r = ["R"].concat(pa.slice(-2));
572			} else if (pa0 == "O") {
573				res.pop();
574				dots = ellipsePath(x, y, pa[1], pa[2]);
575				dots.push(dots[0]);
576				res = res.concat(dots);
577			} else if (pa0 == "U") {
578				res.pop();
579				res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3]));
580				r = ["U"].concat(res[res.length - 1].slice(-2));
581			} else {
582				for (var k = 0, kk = pa.length; k < kk; k++) {
583					r[k] = pa[k];
584				}
585			}
586			pa0 = pa0.toUpperCase();
587			if (pa0 != "O") {
588				switch (r[0]) {
589					case "Z":
590						x = +mx;
591						y = +my;
592						break;
593					case "H":
594						x = r[1];
595						break;
596					case "V":
597						y = r[1];
598						break;
599					case "M":
600						mx = r[r.length - 2];
601						my = r[r.length - 1];
602					default:
603						x = r[r.length - 2];
604						y = r[r.length - 1];
605				}
606			}
607		}
608
609		return res;
610	};
611
612	var l2c = function (x1, y1, x2, y2) {
613		return [x1, y1, x2, y2, x2, y2];
614	};
615	var q2c = function (x1, y1, ax, ay, x2, y2) {
616		var _13 = 1 / 3,
617			_23 = 2 / 3;
618		return [
619			_13 * x1 + _23 * ax,
620			_13 * y1 + _23 * ay,
621			_13 * x2 + _23 * ax,
622			_13 * y2 + _23 * ay,
623			x2,
624			y2,
625		];
626	};
627	var a2c = function (
628		x1,
629		y1,
630		rx,
631		ry,
632		angle,
633		large_arc_flag,
634		sweep_flag,
635		x2,
636		y2,
637		recursive
638	) {
639		// for more information of where this math came from visit:
640		// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
641		var _120 = (Math.PI * 120) / 180,
642			rad = (Math.PI / 180) * (+angle || 0),
643			res = [],
644			xy,
645			rotate = function (x, y, rad) {
646				var X = x * Math.cos(rad) - y * Math.sin(rad),
647					Y = x * Math.sin(rad) + y * Math.cos(rad);
648				return { x: X, y: Y };
649			};
650		if (!recursive) {
651			xy = rotate(x1, y1, -rad);
652			x1 = xy.x;
653			y1 = xy.y;
654			xy = rotate(x2, y2, -rad);
655			x2 = xy.x;
656			y2 = xy.y;
657			var cos = Math.cos((Math.PI / 180) * angle),
658				sin = Math.sin((Math.PI / 180) * angle),
659				x = (x1 - x2) / 2,
660				y = (y1 - y2) / 2;
661			var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
662			if (h > 1) {
663				h = Math.sqrt(h);
664				rx = h * rx;
665				ry = h * ry;
666			}
667			var rx2 = rx * rx,
668				ry2 = ry * ry,
669				k =
670					(large_arc_flag == sweep_flag ? -1 : 1) *
671					Math.sqrt(
672						Math.abs(
673							(rx2 * ry2 - rx2 * y * y - ry2 * x * x) /
674								(rx2 * y * y + ry2 * x * x)
675						)
676					),
677				cx = (k * rx * y) / ry + (x1 + x2) / 2,
678				cy = (k * -ry * x) / rx + (y1 + y2) / 2,
679				f1 = Math.asin(((y1 - cy) / ry).toFixed(9)),
680				f2 = Math.asin(((y2 - cy) / ry).toFixed(9));
681
682			f1 = x1 < cx ? Math.PI - f1 : f1;
683			f2 = x2 < cx ? Math.PI - f2 : f2;
684			f1 < 0 && (f1 = Math.PI * 2 + f1);
685			f2 < 0 && (f2 = Math.PI * 2 + f2);
686			if (sweep_flag && f1 > f2) {
687				f1 = f1 - Math.PI * 2;
688			}
689			if (!sweep_flag && f2 > f1) {
690				f2 = f2 - Math.PI * 2;
691			}
692		} else {
693			f1 = recursive[0];
694			f2 = recursive[1];
695			cx = recursive[2];
696			cy = recursive[3];
697		}
698		var df = f2 - f1;
699		if (Math.abs(df) > _120) {
700			var f2old = f2,
701				x2old = x2,
702				y2old = y2;
703			f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
704			x2 = cx + rx * Math.cos(f2);
705			y2 = cy + ry * Math.sin(f2);
706			res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [
707				f2,
708				f2old,
709				cx,
710				cy,
711			]);
712		}
713		df = f2 - f1;
714		var c1 = Math.cos(f1),
715			s1 = Math.sin(f1),
716			c2 = Math.cos(f2),
717			s2 = Math.sin(f2),
718			t = Math.tan(df / 4),
719			hx = (4 / 3) * rx * t,
720			hy = (4 / 3) * ry * t,
721			m1 = [x1, y1],
722			m2 = [x1 + hx * s1, y1 - hy * c1],
723			m3 = [x2 + hx * s2, y2 - hy * c2],
724			m4 = [x2, y2];
725		m2[0] = 2 * m1[0] - m2[0];
726		m2[1] = 2 * m1[1] - m2[1];
727		if (recursive) {
728			return [m2, m3, m4].concat(res);
729		} else {
730			res = [m2, m3, m4].concat(res).join().split(",");
731			var newres = [];
732			for (var i = 0, ii = res.length; i < ii; i++) {
733				newres[i] =
734					i % 2
735						? rotate(res[i - 1], res[i], rad).y
736						: rotate(res[i], res[i + 1], rad).x;
737			}
738			return newres;
739		}
740	};
741
742	var path2curve = function (path, path2) {
743		var p = pathToAbsolute(path),
744			p2 = path2 && pathToAbsolute(path2),
745			attrs = {
746				x: 0,
747				y: 0,
748				bx: 0,
749				by: 0,
750				X: 0,
751				Y: 0,
752				qx: null,
753				qy: null,
754			},
755			attrs2 = {
756				x: 0,
757				y: 0,
758				bx: 0,
759				by: 0,
760				X: 0,
761				Y: 0,
762				qx: null,
763				qy: null,
764			},
765			processPath = function (path, d, pcom) {
766				var nx, ny;
767				if (!path) {
768					return ["C", d.x, d.y, d.x, d.y, d.x, d.y];
769				}
770				!(path[0] in { T: 1, Q: 1 }) && (d.qx = d.qy = null);
771				switch (path[0]) {
772					case "M":
773						d.X = path[1];
774						d.Y = path[2];
775						break;
776					case "A":
777						path = ["C"].concat(
778							a2c.apply(0, [d.x, d.y].concat(path.slice(1)))
779						);
780						break;
781					case "S":
782						if (pcom == "C" || pcom == "S") {
783							// In "S" case we have to take into account, if the previous command is C/S.
784							nx = d.x * 2 - d.bx; // And reflect the previous
785							ny = d.y * 2 - d.by; // command's control point relative to the current point.
786						} else {
787							// or some else or nothing
788							nx = d.x;
789							ny = d.y;
790						}
791						path = ["C", nx, ny].concat(path.slice(1));
792						break;
793					case "T":
794						if (pcom == "Q" || pcom == "T") {
795							// In "T" case we have to take into account, if the previous command is Q/T.
796							d.qx = d.x * 2 - d.qx; // And make a reflection similar
797							d.qy = d.y * 2 - d.qy; // to case "S".
798						} else {
799							// or something else or nothing
800							d.qx = d.x;
801							d.qy = d.y;
802						}
803						path = ["C"].concat(
804							q2c(d.x, d.y, d.qx, d.qy, path[1], path[2])
805						);
806						break;
807					case "Q":
808						d.qx = path[1];
809						d.qy = path[2];
810						path = ["C"].concat(
811							q2c(d.x, d.y, path[1], path[2], path[3], path[4])
812						);
813						break;
814					case "L":
815						path = ["C"].concat(l2c(d.x, d.y, path[1], path[2]));
816						break;
817					case "H":
818						path = ["C"].concat(l2c(d.x, d.y, path[1], d.y));
819						break;
820					case "V":
821						path = ["C"].concat(l2c(d.x, d.y, d.x, path[1]));
822						break;
823					case "Z":
824						path = ["C"].concat(l2c(d.x, d.y, d.X, d.Y));
825						break;
826				}
827				return path;
828			},
829			fixArc = function (pp, i) {
830				if (pp[i].length > 7) {
831					pp[i].shift();
832					var pi = pp[i];
vendor: 4,173 bytes, lines 833-991
833					while (pi.length) {
834						pcoms1[i] = "A"; // if created multiple C:s, their original seg is saved
835						p2 && (pcoms2[i] = "A"); // the same as above
836						pp.splice(i++, 0, ["C"].concat(pi.splice(0, 6)));
837					}
838					pp.splice(i, 1);
839					ii = Math.max(p.length, (p2 && p2.length) || 0);
840				}
841			},
842			fixM = function (path1, path2, a1, a2, i) {
843				if (
844					path1 &&
845					path2 &&
846					path1[i][0] == "M" &&
847					path2[i][0] != "M"
848				) {
849					path2.splice(i, 0, ["M", a2.x, a2.y]);
850					a1.bx = 0;
851					a1.by = 0;
852					a1.x = path1[i][1];
853					a1.y = path1[i][2];
854					ii = Math.max(p.length, (p2 && p2.length) || 0);
855				}
856			},
857			pcoms1 = [], // path commands of original path p
858			pcoms2 = [], // path commands of original path p2
859			pfirst = "", // temporary holder for original path command
860			pcom = ""; // holder for previous path command of original path
861		for (
862			var i = 0, ii = Math.max(p.length, (p2 && p2.length) || 0);
863			i < ii;
864			i++
865		) {
866			p[i] && (pfirst = p[i][0]); // save current path command
867
868			if (pfirst != "C") {
869				// C is not saved yet, because it may be result of conversion
870				pcoms1[i] = pfirst; // Save current path command
871				i && (pcom = pcoms1[i - 1]); // Get previous path command pcom
872			}
873			p[i] = processPath(p[i], attrs, pcom); // Previous path command is inputted to processPath
874
875			if (pcoms1[i] != "A" && pfirst == "C") pcoms1[i] = "C"; // A is the only command
876			// which may produce multiple C:s
877			// so we have to make sure that C is also C in original path
878
879			fixArc(p, i); // fixArc adds also the right amount of A:s to pcoms1
880
881			if (p2) {
882				// the same procedures is done to p2
883				p2[i] && (pfirst = p2[i][0]);
884				if (pfirst != "C") {
885					pcoms2[i] = pfirst;
886					i && (pcom = pcoms2[i - 1]);
887				}
888				p2[i] = processPath(p2[i], attrs2, pcom);
889
890				if (pcoms2[i] != "A" && pfirst == "C") {
891					pcoms2[i] = "C";
892				}
893
894				fixArc(p2, i);
895			}
896			fixM(p, p2, attrs, attrs2, i);
897			fixM(p2, p, attrs2, attrs, i);
898			var seg = p[i],
899				seg2 = p2 && p2[i],
900				seglen = seg.length,
901				seg2len = p2 && seg2.length;
902			attrs.x = seg[seglen - 2];
903			attrs.y = seg[seglen - 1];
904			attrs.bx = parseFloat(seg[seglen - 4]) || attrs.x;
905			attrs.by = parseFloat(seg[seglen - 3]) || attrs.y;
906			attrs2.bx = p2 && (parseFloat(seg2[seg2len - 4]) || attrs2.x);
907			attrs2.by = p2 && (parseFloat(seg2[seg2len - 3]) || attrs2.y);
908			attrs2.x = p2 && seg2[seg2len - 2];
909			attrs2.y = p2 && seg2[seg2len - 1];
910		}
911
912		return p2 ? [p, p2] : p;
913	};
914
915	var box = function (x, y, width, height) {
916		if (x == null) {
917			x = y = width = height = 0;
918		}
919		if (y == null) {
920			y = x.y;
921			width = x.width;
922			height = x.height;
923			x = x.x;
924		}
925		return {
926			x: x,
927			y: y,
928			w: width,
929			h: height,
930			cx: x + width / 2,
931			cy: y + height / 2,
932		};
933	};
934
935	// Returns bounding box of cubic bezier curve.
936	// Source: http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
937	// Original version: NISHIO Hirokazu
938	// Modifications: https://github.com/timo22345
939	var curveDim = function (x0, y0, x1, y1, x2, y2, x3, y3) {
940		var tvalues = [],
941			bounds = [[], []],
942			a,
943			b,
944			c,
945			t,
946			t1,
947			t2,
948			b2ac,
949			sqrtb2ac;
950		for (var i = 0; i < 2; ++i) {
951			if (i == 0) {
952				b = 6 * x0 - 12 * x1 + 6 * x2;
953				a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;
954				c = 3 * x1 - 3 * x0;
955			} else {
956				b = 6 * y0 - 12 * y1 + 6 * y2;
957				a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;
958				c = 3 * y1 - 3 * y0;
959			}
960			if (Math.abs(a) < 1e-12) {
961				if (Math.abs(b) < 1e-12) {
962					continue;
963				}
964				t = -c / b;
965				if (0 < t && t < 1) {
966					tvalues.push(t);
967				}
968				continue;
969			}
970			b2ac = b * b - 4 * c * a;
971			sqrtb2ac = Math.sqrt(b2ac);
972			if (b2ac < 0) {
973				continue;
974			}
975			t1 = (-b + sqrtb2ac) / (2 * a);
976			if (0 < t1 && t1 < 1) {
977				tvalues.push(t1);
978			}
979			t2 = (-b - sqrtb2ac) / (2 * a);
980			if (0 < t2 && t2 < 1) {
981				tvalues.push(t2);
982			}
983		}
984
985		var x,
986			y,
987			j = tvalues.length,
988			jlen = j,
989			mt;
990		while (j--) {
991			t = tvalues[j];
992			mt = 1 - t;
993			bounds[0][j] =
994				mt * mt * mt * x0 +
995				3 * mt * mt * t * x1 +
996				3 * mt * t * t * x2 +
997				t * t * t * x3;
998			bounds[1][j] =
999				mt * mt * mt * y0 +
1000				3 * mt * mt * t * y1 +
1001				3 * mt * t * t * y2 +
1002				t * t * t * y3;
1003		}
1004
1005		bounds[0][jlen] = x0;
1006		bounds[1][jlen] = y0;
1007		bounds[0][jlen + 1] = x3;
1008		bounds[1][jlen + 1] = y3;
1009		bounds[0].length = bounds[1].length = jlen + 2;
1010
1011		return {
1012			min: {
1013				x: Math.min.apply(0, bounds[0]),
1014				y: Math.min.apply(0, bounds[1]),
1015			},
1016			max: {
1017				x: Math.max.apply(0, bounds[0]),
1018				y: Math.max.apply(0, bounds[1]),
1019			},
1020		};
1021	};
1022
1023	var curvePathBBox = function (path) {
1024		var x = 0,
1025			y = 0,
1026			X = [],
1027			Y = [],
1028			p;
1029		for (var i = 0, ii = path.length; i < ii; i++) {
1030			p = path[i];
1031			if (p[0] == "M") {
1032				x = p[1];
1033				y = p[2];
1034				X.push(x);
1035				Y.push(y);
1036			} else {
1037				var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
1038				X = X.concat(dim.min.x, dim.max.x);
1039				Y = Y.concat(dim.min.y, dim.max.y);
1040				x = p[5];
1041				y = p[6];
1042			}
1043		}
1044		var xmin = Math.min.apply(0, X),
1045			ymin = Math.min.apply(0, Y),
1046			xmax = Math.max.apply(0, X),
1047			ymax = Math.max.apply(0, Y),
1048			bb = box(xmin, ymin, xmax - xmin, ymax - ymin);
1049
1050		return bb;
1051	};
1052
1053	var p2s = /,?([a-z]),?/gi;
1054	var path2string = function (path) {
1055		return path.join(",").replace(p2s, "$1");
1056	};
1057
1058	/*
1059	 * Styles
1060	 */
1061
1062	var hsrg = { hs: 1, rg: 1 },
1063		has = "hasOwnProperty",
1064		colourRegExp =
1065			/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i,
1066		commaSpaces = new RegExp("[" + spaces + "]*,[" + spaces + "]*");
1067
1068	// Converts RGB values to a hex representation of the color
1069	// var rgb = function (r, g, b, o) {
1070	//   if (isFinite(o)) {
1071	//     var round = math.round;
1072	//     return "rgba(" + [round(r), round(g), round(b), +o.toFixed(2)] + ")";
1073	//   }
1074	//   return "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1);
1075	// };
1076	var rgbToString = function (rgb) {
1077		var round = Math.round;
1078		return (
1079			"rgba(" +
1080			[
1081				round(rgb.r),
1082				round(rgb.g),
1083				round(rgb.b),
1084				+rgb.opacity.toFixed(2),
1085			] +
1086			")"
1087		);
1088	};
1089	var toHex = function (color) {
1090		var i =
1091				window.document.getElementsByTagName("head")[0] ||
1092				window.document.getElementsByTagName("svg")[0],
1093			red = "rgb(255, 0, 0)";
1094		toHex = function (color) {
1095			if (color.toLowerCase() == "red") {
1096				return red;
1097			}
1098			i.style.color = red;
1099			i.style.color = color;
1100			var out = window.document.defaultView
1101				.getComputedStyle(i, "")
1102				.getPropertyValue("color");
1103			return out == red ? null : out;
1104		};
1105		return toHex(color);
1106	};
1107
1108	var packageRGB = function (r, g, b, o) {
1109		r = Math.round(r * 255);
1110		g = Math.round(g * 255);
1111		b = Math.round(b * 255);
1112		var rgb = {
1113			r: r,
1114			g: g,
1115			b: b,
1116			opacity: isFinite(o) ? o : 1,
1117		};
1118		return rgb;
1119	};
1120
1121	// Converts HSB values to an RGB object
1122	var hsb2rgb = function (h, s, v, o) {
1123		if (typeof h === typeof {} && "h" in h && "s" in h && "b" in h) {
1124			v = h.b;
1125			s = h.s;
1126			h = h.h;
1127			o = h.o;
1128		}
1129		h *= 360;
1130		var R, G, B, X, C;
1131		h = (h % 360) / 60;
1132		C = v * s;
1133		X = C * (1 - Math.abs((h % 2) - 1));
1134		R = G = B = v - C;
1135
1136		h = ~~h;
1137		R += [C, X, 0, 0, X, C][h];
1138		G += [X, C, C, X, 0, 0][h];
1139		B += [0, 0, X, C, C, X][h];
1140		return packageRGB(R, G, B, o);
1141	};
1142
1143	// Converts HSL values to an RGB object
1144	var hsl2rgb = function (h, s, l, o) {
1145		if (typeof h === typeof {} && "h" in h && "s" in h && "l" in h) {
1146			l = h.l;
1147			s = h.s;
1148			h = h.h;
1149		}
1150		if (h > 1 || s > 1 || l > 1) {
1151			h /= 360;
1152			s /= 100;
1153			l /= 100;
1154		}
1155		h *= 360;
1156		var R, G, B, X, C;
1157		h = (h % 360) / 60;
1158		C = 2 * s * (l < 0.5 ? l : 1 - l);
1159		X = C * (1 - Math.abs((h % 2) - 1));
1160		R = G = B = l - C / 2;
1161
1162		h = ~~h;
1163		R += [C, X, 0, 0, X, C][h];
1164		G += [X, C, C, X, 0, 0][h];
1165		B += [0, 0, X, C, C, X][h];
1166		return packageRGB(R, G, B, o);
1167	};
1168
1169	// Parses color string as RGB object
1170	var getRGB = function (colour) {
1171		if (!colour || !!((colour = String(colour)).indexOf("-") + 1)) {
1172			return { r: -1, g: -1, b: -1, opacity: -1, error: 1 };
1173		}
1174		if (colour == "none") {
1175			return { r: -1, g: -1, b: -1, opacity: -1 };
1176		}
1177		!(
1178			hsrg[has](colour.toLowerCase().substring(0, 2)) ||
1179			colour.charAt() == "#"
1180		) && (colour = toHex(colour));
1181		if (!colour) {
1182			return { r: -1, g: -1, b: -1, opacity: -1, error: 1 };
1183		}
1184		var res,
1185			red,
1186			green,
1187			blue,
1188			opacity,
1189			t,
1190			values,
1191			rgb = colour.match(colourRegExp);
1192		if (rgb) {
1193			if (rgb[2]) {
1194				blue = parseInt(rgb[2].substring(5), 16);
1195				green = parseInt(rgb[2].substring(3, 5), 16);
1196				red = parseInt(rgb[2].substring(1, 3), 16);
1197			}
1198			if (rgb[3]) {
1199				blue = parseInt((t = rgb[3].charAt(3)) + t, 16);
1200				green = parseInt((t = rgb[3].charAt(2)) + t, 16);
1201				red = parseInt((t = rgb[3].charAt(1)) + t, 16);
1202			}
1203			if (rgb[4]) {
1204				values = rgb[4].split(commaSpaces);
1205				red = parseFloat(values[0]);
1206				values[0].slice(-1) == "%" && (red *= 2.55);
1207				green = parseFloat(values[1]);
1208				values[1].slice(-1) == "%" && (green *= 2.55);
1209				blue = parseFloat(values[2]);
1210				values[2].slice(-1) == "%" && (blue *= 2.55);
1211				rgb[1].toLowerCase().slice(0, 4) == "rgba" &&
1212					(opacity = parseFloat(values[3]));
1213				values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
1214			}
1215			if (rgb[5]) {
1216				values = rgb[5].split(commaSpaces);
1217				red = parseFloat(values[0]);
1218				values[0].slice(-1) == "%" && (red /= 100);
1219				green = parseFloat(values[1]);
1220				values[1].slice(-1) == "%" && (green /= 100);
1221				blue = parseFloat(values[2]);
1222				values[2].slice(-1) == "%" && (blue /= 100);
1223				(values[0].slice(-3) == "deg" ||
1224					values[0].slice(-1) == "\xb0") &&
1225					(red /= 360);
1226				rgb[1].toLowerCase().slice(0, 4) == "hsba" &&
1227					(opacity = parseFloat(values[3]));
1228				values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
1229				return hsb2rgb(red, green, blue, opacity);
1230			}
1231			if (rgb[6]) {
1232				values = rgb[6].split(commaSpaces);
1233				red = parseFloat(values[0]);
1234				values[0].slice(-1) == "%" && (red /= 100);
1235				green = parseFloat(values[1]);
1236				values[1].slice(-1) == "%" && (green /= 100);
1237				blue = parseFloat(values[2]);
1238				values[2].slice(-1) == "%" && (blue /= 100);
1239				(values[0].slice(-3) == "deg" ||
1240					values[0].slice(-1) == "\xb0") &&
1241					(red /= 360);
1242				rgb[1].toLowerCase().slice(0, 4) == "hsla" &&
1243					(opacity = parseFloat(values[3]));
1244				values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
1245				return hsl2rgb(red, green, blue, opacity);
1246			}
1247			red = Math.min(Math.round(red), 255);
1248			green = Math.min(Math.round(green), 255);
1249			blue = Math.min(Math.round(blue), 255);
1250			opacity = Math.min(Math.max(opacity, 0), 1);
1251			rgb = { r: red, g: green, b: blue };
1252			rgb.opacity = isFinite(opacity) ? opacity : 1;
1253			return rgb;
1254		}
1255		return { r: -1, g: -1, b: -1, opacity: -1, error: 1 };
1256	};
1257
1258	function SVGMorpheus(element, options, callback) {
1259		if (!element) {
1260			throw new Error('SVGMorpheus > "element" is required');
1261		}
1262
1263		if (typeof element === typeof "") {
1264			element = document.querySelector(element);
1265			if (!element) {
1266				throw new Error(
1267					'SVGMorpheus > "element" query is not related to an existing DOM node'
1268				);
1269			}
1270		}
1271
1272		if (!!options && typeof options !== typeof {}) {
1273			throw new Error(
1274				'SVGMorpheus > "options" parameter must be an object'
1275			);
1276		}
1277		options = options || {};
1278
1279		if (!!callback && typeof callback !== typeof function () {}) {
1280			throw new Error(
1281				'SVGMorpheus > "callback" parameter must be a function'
1282			);
1283		}
1284
1285		var that = this;
1286
1287		this._icons = {};
1288		this._curIconId = options.iconId || "";
1289		this._toIconId = "";
1290		this._curIconItems = [];
1291		this._fromIconItems = [];
1292		this._toIconItems = [];
1293		this._morphNodes = [];
1294		this._morphG;
1295		this._startTime;
1296		this._defDuration = options.duration || 750;
1297		this._defEasing = options.easing || "quad-in-out";
1298		this._defRotation = options.rotation || "clock";
1299		this._defCallback = callback || function () {};
1300		this._duration = this._defDuration;
1301		this._easing = this._defEasing;
1302		this._rotation = this._defRotation;
1303		this._callback = this._defCallback;
1304		this._rafid;
1305
1306		this._fnTick = function (timePassed) {
1307			if (!that._startTime) {
1308				that._startTime = timePassed;
1309			}
1310			var progress = Math.min(
1311				(timePassed - that._startTime) / that._duration,
1312				1
1313			);
1314			that._updateAnimationProgress(progress);
1315			if (progress < 1) {
1316				that._rafid = _reqAnimFrame(that._fnTick);
1317			} else {
1318				if (that._toIconId != "") {
1319					that._animationEnd();
1320				}
1321			}
1322		};
1323
1324		if (element.nodeName.toUpperCase() === "SVG") {
1325			this._svgDoc = element;
1326		} else {
1327			this._svgDoc = element.getSVGDocument();
1328		}
1329		if (!this._svgDoc) {
1330			element.addEventListener(
1331				"load",
1332				function () {
1333					that._svgDoc = element.getSVGDocument();
1334					that._init();
1335				},
1336				false
1337			);
1338		} else {
1339			that._init();
1340		}
1341	}
1342
1343	SVGMorpheus.prototype._init = function () {
1344		if (this._svgDoc.nodeName.toUpperCase() !== "SVG") {
1345			this._svgDoc = this._svgDoc.getElementsByTagName("svg")[0];
1346		}
1347
1348		if (!!this._svgDoc) {
1349			var lastIconId = "",
1350				i,
1351				len,
1352				id,
1353				items,
1354				item,
1355				j,
1356				len2,
1357				icon;
1358
1359			// Read Icons Data
1360			// Icons = 1st tier G nodes having ID
1361			for (i = this._svgDoc.childNodes.length - 1; i >= 0; i--) {
1362				var nodeIcon = this._svgDoc.childNodes[i];
1363				if (nodeIcon.nodeName.toUpperCase() === "G") {
1364					id = nodeIcon.getAttribute("id");
1365					if (!!id) {
1366						items = [];
1367						for (
1368							j = 0, len2 = nodeIcon.childNodes.length;
1369							j < len2;
1370							j++
1371						) {
1372							var nodeItem = nodeIcon.childNodes[j];
1373							item = {
1374								path: "",
1375								attrs: {},
1376								style: {},
1377							};
1378
1379							// Get Item Path (Convert all shapes into Path Data)
1380							switch (nodeItem.nodeName.toUpperCase()) {
1381								case "PATH":
1382									item.path = nodeItem.getAttribute("d");
1383									break;
1384								case "CIRCLE":
1385									var cx = nodeItem.getAttribute("cx") * 1,
1386										cy = nodeItem.getAttribute("cy") * 1,
1387										r = nodeItem.getAttribute("r") * 1;
1388									item.path =
1389										"M" +
1390										(cx - r) +
1391										"," +
1392										cy +
1393										"a" +
1394										r +
1395										"," +
1396										r +
1397										" 0 1,0 " +
1398										r * 2 +
1399										",0a" +
1400										r +
1401										"," +
1402										r +
1403										" 0 1,0 -" +
1404										r * 2 +
1405										",0z";
1406									break;
1407								case "ELLIPSE":
1408									var cx = nodeItem.getAttribute("cx") * 1,
1409										cy = nodeItem.getAttribute("cy") * 1,
1410										rx = nodeItem.getAttribute("rx") * 1,
1411										ry = nodeItem.getAttribute("ry") * 1;
1412									item.path =
1413										"M" +
1414										(cx - rx) +
1415										"," +
1416										cy +
1417										"a" +
1418										rx +
1419										"," +
1420										ry +
1421										" 0 1,0 " +
1422										rx * 2 +
1423										",0a" +
1424										rx +
1425										"," +
1426										ry +
1427										" 0 1,0 -" +
1428										rx * 2 +
1429										",0z";
1430									break;
1431								case "RECT":
1432									var x = nodeItem.getAttribute("x") * 1,
1433										y = nodeItem.getAttribute("y") * 1,
1434										w = nodeItem.getAttribute("width") * 1,
1435										h = nodeItem.getAttribute("height") * 1,
1436										rx = nodeItem.getAttribute("rx") * 1,
1437										ry = nodeItem.getAttribute("ry") * 1;
1438									if (!rx && !ry) {
1439										item.path =
1440											"M" +
1441											x +
1442											"," +
1443											y +
1444											"l" +
1445											w +
1446											",0l0," +
1447											h +
1448											"l-" +
1449											w +
1450											",0z";
1451									} else {
1452										item.path =
1453											"M" +
1454											(x + rx) +
1455											"," +
1456											y +
1457											"l" +
1458											(w - rx * 2) +
1459											",0" +
1460											"a" +
1461											rx +
1462											"," +
1463											ry +
1464											" 0 0,1 " +
1465											rx +
1466											"," +
1467											ry +
1468											"l0," +
1469											(h - ry * 2) +
1470											"a" +
1471											rx +
1472											"," +
1473											ry +
1474											" 0 0,1 -" +
1475											rx +
1476											"," +
1477											ry +
1478											"l" +
1479											(rx * 2 - w) +
1480											",0" +
1481											"a" +
1482											rx +
1483											"," +
1484											ry +
1485											" 0 0,1 -" +
1486											rx +
1487											",-" +
1488											ry +
1489											"l0," +
1490											(ry * 2 - h) +
1491											"a" +
1492											rx +
1493											"," +
1494											ry +
1495											" 0 0,1 " +
1496											rx +
1497											",-" +
1498											ry +
1499											"z";
1500									}
1501									break;
1502								case "POLYGON":
1503									var points =
1504										nodeItem.getAttribute("points");
1505									var p = points.split(/\s+/);
1506									var path = "";
1507									for (
1508										var k = 0, len = p.length;
1509										k < len;
1510										k++
1511									) {
1512										path += ((k && "L") || "M") + p[k];
1513									}
1514									item.path = path + "z";
1515									break;
1516								case "LINE":
1517									var x1 = nodeItem.getAttribute("x1") * 1,
1518										y1 = nodeItem.getAttribute("y1") * 1,
1519										x2 = nodeItem.getAttribute("x2") * 1,
1520										y2 = nodeItem.getAttribute("y2") * 1;
1521									item.path =
1522										"M" +
1523										x1 +
1524										"," +
1525										y1 +
1526										"L" +
1527										x2 +
1528										"," +
1529										y2 +
1530										"z";
1531									break;
1532							}
1533							if (item.path != "") {
1534								// Traverse all attributes and get style values
1535								for (
1536									var k = 0,
1537										len3 = nodeItem.attributes.length;
1538									k < len3;
1539									k++
1540								) {
1541									var attrib = nodeItem.attributes[k];
1542									if (attrib.specified) {
1543										var name = attrib.name.toLowerCase();
1544										switch (name) {
1545											case "fill":
1546											case "fill-opacity":
1547											case "opacity":
1548											case "stroke":
1549											case "stroke-opacity":
1550											case "stroke-width":
1551												item.attrs[name] = attrib.value;
1552										}
1553									}
1554								}
1555
1556								// Traverse all inline styles and get supported values
1557								for (
1558									var l = 0, len4 = nodeItem.style.length;
1559									l < len4;
1560									l++
1561								) {
1562									var styleName = nodeItem.style[l];
1563									switch (styleName) {
1564										case "fill":
1565										case "fill-opacity":
1566										case "opacity":
1567										case "stroke":
1568										case "stroke-opacity":
1569										case "stroke-width":
1570											item.style[styleName] =
1571												nodeItem.style[styleName];
1572									}
1573								}
1574
1575								items.push(item);
1576							}
1577						}
1578
1579						// Add Icon
1580						if (items.length > 0) {
1581							icon = {
1582								id: id,
1583								items: items,
1584							};
1585							this._icons[id] = icon;
1586						}
1587
1588						// Init Node for Icons Items and remove Icon Nodes
1589						if (!this._morphG) {
1590							lastIconId = id;
1591							this._morphG = document.createElementNS(
1592								"http://www.w3.org/2000/svg",
1593								"g"
1594							);
1595							this._svgDoc.replaceChild(this._morphG, nodeIcon);
1596						} else {
1597							this._svgDoc.removeChild(nodeIcon);
1598						}
1599					}
1600				}
1601			}
1602			// To Default Icon
1603			var defaultIcon = this._curIconId || lastIconId;
1604			if (defaultIcon !== "") {
1605				this._setupAnimation(defaultIcon);
1606				this._updateAnimationProgress(1);
1607				this._animationEnd();
1608			}
1609		}
1610	};
1611
1612	SVGMorpheus.prototype._setupAnimation = function (toIconId) {
1613		if (!!toIconId && !!this._icons[toIconId]) {
1614			this._toIconId = toIconId;
1615			this._startTime = undefined;
1616			var i, len, j, len2;
1617			this._fromIconItems = clone(this._curIconItems);
1618			this._toIconItems = clone(this._icons[toIconId].items);
1619
1620			for (i = 0, len = this._morphNodes.length; i < len; i++) {
1621				var morphNode = this._morphNodes[i];
1622				morphNode.fromIconItemIdx = i;
1623				morphNode.toIconItemIdx = i;
1624			}
1625
1626			var maxNum = Math.max(
1627				this._fromIconItems.length,
1628				this._toIconItems.length
1629			);
1630			var toBB;
1631			for (i = 0; i < maxNum; i++) {
1632				// Add items to fromIcon/toIcon if needed
1633				if (!this._fromIconItems[i]) {
1634					if (!!this._toIconItems[i]) {
1635						toBB = curvePathBBox(
1636							path2curve(this._toIconItems[i].path)
1637						);
1638						this._fromIconItems.push({
1639							path: "M" + toBB.cx + "," + toBB.cy + "l0,0",
1640							attrs: {},
1641							style: {},
1642							trans: {
1643								rotate: [0, toBB.cx, toBB.cy],
1644							},
1645						});
1646					} else {
1647						this._fromIconItems.push({
1648							path: "M0,0l0,0",
1649							attrs: {},
1650							style: {},
1651							trans: {
1652								rotate: [0, 0, 0],
1653							},
1654						});
1655					}
1656				}
1657				if (!this._toIconItems[i]) {
1658					if (!!this._fromIconItems[i]) {
1659						toBB = curvePathBBox(
1660							path2curve(this._fromIconItems[i].path)
1661						);
1662						this._toIconItems.push({
1663							path: "M" + toBB.cx + "," + toBB.cy + "l0,0",
1664							attrs: {},
1665							style: {},
1666							trans: {
1667								rotate: [0, toBB.cx, toBB.cy],
1668							},
1669						});
1670					} else {
1671						this._toIconItems.push({
1672							path: "M0,0l0,0",
1673							attrs: {},
1674							style: {},
1675							trans: {
1676								rotate: [0, 0, 0],
1677							},
1678						});
1679					}
1680				}
1681
1682				// Add Node to DOM if needed
1683				if (!this._morphNodes[i]) {
1684					var node = document.createElementNS(
1685						"http://www.w3.org/2000/svg",
1686						"path"
1687					);
1688					this._morphG.appendChild(node);
1689					this._morphNodes.push({
1690						node: node,
1691						fromIconItemIdx: i,
1692						toIconItemIdx: i,
1693					});
1694				}
1695			}
1696
1697			for (i = 0; i < maxNum; i++) {
1698				var fromIconItem = this._fromIconItems[i];
1699				var toIconItem = this._toIconItems[i];
1700
1701				// Calculate from/to curve data and set to fromIcon/toIcon
1702				var curves = path2curve(
1703					this._fromIconItems[i].path,
1704					this._toIconItems[i].path
1705				);
1706				fromIconItem.curve = curves[0];
1707				toIconItem.curve = curves[1];
1708
1709				// Normalize from/to attrs
1710				var attrsNorm = styleToNorm(
1711					this._fromIconItems[i].attrs,
1712					this._toIconItems[i].attrs
1713				);
1714				fromIconItem.attrsNorm = attrsNorm[0];
1715				toIconItem.attrsNorm = attrsNorm[1];
1716				fromIconItem.attrs = styleNormToString(fromIconItem.attrsNorm);
1717				toIconItem.attrs = styleNormToString(toIconItem.attrsNorm);
1718
1719				// Normalize from/to style
1720				var styleNorm = styleToNorm(
1721					this._fromIconItems[i].style,
1722					this._toIconItems[i].style
1723				);
1724				fromIconItem.styleNorm = styleNorm[0];
1725				toIconItem.styleNorm = styleNorm[1];
1726				fromIconItem.style = styleNormToString(fromIconItem.styleNorm);
1727				toIconItem.style = styleNormToString(toIconItem.styleNorm);
1728
1729				// Calculate from/to transform
1730				toBB = curvePathBBox(toIconItem.curve);
1731				toIconItem.trans = {
1732					rotate: [0, toBB.cx, toBB.cy],
1733				};
1734				var rotation = this._rotation,
1735					degAdd;
1736				if (rotation === "random") {
1737					rotation = Math.random() < 0.5 ? "counterclock" : "clock";
1738				}
1739				switch (rotation) {
1740					case "none":
1741						if (!!fromIconItem.trans.rotate) {
1742							toIconItem.trans.rotate[0] =
1743								fromIconItem.trans.rotate[0];
1744						}
1745						break;
1746					case "counterclock":
1747						if (!!fromIconItem.trans.rotate) {
1748							toIconItem.trans.rotate[0] =
1749								fromIconItem.trans.rotate[0] - 360;
1750							degAdd = -fromIconItem.trans.rotate[0] % 360;
1751							toIconItem.trans.rotate[0] +=
1752								degAdd < 180 ? degAdd : degAdd - 360;
1753						} else {
1754							toIconItem.trans.rotate[0] = -360;
1755						}
1756						break;
1757					default: // Clockwise
1758						if (!!fromIconItem.trans.rotate) {
1759							toIconItem.trans.rotate[0] =
1760								fromIconItem.trans.rotate[0] + 360;
1761							degAdd = fromIconItem.trans.rotate[0] % 360;
1762							toIconItem.trans.rotate[0] +=
1763								degAdd < 180 ? -degAdd : 360 - degAdd;
1764						} else {
1765							toIconItem.trans.rotate[0] = 360;
1766						}
1767						break;
1768				}
1769			}
1770
1771			this._curIconItems = clone(this._fromIconItems);
1772		}
1773	};
1774
1775	SVGMorpheus.prototype._updateAnimationProgress = function (progress) {
1776		progress = easings[this._easing](progress);
1777
1778		var i, j, k, len;
1779		// Update path/attrs/transform
1780		for (i = 0, len = this._curIconItems.length; i < len; i++) {
1781			this._curIconItems[i].curve = curveCalc(
1782				this._fromIconItems[i].curve,
1783				this._toIconItems[i].curve,
1784				progress
1785			);
1786			this._curIconItems[i].path = path2string(
1787				this._curIconItems[i].curve
1788			);
1789
1790			this._curIconItems[i].attrsNorm = styleNormCalc(
1791				this._fromIconItems[i].attrsNorm,
1792				this._toIconItems[i].attrsNorm,
1793				progress
1794			);
1795			this._curIconItems[i].attrs = styleNormToString(
1796				this._curIconItems[i].attrsNorm
1797			);
1798
1799			this._curIconItems[i].styleNorm = styleNormCalc(
1800				this._fromIconItems[i].styleNorm,
1801				this._toIconItems[i].styleNorm,
1802				progress
1803			);
1804			this._curIconItems[i].style = styleNormToString(
1805				this._curIconItems[i].styleNorm
1806			);
1807
1808			this._curIconItems[i].trans = transCalc(
1809				this._fromIconItems[i].trans,
1810				this._toIconItems[i].trans,
1811				progress
1812			);
1813			this._curIconItems[i].transStr = trans2string(
1814				this._curIconItems[i].trans
1815			);
1816		}
1817
1818		// Update DOM
1819		for (i = 0, len = this._morphNodes.length; i < len; i++) {
1820			var morphNode = this._morphNodes[i];
1821			morphNode.node.setAttribute("d", this._curIconItems[i].path);
1822			var attrs = this._curIconItems[i].attrs;
1823			for (j in attrs) {
1824				morphNode.node.setAttribute(j, attrs[j]);
1825			}
1826			var style = this._curIconItems[i].style;
1827			for (k in style) {
1828				morphNode.node.style[k] = style[k];
1829			}
1830			morphNode.node.setAttribute(
1831				"transform",
1832				this._curIconItems[i].transStr
1833			);
1834		}
1835	};
1836
1837	SVGMorpheus.prototype._animationEnd = function () {
1838		for (var i = this._morphNodes.length - 1; i >= 0; i--) {
1839			var morphNode = this._morphNodes[i];
1840			if (!!this._icons[this._toIconId].items[i]) {
1841				morphNode.node.setAttribute(
1842					"d",
1843					this._icons[this._toIconId].items[i].path
1844				);
1845			} else {
1846				morphNode.node.parentNode.removeChild(morphNode.node);
1847				this._morphNodes.splice(i, 1);
1848			}
1849		}
1850
1851		this._curIconId = this._toIconId;
1852		this._toIconId = "";
1853
1854		this._callback();
1855	};
1856
1857	/*
1858	 * Public methods
1859	 */
1860
1861	// Morph To Icon
1862	SVGMorpheus.prototype.to = function (iconId, options, callback) {
1863		if (iconId !== this._toIconId) {
1864			if (!!options && typeof options !== typeof {}) {
1865				throw new Error(
1866					'SVGMorpheus.to() > "options" parameter must be an object'
1867				);
1868			}
1869			options = options || {};
1870
1871			if (!!callback && typeof callback !== typeof function () {}) {
1872				throw new Error(
1873					'SVGMorpheus.to() > "callback" parameter must be a function'
1874				);
1875			}
1876
1877			_cancelAnimFrame(this._rafid);
1878
1879			this._duration = options.duration || this._defDuration;
1880			this._easing = options.easing || this._defEasing;
1881			this._rotation = options.rotation || this._defRotation;
1882			this._callback = callback || this._defCallback;
1883
1884			this._setupAnimation(iconId);
1885			this._rafid = _reqAnimFrame(this._fnTick);
1886		}
1887	};
1888
1889	// Register custom Easing function
1890	SVGMorpheus.prototype.registerEasing = function (name, fn) {
1891		easings[name] = fn;
1892	};
1893
1894	if (typeof define === "function" && define.amd) {
1895		define(function () {
1896			return SVGMorpheus;
1897		});
1898	} else if (
1899		typeof module !== "undefined" &&
1900		typeof module.exports !== "undefined"
1901	) {
1902		module.exports = SVGMorpheus;
1903	} else {
1904		window.SVGMorpheus = SVGMorpheus;
1905	}
1906})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.