text:
(function() {

	var slideSpeed = 10; // milliseconds between each JS sliding step - only if CSS transition is not supported
	var slideStep = 5; // percent of each JS sliding step - only if CSS transition is not supported
	var ajaxTimeoutVal = 30000;
	var prefix = null;

	var originalView = null;
	var currentView = null;
	var currentDialog = null;
	var currentWidth = 0;
	var currentHeight = 0;
	var currentHash = location.hash;
	var hashPrefix = "#_";
	var navStackStartIndex = 0; // Browser navigation stack index onload
	var navStack = []; // Navigation stack
	var checkTimer;
	var screenHeight = 0;

	// *************************************************************************************************

	/*
	events:
	emy fires a number of custom events on your panel and dialog elements. Handling
	these events is the recommended way to do any just-in-time transformations or
	loading (besides the ajax pre-loading built into emy).
	*/

	window.emy = {
	/*
	version
	useful for plugins, support & debug
	*/
	v : 1.0,
    /*
	used in emy.log()
	initialized at: onload.
	This is set to `true`, console.log is enabled
	*/
	logging: false,

	/*
	emy.busy
	initialized at: onload.
	This is set to `true` if a slide animation is in progress.
	*/
	busy: false,

	/*
	emy.transitionMode
	initialized at: onload.
	Determines which transition mode to use between two screens.
	Value can be 'css', 'js' or 'none' - if 'css', a test is done onLoad to determine is 'css' transition is supported. If not, value is changed to 'js'.
	*/
	transitionMode: 'css',

	/*
	emy.httpHeaders
	initialized at: onload.
	An object defining headers to be sent with Ajax requests.
	*/
	httpHeaders: {
		"X-Requested-With": "XMLHttpRequest"
	},

	/*
	emy.prefixedProperty
	initialized at: onload.
	Vendor prefixed CSS3 events methods for transform, transition and transitionEnd
	NOTE: This might be removed when more than 90% of daily-used browsers support non-prefixed events
	*/
	prefixedProperty: [],

		/*
	emy.prefixedProperty
	initialized at: onload.
	An array where all plugins should be
	*/
	plugin: [],

	/*
	emy.ready
	initialized at: onload.
	Determines if Emy has been initialized yet (if the init() function has been already loaded)
	*/
	ready : false,

    /* version
	useful for plugins, support & debug
	*/
	v : function() {
        return 1.1;
    },
	/*
	emy.init
	Loads private function init(), automatically loaded by onload event, but you can manually load it
	This change is really helpful when using Emy inside for a PhoneGap/Cordova app with deviceready event for ex
	*/
	 init : function() {
		init();
	 },
	/*
	emy.showView(view[, backwards=false])
	`showView()` should probably be an internal function, outside callers should
	call `showViewById()` instead. `showView()` does NOT set the busy flag because
	it is already set by the public-facing functions.

	`view` is the html element to show. If `backwards` is set to `true`, it will
	display a right-to-left animation instead of the default left-to-right.

	If the currently-displayed view is passed, emy will do nothing. `showView()`
	is used for both panel-type views and dialog-type views (dialogs float on top
	of the panels, have a cancel button and do not participate in sliding
	animations). Panel-type views receive blur/focus events and load/unload events,
	but dialog-type views only receive blur/focus events.
	*/
		showView: function(view, backwards) {
			if (view) {
				if (view == currentView) {
					emy.busy = false; //  Don't do anything, just clear the busy flag and exit
					return;
				}

				if (currentDialog) {
					currentDialog.removeAttribute("selected");
					emy.sendEvent("emy-blur", currentDialog); // EVENT: BLUR
					currentDialog = null;
				}

				/*
			events:
			Dialogs receive a `focus` event when they are shown and a `blur` event
			when hidden. Currently they don't receive any `load` or `unload` events.
			*/
				if (emy.hasClass(view, "dialog")) {
					emy.sendEvent("emy-focus", view); // EVENT: FOCUS
					showDialog(view);
				}
				/*
			events:
			Panels receive `focus` and `blur` events and also receive a `load` event
			and (only when going backwards away from a panel) an `unload` event.
			*/
				else {
					//			  emy.$('header.toolbar').style.display='';
					emy.sendEvent("emy-load", view); // EVENT: LOAD
					var fromView = currentView;
					emy.sendEvent("emy-blur", currentView); // EVENT: BLUR
					currentView = view;
					emy.sendEvent("emy-focus", view); // EVENT: FOCUS

					if (fromView) {
						setTimeout(slideViews, 0, fromView, view, backwards);
					} else {
						updateView(view, fromView);
					}
				}
			}
		},

		gotoView: function(view, replace) {
			var node, nodeId;

			if (view instanceof HTMLElement) {
				node = view;
				nodeId = node.id;
			} else {
				nodeId = view;
				node = emy.$('#'+nodeId);
			}

			if (!node) emy.log("gotoView: node is null");

			if (!emy.busy) {
				emy.busy = true;
				var index = navStack.indexOf(nodeId);
				var backwards = index != -1;
				if (backwards) {
					// we're going back, remove history from index on
					// remember - viewId will be added again in updateView
					navStack.splice(index);
				} else if (replace) navStack.pop();

				emy.showView(node, backwards);
				return false;
			} else {
				return true;
			}
		},

		/*
	emy.showViewById(viewId)
	Looks up the view element by the id and checks the internal history to
	determine if the view is on the stack -- if so, it will call `showView()` with
	`backwards` set to `true`, reversing the direction of the animation.
	*/
		showViewById: function(viewId) {
			emy.gotoView(viewId, false);
		},

		/*
	emy.goBack()
	Navigates to the previous view in the history stack.
	*/
		goBack: function(viewId) {
			if (viewId) {
				var a = navStack.length - (navStack.indexOf(viewId) + 1);
				navStack = navStack.slice(0, (navStack.length - a));
				if(window.history.length > navStackStartIndex)
					window.history.go(-a);
				else
					emy.showView(viewId, true);
			} else {
				if(window.history.length - (navStackStartIndex-1) == 1) {
					// history.length can't be equal to 1 when you ask to go back so it means
					// the cache manifest is goofing browser's history stack. In this case, we use
					// showView to navigate between views
					// navStackStartIndex is important here since window.history can be more than 1
					// if user comes from another page
					emy.showView(navStack.pop(), true);
				} else {
					navStack.pop();
					window.history.go(-1);
				}
			}
			return navStack;
		},

		/*
	method: emy.showViewByHref(href, args, method, replace, cb)
	Outside callers should use this version to do an ajax load programmatically
	from your webapp.

	`href` is a URL string, `method` is the HTTP method (defaults to `GET`),
	`args` is an Object of key-value pairs that are used to generate the querystring,
	`replace` is an existing element that either is the panel or is a child of the
	panel that the incoming HTML will replace (if not supplied, emy will append
	the incoming HTML to the `body`), and `cb` is a user-supplied callback function.
	*/
		showViewByHref: function(url, args, method, replace, callback , errorCallback) {

            function successCb(ajaxResult) {
                var frag = document.createElement("div");
                frag.innerHTML = ajaxResult;
                // EVENT beforeInsert->body
                if (replace) {
                    replaceElementWithFrag(replace, frag);
                    emy.busy = false;
                } else {
                    emy.insertViews(frag);
                }

                if (callback) {
                    emy.log('showViewByHref error callback');
                    setTimeout(callback, 1000, true);
                }
			}

            function errorCb() {
                emy.log('showViewByHref error callback');
                emy.busy = false;
                errorCallback();
            }

            if (!emy.busy) {
				emy.busy = true;
				emy.ajax(url, args, method, successCb, errorCb);
			} else {
				callback(); // We didn't get the "lock", we may need to unselect something
			}
		},

		/*
	method: emy.ajax(url, parameters, method, callback, errorCallback)
	Handles ajax requests and also fires a `setTimeout()` call
	to abort the request if it takes longer than 30 seconds. See `showViewByHref()`
	above for a description of the various arguments (`url` is the same as `href`).
	*/
		ajax: function(url, args, method, callback, errorCallback) {

            var xhr = new XMLHttpRequest();
            if(!xhr)
                xhr = new ActiveXObject("Msxml2.XMLHTTP");
            if(!xhr)
                xhr = new ActiveXObject("Microsoft.XMLHTTP");

			method = method ? method.toUpperCase() : "GET";
			if (args && method == "GET") {
				url = url + "?" + ajaxParam(args);
			}
			xhr.open(method, url, true);
            if (callback) {
                // only if a callback function is set
                xhr.onreadystatechange = function() {
                    if(xhr.readyState==4 && !xhr.aborted)
                    {
                        // once call is done
                        if(xhr.status==200 && xhr.responseText) {
                            // if call status is ok
                            xhr.aborted = true;
                            callback(xhr.responseText);
                        } else if(xhr.status==0) {
                            // if ajax call failed
                            ajaxTimeout();
                        }
                    }
                };
			}
			var data = null;
			if (args && method != "GET") {
				xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				data = ajaxParam(args);
			}
			for (var header in emy.httpHeaders) {
				xhr.setRequestHeader(header, emy.httpHeaders[header]);
			}
			xhr.send(data);
            // make the ajax call act as a failure is call is too long
            // too long = 30sec by default
            // but this can be change in global variables on top of the file
			xhr.requestTimer = setTimeout(ajaxTimeout, ajaxTimeoutVal);
			return xhr;

			function ajaxTimeout() {
                xhr.aborted = true;
                if(errorCallback)
                    errorCallback(xhr);
            }
		},

		/*
	method: emy.insertViews(frag)
	If an AJAX call (`showViewByHref()`) is made without supplying a `replace`
	element, `insertViews()` is called to insert the newly-created element
	fragment into the view DOM. Each child-node of the HTML fragment is a panel
	and if any of them are already in the DOM, they will be replaced by the
	incoming elements.
	go parameter can be set to false if you don't want Emy to navigate to this newly inserted screen
	*/
		insertViews: function(frag, go) {

			var newfrag;
			if(typeof frag==='string') {
				// if the frag parameter is a HTML string
				// it is added to a DIV element to loop on childNodes
				newfrag = document.createElement('div');
				newfrag.innerHTML = frag;
			} else if(frag.nodeName.toLowerCase()=='section' && frag.getAttribute('data-title')) {
				// if the frag parameter is a section view element
				// it is added to a DIV element for code consistency
				newfrag = document.createElement('div');
				newfrag.appendChild(frag);
			} else
				newfrag = frag;

			var nodes = newfrag.childNodes, targetView;
			// set go to false if you dont want to navigate to the inserted view
			go = (go==false)?false:true;

			emy.sendEvent("emy-beforeinsert", document.body, {
				fragment: newfrag
			});

			for (var i = 0, inb = nodes.length; i < inb; i++) {
				var child = nodes[i];
				if (child && child.nodeName.toLowerCase()=='section') {
					if (!child.id) child.id = "__" + (new Date().getTime()) + "__";

					var clone = emy.$('#' + child.id);
					var docNode;
					if (clone) {
						clone.parentNode.replaceChild(child, clone);
						docNode = emy.$(child.id);
					} else
						docNode = document.body.appendChild(child);

					emy.sendEvent("emy-afterinsert", document.body, {
						insertedNode: docNode
					});
					fitHeight();

					// First child becomes selected view/view by default unless
					// selected="true" is set
					// BUG: selected="true" results in a visually incorrect transition
					if (child.getAttribute("selected") == "true" || !targetView) targetView = child;
					--i;
				}
			}

			emy.sendEvent("emy-afterinsertend", document.body, {
				fragment: newfrag
			})

			if (targetView && go) {
				setTimeout(function() { emy.showView(targetView); }, 1);
			}
		},

		/*
	method: emy.getSelectedView()
	Returns the panel element that is currently being viewed. Each panel must be a
	direct child of the `body` element. A panel is set as the selected panel by
	setting the `selected` attribute to `true`.
	*/

		getSelectedView: function() {
			for (var child = document.body.firstChild; child; child = child.nextSibling) {
				if (child.nodeType == 1 && child.getAttribute("selected") == "true") return child;
			}
		},

		/*
	emy.getAllViews()
	Returns all views, aka direct body childnodes with both `id` and `data-title` attributes
	*/
		getAllViews: function() {
			var views=[];
			for (var child = document.body.firstChild; child; child = child.nextSibling) {
				if (child.nodeType == 1 && child.getAttribute("data-title"))
					views.push(child);
			}
			return (views.length>0)?views:false;
		},

		/*
	emy.isNativeUrl(href)
	Determines whether the supplied URL string launches a native app (maps, YouTube, phone, email, etc).
    If so, emy does not attempt to load or slide to a view and do let the phone handling the click natively.
	*/
		isNativeUrl: function(url) {
			var urlPatterns = [
                new RegExp("^javascript:"),
                new RegExp("^mailto:"),
                new RegExp("^tel:"),
                new RegExp("^sms:"),
                new RegExp("^callto:"),
                new RegExp("^skype:"),
                new RegExp("^video:"),
                new RegExp("^music:"),
                new RegExp("^maps:"),
                new RegExp("^feed:"),
                new RegExp("^(http|https):\/\/itunes.apple.com\/"),
                new RegExp("^(http|https):\/\/youtube.com\/watch\\?v="),
                new RegExp("^(http|https):\/\/youtube.com\/v\/"),
                new RegExp("^http:\/\/youtu.be\/"),
                new RegExp("^(http|https):\/\/maps.google.com\/?"),
                new RegExp("^(http|https):\/\/www.google.com\/maps\/?"),
                new RegExp("^(http|https):\/\/facebook.com\/"),
                new RegExp("^(http|https):\/\/twitter.com\/")
            ];
			var out = false;
			for (var i = 0; i < urlPatterns.length; i++) {
				if (url.match(urlPatterns[i])) out = true;
			}
			return out;
		},

		/*
	emy.hasClass(el, name)
	Returns true/false if the given element `el` has the class `name`.
	*/
		hasClass: function(el, name) {
			if(el)
				return ((el.className).indexOf(name) > -1)?true:false;
			else
				return false;
		},

		/*
	emy.addClass(el, name)
	Add the given class `name` to element `el`
	*/
		addClass: function(el, name) {
			if (!emy.hasClass(el, name))
				el.className += " "+name;
		},

		/*
	emy.changeClass(el, name)
	change the given class `name` to `newname` to element `el`
	*/
		changeClass: function(el, name, newname) {
			if (emy.hasClass(el, name)) el.className = el.className.replace(new RegExp('(\\s|^)' + name + '(\\s|$)'), ' '+newname+' ');
		},

		/*
	Basic selector : if you need a complete Jquery-style, you might consider Zepto.js
	Use emy.$('#myElement') to select an element with id attribute equals to myElement
	Use emy.$('.myClass') to select all elements having myClass in their class value
	Use emy.$('a') to select all a elements (links)
	Use emy.$('a.myClass') to select all a elements having myClass in their class value (links)
	*/
		$: function(a) {
			if(document.querySelectorAll) {
				var res = document.querySelectorAll(a);
				return (res.length==0)?null:((res.length==1 && '#'+res[0].id==a)?res[0]:res);
			} else {
				// this should soon be removed, since all modern browsers supports querySelectorAll now
				if (a.substr(0, 1) == '#') return (document.getElementById(a.substr(1))) ? document.getElementById(a.substr(1)) : null;
				else if (a.substr(0, 1) == '.') return (document.getElementsByClassName(a.substr(1))) ? document.getElementsByClassName(a.substr(1)) : null;
				else if (a.indexOf('.') > -1) {
					var c = document.getElementsByTagName(a.split('.')[0]),
						d = a.split('.')[1];
					for (var i = 0, inb = c.length; i < inb; i++) {
						if (c[i].className.indexOf(d) > -1) {
							return c[i];
							exit;
						}
					}
				} else if (a) return (document.getElementsByTagName(a)) ? document.getElementsByTagName(a) : null;
			}
		},

		/*
		Performs a console.log if browser supports it
		Keep logging to false by default, console.log can create huge performance issues, specially in Cordova
		*/
		log: function() {
			if ((window.console != undefined) && emy.logging==true) console.log.apply(console, arguments);
		},

		findParent : function(node, localName) {
			while (node && (node.nodeType != 1 || node.localName.toLowerCase() != localName))
			node = node.parentNode;
			return node;
		},

		sendEvent : function(type, node, props) {
			if (node) {
				var event = document.createEvent("UIEvent");
				event.initEvent(type, false, false); // no bubble, no cancel
				if (props) {
					for (i in props) {
						event[i] = props[i];
					}
				}
				node.dispatchEvent(event);
			}
			emy.log('event sent: ' + type);
		}
	};

	// *************************************************************************************************

/*
load: On Load event
*/
	addEventListener("load", init, false);

/*
init: On Load
On load, emy will determine which view to display primarily based on
the anchor part of the URL (everything after `#_`) and secondarily based on the
top-level (child of the `body`) element with the `selected` attribute set to
`true`. If these both exist, emy.showView() will be called twice, but the
anchor-based load will win because it is done second.
*/

	function init()
	{
		if(!emy.ready)
		{
			emy.changeClass(emy.$('html')[0],'no-js','js');

			emy.ready=true;
			var a = document.createElement('div').style;
			prefix = (a.WebkitTransform == '') ? 'webkit' : (a.MozTransform == '') ? 'moz' : (a.msTransform == '') ? 'ms' : (a.transform == '') ? 'none' : null;
			if (emy.transitionMode == 'css') emy.transitionMode = (prefix) ? 'css' : 'js';
			if (prefix == 'webkit') {
				emy.prefixedProperty['transform'] = 'webkitTransform';
				emy.prefixedProperty['transformDuration'] = 'webkitTransformDuration';
				emy.prefixedProperty['transitionEnd'] = 'webkitTransitionEnd';
				emy.prefixedProperty['animationStart'] = 'webkitAnimationStart';
				emy.prefixedProperty['animationDuration'] = 'webkitAnimationDuration';
				emy.prefixedProperty['animationEnd'] = 'webkitAnimationEnd';
			} else if (prefix == 'moz') {
				emy.prefixedProperty['transform'] = 'MozTransform';
				emy.prefixedProperty['transformDuration'] = 'MozTransformDuration';
				emy.prefixedProperty['transitionEnd'] = 'transitionend';
				emy.prefixedProperty['animationStart'] = 'animationstart';
				emy.prefixedProperty['animationDuration'] = 'animationduration';
				emy.prefixedProperty['animationEnd'] = 'animationend';
			} else if (prefix == 'ms') {
				emy.prefixedProperty['transform'] = 'msTransform';
				emy.prefixedProperty['transformDuration'] = 'msTransformDuration';
				emy.prefixedProperty['transitionEnd'] = 'transitionend';
				emy.prefixedProperty['animationStart'] = 'MSAnimationStart';
				emy.prefixedProperty['animationDuration'] = 'MSAnimationDuration';
				emy.prefixedProperty['animationEnd'] = 'MSAnimationEnd';
			} else if (prefix == 'none') {
				emy.prefixedProperty['transform'] = 'msTransform';
				emy.prefixedProperty['transformDuration'] = 'msTransformDuration';
				emy.prefixedProperty['transitionEnd'] = 'transitionend';
				emy.prefixedProperty['animationStart'] = 'MSAnimationStart';
				emy.prefixedProperty['animationDuration'] = 'MSAnimationDuration';
				emy.prefixedProperty['animationEnd'] = 'MSAnimationEnd';
			}

			navStackStartIndex = history.length;

			var defaultView = emy.getSelectedView();

			// get requested view ID as a hash value in the URL
			var locViewId = location.hash.substr(hashPrefix.length);
			var locView = (locViewId)?emy.$('#' + locViewId):null;

			if (defaultView) {
				// get the default view node, aka got a "selected" attribute
				emy.originalView = defaultView;
				emy.showView(defaultView);
			} else {
				// no default view set, so we take the first view
				var views = emy.getAllViews();
				emy.originalView = (views.length>0)?views[0]:false;
			}

			// navigate to the requested view if different than the default one
			if (locView && (locView != defaultView))
				emy.showView(locView);

			//set resize handler onorientationchange if available, otherwise use onresize
			if (typeof window.onorientationchange == "object") window.onorientationchange = resizeHandler;
			else window.onresize = resizeHandler;

			// use modern onhashchange listener for navigation, fallback to listener if not supported
			if ("onhashchange" in window) window.onhashchange = checkLocation;
			else checkTimer = setInterval(checkLocation, 300);

			setTimeout(function() {
				preloadImages();
				checkLocation();
				fitHeight();
				emy.sendEvent('emy-ready', document);
			}, 1);
		}
	}

	/*
	click: Link Click Handling
	emy captures all clicks on `a` elements and goes through a series of checks to
	determine what to do:

	1. If the link has a `href="#..."`, emy will navigate to the panel ID specified
	   after the # (no underscore).
	2. If the link's ID is `backButton`, emy will navigate to the previous screen
	   (see `emy.goBack()`).
	3. If the link has a `type="submit"`, emy will find the parent `form` element,
	   gather up all the input values and submit the form via AJAX (see
	   `emy.showViewByHref()`).
	4. If the link has a `type="cancel"`, emy will cancel the parent `form` element
	   dialog.
	5. If the link has a `target="_replace"`, emy will do an AJAX call based on the
	   href of the link and replace the panel that the link is in with the contents
	   of the AJAX response.
	6. If the link is a native URL (see `emy.isNativeURL()`), emy will do nothing.
	7. If the link has a `target="_webapp"`, emy will perform a normal link,
	   navigating completely away from the emy app and pointing the browser to the
	   linked-to webapp instead.
	8. If there is no `target` attribute, emy will perform a normal (non-replace)
	   AJAX slide (see `emy.showViewByHref()`).
	*/
	addEventListener("click", function(event) { /* an iOS6 bug stops the timer when a new tab fires an alert - this fixes the issue */
		if (!emy.busy && !("onhashchange" in window)) checkTimer = setInterval(checkLocation, 300);

		var link = emy.findParent(event.target, "a");
		if (link) {
			function unselect() {
				link.removeAttribute("selected");
			}
			if (link.href && link.hash && link.hash != "#" && !link.target) {
				followAnchor(link);
			} else if (link == emy.$("#backButton")) {
				link.setAttribute("selected", "true");
				setTimeout(function() {
					unselect();
				}, 300);
				emy.goBack();
			} else if (link.target == "_replace") {
				followAjax(link, link);
			} else if (emy.isNativeUrl(link.href)) {
				return;
			} else if (link.target == "_webapp") {
				location.href = link.href;
			} else if (!link.target && link.getAttribute('href')) {
				followAjax(link, null);
			} else if (link.getAttribute('href') == '') {

			} else if (link.href == '' || !link.href) {
				return;
			} else {
				return;
			}
			event.preventDefault();
		}

		var button = emy.findParent(event.srcElement, "button");
		if (button && button.getAttribute("type") == "cancel") {
			var view = emy.findParent(event.srcElement, "section");
			if(emy.hasClass(view,'dialog'))
				cancelDialog(view);
		} else if(button && button.getAttribute("type") != "submit") {
			event.preventDefault();
		}
	}, true);

	/*
submit: Form submit handling
All forms without target="_self" will use emy's Ajax from submission.
*/
	addEventListener("submit", function(event) {
		var form = event.target;
		if (form.target != "_self") {
			event.preventDefault();
			submitForm(form);
		}
	}, true);

	function followAnchor(link) {
		link.setAttribute("selected", "true");
		var busy = emy.gotoView(link.hash.substr(1), false);
		// clear selected immmediately if busy, else wait for transition to finish
		setTimeout(function() {
			link.removeAttribute("selected");
		}, busy ? 0 : 500);
	}

	function followAjax(link, replaceLink) {
		link.setAttribute("selected", "progress");
		emy.showViewByHref(link.href, null, "GET", replaceLink, function() {
			link.removeAttribute("selected");
		}, function error() {
            link.removeAttribute("selected");
        });
	}

	function resizeHandler() {
		fitHeight();
	}

	function checkLocation() {
		if (location.hash != currentHash) {
			var viewId = location.hash.substr(hashPrefix.length);
			if ((viewId == "") && originalView) // Workaround for WebKit Bug #63777
			viewId = originalView.id;
			emy.showViewById(viewId);
		}
	}

	function showDialog(view) {
		scrollTo(0, 1);
		currentDialog = view;
		view.setAttribute("selected", "true");
		if (emy.transitionMode == 'css') setTimeout(function() {
			emy.addClass(view, 'show');
		}, 1); // adding the classname one second later otherwise CSS3 transitions does not apply
		else emy.addClass(view, 'show');
		showForm(view);
		view.onclick = function(e) {
			if (e.srcElement) {
				if (emy.hasClass(e.srcElement, 'dialog')) cancelDialog(e.srcElement);
			}
		};
	}

	function cancelDialog(form) {
		if (emy.transitionMode == 'css') {
			setTimeout(function() {
				emy.changeClass(form, 'show', '');
			}, 1);
			form.addEventListener(emy.prefixedProperty['transitionEnd'], hideForm, false);
		} else {
			emy.changeClass(form, 'show', '');
			hideForm(form);
		}
	}

	function showForm(form) { /* Noop click-handler on the view works around problem where our main click handler doesn't get called in Mobile Safari */
		form.addEventListener("click", function(event) {}, true);
		emy.busy = false;
	}

	function hideForm(form) {
		if (undefined == form.srcElement) {
			form.removeAttribute("selected");
		}
		else {
			var toolbarElement = emy.$('#'+form.srcElement.id+' .toolbar')[0];
			toolbarElement.style.display = '';
			form.srcElement.removeAttribute("selected");
			form.srcElement.removeEventListener(emy.prefixedProperty['transitionEnd'], hideForm, false);
		}
	}

	function updateView(view, fromView) {
		if (!view.id) view.id = "__" + (new Date().getTime()) + "__";

		currentHash = hashPrefix + view.id;
		if (!fromView) { // If fromView is null, this is the initial load and we want to replace a hash of "" with "#_home" or whatever the initial view id is.
			//		location.replace(location.protocol + "//" + location.hostname + location.port + location.pathname + newHash + location.search);
			location.replace(currentHash);
		} else { // Otherwise, we want to generate a new history entry
			//		location.hash = currentHash;
			location.assign(currentHash);
		}

		navStack.push(view.id);

		var viewTitle = emy.$('#viewTitle');
		if (view.getAttribute('data-title')) {
			viewTitle.innerHTML = view.getAttribute('data-title');
		}

		if (view.localName.toLowerCase() == "form") showForm(view);

		var backButton = emy.$("#backButton");
		if (backButton) {
			var prevView = emy.$('#' + navStack[navStack.length - 2]);
			if (prevView && !view.getAttribute("data-hidebackbutton")) {
				backButton.style.display = "block";
				backButton.innerHTML = (prevView.getAttribute('data-title')) ? prevView.getAttribute('data-title') : "Back";
				//			var bbClass = prevView.getAttribute("bbclass");
				//			backButton.className = (bbClass) ? 'button ' + bbClass : 'button';
			} else backButton.style.display = "none";
		}
		emy.busy = false;
	}

	function canDoSlideAnim() {
		return (emy.transitionMode != 'none') && (emy.prefixedProperty != null);
	}
	/*
events:
Both panels involved in a slide animation receive `beforetransition` and
`aftertransition` events. The panel being navigated from receives event
parameters `{ out :true }`, the panel being navigated to receives `{ out: false }`.
*/
	function slideViews(fromView, toView, backwards) {
		scrollTo(0, 1);
		clearInterval(checkTimer);

		emy.sendEvent("emy-beforetransition", fromView, {
			out: true
		});
		emy.sendEvent("emy-beforetransition", toView, {
			out: false
		});

		if (emy.transitionMode == 'css') slideCSS(fromView, toView, backwards, slideDone);
		else if (emy.transitionMode == 'js') slideJS(fromView, toView, backwards, slideDone);
		else noSlide(fromView, toView, slideDone);

		function slideDone() {
			if (!emy.hasClass(toView, "dialog")) {
				fromView.removeAttribute("selected");
				fromView.removeAttribute('emy-transition');
				toView.removeAttribute('emy-transition');
			}

			if (!("onhashchange" in window)) checkTimer = setInterval(checkLocation, 300);

			setTimeout(updateView, 0, toView, fromView);
			fromView.removeEventListener(emy.prefixedProperty['animationEnd'], slideDone, false);

			if (fromView.getAttribute('data-onexit')) eval(fromView.getAttribute('data-onexit'));
			if (toView.getAttribute('data-onshow')) eval(toView.getAttribute('data-onshow'));

			emy.sendEvent("emy-aftertransition", fromView, {
				out: true
			});
			emy.sendEvent("emy-aftertransition", toView, {
				out: false
			});

			if (backwards) emy.sendEvent("emy-unload", fromView); // EVENT: UNLOAD
		}
	}

	function slideJS(fromView, toView, backwards, cb) {
		toView.style.left = "100%";
		scrollTo(0, 1);
		toView.setAttribute("selected", "true");
		var percent = 100;

		function slide() {
			percent -= slideStep;
			fromView.style.left = (backwards ? (100 - percent) : (percent - 100)) + "%";
			toView.style.left = (backwards ? -percent : percent) + "%";
			if (percent <= 0) {
				clearInterval(slideInterval);
				percent = 0;
				cb();
			}
		}
		var slideInterval = setInterval(slide, slideSpeed);
		slide();
	}

	function slideCSS(fromView, toView, backwards, cb) {
		toView.style.visibility = 'hidden';
		if (!backwards) var transName = (toView.getAttribute('custom-transition')) ? toView.getAttribute('custom-transition') : 'slide';
		else var transName = (fromView.getAttribute('custom-transition')) ? fromView.getAttribute('custom-transition') : 'slide';

		var fromViewTransition = backwards ? (transName + 'backout') : (transName + 'out');
		var toViewTransition = backwards ? (transName + 'backin') : (transName + 'in');
		toView.setAttribute("selected", "true");

		function startTrans() {
			fromView.setAttribute('emy-transition', fromViewTransition);
			toView.setAttribute('emy-transition', toViewTransition);
			toView.style.visibility = '';
		}
		fromView.addEventListener(emy.prefixedProperty['animationEnd'], cb, false);
		setTimeout(startTrans, 1);
	}

	function noSlide(fromView, toView, cb) {
		setTimeout(function() {
			fromView.removeAttribute("selected");
			toView.setAttribute("selected", "true");
			cb();
		}, 1);
	}

	function submitForm(form) {
		emy.addClass(form, "progress");
		emy.sendEvent("emy-beforeformsubmit", document.body, {
			form: form
		})
		emy.showViewByHref(form.getAttribute('action'), encodeForm(form), form.hasAttribute('method') ? form.getAttribute('method') : 'GET', null, function() {
			emy.changeClass(form, 'progress', '');
			cancelDialog(form);
			emy.sendEvent("emy-afterformsubmit", document.body, {
				form: form
			})
		});
	}

    /*
	Stripped-down, simplified object-only version of a jQuery function that
	converts an object of keys/values into a URL-encoded querystring.
	*/
	function ajaxParam(o) {
			var s = [];
			// Serialize the key/values
			for (var key in o) {
				var value = o[key];
				if (value != null && typeof(value) == "object" && typeof(value.length) == "number") {
					for (var i = 0; i < value.length; i++) {
						s[s.length] = encodeURIComponent(key) + '=' + encodeURIComponent(value[i]);
					}
				} else s[s.length] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
			}
			// Return the resulting serialization
			return s.join("&").replace(/%20/g, "+");
    }

	function encodeForm(form) {
		function encode(inputs) {
			for (var i = 0; i < inputs.length; ++i) {
				if (inputs[i].name) {
					var input = inputs[i];
					if (input.getAttribute("type") == "checkbox" && !input.checked || input.getAttribute("type") == "radio" && !input.checked || input.disabled) {
						continue;
					}
					if (input.getAttribute("type") == "submit") {
						if (input.getAttribute("submitvalue")) { // Was marked, this is the value to send, but clear it for next time
							input.removeAttribute("submitvalue");
						} else { // not marked, don't send value -- continue
							continue;
						}
					}
					var value = args[input.name];
					if (value === undefined) { // If parm is 'empty' just set it
						args[input.name] = input.value;
					} else if (value instanceof Array) { // If parm is array, add to it
						value.push(input.value);
					} else { // If parm is scalar, change to array and add to it
						args[input.name] = [value, input.value];
					}
				}
			}
		}

		var args = {};
		encode(form.getElementsByTagName("input"));
		encode(form.getElementsByTagName("textarea"));
		encode(form.getElementsByTagName("select"));
		encode(form.getElementsByTagName("button"));
		return args;
	}

	function replaceElementWithFrag(replace, frag) {
		var parent = replace.parentNode;
		var parentTarget = parent.parentNode;
		parentTarget.removeChild(parent);

		emy.sendEvent("beforereplace", document.body, {
			fragment: frag
		});

        var docNode;
		while (frag.firstChild) {
			docNode = parentTarget.appendChild(frag.firstChild);
			emy.sendEvent("afterreplace", document.body, {
				insertedNode: docNode
			});
		}
		emy.sendEvent("afterreplaceend", document.body, {
			fragment: frag
		});
	}

	function preloadImages() {
		var preloader = document.createElement("div");
		preloader.id = "preloader";
		document.body.appendChild(preloader);
	}

	function fitHeight(a) {
		// this script could use a cleanup...
		// to avoid innerHeight with scrollTo(0,0) address hide trick, on afterInserted for ex
		window.scrollTo(0, 0);
		if (screenHeight == 0) var wih = screenHeight;
		else var wih = window.innerHeight;

		// we put this in a timeout to be sure the scrollTo(0,0) is done
		setTimeout(function() {
			var heightVal;
			var toolbarHeight = emy.$('.toolbar')[0].clientHeight;
			var sc = emy.$('body')[0].childNodes;
			if (sc) {
				for (var i = 1; i <= (sc.length - 1); i++) {
					if ((sc[i].id != '') && (sc[i].id != undefined) && (typeof sc[i] === 'object') && !emy.hasClass(sc[i], 'toolbar')) {
						heightVal = wih; /* default value */
						if (window.navigator.standalone === false) { // for iphone
							if (navigator.userAgent.toLowerCase().search('ipad') > -1) heightVal = (wih);
							else if (emy.hasClass(sc[i], 'dialog')) heightVal = (wih + 60);
							else if (screenHeight < 2) heightVal = (wih + 60);
						} else {
							if (navigator.userAgent.toLowerCase().search('android') > -1 && screenHeight == 0) heightVal = (wih + 50);
							else if (navigator.userAgent.toLowerCase().search('firefox') > -1) heightVal = (wih - toolbarHeight);
						}
						sc[i].style.minHeight = heightVal + 'px';
					}
				}
			}
			if (screenHeight == 0) {
				screenHeight = 1;
				fitHeight();
			} else if (screenHeight == 1) {
				screenHeight = heightVal;
			}
			setTimeout(function() {
				window.scrollTo(0, 1)
			}, 1);

		}, 1);

	}

})();


