| 
					
				 | 
			
			
				@@ -1,138 +1,284 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-;(function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	function normalize(opt){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var el = $(this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		opt = opt || $.extend(true, normalize.opt, opt||{}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		el.children().each(function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			var a = {$: $(this), opt: opt}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			a.tag = normalize.tag(a.$); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			$(a.opt.mutate).each(function(i,fn){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				fn && fn(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return el; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	var n = normalize, u; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	n.get = function(o, p){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		p = p.split('.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var i = 0, l = p.length, u; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		while((o = o[p[i++]]) != null && i < l){}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return i < l ? u : o; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	n.has = function(o,p){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return Object.prototype.hasOwnProperty.call(o, p);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	n.tag = function(e){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return (($(e)[0]||{}).nodeName||'').toLowerCase(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	n.attrs = function(e, cb){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	  var attr = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	  (e = $(e)) && e.length && $(e[0].attributes||[]).each(function(v,n){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	  	n = n.nodeName||n.name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	    v = e.attr(n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			v = cb? cb(v,n,e) : v; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	    if(v !== u && v !== false){ attr[n] = v } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	  return attr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	n.joint = function(e, d){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		d = (d? 'next' : 'previous') + 'Sibling' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return $(($(e)[0]||{})[d]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	var h = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		attr: function(a$, av, al){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			var l = function(i,v){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				var t = v; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				i = al? v : i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				v = al? av[v.toLowerCase()] : t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				a$.attr(i, v); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			al? $(al.sort()).each(l) : $.each(av,l); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	n.opt = { // some reasonable defaults, limited to content alone. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		tags: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'a': {attrs:{'src':1}, exclude:{'a':1}},  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'b': {exclude:{'b':1}}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			//'blockquote':1,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'br': {empty: 1}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'div': 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			//'code':1,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'i': {exclude:{'i':1}}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'img': {attrs:{'src':1}, empty: 1}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'li':1, 'ol':1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'p': {exclude:{'p':1,'div':1}}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			//'pre':1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			's': {exclude:{'s':1}}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'sub':1, 'sup':1,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'span': {exclude:{'p':1,'ul':1,'ol':1,'li':1,'br':1}},  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'u': {exclude:{'u':1,'p':1}}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'ul':1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// a, audio, b, br, div, i, img, li, ol, p, s, span, sub, sup, u, ul, video 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// button, canvas, embed, form, iframe, input, style, svg, table, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// Text: bold, italics, underline, align, bullet, list,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		,convert: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'em': 'i', 'strong': 'b' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		,attrs: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			'id':1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			,'class':1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			,'style':1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		,mutate: [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			function(a){ // attr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				a.attrs = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				a.attr = $.extend(a.opt.attrs, n.get(a.opt,'tags.'+ a.tag +'attrs')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				a.attr = n.attrs(a.$, function(v,i){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					a.$.removeAttr(i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if(a.attr[i.toLowerCase()]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						a.attrs.push(i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						return v; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// if this tag is gonna get converted, wait to add attr back till after the convert 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if(a.attrs && !n.get(a.opt, 'convert.' + a.tag)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					h.attr(a.$, a.attr, a.attrs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			,function(a, tmp){ // convert 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if(!(tmp = n.get(a.opt,'convert.' + a.tag))){ return } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				a.attr = a.attr || n.attrs(a.$); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				a.$.replaceWith(a.$ = $('<'+ (a.tag = tmp.toLowerCase()) +'>').append(a.$.contents())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				h.attr(a.$, a.attr, a.attrs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			,function(a, tmp){ // lookahead 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if((tmp = n.joint(a.$,1)) && (tmp = tmp.contents()).length === 1 && a.tag === n.tag(tmp = tmp.first())){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					a.$.append(tmp.parent()); // no need to unwrap the child, since the recursion will do it for us 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			,function(a){ // recurse 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// this needs to precede the exclusion and empty. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				normalize(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			,function(a, tmp){ // exclude 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if(!n.get(a.opt,'tags.' + a.tag)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				|| ((tmp = n.get(a.opt,'tags.'+ a.tag +'.exclude'))  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				&& a.$.parents($.map(tmp,function(i,v){return v})+' ').length) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				){  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					a.$.replaceWith(a.$.contents()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			,function(a, tmp){ // prior 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if((tmp = n.joint(a.$)).length && a.tag === n.tag(tmp)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					tmp.append(a.$.contents()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			,function(a){ // empty 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// should always go last, since the element will be removed! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if(a.opt.empty || !n.has(a.opt,'empty')){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if(!n.get(a.opt,'tags.'+ a.tag +'.empty')  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					&& !a.$.contents().length){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						a.$.remove(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	$.fn.normalize = normalize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  $.normalize = function(html, customOpt){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var html, root$, wrapped, opt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    opt = html.opt || (customOpt ? prepareOptTags($.extend(true, baseOpt, customOpt)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 : defaultOpt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!html.opt){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // first call 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      unstableList.length = 0; // drop state from previous run (in case there has been error) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      root$ = $('<div>'+html+'</div>'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // initial recursion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (html.$ || root$).contents().each(function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(this.nodeType === this.TEXT_NODE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.textContent = this.textContent.replace(/^[ \n]+|[ \n]+$/g, ' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var a = {$: $(this), opt: opt}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      initTag(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      $.normalize(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(root$){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      stateMachine(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return root$.html(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var baseOpt = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    hierarchy: ['div', 'pre', 'ol', 'ul', 'li', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'h1', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'a', // block 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'b', 'code', 'i', 'span', 's', 'sub', 'sup', 'u',   // inline 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'br']                                               // empty 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ,tags: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'a': {attrs:{'href':1}, exclude:{'a':1}}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'b': {exclude:{'b':1,'p':1}}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'br': {empty: 1}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'i': {exclude:{'i':1,'p':1}}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'span': {exclude:{'p':1,'ul':1,'ol':1,'li':1,'br':1}}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      's': {space:1}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'u': {exclude:{'u':1,'p':1},space:1}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ,convert: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'em': 'i', 'strong': 'b', 'strike': 's', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ,attrs: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'id':1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ,'class':1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ,'style':1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ,blockTag: function(a){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return a.opt.tags[a.tag].order < a.opt.tags.a.order; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ,mutate: [exclude, moveSpaceUp, next, parentOrderWrap] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var defaultOpt = prepareOptTags($.extend(true, {}, baseOpt)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var unstableList = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function addUnstable(a) { // NOT ES5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!a.tag) { throw Error("not tag in ", a) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(a.unstable) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    unstableList.push(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    a.unstable = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function initTag(a) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // initial handling (container, convert, attributes): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    a.tag = tag(a.$); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(empty(a)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    parseAndRemoveAttrs(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    convert(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setAttrs(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    a.$[0].a = a; // link from dom element back to a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // state machine init 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    unstableList.push(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    a.unstable = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return a; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function stateMachine() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(unstableList.length===0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var a, i = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while (a = unstableList.pop()) { // PERF: running index is probably faster than shift (mutates array) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      a.unstable = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      $(a.opt.mutate).each(function(i,fn){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return fn && fn(a, addUnstable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function prepareOptTags(opt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var name, tag, tags = opt.tags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for(name in tags) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(opt.hierarchy.indexOf(name)===-1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        throw Error('tag "'+name+'" is missing hierachy definition'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    opt.hierarchy.forEach(function(name){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(!tags[name]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tags[name] = {attrs: opt.attrs}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (tag=tags[name]).attrs = $.extend(tag.attrs||{}, opt.attrs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tag.name = name; // not used, debug help (REMOVE later?) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // order 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tag.order = opt.hierarchy.indexOf(name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(tag.order === -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      throw Error("Order of '"+name+"' not defined in hierarchy"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return opt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // GENERAL UTILS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function get(o, args){ // path argments as separate string parameters 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(typeof args === 'string') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return o[args[0]]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var i = 0, l = args.length, u; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while((o = o[args[i++]]) != null && i < l){}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return i < l ? u : o; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function has(obj,prop){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return Object.prototype.hasOwnProperty.call(obj, prop); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // ELEMENT UTILS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function tag(e){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return (($(e)[0]||{}).nodeName||'').toLowerCase(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function joint(e, d){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    d = (d? 'next' : 'previous') + 'Sibling'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return $(($(e)[0]||{})[d]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // create key val attributes object from elements attributes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function attrsAsObj(e, filterCb){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var attrObj = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (e = $(e)) && e.length && $(e[0].attributes||[]).each(function(value,name){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      name = name.nodeName||name.name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      value = e.attr(name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      value = filterCb? filterCb(value,name,e) : value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(value !== undefined && value !== false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        attrObj[name] = value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return attrObj; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // TODO: PERF testing - for loop to compare through? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function sameAttrs(a, b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return JSON.stringify(a.attr) === JSON.stringify(b.attr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // INITIAL MUTATORS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function parseAndRemoveAttrs(a) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    a.attrs = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var tag = a.opt.convert[a.tag] || a.tag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tOpt = a.opt.tags[tag]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    a.attr = tOpt && attrsAsObj(a.$, function(value,name){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    a.$.removeAttr(name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(tOpt.attrs[name.toLowerCase()]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      a.attrs.push(name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function setAttrs(a){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var l  = function(ind,name){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var t = name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      name = a.attrs? name : ind; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var value = a.attrs? a.attr[name.toLowerCase()] : t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      a.$.attr(name, value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    a.attrs? $(a.attrs.sort()).each(l) : $.each(a.attr,l); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function convert(a){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(t = a.opt.convert[a.tag]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      a.$.replaceWith(a.$ = $('<'+ (a.tag = t.toLowerCase()) +'>').append(a.$.contents())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // LOOPING (STATE MACHINE) MUTATORS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function exclude(a, addUnstable){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var t = get(a.opt, ['tags', a.tag]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pt = get(a.opt, ['tags', tag(a.$.parent())]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!t || (pt && get(pt, ['exclude', a.tag]))){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var c = a.$.contents(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      a.$.replaceWith(c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      c.length===1 && c[0].a && addUnstable(c[0].a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function moveSpaceUp(a, addUnstable){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var n = a.$[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(moveSpace(n, true) + moveSpace(n, false)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // either front, back or both spaces moved 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(n.textContent==='') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        empty(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else if((c = a.$.contents()[0]) && c.a) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        parentOrderWrap(c.a, addUnstable) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function moveSpace(n, bef) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var childRe  = bef? /^ / : / $/, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        parentRe = bef? / $/ : /^ /, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        c = bef? 'firstChild' : 'lastChild', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        s = bef? 'previousSibling' : 'nextSibling'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sAdd = bef? 'after' : 'before'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        pAdd = bef? 'prepend' : 'append'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!n || !n[c] || n[c].nodeType !== n.TEXT_NODE || !n[c].wholeText.match(childRe)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if((n2 = n[s]) && !n.a.opt.blockTag(n.a)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(n2.nodeType === 3 && !n2.textContent.match(parentRe)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        n2.textContent = (bef?'':' ') + n2.textContent + (bef?' ':''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else if(n2.nodeType === 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        $(n2)[sAdd](' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if((n2 = n.parentNode) && !n.a.opt.blockTag(n.a)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      $(n2)[pAdd](' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    n[c].textContent = n[c].wholeText.replace(childRe, ''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!n[c].wholeText.length) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      $(n[c]).remove(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function next(a, addUnstable, t){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var t = t || joint(a.$, true), sm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!t.length || a.opt.blockTag(a)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(a.opt.spaceMerge && t.length===1 && t[0].nodeType === 3 && t[0].wholeText===' '){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(!(t2 = joint(t, true)).length || a.opt.blockTag(t2[0].a)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      t.remove(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      t2.prepend(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return next(a, addUnstable, t2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!t[0].a || a.tag !== t[0].a.tag || !sameAttrs(a, t[0].a)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    t.prepend(a.$.contents()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    empty(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    addUnstable(t[0].a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (t = t.children(":first")).length && addUnstable(t[0].a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function empty(a){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var t = a.opt.tags[a.tag]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if((!t || !t.empty) && !a.$.contents().length && !a.$[0].attributes.length){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      a.$.remove(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return true; // NOTE true/false - different API than in exclude 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function parentOrderWrap(a, addUnstable){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var parent = a.$.parent(), children = parent.contents(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tags = a.opt.tags, ptag; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(children.length===1 && children[0] === a.$[0] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    && (ptag=tags[tag(parent)]) && ptag.order > tags[a.tag].order){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      parent.after(a.$); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      parent.append(a.$.contents()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      a.$.append(parent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      addUnstable(parent[0].a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      addUnstable(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 |