text:
using System;
using System.Diagnostics;
using System.IO;

using MapSurfer;
using MapSurfer.Logging;

namespace MapSurfer.Styling.Formats.CartoCSS.Export
{
	/// <summary>
	/// Description of MagnacartoExporter.
	/// </summary>
	internal class MagnacartoExporter : ICartoExporter
	{
		private string _format;
		private static string _exePath;

		static MagnacartoExporter()
		{
			_exePath = Path.Combine(Path.Combine(Path.GetDirectoryName(MapSurfer.Utilities.MSNEnvironment.GetAssemblyLocation(typeof(MagnacartoExporter).Assembly)), EnvironmentEx.GetNativePath()), "magnacarto.exe");
		}

    public static bool IsReady()
    {
      return File.Exists(_exePath);
    }

		public MagnacartoExporter(string format)
		{
			_format = format != null ? format.ToLower(): "mapnik2";
		}

		public void Export(string projectPath, string outPath, Logger logger)
		{
			if (string.IsNullOrEmpty(Path.GetExtension(outPath)))
		  {
				string ext = null;
				switch(_format)
				{
					case "mapnik2":
					case "mapnik3":
						ext = ".xml";
						break;
					case "mapserver":
						ext = ".map";
						break;
				}

				if (!string.IsNullOrEmpty(ext))
					outPath = Path.ChangeExtension(outPath, ext);
			}

			ProcessStartInfo startInfo = new ProcessStartInfo(_exePath);
			startInfo.Arguments = string.Format("-builder {0} -mml {1} -out {2}", _format, projectPath, outPath);
			startInfo.UseShellExecute = false;
			startInfo.CreateNoWindow = true;
			startInfo.WindowStyle = ProcessWindowStyle.Hidden;
      startInfo.RedirectStandardOutput = true;
      startInfo.RedirectStandardError = true;
      //   Process.Start(startInfo);

      Process p = new Process();
      p.StartInfo = startInfo;
      p.StartInfo.RedirectStandardOutput = true;
      p.Start();

      string err = p.StandardError.ReadToEnd();

      if (!string.IsNullOrEmpty(err))
      {
        LogFactory.WriteLogEntry(logger, new Exception(err));
        throw new Exception(err);
      }
		}
	}
}

redpajama_set_name: RedPajamaGithub


text:
package io.agrest.cayenne.cayenne.main;

import io.agrest.cayenne.cayenne.main.auto._E29;

public class E29 extends _E29 {

    private static final long serialVersionUID = 1L;

}


text:
//
//  DTVerticalBarChartController.h
//  DTiseChart
//
//  Created by Jo Shin on 2017/1/13.
//  Copyright © 2017年 studio.joshin. All rights reserved.
//

#import "DTChartController.h"
#import "DTBarChart.h"

@interface DTVerticalBarChartController : DTChartController

@property (nonatomic) DTBarChartStyle barChartStyle;
/**
 * 柱状体宽度,以单元格为单位,默认1个单元格
 */
@property (nonatomic) CGFloat barWidth;

/**
 * 柱状图触摸回调
 * @return 触摸提示内容
 * @note param dataIndex 第几组数据
 * @note param barIndex  数据里的第几根柱状体
 */
@property(nonatomic) NSString *(^barChartControllerTouchBlock)(NSUInteger dataIndex, NSUInteger barIndex);

@end


text:
"""
Tumblr OAuth1 backend, docs at:
    http://psa.matiasaguirre.net/docs/backends/tumblr.html
"""
from social.utils import first
from social.backends.oauth import BaseOAuth1

class TumblrOAuth(BaseOAuth1):
    name = 'tumblr'
    ID_KEY = 'username'
    AUTHORIZATION_URL = 'http://www.tumblr.com/oauth/authorize'
    REQUEST_TOKEN_URL = 'http://www.tumblr.com/oauth/request_token'
    REQUEST_TOKEN_METHOD = 'POST'
    ACCESS_TOKEN_URL = 'http://www.tumblr.com/oauth/access_token'

    def get_user_details(self, response):
        # http://www.tumblr.com/docs/en/api/v2#user-methods
        user_info = response['response']['user']
        data = {'username': user_info['name']}
        blog = first(lambda blog: blog['primary'], user_info['blogs'])
        if blog:
            data['fullname'] = blog['title']
        return data

    def user_data(self, access_token):
        return self.get_json('http://api.tumblr.com/v2/user/info',
                             auth=self.oauth_auth(access_token))


text:
namespace blink {

class Base : public GarbageCollected<Base> {
public:
 virtual void Trace(Visitor*) const;
};

class Mixin1 : public GarbageCollectedMixin {
public:
 void Trace(Visitor*) const;
};

class Mixin2 : public GarbageCollectedMixin {
public:
 void Trace(Visitor*) const;
};

class Derived1 : public Base, public Mixin1 {
    // Requires Trace method.
};

class Derived2 : public Base, public Mixin1, public Mixin2 {
    void Trace(Visitor*) const override;
};

}

#endif


text:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AssignMessageSetLogMessage">
    <DisplayName>AssignMessage.SetLogMessage</DisplayName>
    <Properties/>
    <AssignVariable>
        <Name>flow.log.message</Name>
        <Value>Message sent from shared flow.</Value>
    </AssignVariable>
    <AssignVariable>
        <Name>flow.log.severity</Name>
        <Value>INFO</Value>
    </AssignVariable>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>


text:
"""
Author: Shankun Lin
Date: Nov, 2015
Description:
	This file contains the constant codes being used throughout the
	dispensing routine as well as the ERROR dictionary that maps error
	codes to string descriptions.

***THE VALUES IN THIS CODE SHOULD NOT BE DIRECTLY MODIFY!***

"""

#Communication protocol code. These code should reflect the code
#in the trinket code, located in Pro_Trinket_Code/dispenser_unit.ino
KNOCK_KNOCK = 200
WHOS_THERE = 210
DISPENSER_COMPLETE = 220
DISPENSER_RESET = 222
DISPENSER_ERROR = 234

#Dispensing Result Codes:
#Code 0 to 50 reserved for number of pills NOT dispensed
#Code 0 = successfully dispensed everything
NO_ONE_HOME = 404404
WRONG_ANSWER = -999999
LOCATION_UNKNOWN = -555555
UNEXPECTED_ERROR_CODE = -666666
CONNECTION_LOST = -1010101

#dictionary to map error code to error message
ERROR = {
	NO_ONE_HOME : "Expected container did not respond to knock request.",
	WRONG_ANSWER : "Container returned the wrong response.",
	LOCATION_UNKNOWN : "There was an unknown error with the container.",
	UNEXPECTED_ERROR_CODE : "The thread communicating with the container threw an unexpected error.",
	CONNECTION_LOST : "Connection lost with container during operation"
}


text:
package org.apereo.cas.adaptors.generic.remote;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apereo.cas.authentication.AbstractCredential;

/**
 * Represents a remote address as CAS credential.
 * @author Scott Battaglia
 * @since 3.2.1
 *
 */
public class RemoteAddressCredential extends AbstractCredential {

    /** Serialization version marker. */
    private static final long serialVersionUID = -3638145328441211073L;

    private final String remoteAddress;

    /**
     * Instantiates a new remote address credential.
     *
     * @param remoteAddress the remote address
     */
    @JsonCreator
    public RemoteAddressCredential(@JsonProperty("remoteAddress") final String remoteAddress) {
        this.remoteAddress = remoteAddress;
    }

    public String getRemoteAddress() {
        return this.remoteAddress;
    }

    @JsonIgnore
    @Override
    public String getId() {
        return this.remoteAddress;
    }
}


text:
package id.bizdir.ui.activity;

import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;

import id.bizdir.R;
import id.bizdir.ui.adapter.ChooseLocationStatePagerAdapter;
import id.bizdir.ui.widget.SlidingTabLayout;
import id.bizdir.util.Helpers;

public class ChooseLocationActivity extends AppCompatActivity {

    //private City city;
    //private Province province;
    private ViewPager mPager;
    private ChooseLocationStatePagerAdapter chooseLocationStatePagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_choose_location);
        Helpers.setLockOrientation(ChooseLocationActivity.this);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        mPager = (ViewPager) findViewById(R.id.pager);
        chooseLocationStatePagerAdapter = new ChooseLocationStatePagerAdapter(getSupportFragmentManager());
        mPager.setAdapter(chooseLocationStatePagerAdapter);
        setSlidingTabLayout();
        setSupportActionBar(toolbar);
        //getDataFromPreviousPage();
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            Helpers.setMainActionBarNoShadow(actionBar);
        }

    }

    private void setSlidingTabLayout() {
        SlidingTabLayout slidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
        slidingTabLayout.setCustomTabView(R.layout.tab_indicator, android.R.id.text1);
        slidingTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.material_drawer_accent));
        slidingTabLayout.setDistributeEvenly(true);
        slidingTabLayout.setViewPager(mPager);
        slidingTabLayout.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                Helpers.hideKeyboard(ChooseLocationActivity.this);
            }
        });
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    }

    /*
    private void getDataFromPreviousPage() {
        Intent intent = this.getIntent();
        int objectIndex = intent.getIntExtra(Const.OBJECT_INDEX, 0);
        if (objectIndex != 0) {
            CityHelper cityHelper = new CityHelper();
            city = cityHelper.getCity(objectIndex);
            ProvinceHelper provinceHelper = new ProvinceHelper();
            province = provinceHelper.getProvince(city.getProvinceId());
        }
    }*/

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                onBackPressed();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }

}


text:
$(document).ready(function() {
    var short_address = getParameterByName('sa');
    console.log(short_address);
})


text:
> Why? While I've been working on [Under-the-hood-ReactJS](https://github.com/Bogdan-Lyashenko/Under-the-hood-ReactJS) I spent enormous amount of time on creating schemes. Each change in code or flowchart affects all entire scheme instantly, forcing you to move and align 'broken pieces'. Just repeated manual work...

### For multiple files support (and other cool features to simplify codebase learning and documentation) checkout [Codecrumbs project](https://codecrumbs.io/) I am building right now.

Imagine a library which takes any JS code and generate SVG flowchart from it, works on client and server. Allows you easily adjust styles scheme for your context or demonstrate your code logic from different abstractions levels. Highlighting, destructing whole blocks, custom modifiers for your needs etc.

# js2flowchart.js [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Generate%20beautiful%20flowcharts%20from%20JavaScript&url=https://github.com/Bogdan-Lyashenko/js-code-to-svg-flowchart&via=bliashenko&hashtags=javascript,flowchart,svg)
[![MIT Licence](https://badges.frapsoft.com/os/mit/mit.svg?v=103)](https://opensource.org/licenses/mit-license.php) [![npm version](https://badge.fury.io/js/js2flowchart.svg)](https://badge.fury.io/js/js2flowchart)

js2flowchart is a tool for generating beautiful SVG flowcharts™ from JavaScript code.

To get started install package from NPM
> yarn add js2flowchart

or try it right away at [codepen sample](https://codepen.io/Bogdan-Lyashenko/pen/XzmzNv), or play with the demo below.

## [Demo](https://bogdan-lyashenko.github.io/js-code-to-svg-flowchart/docs/live-editor/index.html)
Check out live [**code editor**](https://bogdan-lyashenko.github.io/js-code-to-svg-flowchart/docs/live-editor/index.html), paste your code and **download SVG file** of flowchart!

[](https://bogdan-lyashenko.github.io/js-code-to-svg-flowchart/docs/live-editor/index.html)

### What does js2flowchart do?
js2flowchart takes your JS code and returns SVG flowchart, works on client/server, support ES6.

Main features:
- **defined abstractions levels** to render only import/exports, classes/function names, function dependencies to learn/explain the code step by step.
- **custom abstractions levels support** create your own one
- **presentation generator** to generate list of SVGs in order to different abstractions levels
- **defined flow tree modifiers** to map well-known APIs like i.e. [].map, [].forEach, [].filter to Loop structure on scheme etc.
- **destruction modifier** to replace block of code with one shape on scheme
- **custom flow tree modifiers support** create your own one
- **flow tree ignore filter** to omit some code nodes completely i.e. log lines
- **focus node or entire code logic branch** to highlight important section on scheme
- **blur node or entire code logic branch** to hide less-important stuff
- **defined styles themes supports** choose one you like
- **custom themes support** create your own one which fits your context colors better
- **custom colors and styles support** provides handy API to change specific styles without boilerplate

Use cases:
- **explain/document** your code by flowcharts
- **learn** other's code by visual understanding
- **create** flowcharts for any process simply described by valid JS syntax

### CLI
You can simply generate SVG files from your local JS files using CLI tool.
Install js2flowchart globally by running:
> yarn global add js2flowchart

Or in a project by running:
> yarn add js2flowchart --dev

Open terminal and navigate to needed directory with JS file you want to visualize (e.g. './my-project/main.js').
Run the command (if you installed it globally)
```cli
js2flowchart main.js
```
Or add this to your _package.json_ file:
```json
{
  "scripts": {
    "js2flowchart": "js2flowchart"
  }
}
```
And run (with either npm or yarn):
```cli
yarn run js2flowchart main.js
```

After script is executed observe log ```SVG file was created: ./js2flowchart/main.js.svg```. SVG file will be placed in new directory '/js2flowchart' near your JS file.

### API and examples
You can find sources for examples explained below in [docs directory](/docs).

**In examples only** js2flowchart library included explicitly, by ```<script>``` tag and accessed by global variable from ```window``` **to make it simpler to run for you without boilerplate**. But feel free to use it through ES6 modules as well, when you have Babel&Webpack local server configured.
```javascript
/**
* Access APIs when js2flowchart injected into HTML page
*/
const {convertCodeToFlowTree, convertFlowTreeToSvg} = window.js2flowchart;

/**
* or import from node_modules
*/
import {convertCodeToFlowTree, convertFlowTreeToSvg} from 'js2flowchart';//way 1
import * as js2flowchart from 'js2flowchart';//way 2
```

#### Default

Here is a code function for classic case Binary search

```javascript
const code = `function indexSearch(list, element) {
    let currentIndex,
        currentElement,
        minIndex = 0,
        maxIndex = list.length - 1;

    while (minIndex <= maxIndex) {
        currentIndex = Math.floor(minIndex + maxIndex) / 2;
        currentElement = list[currentIndex];

        if (currentElement === element) {
            return currentIndex;
        }

        if (currentElement < element) {
            minIndex = currentIndex + 1;
        }

        if (currentElement > element) {
            maxIndex = currentIndex - 1;
        }
    }

    return -1;
}`;
```
let's convert it to SVG(the simplest way):
```javascript
const svg = js2flowchart.convertCodeToSvg(code);
```
Result:

![](/docs/examples/default/flowchart-image.png)

If you need to modify default behavior you can split ```js2flowchart.convertCodeToSvg``` into two building block:
- flow tree building
- shapes printing

```javascript
const {convertCodeToFlowTree, convertFlowTreeToSvg} = js2flowchart;

const flowTree = convertCodeToFlowTree(code);

const svg = convertFlowTreeToSvg(flowTree);//XML string
```

or when you need full control create main instances manually:
```javascript
const {createFlowTreeBuilder, createSVGRender} = js2flowchart;

const flowTreeBuilder = createFlowTreeBuilder(),
    svgRender = createSVGRender();

const flowTree = flowTreeBuilder.build(code),
    shapesTree = svgRender.buildShapesTree(flowTree);

const svg = shapesTree.print();//XML string
```

See the example running [here](https://bogdan-lyashenko.github.io/js-code-to-svg-flowchart/docs/examples/default/index.html) or check out complete source code [of it](/docs/examples/default/index.html).

#### Defined abstraction level

What is called 'abstraction level'? Let's say you would like to omit some details, like, e.g. for given module you are interested only in what the module ```exports```, or, what classes it contains.
There is a list of defined levels you can do that with. Accessible by ```ABSTRACTION_LEVELS``` interface.
- ```FUNCTION```
- ```FUNCTION_DEPENDENCIES```
- ```CLASS```
- ```IMPORT```
- ```EXPORT```

Let's take example with module imports&exports. Below is the code of some ```print-util.js```.
```javascript
const code = `
    import {format, trim} from 'formattier';
    import {log} from 'logger';

    const data = [];

    export default print = (list) => {
        list.forEach(i => {
            console.log(i);
        });
    }

    export const formatString = (str) => formatter(str);
    export const MAX_STR_LENGTH = 15;
`;
```
we need to instantiate ```flowTreeBuilder``` and assign abstraction level on it.

```javascript
    const {
        ABSTRACTION_LEVELS,  createFlowTreeBuilder, convertFlowTreeToSvg
    } = js2flowchart;

    const flowTreeBuilder = createFlowTreeBuilder();

    //you can pass one level or multiple levels
    flowTreeBuilder.setAbstractionLevel([
        ABSTRACTION_LEVELS.IMPORT,
        ABSTRACTION_LEVELS.EXPORT
    ]);

    const flowTree = flowTreeBuilder.build(code);
    const svg = convertFlowTreeToSvg(flowTree);
```

Result:

![](/docs/examples/defined-abstraction-level/flowchart-image.png)

See the example running [here](https://bogdan-lyashenko.github.io/js-code-to-svg-flowchart/docs/examples/defined-abstraction-level/index.html) or check out complete source code [of it](/docs/examples/defined-abstraction-level/index.html).

**Custom abstraction level (label:advanced)**

What if you want your 'own' level? To the same API endpoint ```flowTreeBuilder.setAbstractionLevel``` you can provide configuration object.
For example, have a look at the code of [function dependencies](/src/builder/abstraction-levels/functionDependencies.js) abstraction level.
Check out the export of it
```javascript
export const getFunctionDependenciesLevel = () => ({
    defined: [TOKEN_TYPES.CALL_EXPRESSION],
    custom: [
        getCustomFunctionDeclaration(),
        getCustomAssignmentExpression(),
        getCustomVariableDeclarator()
    ]
});
```
It's a format of data you need to pass:

```javascript
flowTreeBuilder.setAbstractionLevel({
    defined: [TOKEN_TYPES.CALL_EXPRESSION],
    custom: [
        getCustomFunctionDeclaration(),
        getCustomAssignmentExpression(),
        getCustomVariableDeclarator()
    ]
})

````
And what is behind of ```getCustomAssignmentExpression``` for example?
There is a token parsing config.
```javascript
{
    type: 'TokenType', /*see types in TOKEN_TYPES map*/
    getName: (path) => {/*extract name from token*/},
    ignore: (path) => {/*return true if want to omit entry*/}
    body: true /* should it contain nested blocks? */
}
```
Check out more token parsing configs from [source code (entryDefinitionsMap.js)](/src/builder/entryDefinitionsMap.js)

#### Presentation generator

When you learn other's code it's good to go through it by different abstractions levels.
Take a look what module exports, which function and classes contains etc.
There is a sub-module ```createPresentationGenerator``` to generate list of SVGs in order to different abstractions levels.

Let's take the next code for example:
```javascript
const code = `
    import {format} from './util/string';

    function formatName(name) {
        if (!name) return 'no-name';

        return format(name);
    }

    class Animal {
        constructor(breed) {
            this.breed = breed;
        }

        getBreed() {
            return this.breed;
        }

        setName(name) {
            if (this.nameExist()) {
                return;
            }

            this.name = name;
        }
    }

    class Man extends Animal {
       sayName() {
            console.log('name', this.name);
       }
    }

    export default Man;
`;
```
pass it to
```javascript
const { createPresentationGenerator } = js2flowchart;

const presentationGenerator = createPresentationGenerator(code);
const slides = presentationGenerator.buildSlides();//array of SVGs
```

Result (one of slides):

![](/docs/examples/one-module-presentation/flowchart-image.png)

You can switch slides by prev-next buttons.

[](https://bogdan-lyashenko.github.io/js-code-to-svg-flowchart/docs/examples/one-module-presentation/index.html)

See the example running [here](https://bogdan-lyashenko.github.io/js-code-to-svg-flowchart/docs/examples/one-module-presentation/index.html) or check out complete source code [of it](/docs/examples/one-module-presentation/index.html).

#### Defined colors theme

You can apply different themes to your ```svgRender``` instance. Simply calling e.g. ```svgRender.applyLightTheme()``` to apply light scheme.

There are next predefined color schemes:
- DEFAULT: ```applyDefaultTheme```
- BLACK_AND_WHITE: ```applyBlackAndWhiteTheme```
- BLURRED: ```applyBlurredTheme```
- LIGHT: ```applyLightTheme```

Let's simple code sample of ```switch``` statement from Mozzila Web Docs.
```javascript
const code = `
    function switchSampleFromMDN() {
        const foo = 0;

        switch (foo) {
          case -1:
            console.log('negative 1');
            break;
          case 0:
            console.log(0);
          case 1:
            console.log(1);
            return 1;
          default:
            console.log('default');
        }
    }
`;
```
and apply scheme to render.

```javascript
const {createSVGRender, convertCodeToFlowTree} = js2flowchart;

const flowTree = convertCodeToFlowTree(code),
    svgRender = createSVGRender();

//applying another theme for render
svgRender.applyLightTheme();

const svg = svgRender.buildShapesTree(flowTree).print();
```

Result:

![](/docs/examples/defined-color-theme/flowchart-image.png)

See the example running [here](https://bogdan-lyashenko.github.io/js-code-to-svg-flowchart/docs/examples/defined-color-theme/index.html) or check out complete source code [of it](/docs/examples/defined-color-theme/index.html).

#### Custom colors theme

Well, but what if you would like to have different colors? Sure, below is an example of Light theme colors but created manually.
```javascript
svgRender.applyColorBasedTheme({
   strokeColor: '#555',
   defaultFillColor: '#fff',
   textColor: '#333',
   arrowFillColor: '#444',
   rectangleFillColor: '#bbdefb',
   rectangleDotFillColor: '#ede7f6',
   functionFillColor: '#c8e6c9',
   rootCircleFillColor: '#fff9c4',
   loopFillColor: '#d1c4e9',
   conditionFillColor: '#e1bee7',
   destructedNodeFillColor: '#ffecb3',
   classFillColor: '#b2dfdb',
   debuggerFillColor: '#ffcdd2',
   exportFillColor: '#b3e5fc',
   throwFillColor: '#ffccbc',
   tryFillColor: '#FFE082',
   objectFillColor: '#d1c4e9',
   callFillColor: '#dcedc8',
   debugModeFillColor: '#666'
});
```

#### Custom styles

What if you need different styles, not only colors? Here it's ```svgRender.applyTheme({})```. You can apply styles above of current theme, overriding only that behaviour you need.
Let's take an example with Return statement.
```javascript
svgRender.applyTheme({
    common: {
        maxNameLength: 100
    },
    ReturnStatement: {
        fillColor: 'red',
        roundBorder: 10
    }
});
```

Please check definition of [```DefaultBaseTheme```](/src/render/svg/appearance/themes/DefaultBaseTheme.js) to see all possible shapes names and properties.

#### Shapes tree editor

There is sub-module for modifying shapes tree called 'ShapesTreeEditor'.
It provides next interfaces:
- ```findShape```
- ```applyShapeStyles```
- ```blur```
- ```focus```
- ```blurShapeBranch```
- ```focusShapeBranch```
- ```print```

Let's learn its usage on an example as well. Below is the code with some 'devMode hooks'.
```javascript
const code = `
const doStuff = (stuff) => {
    if (stuff) {
        if (devFlag) {
            log('perf start');
            doRecursion();
            log('perf end');

            return;
        }

        doRecursion();
        end();
    } else {
        throw new Error('No stuff!');
    }

    return null;
};
`;
```

what we want here is 'blur' that dev-branch condition, because it interferes code readability.

```javascript
const {
    convertCodeToFlowTree,
    createSVGRender,
    createShapesTreeEditor
} = js2flowchart;

const flowTree = convertCodeToFlowTree(code),
    svgRender = createSVGRender();
    shapesTree = svgRender.buildShapesTree(flowTree);

const shapesTreeEditor = createShapesTreeEditor(shapesTree);

shapesTreeEditor.blurShapeBranch(
    (shape) => shape.getName() === '(devFlag)'
);

const svg = shapesTreeEditor.print();
```

Result:

![](/docs/examples/blur-shape-branch/flowchart-image.png)

See the example running [here](https://bogdan-lyashenko.github.io/js-code-to-svg-flowchart/docs/examples/blur-shape-branch/index.html) or check out complete source code [of it](/docs/examples/blur-shape-branch/index.html).

#### Flow tree modifier

There is sub-module for modifying flow tree called 'FlowTreeModifier' which allows you to apply modifiers defined separately to your existing flow tree.
Let's take simple use-case: you want to change 'names'(titles) on tree-nodes, here it is, just define modifier for that. But, actually, there are some behaviours where we already know we need to modify flow tree.

Let's have a look at ES5 Array iterators, like ```forEach```, ```map``` and so on. We all know they behave like a loop, right? Let's treat them as a 'loop' then.

```javascript
const code = `
function print(list) {
    const newList = list.map(i => {
        return i + 1;
    });

    newList.forEach(i => {
        console.debug('iteration start');
        console.log(i);
        console.debug('iteration end');
    });
}
`;
```

```javascript
const {
    createFlowTreeBuilder,
    createFlowTreeModifier,
    convertFlowTreeToSvg,
    MODIFIER_PRESETS
} = js2flowchart;

const flowTreeBuilder = createFlowTreeBuilder(),
    flowTree = flowTreeBuilder.build(code);

const flowTreeModifier = createFlowTreeModifier();

flowTreeModifier.setModifier(MODIFIER_PRESETS.es5ArrayIterators);
flowTreeModifier.applyToFlowTree(flowTree);

const svg = convertFlowTreeToSvg(flowTree);
```

Result:

As you can see, both iterators handled as a loop. And ```forEach``` omit function-callback as well.

![](/docs/examples/defined-modifier/flowchart-image.png)

See the example running [here](https://bogdan-lyashenko.github.io/js-code-to-svg-flowchart/docs/examples/defined-modifier/index.html) or check out complete source code [of it](/docs/examples/defined-modifier/index.html).

There is one more defined modifier for node destruction. It takes a block you specified and destruct it to on block.
```javascript
flowTreeModifier.destructNodeTree((node) => node.name.indexOf('.forEach') !== -1, 'and print list...');
```
What if you want **custom modifier**?
```javascript
flowTreeModifier.registerNewModifier((node)=> node.name.includes('hello'), {
    name: 'world'
});
```

#### Debug rendering
What if you want to select a shape for applying special styles and want some unique id selector? Just pass ```debug``` flag to ```print```;

```javascript
    const {
        convertCodeToFlowTree,
        createSVGRender,
        createShapesTreeEditor
    } = js2flowchart;

    const svgRender = createSVGRender();

    const shapesTree = svgRender.buildShapesTree(convertCodeToFlowTree(code));
    const shapesTreeEditor = createShapesTreeEditor(shapesTree);

    shapesTreeEditor.applyShapeStyles(
        shape => shape.getNodePathId() === 'NODE-ID:|THIS.NAME=N|TCCP-', {
        fillColor: '#90caf9'
    });

    const svg = shapesTreeEditor.print({debug: true});
```

Result:

![](/docs/examples/debug-rendering/flowchart-image.png)

See the example running [here](https://bogdan-lyashenko.github.io/js-code-to-svg-flowchart/docs/examples/debug-rendering/index.html) or check out complete source code [of it](/docs/examples/debug-rendering/index.html).

### Tools
Thanks to @LucasBadico we got Visual Studio extension. Check [it out](https://marketplace.visualstudio.com/items?itemName=lucasbadico.code-flowchart).
![](https://user-images.githubusercontent.com/16516889/32584821-824634c8-c4e1-11e7-9e83-4c97561f01e0.png)

### Under the hood
Main stages:
- get AST from code, [Babylon](https://github.com/babel/babel/tree/master/packages/babylon) parser is used (develops by Babel team)
- convert AST to FlowTree, remove and combing nodes ([FlowTreeBuilder](src/builder/FlowTreeBuilder.js))
  - apply modifiers ([FlowTreeModifier](src/builder/FlowTreeModifier.js))
- create SVG objects based on FlowTree ([SVGRender](src/render/svg/SVGRender.js))
  - apply ShapesTreeEditor
  - apply theme ([see themes](src/render/svg/appearance/themes))
- print SVG objects to XML string

### Things planned TODO
- Full CLI support
- JSX support
- Flow support
- TypeScript support
- Multi files support
- Webstorm plugin
- Chrome extension for dev-tools

### Contributing
Feel free to file an issue if it doesn't work for your code sample (please add 'breaking' lines of code if it's possible to identify) or for any other things you think can be improved.
Highly appreciated if you can join and help with any TODOs above. Thanks.

### License
MIT license

### Version
First shoot! Take it easy (check version number above in NPM badge)


text:
import React from 'react';
import {connect} from 'react-redux';
import {getTeamRulerItems} from '../../selectors/workflow';
import {List} from '../../dumb/common/List';
import {EDITOR} from '../../styles';
import {EditableWorkflowTeamRulerItem} from "./EditableWorkflowTeamRulerItem";
import {getEditMode} from "../../selectors/ui";
import {ReadonlyWorkflowTeamRulerItem} from "./ReadonlyWorkflowTeamRulerItem";

const mapStateToProps = (state) => {
    const editMode = getEditMode(state);
    const items = getTeamRulerItems(state).map(
        item => (
            editMode
                ? <EditableWorkflowTeamRulerItem
                    id={item.id}
                    size={item.size}
                />
                : <ReadonlyWorkflowTeamRulerItem
                    id={item.id}
                    size={item.size}
                />
        )
    );

    return {
        vertical: true,
        inner: true,
        border: EDITOR.BORDER,
        items: items,
    };
};

export const WorkflowTeamRuler = connect(mapStateToProps)(List);


text:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.penmanship.example">

  <application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Holo.Light">

    <activity
      android:name="com.penmanship.example.MainActivity">

      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>

    </activity>

  </application>

</manifest>


text:
{-# LANGUAGE QuasiQuotes     #-}
{-# LANGUAGE TemplateHaskell #-}

module Command.Update (Options, parserInfo, run) where

import           Strings

import           Data.String.Interpolate
import qualified Dupes.Actions           as Actions
import qualified Dupes.Repository        as Repository
import           Logging
import           Options.Applicative
import           Pipes
import qualified Pipes.Prelude           as P
import           Pipes.Safe
import           System.Directory

data Options = Options { }

parserInfo :: ParserInfo Options
parserInfo = info parser (progDesc "Update index to match working directory")

parser :: Parser Options
parser = pure Options

run :: Options -> IO ()
run _ = getCurrentDirectory >>= Repository.findFrom >>= maybe errorNoIndex update
  where
    errorNoIndex = exitErrorM $(logTag)
                     [i|Neither path nor any of its parents have a #{appName} index|]
    update path = runSafeT . runEffect $ Actions.update path >-> printUpdateEntry
    printUpdateEntry = P.print


text:
/**
 * package-info
 *
 * @author apete
 */
package org.algo.finance;


text:
package org.cyclops.integrateddynamics.core.network;

import org.cyclops.integrateddynamics.api.ingredient.IIngredientPositionsIndex;
import org.cyclops.integrateddynamics.api.part.PartPos;

import javax.annotation.Nonnull;
import java.util.Iterator;

/**
 * An ingredient channel that exploits the network's index.
 *
 * @param <T> The instance type.
 * @param <M> The matching condition parameter.
 */
public class IngredientChannelIndexed<T, M> extends IngredientChannelAdapter<T, M> {

    private final IIngredientPositionsIndex<T, M> index;

    public IngredientChannelIndexed(PositionedAddonsNetworkIngredients<T, M> network, int channel,
                                    IIngredientPositionsIndex<T, M> index) {
        super(network, channel);
        this.index = index;
    }

    public IIngredientPositionsIndex<T, M> getIndex() {
        return index;
    }

    @Override
    protected Iterator<PartPos> getNonFullPositions() {
        this.scheduleObservation();
        return this.getNetwork().getPositions(getChannel()).iterator();
    }

    @Override
    protected Iterator<PartPos> getAllPositions() {
        this.scheduleObservation();
        return this.getNetwork().getPositions(getChannel()).iterator();
    }

    @Override
    protected Iterator<PartPos> getNonEmptyPositions() {
        this.scheduleObservation();
        return this.index.getNonEmptyPositions();
    }

    @Override
    protected Iterator<PartPos> getMatchingPositions(@Nonnull T prototype, M matchFlags) {
        this.scheduleObservation();
        return this.index.getPositions(prototype, matchFlags);
    }

    @Override
    public Iterator<T> iterator() {
        this.scheduleObservation();
        return this.index.iterator();
    }

    @Override
    public Iterator<T> iterator(@Nonnull T prototype, M matchFlags) {
        this.scheduleObservation();
        return this.index.iterator(prototype, matchFlags);
    }

}


text:
{-# LANGUAGE OverloadedStrings #-}
module Main (main) where

import qualified Control.Concurrent as Concurrent
import qualified Control.Monad.State.Strict as MTL
import qualified Data.Aeson as JSON
import qualified Data.Bits as Bits
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Char as Char
import qualified Data.Map as Map
import qualified Data.UUID as UUID
import qualified Data.Word as Word
import qualified Database.SQLite.Simple as SQL
import qualified Database.SQLite.Simple.FromRow as SQL
import qualified Network.HTTP as HTTP
import qualified Network.Socket as Net
import qualified System.Environment as IO
import qualified System.Exit as IO

import Control.Applicative
import Control.Exception.Lifted
import Control.Monad
import Data.Dynamic
import Data.List
import Data.Maybe

data Configuration =
  Configuration {
      configurationDatabasePath :: FilePath,
      configurationPort :: Int,
      configurationAccessLogPath :: Maybe FilePath,
      configurationErrorLogPath :: Maybe FilePath,
      configurationUser :: Maybe String,
      configurationGroup :: Maybe String
    }
instance JSON.FromJSON Configuration where
  parseJSON (JSON.Object value) =
    Configuration <$> value JSON..: "database"
                  <*> value JSON..: "port"
                  <*> value JSON..:? "access-log"
                  <*> value JSON..:? "error-log"
                  <*> value JSON..:? "user"
                  <*> value JSON..:? "group"
  parseJSON _ = mzero

data Request =
  Request {
      requestMethod :: String,
      requestPath :: [String],
      requestHasTrailingSlash :: Bool,
      requestQueryVariables :: Map.Map String String,
      requestContent :: RequestContent
    }
  deriving (Show)

data RequestContent
  = NoRequestContent
  | JSONRequestContent BS.ByteString
  | UnknownRequestContent
  deriving (Show)

data RequestPattern =
  RequestPattern {
      requestPatternMethod :: String,
      requestPatternPath :: [PathComponentPattern],
      requestPatternTrailingSlash :: Bool,
      requestPatternQueryVariables :: Map.Map String (String -> Maybe Dynamic),
      requestPatternContent :: RequestContentPattern
    }

data PathComponentPattern
  = ConstantPathComponentPattern String
  | VariablePathComponentPattern String (String -> Maybe Dynamic)

data RequestContentPattern
  = NoRequestContentPattern
  | JSONRequestContentPattern String

getServerParameters :: Configuration -> IO HTTP.HTTPServerParameters
getServerParameters configuration = do
  let port =
        (Bits.shiftL ((fromIntegral $ configurationPort configuration)
                      Bits..&. 0xFF) 8)
        Bits..|. (Bits.shiftR (fromIntegral $ configurationPort configuration)
                              8 Bits..&. 0xFF)
      address = Net.SockAddrInet (Net.PortNum port) 0x0100007F
  return $
    HTTP.HTTPServerParameters {
        HTTP.serverParametersAccessLogPath =
          configurationAccessLogPath configuration,
        HTTP.serverParametersErrorLogPath =
          configurationErrorLogPath configuration,
        HTTP.serverParametersDaemonize =
          True,
        HTTP.serverParametersUserToChangeTo =
          configurationUser configuration,
        HTTP.serverParametersGroupToChangeTo =
          configurationGroup configuration,
        HTTP.serverParametersForkPrimitive =
          Concurrent.forkIO,
        HTTP.serverParametersListenSockets =
          [HTTP.HTTPListenSocketParameters {
                HTTP.listenSocketParametersAddress = address,
                HTTP.listenSocketParametersSecure = False
             }]
      }

main :: IO ()
main = do
  arguments <- IO.getArgs
  case arguments of
    [configurationFilePath] -> do
      configurationJSON <- BS.readFile configurationFilePath
      case JSON.eitherDecode' (LBS.fromChunks [configurationJSON]) of
        Left message -> do
          putStrLn message
          IO.exitFailure
        Right configuration -> do
          serverParameters <- getServerParameters configuration
          HTTP.acceptLoop serverParameters $ do
            request <- getRequest
            dispatchRequest request allHandlers
    _ -> do
      putStrLn $ "Usage: qmic configuration.json"
      IO.exitFailure

simpleRequestPattern :: String -> RequestPattern
simpleRequestPattern method =
  RequestPattern {
      requestPatternMethod = method,
      requestPatternPath = [],
      requestPatternTrailingSlash = True,
      requestPatternQueryVariables = Map.empty,
      requestPatternContent = NoRequestContentPattern
    }

expectConstantPathComponent :: String -> RequestPattern -> RequestPattern
expectConstantPathComponent component oldPattern =
  let oldPath = requestPatternPath oldPattern
      newPath = oldPath ++ [ConstantPathComponentPattern component]
  in oldPattern {
         requestPatternPath = newPath
       }

expectVariablePathComponent
  :: String -> (String -> Maybe Dynamic) -> RequestPattern -> RequestPattern
expectVariablePathComponent name parser oldPattern =
  let oldPath = requestPatternPath oldPattern
      newPath = oldPath ++ [VariablePathComponentPattern name parser]
  in oldPattern {
         requestPatternPath = newPath
       }

expectTrailingSlash :: RequestPattern -> RequestPattern
expectTrailingSlash oldPattern =
  oldPattern {
      requestPatternTrailingSlash = True
    }

expectNoTrailingSlash :: RequestPattern -> RequestPattern
expectNoTrailingSlash oldPattern =
  oldPattern {
      requestPatternTrailingSlash = False
    }

expectQueryVariable
  :: String -> (String -> Maybe Dynamic) -> RequestPattern -> RequestPattern
expectQueryVariable name parser oldPattern =
  let oldMap = requestPatternQueryVariables oldPattern
      newMap = Map.insert name parser oldMap
  in oldPattern {
         requestPatternQueryVariables = newMap
       }

expectNoContent :: RequestPattern -> RequestPattern
expectNoContent oldPattern =
  oldPattern {
      requestPatternContent = NoRequestContentPattern
    }

expectJSONContent
  :: String
  -> RequestPattern
  -> RequestPattern
expectJSONContent name oldPattern =
  oldPattern {
      requestPatternContent = JSONRequestContentPattern name
    }

getRequest :: (HTTP.MonadHTTP m) => m Request
getRequest = do
  method <- HTTP.getRequestMethod
  uri <- HTTP.getRequestURI
  let (pathString, query) = break (\c -> c == '?') uri
      pathString' = fromMaybe pathString $ stripPrefix "/" pathString
      (pathString'', hasTrailingSlash) =
        if isSuffixOf "/" pathString'
          then (take (length pathString' - 1) pathString', True)
          else (pathString', False)
      path = wordsLoop [] pathString''
      wordsLoop soFar string =
        case break (\c -> c == '/') string of
          (_, "") -> soFar ++ [string]
          (next, rest) -> wordsLoop (soFar ++ [next]) (tail rest)
      query' = fromMaybe query $ stripPrefix "?" query
      queryVariables = decodeFormVariables query'
  return Request {
             requestMethod = method,
             requestPath = path,
             requestHasTrailingSlash = hasTrailingSlash,
             requestQueryVariables = queryVariables,
             requestContent = NoRequestContent
           }

dispatchRequest
  :: (HTTP.MonadHTTP m)
  => Request
  -> [(RequestPattern, Map.Map String Dynamic -> m ())]
  -> m ()
dispatchRequest request [] = do
  HTTP.httpLog $ "No request-pattern matched."
  HTTP.setResponseStatus 400
dispatchRequest request ((pattern, handler) : rest) = do
  case matchRequest request pattern of
    Right variables -> handler variables
    Left maybeMessage -> do
      case maybeMessage of
        Just message -> HTTP.httpLog message
        Nothing -> return ()
      dispatchRequest request rest

matchRequest
  :: Request
  -> RequestPattern
  -> Either (Maybe String) (Map.Map String Dynamic)
matchRequest request pattern = do
  if requestMethod request /= requestPatternMethod pattern
    then Left Nothing
    else do
      uriVariables <-
        foldM (\soFar (requestComponent, patternComponent) -> do
                 case patternComponent of
                   ConstantPathComponentPattern expectedComponent -> do
                     if requestComponent == expectedComponent
                       then return soFar
                       else Left Nothing
                   VariablePathComponentPattern name parser -> do
                     case parser requestComponent of
                       Nothing -> Left Nothing
                       Just value -> return $ Map.insert name value soFar)
             Map.empty
             (zip (requestPath request) (requestPatternPath pattern))
      if requestHasTrailingSlash request /= requestPatternTrailingSlash pattern
        then Left Nothing
        else do
          let patternQueryVariables = requestPatternQueryVariables pattern
              (expectedQueryVariables, unexpectedQueryVariables) =
                partition (\(key, value) ->
                              case Map.lookup key patternQueryVariables of
                                Just _ -> True
                                Nothing -> False)
                          (Map.toList $ requestQueryVariables request)
          case map fst unexpectedQueryVariables of
            [key] ->
              Left $ Just $ "Unexpected query variable " ++ key ++ "."
            keys@(_ : _) ->
              Left $ Just $ "Unexpected query variables "
                            ++ englishList keys
                            ++ "."
            [] -> do
              let queryVariables = Map.fromList expectedQueryVariables
                  missingQueryVariables =
                    Map.difference patternQueryVariables queryVariables
              case map fst $ Map.toList missingQueryVariables of
                [key] ->
                  Left $ Just $ "Missing query variable " ++ key ++ "."
                keys@(_ : _) ->
                  Left $ Just $ "Missing query variables "
                                ++ englishList keys
                                ++ "."
                [] -> do
                  let visit key value = do
                        case Map.lookup key patternQueryVariables of
                          Nothing -> Left Nothing
                          Just parser ->
                            case parser value of
                              Nothing -> Left Nothing
                              Just result -> return (key, result)
                  queryVariables <-
                    mapM (\(key, value) -> visit key value)
                         (Map.toList queryVariables)
                    >>= return . Map.fromList
                  return $ foldl' Map.union
                                  Map.empty
                                  [uriVariables, queryVariables]

englishList :: [String] -> String
englishList [] = "(none)"
englishList [item] = item
englishList [item1, item2] = item1 ++ " and " ++ item2
englishList items = intercalate ", " (init items ++ ["and " ++ last items])

decodeFormVariables :: String -> Map.Map String String
decodeFormVariables input =
  let result =
        Map.fromList
         $ concatMap (\word ->
                        let (key, value) = break (\c -> c == '=') word
                        in case (unescape "" key,
                                 unescape "" $ drop 1 value) of
                             (Just key, Just value) -> [(key, value)]
                             _ -> [])
                     $ filter (\word -> length word > 0)
                              $ wordsLoop [] input
      wordsLoop soFar string =
        case break (\c -> c == '&') string of
          (_, "") -> soFar ++ [string]
          (next, rest) -> wordsLoop (soFar ++ [next]) (tail rest)
      unescape soFar [] = Just soFar
      unescape soFar ('%' : high : low : rest) =
        let hexValue c =
              if Char.isDigit c
                then Just $ Char.ord c - Char.ord '0'
                else if Char.isAlpha c
                       then let value = Char.ord (Char.toLower c)
                                        - Char.ord 'a' + 10
                            in if value < 16
                                 then Just value
                                 else Nothing
                       else Nothing
        in case (hexValue high, hexValue low) of
             (Just high, Just low) | high < 8 ->
               unescape (soFar ++ [Char.chr (high * 16 + low)]) rest
             _ -> Nothing
      unescape soFar ('%' : _) = Nothing
      unescape soFar ('+' : rest) = unescape (soFar ++ " ") rest
      unescape soFar (c : rest) = unescape (soFar ++ [c]) rest
  in result

allHandlers
  :: (HTTP.MonadHTTP m)
  => [(RequestPattern, Map.Map String Dynamic -> m ())]
allHandlers =
  let infixl 1 $>>
      infixl 2 >>>
      ($>>) :: RequestPattern
            -> (RequestPattern -> RequestPattern)
            -> RequestPattern
      ($>>) = flip ($)
      (>>>) :: (RequestPattern -> RequestPattern)
            -> (RequestPattern -> RequestPattern)
            -> (RequestPattern -> RequestPattern)
      (>>>) = flip (.)
      prefix :: RequestPattern -> RequestPattern
      prefix = expectConstantPathComponent "qmic"
      apiPrefix :: RequestPattern -> RequestPattern
      apiPrefix = prefix >>> expectConstantPathComponent "api"
      frontEndPrefix :: RequestPattern -> RequestPattern
      frontEndPrefix = prefix
  in [(simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "login"
       >>> expectNoTrailingSlash
       >>> expectJSONContent "json",
       loginAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "logout"
       >>> expectNoTrailingSlash
       >>> expectJSONContent "json",
       logoutAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "confirm"
       >>> expectNoTrailingSlash
       >>> expectJSONContent "json",
       confirmAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "account"
       >>> expectConstantPathComponent "email"
       >>> expectTrailingSlash
       >>> expectJSONContent "json",
       accountEmailListAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "account"
       >>> expectConstantPathComponent "email"
       >>> expectVariablePathComponent "email" emailParser
       >>> expectNoTrailingSlash
       >>> expectJSONContent "json",
       accountEmailAddAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "account"
       >>> expectConstantPathComponent "email"
       >>> expectVariablePathComponent "email" emailParser
       >>> expectConstantPathComponent "delete"
       >>> expectNoTrailingSlash
       >>> expectJSONContent "json",
       accountEmailDeleteAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "account"
       >>> expectConstantPathComponent "email"
       >>> expectVariablePathComponent "email" emailParser
       >>> expectConstantPathComponent "primary"
       >>> expectNoTrailingSlash
       >>> expectJSONContent "json",
       accountEmailSetPrimaryAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "player"
       >>> expectTrailingSlash
       >>> expectJSONContent "json",
       playerListAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "rule"
       >>> expectTrailingSlash
       >>> expectJSONContent "json",
       ruleListAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "proposal"
       >>> expectTrailingSlash
       >>> expectJSONContent "json",
       proposalListAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "proposal"
       >>> expectConstantPathComponent "vote"
       >>> expectNoTrailingSlash
       >>> expectJSONContent "json",
       proposalVoteAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "proposal"
       >>> expectConstantPathComponent "add"
       >>> expectNoTrailingSlash
       >>> expectJSONContent "json",
       proposalAddAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "proposal"
       >>> expectVariablePathComponent "proposal_id" uuidParser
       >>> expectNoTrailingSlash
       >>> expectJSONContent "json",
       proposalDetailsAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "proposal"
       >>> expectVariablePathComponent "proposal_id" uuidParser
       >>> expectConstantPathComponent "update"
       >>> expectNoTrailingSlash
       >>> expectJSONContent "json",
       proposalUpdateAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "proposal"
       >>> expectVariablePathComponent "proposal_id" uuidParser
       >>> expectConstantPathComponent "delete"
       >>> expectNoTrailingSlash
       >>> expectJSONContent "json",
       proposalDeleteAPIHandler),

      (simpleRequestPattern "POST" $>> apiPrefix
       >>> expectConstantPathComponent "proposal"
       >>> expectVariablePathComponent "proposal_id" uuidParser
       >>> expectConstantPathComponent "submit"
       >>> expectNoTrailingSlash
       >>> expectJSONContent "json",
       proposalSubmitAPIHandler),

      (simpleRequestPattern "GET" $>> frontEndPrefix
       >>> expectTrailingSlash
       >>> expectNoContent,
       frontEndHandler),

      (simpleRequestPattern "GET" $>> frontEndPrefix
       >>> expectConstantPathComponent "confirm"
       >>> expectNoTrailingSlash
       >>> expectQueryVariable "code" confirmationCodeParser
       >>> expectNoContent,
       frontEndConfirmHandler)]

emailParser :: String -> Maybe Dynamic
emailParser input = do
  return $ toDyn input

uuidParser :: String -> Maybe Dynamic
uuidParser input = do
  uuid <- case reads input of
            [(uuid, "")] -> return uuid
            _ -> Nothing
  return $ toDyn (uuid :: UUID.UUID)

confirmationCodeParser :: String -> Maybe Dynamic
confirmationCodeParser input =
  decodeConfirmationCode input >>= return . toDyn

encodeConfirmationCode :: Bool -> BS.ByteString -> Maybe String
encodeConfirmationCode spaced byteString = do
  let (string, _, _) =
        foldl' (\(soFar, sum, nBits) byte ->
                   let sum' = Bits.shiftL sum 8 + fromIntegral byte
                       encode n = confirmationCodeCharacters !! n
                       takeSome (soFar, sum, nBits) =
                         if nBits >= 5
                           then takeSome
                                  (soFar ++ [encode $
                                              Bits.shiftR sum (nBits - 5)],
                                   sum Bits..&.
                                     (Bits.shiftR 1 (nBits - 5) - 1),
                                   nBits - 5)
                           else (soFar, sum, nBits)
                   in takeSome (soFar, sum', nBits + 8))
               ("" :: String, 0 :: Int, 0 :: Int)
               (BS.unpack byteString)
  if spaced
    then do
      let group1 = take 4 string
          group2 = take 4 $ drop 4 string
          group3 = take 4 $ drop 8 string
          group4 = drop 12 string
          spaced = group1 ++ " " ++ group2 ++ " " ++ group3 ++ " " ++ group4
      return spaced
    else return string

decodeConfirmationCode :: String -> Maybe BS.ByteString
decodeConfirmationCode string = do
  let bitBundles =
        foldl' (\soFar c ->
                  case elemIndex (Char.toLower c) confirmationCodeCharacters of
                    Nothing -> soFar
                    Just bitBundle -> soFar ++ [bitBundle])
               []
               string
  if length bitBundles /= 16
    then Nothing
    else return ()
  let (bytes, _, _) =
        foldl' (\(bytes, sum, nBits) bitBundle ->
                   let sum' = Bits.shiftL sum 5 + bitBundle
                   in if nBits + 5 >= 8
                       then (bytes ++ [fromIntegral $ sum' Bits..&. 0xFF],
                             Bits.shiftR sum' 8,
                             nBits + 5 - 8)
                       else (bytes, sum', nBits + 5))
               ([] :: [Word.Word8], 0 :: Int, 0 :: Int)
               bitBundles
  return $ BS.pack bytes

confirmationCodeCharacters :: String
confirmationCodeCharacters = "23456789abcdefghjkmnpqrstuvwxyz"

loginAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
loginAPIHandler variables = do
  HTTP.httpPutStr $ "Login placeholder."

logoutAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
logoutAPIHandler variables = do
  HTTP.httpPutStr $ "Logout placeholder."

confirmAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
confirmAPIHandler variables = do
  HTTP.httpPutStr $ "Confirm placeholder."

accountEmailListAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
accountEmailListAPIHandler variables = do
  HTTP.httpPutStr $ "Account email list placeholder."

accountEmailAddAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
accountEmailAddAPIHandler variables = do
  HTTP.httpPutStr $ "Account email add placeholder."

accountEmailDeleteAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
accountEmailDeleteAPIHandler variables = do
  HTTP.httpPutStr $ "Account email delete placeholder."

accountEmailSetPrimaryAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
accountEmailSetPrimaryAPIHandler variables = do
  HTTP.httpPutStr $ "Account email set primary placeholder."

playerListAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
playerListAPIHandler variables = do
  HTTP.httpPutStr $ "Player list placeholder."

ruleListAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
ruleListAPIHandler variables = do
  HTTP.httpPutStr $ "Rule list placeholder."

proposalListAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
proposalListAPIHandler variables = do
  HTTP.httpPutStr $ "Proposal list placeholder."

proposalVoteAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
proposalVoteAPIHandler variables = do
  HTTP.httpPutStr $ "Proposal vote placeholder."

proposalAddAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
proposalAddAPIHandler variables = do
  HTTP.httpPutStr $ "Proposal add placeholder."

proposalDetailsAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
proposalDetailsAPIHandler variables = do
  HTTP.httpPutStr $ "Proposal details placeholder."

proposalUpdateAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
proposalUpdateAPIHandler variables = do
  HTTP.httpPutStr $ "Proposal update placeholder."

proposalDeleteAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
proposalDeleteAPIHandler variables = do
  HTTP.httpPutStr $ "Proposal delete placeholder."

proposalSubmitAPIHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
proposalSubmitAPIHandler variables = do
  HTTP.httpPutStr $ "Proposal submit placeholder."

frontEndHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
frontEndHandler variables = do
  HTTP.setResponseHeader HTTP.HttpTransferEncoding "chunked"
  HTTP.httpPutStr $ "Front-end placeholder."

frontEndConfirmHandler
  :: (HTTP.MonadHTTP m) => Map.Map String Dynamic -> m ()
frontEndConfirmHandler variables = do
  HTTP.setResponseHeader HTTP.HttpTransferEncoding "chunked"
  let maybeCode :: Maybe BS.ByteString
      maybeCode = Map.lookup "code" variables >>= fromDynamic
  case maybeCode of
    Nothing -> HTTP.httpCloseOutput
    Just code -> do
      HTTP.httpPutStr $ "Front-end confirm placeholder."
                        ++ "\n" ++ (show $ encodeConfirmationCode True code)
                        ++ "\n" ++ "http://ireneknapp.com/qmic/confirm?code="
                        ++ (show $ encodeConfirmationCode False code)
                        ++ "\n" ++ (show $ encodeConfirmationCode True
                                     $ BS.pack $ take 16 $ repeat 0xAA)


text:
#ifndef RUN_TBCS_PPZKSNARK_HPP_
#define RUN_TBCS_PPZKSNARK_HPP_

#include "relations/circuit_satisfaction_problems/tbcs/examples/tbcs_examples.hpp"

namespace libsnark {

/**
 * Runs the ppzkSNARK (generator, prover, and verifier) for a given
 * TBCS example (specified by a circuit, primary input, and auxiliary input).
 *
 * Optionally, also test the serialization routines for keys and proofs.
 * (This takes additional time.)
 */
template<typename ppT>
bool run_tbcs_ppzksnark(const tbcs_example &example,
                        const bool test_serialization);

} // libsnark

#include "zk_proof_systems/ppzksnark/tbcs_ppzksnark/examples/run_tbcs_ppzksnark.tcc"

#endif // RUN_TBCS_PPZKSNARK_HPP_


text:
package io.lavoisier.model.fuel;

import javax.persistence.*;

import io.lavoisier.model.enumerated.ParameterType;
import io.lavoisier.model.fuel.pk.FuelParamPk;
import lombok.Data;

@Entity
@Table(name = "lav_fuel_output")
@Data
public class FuelOutput {
    @EmbeddedId
    private FuelParamPk id;

    @Enumerated(EnumType.STRING)
    @Column(name = "type", nullable = false, length = 10)
    private ParameterType type;
}


text:
({
  settsLinkClicked : function(component, event, helper) {
    helper.settsLinkClicked(component);
  },

  backfillLinkClicked : function(component, event, helper) {
    helper.backfillLinkClicked(component);
  },

  startBackfill : function(component, event, helper) {
    helper.startBackfill(component);
  },

})


text:
  Specify the repository to track. This can be a URL or a local file path.
  Note that for super-projects (repositories with submodules), only a local file
  path or a complete URL is valid.  The following are examples of valid git URLs.

ssh://git@github.com/github/git.git

git@github.com:github/git.git (short notation for ssh protocol)

ssh://user@other.host.com/~/repos/R.git (to access the repos/R.git
    repository in the user's home directory)

https://github.com/github/git.git

  If the repository is a super-project, the
  location from which to clone submodules is dependent on whether the repository
  is bare or non-bare (i.e. has a working directory).

If the super-project is bare, the location of the submodules will be
    taken from .gitmodules.

If the super-project is not bare, it is assumed that the
    repository has each of its submodules cloned and checked out appropriately.
    Thus, the submodules will be taken directly from a path like
    ${SUPER_PROJECT_URL}/${SUBMODULE}, rather than relying on
    information from .gitmodules.

  For a local URL/path to a super-project,
  git rev-parse --is-bare-repository
  is used to detect whether the super-project is bare or not.

  For a remote URL to a super-project, the ending of the URL determines whether
  a bare or non-bare repository is assumed:

If the remote URL ends with /.git, a non-bare repository is
    assumed.

If the remote URL does NOT end with /.git, a bare
    repository is assumed.


text:
import pytest
from ritoapi.rate_limit.rate_limit import RateLimit

@pytest.fixture()
def sample_api_key():
    with open('api_key.txt') as f:
        return f.readline().strip()

@pytest.fixture()
def sample_region():
    return 'na1'

@pytest.fixture()
def sample_endpoint_prefix():
    return 'spectator/v3/'

@pytest.fixture()
def sample_query_id():
    return 'featured-games'

@pytest.fixture()
def sample_base_url():
    return 'https://' + sample_region() + '.api.riotgames.com/lol/'

@pytest.fixture()
def sample_total_url():
    return sample_base_url() + sample_endpoint_prefix() + sample_query_id() + '?api_key=' + sample_api_key()

@pytest.fixture()
def sample_summoner_id():
    return 53109346

@pytest.fixture()
def sample_summoner_name():
    return 'Truffle Monster'

@pytest.fixture()
def sample_account_id():
    return 215665562

@pytest.fixture()
def sample_match_id():
    return 2549351071

@pytest.fixture()
def sample_rate_limit():
    return RateLimit(0.1)